【SpringCloud】05 Eureka 02 高可用与集群
Eureka集群环境搭建:
新建Eureka集群模块,模块名称:Eureka-Cluster-Server-Port-7002
导入7001依赖坐标:
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>cn.dzz.springcloud</groupId> <artifactId>API-Commons</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
Host文件地址:
C:\Windows\System32\drivers\etc
修改Host文件:
# Copyright (c) 1993-2009 Microsoft Corp. # # This is a sample HOSTS file used by Microsoft TCP/IP for Windows. # # This file contains the mappings of IP addresses to host names. Each # entry should be kept on an individual line. The IP address should # be placed in the first column followed by the corresponding host name. # The IP address and the host name should be separated by at least one # space. # # Additionally, comments (such as these) may be inserted on individual # lines or following the machine name denoted by a '#' symbol. # # For example: # # 102.54.94.97 rhino.acme.com # source server # 38.25.63.10 x.acme.com # x client host # localhost name resolution is handled within DNS itself. # 127.0.0.1 localhost # ::1 localhost 127.0.0.1 steamcommunity.com #S302 127.0.0.1 www.steamcommunity.com #S302 127.0.0.1 localhost.lodop.net 127.0.0.1 activate.navicat.com 127.0.0.1 eureka7001.cn # 2020.08.25 127.0.0.1 eureka7002.cn # 2020.08.25
配置Application.yml文件
server:
port: 7002
eureka:
instance:
hostname: eureka7002.cn
client:
fetch-registry: false
register-with-eureka: false
service-url:
defaultZone: http://eureka7001.cn:7001/eureka/
互相注册,相互守望

YML配置相互更换服务地址:
server:
port: 7001
eureka:
instance:
hostname: eureka7001.cn
client:
fetch-registry: false
register-with-eureka: false
service-url:
defaultZone: http://eureka7002.cn:7002/eureka/
编写主启动类:
package cn.dzz.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; /** * @author DaiZhiZhou * @file SpringCloud-ATGG-2020 * @create 2020-08-25 16:03 */ @SpringBootApplication @EnableEurekaServer public class EurekaClusterServerPort7002Application { public static void main(String[] args) { SpringApplication.run(EurekaClusterServerPort7002Application.class); } }
访问7002端口
http://eureka7002.cn:7002/

访问7001端口
http://eureka7001.cn:7001/

使用原始的这个localhost也可以是运行的
http://localhost:7001/ http://localhost:7002/
提供者支付模块和消费者订单模块注册到Eureka集群服务中心:
注册接口地址追加集群服务接口:
8001
eureka: client: service-url: defaultZone: http://localhost:7001/eureka/,http://eureka7002.cn:7002/eureka/ register-with-eureka: true fetch-registry: true
80
eureka: client: fetch-registry: true register-with-eureka: true service-url: defaultZone: http://localhost:7001/eureka/,http://eureka7002.cn:7002/eureka/
程序启动顺序
第一:服务中心必须先开启,7001 & 7002 这个集群内的先后顺序可以部分
第二:提供者8001开启
第三:消费者80开启
启动后访问服务,测试是否正常:
http://localhost/order/consumer/payment/get/2
访问7001可以发现服务都被注册到了
http://localhost:7001/

