• 微服务系统设计——子服务项目构建


    摘要

    经过前期的需求分析和模型设计与系统架构设计,我们对项目的整体结构有了更清晰的认识,剩下的工作就是依据设计,将项目骨架拉出来,往里面直充血肉。构建起系统中的子微服务模块。

    一、搭建整个项目骨架

    约定项目名称为 parking-project ,建立 Maven 项目,packaging 方式 为 pom,用于管理所有模块。在 parking-project 项目下依据功能模块依次建立 maven module 子项目。采用 IDE工具。以 Maven Project 形式创建父项目,用于管理子模块功能。

    可以看到,子模块自动将 parent project 设置为 parking-project 父项目。由于是采用 Spring Boot 的方式构建子项目,此处选择 packaging 方式为 jar 。依此连续创建各种子模块即可,最终的结果如下:

    简单介绍下各模块的功用:

    1. parking-base-serv,pom 项目,里面包含两个子模块:parking-admin,parking-gateway。
    2. parking-admin,监控子项目的运行情况。
    3. parking-gateway,网关子服务,配合 JWT 实现会话、验权等功用。
    4. parking-carwash,洗车子服务,连接 park-carwash 数据库。
    5. parking-card,积分子服务,连接 park-card 数据库。
    6. parking-charging,计费子服务,连接 parking-charging 存储库
    7. parking-finance,财务子服务,连接 parking-finance 存储库。
    8. parking-member,会员子服务,连接 park-member 存储库。
    9. parking-resource,资源子服务,连接 park-resource 存储库。
    10. parking-message,消息子服务,连接 park-message 存储库,连同 rocketmq 存储消息数据
    11. parking-common,存储通用的工具类,实体包等等。

    二、创建会员子服务

    2.1 引入 spring-boot-starter-parent 依赖

    每个子模块都是一个 Spring Boot 项目,如果在子模块中引入,会造成大量的重复工作,而且版本不宜统一维护,容易出现多版本的混乱局面,所以 Spring Boot 的版本需要全局统一维护。每个子项目需要构建成 jar 文件运行,子项目中已经依赖父项目的配置,每个子项目 pom.xml 文件都有这样的依赖:

    1. <parent>
    2. <groupId>com.mall.parking.root</groupId>
    3. <artifactId>parking-project</artifactId>
    4. <version>0.0.1-SNAPSHOT</version>
    5. </parent>

    如果按照常见的方式,再用 parent 方式引入 spring-boot-starter-parent 依赖,显然违背单个 pom 文件中只有一个 parent 标签的标准,编译就会不通过。

    1. <parent>
    2. <groupId>org.springframework.boot</groupId>
    3. <artifactId>spring-boot-starter-parent</artifactId>
    4. <version>2.2.2.RELEASE</version>
    5. <relativePath/> <!-- lookup parent from repository -->
    6. </parent>

    为解决这个问题,此处采用 parking-project 父项目中以 depencyMangement 方式引入 spring-boot-starter-parent,子项目依赖 parent 父配置即可。

    1. <dependencyManagement>
    2. <dependencies>
    3. <dependency>
    4. <groupId>org.springframework.boot</groupId>
    5. <artifactId>spring-boot-dependencies</artifactId>
    6. <version>${spring.boot.version}</version>
    7. <type>pom</type>
    8. <scope>import</scope>
    9. </dependency>
    10. </dependencies>
    11. </dependencyManagement>

    有小伙伴可能会提出直接在根项目的 pom 采用 parent 的方式引入,子模块直接通过 maven 依赖就可以,这种方式在独立运行 Spring Boot 项目时没问题。后续以同样的方式引入 Spring Cloud 或 Spring Cloud Alibaba ,一个 parent 标签显然不满足这个需求,用 dependencyManagement 的方式可以规避这个问题。

    2.2 引入 MBG 插件

    MBG 插件可以自动生成 mapper 接口、mapper xml 配置、相应实体类,主要作用在于快速开发,省去不必要的代码编写。

    在 pom 中配置依赖 MBG 的插件:

    1. <build>
    2. <finalName>parking-member-service</finalName>
    3. <plugins>
    4. <plugin>
    5. <groupId>org.mybatis.generator</groupId>
    6. <artifactId>mybatis-generator-maven-plugin</artifactId>
    7. <version>1.4.0</version>
    8. <configuration>
    9. <!-- mybatis 用于生成代码的配置文件 -->
    10. <configurationFile>src/test/resources/generatorConfig.xml</configurationFile>
    11. <verbose>true</verbose>
    12. <overwrite>true</overwrite>
    13. </configuration>
    14. </plugin>
    15. </plugins>
    16. </build>

    在 src/test/resource 目录下写入 generatorConfig.xml 文件,配置 MBG 插件 所需的基本配置项。

    1. <generatorConfiguration>
    2. <!-- 本地 mysql 驱动位置 -->
    3. <classPathEntry location="/Users/apple/.m2/repository/mysql/mysql-connector-java/5.1.42/mysql-connector-java-5.1.42.jar" />
    4. <context id="mysqlTables" targetRuntime="MyBatis3">
    5. <jdbcConnection driverClass="com.mysql.jdbc.Driver"
    6. connectionURL="jdbc:mysql://localhost:3306/park-member?useUnicode=true" userId="root"
    7. password="root">
    8. <property name="useInformationSchema" value="true"/>
    9. </jdbcConnection>
    10. <javaTypeResolver >
    11. <property name="forceBigDecimals" value="false" />
    12. </javaTypeResolver>
    13. <!-- 生成 model 实体类文件位置 -->
    14. <javaModelGenerator targetPackage="com.mall.parking.member.entity" targetProject="src/test/java">
    15. <property name="enableSubPackages" value="true" />
    16. <property name="trimStrings" value="true" />
    17. </javaModelGenerator>
    18. <!-- 生成 mapper.xml 配置文件位置 -->
    19. <sqlMapGenerator targetPackage="mybatis.mapper" targetProject="src/test/resources">
    20. <property name="enableSubPackages" value="true" />
    21. </sqlMapGenerator>
    22. <!-- 生成 mapper 接口文件位置 -->
    23. <javaClientGenerator type="XMLMAPPER" targetPackage="com.mall.parking.member.mapper" targetProject="src/test/java">
    24. <property name="enableSubPackages" value="true" />
    25. </javaClientGenerator>
    26. <!-- 需要生成的实体类对应的表名,多个实体类复制多份该配置即可 -->
    27. <table tableName="member" domainObjectName="Member">
    28. <generatedKey column="tid" sqlStatement="SELECT REPLACE(UUID(), '-', '')"/>
    29. </table>
    30. <table tableName="vehicle" domainObjectName="Vehicle">
    31. <generatedKey column="tid" sqlStatement="SELECT REPLACE(UUID(), '-', '')"/>
    32. </table>
    33. <table tableName="month_card" domainObjectName="MonthCard">
    34. <generatedKey column="tid" sqlStatement="SELECT REPLACE(UUID(), '-', '')"/>
    35. </table>
    36. </context>
    37. </generatorConfiguration>

    配置完成后,在项目名称” parking-member “ 上右键,弹出菜单中选择" Run As " —>" Maven build… ",在 Goals 栏目中输入如下命令:

    mybatis-generator:generate

    命令执行成功后,在对应的目录下找到相应的文件,而后 copy 到 src/java 对应的目录下,再将 test目录下生成的文件删除。

    • 1.4 版本之前的,MBG 插件生成的 xml 文件,是追加模式,而不是覆盖,容易形成重复的标签。
    • MBG 并不会生成 controller/service 层相关的代码,需要自己手动完成。

    2.3 引入 Lombok,简化代码

    由于编译阶段就要使用 lombok,所以需要在 IDE 中安装 lombok 插件,才能正常编译。

    2.4 日志注解

    如果不想每次都写,可以用注解@sl4j来打印日志。

    private  final Logger logger = LoggerFactory.getLogger(当前类名.class);

    2.5 引入MyBatis依赖

    更高效的引入MyBatis,这里采用 starter 的方式引入,同样在根pom.xml 文件中维护组件版本。

    1. <dependency>
    2. <groupId>org.mybatis.spring.boot</groupId>
    3. <artifactId>mybatis-spring-boot-starter</artifactId>
    4. </dependency>
    5. <dependency>
    6. <groupId>mysql</groupId>
    7. <artifactId>mysql-connector-java</artifactId>
    8. </dependency>

    在 application.properties 配置文件中设置数据库连接,Spring Boot 2.x 版本默认采用是 HikariCP 作为 JDBC 连接池。

    1. mybatis.type-aliases-package=com.mall.parking.member.entity
    2. #如果需要更换 Druid 连接池,需要增加如下的配置项:
    3. #spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    4. #use new driver replace deprecated driver:com.mysql.jdbc.Driver.
    5. spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver
    6. spring.datasource.url = jdbc:mysql://localhost:3306/park_member?useUnicode=true&characterEncoding=utf-8
    7. spring.datasource.username = root
    8. spring.datasource.password = root

    使 mapper 接口文件能够被系统扫描,在主类中通过@mapperscan注解,或直接在mapper接口文件上加@mapper注解。

    2.6 测试框架是否成功

    1. @RestController
    2. @RequestMapping("member")
    3. @Slf4j
    4. public class MemberController {
    5. @Autowired
    6. MemberService memberService;
    7. @RequestMapping("/list")
    8. public List<Member> list() {
    9. List<Member> members = memberService.list();
    10. log.debug("query member list = " + members);
    11. return members;
    12. }
    13. }

    MemberServiceImpl 实现类

    1. @Service
    2. public class MemberServiceImpl implements MemberService {
    3. @Autowired
    4. MemberMapper memberMapper;
    5. @Override
    6. public List<Member> list() {
    7. MemberExample example = new MemberExample();
    8. List<Member> members = memberMapper.selectByExample(example);
    9. return members;
    10. }
    11. }

    启动项目,成功后显示成功日志:

    2019-12-30 16:45:13.496  INFO 9784 --- [           main] c.mall.parking.member.MemberApplication  : Started MemberApplication in 6.52 seconds (JVM running for 7.753)

    打开 Postman 插件,测试刚才的方法是否正常,操作如下:

    2.7 多环境配置

    日常产品研发中必然涉及到多部署的问题,比如开发环境、测试环境、生产环境等,这就要求代码部署能够应对多环境的要求。通过人工修改的方式,不但容易出错,也会浪费人力成本,必须结合自动化构建来提高准确性。Spring Boot 提供了基于 profile 的多环境配置,可以在各微服务项目上增加多个配置文件,如

    1. application.properties/yml 基础公共配置
    2. application-dev.properties/yml 开发环境配置
    3. application-test.properties/yml 测试环境配置
    4. application-pro.properties/yml 生产环境配置

    在公共配置文件 application.properties 中,通过配置 spring.profiles.active = dev 来决定启用哪个配置,或在启动构建包时,增加命令来激活不同的环境配置: java -jar parking-member.jar --spring.profiles.active=dev至此,第一个简单的 Spring Boot 模块搭建完成,下一步将 park-member 模块的正常业务功能编码完成即可。

    博文参考

  • 相关阅读:
    java计算机毕业设计线上竞赛训练系统录屏源程序+mysql+系统+lw文档+远程调试
    数据监测都可以监测啥
    12.WPF动画
    2023江西国际餐饮产业博览会/赣菜文化全国推介大会
    CAD Exchanger SDK 3.13 Crack
    智能语法编辑器市场现状及未来发展趋势分析
    如何安全的进行数据获取!!
    好心情精神心理科医生:青春期孩子的心理特征
    【Python性能优化实例】计算 numpy 数组首尾为 0 的数量
    RESTful风格介绍
  • 原文地址:https://blog.csdn.net/weixin_41605937/article/details/125440834