一个标准的微服务制作
以一个咖啡小程序项目的订单模块为例,这个模块必将包括:
各种实体类(pojo,dto,vo....)
控制器 controller? 服务类service
......
其中控制器中有的接口需要提供给其他微服务,订单模块也需要其他微服务提供接口。
那么在项目开发和维护的过程中,如果一个模块里面的内容发生变动,相关的模块的业务也要修改,有种“牵一发而动全身”的感觉。(如订单模块修改了一个订单pojo里面的一个字段,那么用户模块用到这个订单pojo的所有业务也要同时修改,十分麻烦)
于是乎,我们需要将一个完整的微服务模块拆成三个部分
baoder_orders是项目的订单模块,它被拆成了三个部分
其中:
baoder_orders_model?:包含了订单模块要用的所有的实体类
baoder_orders_service?:包含了订单模块的所有的业务,它会调用baoder_orders_model
baoder_orders_api?:包含了订单模块向其他微服务暴露的接口(基于Feign的声明式的http客户端) 其他微服务可以通过引入?baoder_orders_api 来调用baoder_orders_service的服务
********************************************************************
那么这三个部分是怎么相互协作的呢?且看下文细细道来
*********************************************************
我们先分别分析三个部分的结构,最后再通过最上面的这个图来加深理解?
baoder_orders_model
目录结构如下,baoder_orders_model模块用于保存订单模块需要的所有实体类,包括统一封装结果,自定义异常等,异常拦截器仍然放在baoder_orders_service里面。
打开它的pom文件,可以看到它确确实实只是作为存储实体类的模块,甚至连bulid标签都没有
4.0.0
com.gmgx
baoder_orders_model
0.0.1-SNAPSHOT
baoder_orders_model
baoder_orders_model
com.gmgx
baoder_parent
0.0.1-SNAPSHOT
org.springframework.boot
spring-boot-starter
com.mysql
mysql-connector-j
runtime
org.projectlombok
lombok
true
com.baomidou
mybatis-plus-spring-boot3-starter
com.baomidou
mybatis-plus-generator
org.apache.velocity
velocity-engine-core
com.fasterxml.jackson.core
jackson-databind
我们需要做的事情就是让他被service和api引用,那么就需要把它安装到我们本地的maven仓库里面,需要的时候作为依赖在pom文件中引用即可。
执行完这三步后,去我们本地的maven仓库所在的文件夹里面,可以看到打包好的baoder_orders_model依赖
?baoder_orders_service
目录结构如下,baoder_orders_service包含了订单模块的所有业务,这个模块是要被打包发布到docker上的,所以会有有关docker的两个文件
打开application.properties文件,可以看到关于数据库,nacos,redis的相关配置。
其中数据库和redis是业务需要的
同时利用nacos将这个微服务注册到nacos注册中心上,服务名为baoder-orders-service
# 应用服务 WEB 访问端口
server.port=8090
# 数据库配置
spring.datasource.url=jdbc:mysql://192.168.2.222:3306/baoder-orders?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&connectTimeout=10000&socketTimeout=30000&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# Nacos帮助文档: https://nacos.io/zh-cn/docs/concepts.html
spring.application.name=baoder-orders-service
# Nacos认证信息
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discovery.password=nacos
# Nacos 服务发现与注册配置,其中子属性 server-addr 指定 Nacos 服务器主机和端口
spring.cloud.nacos.discovery.server-addr=192.168.2.222:8848
# 注册到 nacos 的指定 namespace,默认为 public
spring.cloud.nacos.discovery.namespace=public
# redis配置
spring.data.redis.host=192.168.2.222
spring.data.redis.database=0
?(重头戏)打开pom文件
4.0.0
com.gmgx
baoder_orders_service
0.0.1-SNAPSHOT
baoder_orders_service
baoder_orders_service
com.gmgx
baoder_parent
0.0.1-SNAPSHOT
org.springframework.boot
spring-boot-starter-web
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
com.mysql
mysql-connector-j
runtime
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
com.baomidou
mybatis-plus-boot-starter
com.github.xiaoymin
knife4j-openapi3-jakarta-spring-boot-starter
org.springframework.boot
spring-boot-starter-data-redis
org.apache.commons
commons-pool2
com.gmgx
baoder_orders_model
0.0.1-SNAPSHOT
org.apache.maven.plugins
maven-compiler-plugin
3.8.1
17
17
UTF-8
org.springframework.boot
spring-boot-maven-plugin
${spring-boot.version}
com.gmgx.BaoderOrdersServiceApplication
false
repackage
repackage
org.apache.maven.plugins
maven-surefire-plugin
2.4.2
true
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
false
可以看到我们刚才install到本地仓库的baoder_orders_model
?
我们随便打开一个服务,能看到baoder_orders_model里面的实体类已经被引进来了
这样一来,负责其他模块的同事们只需要拿到最新的baoder_orders_model,就可以愉快地做自己的模块了,只需要我把最新的?baoder_orders_model给他们,让他们在他们的本地仓库install就可以了。
baoder_orders_api(被调用方)
目录结构如下。baoder_orders_api 负责向其他调用者(其他微服务)提供baoder_service_api暴露出来的接口,我们需要详细说明这个模块是怎么做的,这就是SpringCloud中Feign组件的应用。
1.引入依赖
我们需要引入如下依赖(这两个依赖是feign要用的)
org.springframework.cloud
spring-cloud-starter-openfeign
org.springframework.cloud
spring-cloud-starter-loadbalancer
?最终的pom文件是这样的,声明http请求需要实体类,因此引入了baoder_orders_model?
其实只需要三个依赖(2+1)就行了,boot的依赖调用者肯定会有
4.0.0
com.gmgx
baoder_orders_api
0.0.1-SNAPSHOT
baoder_orders_api
baoder_orders_api
com.gmgx
baoder_parent
0.0.1-SNAPSHOT
org.springframework.cloud
spring-cloud-starter-openfeign
org.springframework.cloud
spring-cloud-starter-loadbalancer
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-test
test
com.gmgx
baoder_orders_model
0.0.1-SNAPSHOT
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.springframework.boot
spring-boot-dependencies
${spring-boot.version}
pom
import
org.apache.maven.plugins
maven-compiler-plugin
3.8.1
17
17
UTF-8
org.springframework.boot
spring-boot-maven-plugin
${spring-boot.version}
com.gmgx.BaoderOrdersApiApplication
true
repackage
repackage
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
false
2.写客户端接口?
package com.gmgx.api;
import com.gmgx.common.Result;
import com.gmgx.dto.OrderSearchDto;
import com.gmgx.dto.SubmitDto;
import com.gmgx.entity.Orders;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;
@FeignClient(
name = "baoder-orders-service",
contextId = "baoder-orders-service"
)
@Component
public interface OrdersClient {
static final String prefix = "order";
@PutMapping(prefix + "/cancel")
public Result
*************************************************************************************************************
?@FeignClient用于声明要调用哪个service,这个从service的配置文件里面找,即nacos注册的服务名(所有的微服务都要注册到nacos)
?要把这个接口注册成一个组件,这样调用方就可以通过@Resource 自动装配使用Feign客户端了
?
feign客户端的接口路径,访问方法,请求参数,返回值等要和service那边的控制器一样
?最后,baoder_orders_api也要被install到本地仓库,我们只需要把这个模块给需要调用我们接口的同事就可以了
调用api
现在用一个demo-useOrders项目来模拟baoder_orders_service的调用方
创建好项目后,打开它的pom文件
4.0.0
com.gmgx
demo-useOrders
0.0.1-SNAPSHOT
demo-useOrders
demo-useOrders
17
UTF-8
UTF-8
3.0.2
2022.0.0.0-RC2
2022.0.0-RC2
org.springframework.boot
spring-boot-starter-web
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
org.springframework.cloud
spring-cloud-starter-openfeign
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
com.github.xiaoymin
knife4j-openapi3-jakarta-spring-boot-starter
4.5.0
com.gmgx
baoder_orders_api
0.0.1-SNAPSHOT
com.gmgx
baoder_orders_model
0.0.1-SNAPSHOT
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.springframework.boot
spring-boot-dependencies
${spring-boot.version}
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
${spring-cloud-alibaba.version}
pom
import
org.apache.maven.plugins
maven-compiler-plugin
3.8.1
17
17
UTF-8
org.springframework.boot
spring-boot-maven-plugin
${spring-boot.version}
com.gmgx.DemoUseOrdersApplication
false
repackage
repackage
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
false
?导入的依赖如下(注意导入了api和model)
?控制器中直接注入就可以使用feign客户端了
applicaton.properties如下
# 应用服务 WEB 访问端口
server.port=8088
# Nacos帮助文档: https://nacos.io/zh-cn/docs/concepts.html
spring.application.name=useOrders-service
# Nacos认证信息
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discovery.password=nacos
# Nacos 服务发现与注册配置,其中子属性 server-addr 指定 Nacos 服务器主机和端口
spring.cloud.nacos.discovery.server-addr=192.168.2.222:8848
# 注册到 nacos 的指定 namespace,默认为 public
spring.cloud.nacos.discovery.namespace=public
# 数据库配置
spring.datasource.url=jdbc:mysql://192.168.2.222:3306/baoder-orders?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&connectTimeout=10000&socketTimeout=30000&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
现在把service和demo-useOrders都跑起来(我服务器已经部署了baoder_orders_service容器和demo-useOrders,但是本地连服务器访问会超时,干脆直接启动本地的service模块,效果是一样的)
?
***********************************************************************************************************
最后再回到这张图,思路是否清晰了点,这就是一个标准的微服务的制作流程。(其中baoder_orders_api和demo-useOrders那里用到了SpringCloud的feign组件)