提供者支付模块集群
现在只是一个提供者支付模块,而我们需要搭建这个提供者支付模块集群
1、创建新模块,模块名称:Provider-Payment-Port-8002
2、Pom的坐标依赖与8001一致
3、application.yml和启动类更换下端口号8002
4、支付模块的集群都使用了Provider-Payment-Service作为服务名称,但是端口并不一致
更改8001模块的Controller配置:
获取端口号用于区分我们的模块调用,同理粘贴8002模块一份
package cn.dzz.springcloud.controller; import cn.dzz.springcloud.component.JsonResult; import cn.dzz.springcloud.entity.Payment; import cn.dzz.springcloud.service.PaymentService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; /** * @author ArkD42 * @file SpringCloud-ATGG-2020 * @create 2020年08月24日 21:28 */ @RestController @Slf4j @RequestMapping("payment") public class PaymentController { @Resource private PaymentService paymentService; @Value("${server.port}") private String serverPort; @PostMapping("create") public JsonResult<Object> createPayment(@RequestBody Payment payment){ int result = paymentService.addPayment(payment); log.info("插入操作结果:" + result); if (result > 0) return new JsonResult<Object>(200, "插入数据成功, 端口:" + serverPort, result); return new JsonResult<Object>(500, "插入数据失败 端口:" + serverPort, result); } @GetMapping("get/{id}") public JsonResult<Payment> getPaymentById(@PathVariable("id") Long id){ Payment paymentById = paymentService.getPaymentById(id); log.info("查询操作结果:" + paymentById + "用来测试热部署的修改"); if (paymentById != null) return new JsonResult<Payment>(200, "查询数据成功 端口:" + serverPort, paymentById); return new JsonResult<Payment>(500, "查询数据失败 端口:" + serverPort, null); } }
启动所有服务模块,查看Eureka界面:
http://eureka7001.cn:7001/

同理7002也是一样
http://eureka7002.cn:7002/
然后测试8002端口号:
http://localhost:8002/payment/get/2 {"code":200,"message":"查询数据成功 端口:8002","data":{"id":2,"serial":"aaabbb222"}}
原先的8001端口也正常:
http://localhost:8001/payment/get/2 {"code":200,"message":"查询数据成功 端口:8001","data":{"id":2,"serial":"aaabbb222"}}
但是通过消费者订单模块调用的时候,始终访问的都是8001端口模块的:
http://localhost/order/consumer/payment/get/2 {"code":200,"message":"查询数据成功 端口:8001","data":{"id":2,"serial":"aaabbb222"}}
这是因为订单模块控制器固定写死了8001的接口调用:

但是我们是希望集群的每一个都能被订单模块调用,所以通过Eureka我们应该使用注册中心的服务名称来实现
我们的集群共用了一个服务名称,通过服务名称,Eureka来自动帮助我们寻找集群的某一服务
// 单机单一模块调用 public static final String PAYMENT_URL = "http://localhost:8001";
// 集群调用则使用共同的服务名称来实现 public static final String PAYMENT_URL = "http://PROVIDER-PAYMENT-SERVICE";
重启所有服务之后,再次调用报错:
Caused by: java.net.UnknownHostException: PROVIDER-PAYMENT-SERVICE
服务并不知道这个名称是指向什么主机地址,发现Eureka不能像Nginx那样,
反向代理多少个集群就会自动分配权重,实现负载均衡
这里还需要我们来配置RestTemplate负载均衡:
打上@LoadBalanced注解
现在可以访问8002端口下的调用了:
http://localhost/order/consumer/payment/get/2 "code":200,"message":"查询数据成功 端口:8002","data":{"id":2,"serial":"aaabbb222"}}
Actuator服务信息完善:
对8001 & 8002 端口设置信息:
eureka: client: service-url: defaultZone: http://localhost:7001/eureka/,http://eureka7002.cn:7002/eureka/ register-with-eureka: true fetch-registry: true instance: instance-id: provider-payment-service-port-8001
访问Eureka界面,会发现我们的地址显示会换成ID显示
但是还好上面的没有替换
http://eureka7002.cn:7002/

当然80订单模块还没有配置,只显示了地址和服务名称
如需要查看具体IP地址,可以再配置这个属性,Eureka将不再显示ID名称,而是IP:
eureka: client: service-url: defaultZone: http://localhost:7001/eureka/,http://eureka7002.cn:7002/eureka/ register-with-eureka: true fetch-registry: true instance: instance-id: provider-payment-service-port-8002 prefer-ip-address: true
之后我们把光标扶上ID的时候,浏览器的左下角就会显示
这个IP地址:


浙公网安备 33010602011771号