当前位置:网站首页>微服务系统设计——子服务项目构建
微服务系统设计——子服务项目构建
2022-06-24 18:32:00 【庄小焱】
摘要
经过前期的需求分析和模型设计与系统架构设计,我们对项目的整体结构有了更清晰的认识,剩下的工作就是依据设计,将项目骨架拉出来,往里面直充血肉。构建起系统中的子微服务模块。
一、搭建整个项目骨架
约定项目名称为 parking-project ,建立 Maven 项目,packaging 方式 为 pom,用于管理所有模块。在 parking-project 项目下依据功能模块依次建立 maven module 子项目。采用 IDE工具。以 Maven Project 形式创建父项目,用于管理子模块功能。


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

简单介绍下各模块的功用:
- parking-base-serv,pom 项目,里面包含两个子模块:parking-admin,parking-gateway。
- parking-admin,监控子项目的运行情况。
- parking-gateway,网关子服务,配合 JWT 实现会话、验权等功用。
- parking-carwash,洗车子服务,连接 park-carwash 数据库。
- parking-card,积分子服务,连接 park-card 数据库。
- parking-charging,计费子服务,连接 parking-charging 存储库
- parking-finance,财务子服务,连接 parking-finance 存储库。
- parking-member,会员子服务,连接 park-member 存储库。
- parking-resource,资源子服务,连接 park-resource 存储库。
- parking-message,消息子服务,连接 park-message 存储库,连同 rocketmq 存储消息数据
- parking-common,存储通用的工具类,实体包等等。
二、创建会员子服务
2.1 引入 spring-boot-starter-parent 依赖
每个子模块都是一个 Spring Boot 项目,如果在子模块中引入,会造成大量的重复工作,而且版本不宜统一维护,容易出现多版本的混乱局面,所以 Spring Boot 的版本需要全局统一维护。每个子项目需要构建成 jar 文件运行,子项目中已经依赖父项目的配置,每个子项目 pom.xml 文件都有这样的依赖:
<parent>
<groupId>com.mall.parking.root</groupId>
<artifactId>parking-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>如果按照常见的方式,再用 parent 方式引入 spring-boot-starter-parent 依赖,显然违背单个 pom 文件中只有一个 parent 标签的标准,编译就会不通过。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>为解决这个问题,此处采用 parking-project 父项目中以 depencyMangement 方式引入 spring-boot-starter-parent,子项目依赖 parent 父配置即可。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>有小伙伴可能会提出直接在根项目的 pom 采用 parent 的方式引入,子模块直接通过 maven 依赖就可以,这种方式在独立运行 Spring Boot 项目时没问题。后续以同样的方式引入 Spring Cloud 或 Spring Cloud Alibaba ,一个 parent 标签显然不满足这个需求,用 dependencyManagement 的方式可以规避这个问题。
2.2 引入 MBG 插件
MBG 插件可以自动生成 mapper 接口、mapper xml 配置、相应实体类,主要作用在于快速开发,省去不必要的代码编写。
在 pom 中配置依赖 MBG 的插件:
<build>
<finalName>parking-member-service</finalName>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.4.0</version>
<configuration>
<!-- mybatis 用于生成代码的配置文件 -->
<configurationFile>src/test/resources/generatorConfig.xml</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
</plugins>
</build>在 src/test/resource 目录下写入 generatorConfig.xml 文件,配置 MBG 插件 所需的基本配置项。
<generatorConfiguration>
<!-- 本地 mysql 驱动位置 -->
<classPathEntry location="/Users/apple/.m2/repository/mysql/mysql-connector-java/5.1.42/mysql-connector-java-5.1.42.jar" />
<context id="mysqlTables" targetRuntime="MyBatis3">
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/park-member?useUnicode=true" userId="root"
password="root">
<property name="useInformationSchema" value="true"/>
</jdbcConnection>
<javaTypeResolver >
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- 生成 model 实体类文件位置 -->
<javaModelGenerator targetPackage="com.mall.parking.member.entity" targetProject="src/test/java">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- 生成 mapper.xml 配置文件位置 -->
<sqlMapGenerator targetPackage="mybatis.mapper" targetProject="src/test/resources">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- 生成 mapper 接口文件位置 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.mall.parking.member.mapper" targetProject="src/test/java">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- 需要生成的实体类对应的表名,多个实体类复制多份该配置即可 -->
<table tableName="member" domainObjectName="Member">
<generatedKey column="tid" sqlStatement="SELECT REPLACE(UUID(), '-', '')"/>
</table>
<table tableName="vehicle" domainObjectName="Vehicle">
<generatedKey column="tid" sqlStatement="SELECT REPLACE(UUID(), '-', '')"/>
</table>
<table tableName="month_card" domainObjectName="MonthCard">
<generatedKey column="tid" sqlStatement="SELECT REPLACE(UUID(), '-', '')"/>
</table>
</context>
</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 文件中维护组件版本。
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>在 application.properties 配置文件中设置数据库连接,Spring Boot 2.x 版本默认采用是 HikariCP 作为 JDBC 连接池。
mybatis.type-aliases-package=com.mall.parking.member.entity
#如果需要更换 Druid 连接池,需要增加如下的配置项:
#spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#use new driver replace deprecated driver:com.mysql.jdbc.Driver.
spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/park_member?useUnicode=true&characterEncoding=utf-8
spring.datasource.username = root
spring.datasource.password = root使 mapper 接口文件能够被系统扫描,在主类中通过@mapperscan注解,或直接在mapper接口文件上加@mapper注解。
2.6 测试框架是否成功
@RestController
@RequestMapping("member")
@Slf4j
public class MemberController {
@Autowired
MemberService memberService;
@RequestMapping("/list")
public List<Member> list() {
List<Member> members = memberService.list();
log.debug("query member list = " + members);
return members;
}
}
MemberServiceImpl 实现类
@Service
public class MemberServiceImpl implements MemberService {
@Autowired
MemberMapper memberMapper;
@Override
public List<Member> list() {
MemberExample example = new MemberExample();
List<Member> members = memberMapper.selectByExample(example);
return members;
}
}启动项目,成功后显示成功日志:
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 的多环境配置,可以在各微服务项目上增加多个配置文件,如
- application.properties/yml 基础公共配置
- application-dev.properties/yml 开发环境配置
- application-test.properties/yml 测试环境配置
- application-pro.properties/yml 生产环境配置
在公共配置文件 application.properties 中,通过配置 spring.profiles.active = dev 来决定启用哪个配置,或在启动构建包时,增加命令来激活不同的环境配置: java -jar parking-member.jar --spring.profiles.active=dev至此,第一个简单的 Spring Boot 模块搭建完成,下一步将 park-member 模块的正常业务功能编码完成即可。
博文参考
边栏推荐
- How can an enterprise successfully complete cloud migration?
- Keep two decimal places
- Easygbs video platform TCP active mode streaming exception repair
- Does the wave of layoffs in Chinese enterprises in 2021 need to be "judged" by morality?
- 2022 network security C module of the secondary vocational group scans the script of the surviving target aircraft (municipal, provincial and national)
- 中电投先融期货这家公司怎么样?期货开户办理安全吗?
- EasyGBS视频平台TCP主动模式拉流异常情况修复
- Redis series (3) - sentry highly available
- Issue 39: MySQL time class partition write SQL considerations
- 国家出手了!对知网启动网络安全审查
猜你喜欢

