Apache ServiceComb集成MyBatis使用GaussDB开源体验任务过程

举报
ftrybe 发表于 2024/12/15 18:04:59 2024/12/15
【摘要】 1. 体验项目介绍体验项目基于Apache ServiceComb Fence , 并针对For Huawei场景进行了少量优化。ServiceComb Fence是包含Java Chassis 3最佳实践的应用开发脚手架,它可以帮助开发者快速构建包含微服务后端、微服务前端和基础原子服务的项目工程。基于Fence,可以快速构建一个韧性、安全和敏捷的微服务项目工程。Fence的核心设计包括韧...

1. 体验项目介绍

体验项目基于Apache ServiceComb Fence , 并针对For Huawei场景进行了少量优化。ServiceComb Fence是包含Java Chassis 3最佳实践的应用开发脚手架,它可以帮助开发者快速构建包含微服务后端、微服务前端和基础原子服务的项目工程。

  • 基于Fence,可以快速构建一个韧性、安全和敏捷的微服务项目工程。Fence的核心设计包括韧性架构、安全认证、可观测性、过载防护等方面,它主要由如下几个微服务组成:
  • edge-service: 微服务网关。微服务网关负责接收用户的请求,并将请求转发给对应的微服务前端和微服务后端进行处理。微服务网关还负责认证鉴权、过载防护等方面的系统功能。
  • authentication-server: 认证服务。认证服务提供基于Oauth2的认证能力,实现了基础的用户、角色管理,认证和授权等功能。
  • resource-server: 资源服务。资源服务是一个示例项目,用户新开发的服务都属于资源服务,这个服务可以作为新增服务的模板。 资源服务实现了一些基础的鉴权功能,提供基于Yaml配置和Java Annotation声明的权限管理机制。
  • admin-service: 微服务管理服务。微服务管理服务提供微服务管理和系统运维功能。包括管理和查看服务列表、管理和查看服务配置、系统问题分析和定位能力。
  • admin-website: 微服务管理服务的前端。这是一个基于OpenTiny 开发的静态页面服务,实现微服务管理服务的Web前端。 它可以作为用户新增前端的模板,提供了基础的Web前端开发框架,包括菜单、导航等方便阅读和扩展的代码框架。

Fence项目遵循约定优于配置原则,定义了日志配置、Web配置、路由配置、代码结构等相关规范,以更加简洁的实现可观测性、过载防护等功能。

项目数据:Fork 819, Star 1.9K, Contributor 136,最近一次提交:2024-12-12

