Version: Next
Provider 微服务集群构建
目前框架
- 到现在为止,已经搭建好了
Eureka
注册中心集群- 实际提供服务的微服务,服务提供者,也应当是集群,防止单点宕机引起系统崩溃
参照
cloud-provider-payment8001
新建cloud-provider-payment8002
- pom:直接复制粘贴
application.yaml
- 端口为
8082
(将错就错)server:port: 8082spring:application:name: cloud-payment-servicedatasource:username: rootpassword: rooturl: jdbc:mysql://localhost:3306/springcloud?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8driver-class-name: com.mysql.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSourcemybatis:mapper-locations: classpath:mapper/*.xmlconfiguration:map-underscore-to-camel-case: true #驼峰映射log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #调试打印SQLeureka:client:#表示是否将自己注册进EurekaServer默认为trueregister-with-eureka: true#是否从EurekaServer抓取已有的注册消息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡fetch-registry: trueservice-url:#集群版defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/#单机版 入驻到这个地址(就是注册中心地址)# defaultZone: http://127.0.0.1:7001/eureka/
复制
mapper
文件夹和整个com
文件夹,修改主启动类的名称为PaymentMain8002
修改 Provider 微服务的 Controller
现在:同一个业务微服务可能存在多个节点,这些相同业务的不同节点之间使用相同的 Spring Application Name,他们之间使用
端口号
进行区分
- 在
Controller
中,添加成员变量String serverPort
,其值直接从application.yaml
中读取- 所有业务的成功响应信息中,都添加上当前端口号,用来显示是 Provider 集群中的哪个节点进行了业务响应
8001
和8002
两个微服务都要做上述修改
@Slf4j
@RestController
public class PaymentController {
@Resource
private PaymentService paymentService;
@Value("${server.port}") // 端口号
private String serverPort; // 从application.yaml中读取
@PostMapping("/payment/create")
public CommonResult<Integer> create(@RequestBody Payment payment) {
int result = paymentService.create(payment);
log.info("=====插入结果:" + result);
return result > 0 ? new CommonResult<>(200, "插入成功,端口号: " + serverPort, result)
: new CommonResult<>(444, "插入失败", null);
}
@GetMapping("/payment/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {
Payment payment = paymentService.getPaymentById(id);
return payment != null ? new CommonResult<>(200, "查询成功,端口号:" + serverPort, payment) :
new CommonResult<>(444, "查询失败", null);
}
}
测试
依次启动
7001
和7002
8001
和8002
80
访问任意 Eureka Server,可以看到 cloud-payment-service
有两个节点
直接访问两个 Provider Payment 微服务的URL,验证查询服务
- 访问
http://127.0.0.1:8081/payment/get/1
,确保得到正确响应- 访问
http://127.0.0.1:8082/payment/get/1
,确保得到正确响应
Provider 微服务集群负载均衡
现在我们希望通过
consumer-order80
来调用provider-payment8001
和8002
之前的
Order80
代码中,使用了RestTemplate
来远程调用provider-payment8001
微服务,其地址端口是写死的有了
Eureka Server
,不再写死,而是通过Eureka 注册中心
中暴露的应用名称 Application
来访问,注意区分大小学// 基于 Eureka Server Application 服务名称private static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";该URL地址还需要进一步被解析为具体的节点URL,并且还要具体到节点的端口号,目前的写法是无法解析的。需要在
Spring 配置类
中,使用@LoadBalanced
为RestTemplate
开启负载均衡
@Configurationpublic class ApplicationContextConfig {@Bean@LoadBalanced // 负载均衡public RestTemplate getRestTemplate() {return new RestTemplate();}}此处体现了,Eureka 是
客户端负载均衡
测试
多次访问
http://127.0.0.1:80/consumer/payment/get/4
- 本质是通过
consumer-order80
消费者 微服务,调用provider-payment
生产者 微服务集群- 可以看到响应信息中,有时是来自
payment8001
的响应,有时是来自payment8002
的响应
来自payment8001
{
"code": 200,
"message": "查询成功,端口号: 8081",
"data": {
"id": 4,
"serial": "长达004"
}
}
来自payment8002
{
"code": 200,
"message": "查询成功,端口号:8082",
"data": {
"id": 4,
"serial": "长达004"
}
}