How to start cloud native application development

About pyqt5 to realize paging function (one window implements different interfaces)

Wechat applet development - Implementation of rotation chart

Constantly changing the emergency dialing of harmonyos ETS during the new year

Number of occurrences of numbers in the array (medium difficulty)
SQL basic tutorial (learning notes)

Architecture decryption from distributed to microservice: several common microservice architecture schemes

How do yaml files and zmail collide with the spark of the framework, and how can code and data be separated gracefully?

How to decompile APK files
An analysis of the comments on the TV series Douban by procedural apes
随机推荐
What is business intelligence (BI)?
RestCloud ETL抽取动态库表数据实践
Analysis on the issue of raising the right of MSSQL in 2021 secondary vocational group network security competition in Shandong Province
这个巡检平台你还不知道,真是亏大了!
[can you really use es] Introduction to es Basics (I)
Some knowledge of the beginning of 2022
Noi Mathematics: solution of quadratic congruence equation
Usage of typedef enum (enumeration)
Leetcode daily question solution: 717 1-bit and 2-bit characters - reverse order
Optimizing bloom filter: challenges, solutions, and comparisons
How does the chief information security officer discuss network security with the enterprise board of directors
Implementation of pure three-layer container network based on BGP
About swagger
Five advantages and disadvantages of Bi
基于BGP实现纯三层容器网络方案
How do yaml files and zmail collide with the spark of the framework, and how can code and data be separated gracefully?
Flutter dart regular regexp special characters $, () (IV)
Recommend a distributed JVM monitoring tool, which is very practical!
How can programmers reduce bugs in development?
【你真的会用ES吗】ES基础介绍(一)