star历史(https://star-history.com/):

image.png

2.开发前的准备

2.1 准备阶段

开始之前,下载 WIKI[https://developer.huaweicloud.com/programs/opensource/contrib],根据README的步骤,本地编译和发布文档。阅读内容“Java示例项目-示例项目介绍”了解DEMO

2.2 克隆仓库

2.2.1 创建SSH公钥

在我使用时华为云开发者账号和gitcode账号不互通,需要重新注册账号。

完成登录后,点击右上角的个人头像进入个人设置界面。点击【安全设置】-【SSH公钥】添加当前计算机的SSH公钥以便后续免登录提交代码。如果当前系统还没生成过,请参考 如何生成SSH公钥

2.2.2 克隆项目

forkJava示例项目(https://gitcode.com/HuaweiCloudDeveloper/OpenSourceForHuaweiDemoJava.git)到自己的仓库。

git clone [你的gitcode地址]
cd OpenSourceForHuaweiDemoJava
mvn clean install

2.2.3 安装Docker

对于Windows/MacOS等拥有可视化环境的系统通过下载Docker Desktop(https://www.docker.com/get-started/)
对于Centos/Debian或者其他只使用终端的系统,安装请参考Docker Engine安装(https://docs.docker.com/engine/install/)

2.2.4 安装Zookeeper(必须)

使用docker安装Zookeeper

# 创建Zookeeper目录
mkdir /opt/zookeeper
# 进入目录
cd /opt/zookeeper
#创建docker-compose.yml文件
nano docker-compose.yml

docker-compose.yml文件如下:


version: '3'

services:
  zoo1:
    image: zookeeper
    hostname: zoo1
    ports:
      - 2181:2181

额外配置请自行修改

# 启动opengauss
dockers compose up -d

使用docker ps检查服务运行状态

2.2.5 安装OpenGauss(可选)

OpenGauss可使用物理机安装或Docker安装。在本文中使用Docker安装OpenGauss。物理机安装请参考OpenGauss安装准备

使用docker安装OpenGauss

# 创建OpenGauss目录
mkdir /opt/opengauss
# 进入目录
cd /opt/opengauss
# 创建挂载目录
mkdir db
# 编写docker-compose.yml文件
nano docker-compose.yml

docker-compose.yml文件内容如下:

version: "3"
services:
  open_gauss:
    image: enmotech/opengauss-lite:latest
    environment:
      GS_PASSWORD: Admin123##
      #GS_USERNAME: gaussdb
      GS_PORT: 5432
    volumes:
      - ./db:/var/lib/opengauss
    ports:
      - '8000:5432'

如果需要更改端口或者opengauss的账号和密码请自行修改。

# 启动opengauss
dockers compose up -d

使用docker ps检查服务运行状态

3. 开发

在环境安装完成后。可以着手进行项目开发了。项目模块架构如下:
架构图
(https://huaweicse.github.io/servicecomb-java-chassis-doc/java-chassis/zh_CN/best-practise/fence-deploy.png)

具体信息请查看韧性架构设计

3.1 初始化数据库

authentication-server依赖数据库,找到 src/resource/sql/user.sql,在数据库执行该初始化脚本。

3.2 修改数据库配置

项目配置中的数据库默认账户密码都为:root, 请修改对应yml中的配置信息。全局检索DB_USERNAME就可以找到。

3.3 代码开发

WIKI中存在一个DEMO的开发示例。可以先看看。

3.3.1 设计表结构

create table t_user_hair
(
    id         serial  not null
        constraint t_user_hair_pk
            primary key,
    user_name  varchar(50) not null,
    hair_color varchar(50),
    hair_count bigint,
    hair_type  varchar(50)
);

3.3.2 创建实体类

apis/resource-server-api/src/main/java/org/apache/servicecomb/fence/api/resource下创建以下实体类

public class UserHair {
    private int id;

    private String userName;

    private long hairCount;

    private String hairColor;

    private String hairType;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }


    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public long getHairCount() {
        return hairCount;
    }

    public void setHairCount(long hairCount) {
        this.hairCount = hairCount;
    }

    public String getHairColor() {
        return hairColor;
    }

    public void setHairColor(String hairColor) {
        this.hairColor = hairColor;
    }

    public String getHairType() {
        return hairType;
    }

    public void setHairType(String hairType) {
        this.hairType = hairType;
    }

    @Override
    public String toString() {
        return "UserHair [id=" + id + ", userName=" + userName + ", hairCount=" + hairCount + ", hairColor=" + hairColor
                + ", hairType=" + hairType + "]";
    }

}

3.3.2 新增加一个REST接口

apis/resource-server-api/.../resource下创建

@RequestMapping(path = "/v1/user/hair")
public interface UserHairService {
    @PostMapping(path = "/")
    int createUserHair(@RequestBody UserHair userHair);

    @PutMapping(path = "/{id}")
    int updateUserHair(@PathVariable("id") int id, @RequestBody UserHair userHair);

    @DeleteMapping(path = "/{id}")
    int deleteUserHair(@PathVariable("id") int id);

    @GetMapping(path = "/{id}")
    UserHair getUserHair(@PathVariable("id") int id);

    @GetMapping(path = "/")
    List<UserHair> getAllUserHair();

    @GetMapping(path = "/search")
    List<UserHair> searchUserHair(
            @RequestParam(value = "hairColor", required = false) String hairColor,
            @RequestParam(value = "hairType", required = false) String hairType,
            @RequestParam(value = "minHairCount", required = false) Long minHairCount);

}

3.3.3 实现REST接口

resource-server/src/.../resource/userHair下创建


@RestSchema(schemaId = "UserHairEndpoint", schemaInterface = UserHairService.class)
public class UserHairEndpoint implements UserHairService {

    @Autowired
    private UserHairMapper userHairMapper;

    @Override
    public int createUserHair(UserHair userHair) {
        return userHairMapper.insert(userHair);
    }

    @Override
    public int updateUserHair(int id, UserHair userHair) {
        userHair.setId(id);
        return userHairMapper.update(userHair);
    }

    @Override
    public int deleteUserHair(int id) {
        return userHairMapper.deleteById(id);
    }

    @Override
    public UserHair getUserHair(int id) {
        return userHairMapper.getById(id);
    }

    @Override
    public List<UserHair> getAllUserHair() {
        return userHairMapper.getAll();
    }

    @Override
    public List<UserHair> searchUserHair(String hairColor, String hairType, Long minHairCount) {
        return userHairMapper.search(hairColor, hairType, minHairCount);
    }

}

3.4.4 编写数据库查询语句

resource-server/.../resource/userHair下创建


@Mapper
public interface UserHairMapper {
    @Insert("INSERT INTO t_user_hair (user_name, hair_count, hair_color, hair_type) VALUES (#{userName}, #{hairCount}, #{hairColor}, #{hairType})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insert(UserHair userHair);

    @Update("UPDATE t_user_hair SET user_name = #{userName}, hair_count = #{hairCount}, hair_color = #{hairColor}, hair_type = #{hairType} WHERE id = #{id}")
    int update(UserHair userHair);

    @Delete("DELETE FROM t_user_hair WHERE id = #{id}")
    int deleteById(int id);

    @Select("SELECT * FROM t_user_hair WHERE id = #{id}")
    UserHair getById(int id);

    @Select("SELECT * FROM t_user_hair")
    List<UserHair> getAll();

    @Select("""
    <script>
    SELECT * FROM t_user_hair WHERE 1=1
    <if test="hairColor != null and hairColor != ''"> AND hair_color = #{hairColor}</if>
    <if test="hairType != null and hairType != ''"> AND hair_type = #{hairType}</if>
    <if test="minHairCount != null"> AND hair_count >= #{minHairCount}</if>
    </script>""")
    List<UserHair> search(@Param("hairColor") String hairColor,
                          @Param("hairType") String hairType,
                          @Param("minHairCount") Long minHairCount);
}

注意,因为没有添加字段映射说明,查询出来的数据不会自动匹配实体类中驼峰式命名的数据。需要添加额外的yaml配置.请在当前模块下的application.yml中添加以下配置

mybatis:
  configuration:
    map-underscore-to-camel-case: true

3.4.5 前端编写

前端编写不在此进行详细讲述。在WIKI中有详细的介绍。前端组件地址opentiny(https://opentiny.design/tiny-vue/zh-CN/os-theme/overview)

开发过程中需要注意以下问题:

  1. 添加菜单后请修改/components/menu/index.vue组件中的内容,不然界面上的菜单Label不会展示国际化内容
  2. 直接使用node运行前端开发调试时,请注意取消edge-service模块的WebsiteConfiguration和 前端根目录下tiny.config.js文件中的注释。

4.部署

4.1 云服务资源购买

4.1.1 购买Gaussdb

在华为云官网,搜索Gaussdb,选择云数据库GaussDB,点击购买
image.png
点击购买后,根据自身需要选择合适的配置。我的测试配置如下:
image.png

注意,使用控制台导入SQL脚本时在左上角选择对应的Schema.

4.1.2 购买CCE

在华为云官网,搜索cce,选择云容器引擎cee。点击购买集群
image.png
我的配置如下:
image.png

  • 虚拟私有云:需要与gaussdb中选择的一致
  • 容器子网(Pod CIDR):需要与gaussdb中选择的一致
  • 其他默认,点击提交。进入插件选择页面。
  • 保持默认插件,点击插件配置,点击确认配置,点击提交。
  • 创建节点池 时注意选择 Euler操作系统
  • 因为编译Docker镜像时使用的是ARM64架构,注意选择鲲鹏的CPU
  • 配置推荐8核16G起步,不然可能实例数不够导致服务启动失败
  • 配置不足时请在节点池添加新的节点

4.2 配置CodeArts

根据华为云提供的文档(https://gitcode.com/HuaweiCloudDeveloper/OpenSourceForHuaweiWiki/blob/main/zh_CN/docs/cicd-pipeline.md),配置CodeArts。

  1. 搜索CodeArts后。控制台入口如下:
    image.png

  2. 创建Scrumn项目
    image.png

  3. 导入代码仓库
    1.选择代码源GitCode
    2.不存在扩展点的话需要新建扩展点。 进入创建访问令牌(https://gitcode.com/setting/token-classic)创建个人令牌。名称随意,到期日期自己选择,其他配置默认就好。
    3.复制个人令牌到扩展点中
    image.png
    4.保存配置,选择你的项目

  4. 剩下步骤请查看华为云提供的文档

成果访问

访问 http://113.45.144.205:9090/ui/admin/ 进入主页。
在本次测试中,我添加了一个头发管理的测试服务
image.png

可以使用编辑将管理员头发更新为0.
image.png

强者不需要头发。

我的项目地址: 点击跳转到我的项目(https://gitcode.com/linkicu/OpenSourceForHuaweiDemoJava/overview)

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。