SpringCloud详细教程4-Eureka集群的构建
学习之前小问题:
微服务RPC远程调用最核心的是什么?懂得略过。
核心:高可用
原因:假如,你的注册中心只有一个,那么当它宕机了之后,整个服务环境都不可用,其带来的后果不言而喻。
解决办法:搭建Eureka注册中心集群,实现负载均衡+故障容错
Eureka-服务注册:将服务信息注册进注册中心
Eureka-服务发现:从注册中心获取服务信息
其实质,也就是存key->服务名,取value->调用地址
OK、言归正传
一、Eureka集群注册中心互相注册,相互守望。
二、新建一个moudle:cloud-eureka-server7002
- 编辑POM.XML(需要依赖同7001)
- 修改映射配置:
由于我们application.yml中eureka.instance.hostname,你不可能都叫localhost吧,为了区分,我们可以去C:\Windows\System32\drivers\etc路径下找到hosts文件,在其中添加:
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
- 创建并编辑application.yml
在修改7002之前呢,由于我们是集群配置,yml文件的写法较之之前稍有不同,我们先去修改7001的YML:
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com #eureka 服务端的实例名称
client:
#false 表示不向注册中心注册自己
register-with-eureka: false
#flase 表示自己就是注册中心,自己只负责维护服务实例,并不需要去检索服务
fetch-registry: false
service-url:
defaultZone: http://eureka7002.com:7002/eureka/
看到7001的ynl后其实7002就很清晰了,两者互相注册就可以了。节省空间,这里就不在展示7002了。
- 此时可以打开浏览器,查看哦。图就不截了。
- 将我们的8001、80注册进注册中心,只需要一步,修改yml。
service-url:
#defaultZone: http://localhost:7001/eureka/ # 注册地址 单机版
defaultZone: http://eureka7001.com:7001/eureka/ ,http://eureka7002.com:7002/eureka/ # 注册地址 集群
三、建一个支付模块的moudle:cloud-spring-payment8002,源代码基本与8001相同。可以直接copy,但是注意修改yml中的端口号哦。完成后也是注册到注册中心,这个时候不用修改spring-application-name。
- 建好8002之后,我们直接运行,测试8002是否可行。通过后,运行80,为了让我们可以清楚的看到我们调用的是哪一个支付模块,我们在80的controller层返回值出加上我们访问的端口号:
1. 在8001、8002的controller层,创建下面的属性,并使用value注解注入我们yml中的server端口号
@Value("${server.port}")
private String serverPost;
2. 在返回值处,添加上端口号:
@GetMapping(value = "/payment/getPaymentById/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {
Payment payment = paymentService.getPaymentById(id);
log.info("******查询结果:" + payment);
if (payment != null) {
return new CommonResult<>(200, "查询数据库成功+serverPost:"+serverPost, payment);
} else {
return new CommonResult<>(444, "没有查询到数据,查询ID:" + id+",serverPost:"+serverPost, null);
}
}
-
打开浏览器,我们先查看注册中心是否注册了我们的服务。然后输入我们要访问的地址:先测试8001、8002是否畅通。在测试80.
-
8001、8002测试通过的情况下测试80,此时可以查询到结果
{"code":200,"message":"查询数据库成功+serverPost:8001","data":{"id":1,"serial":"202103041827"}}
- 查询出结果后,刷新,但是不论怎么刷新怎么访问,我们访问的永远都是我们的8001端口。原因在哪呢?
哦,对了,我们是不是在80的controller层吧我们的访问地址写死了啊:
public static final String PAYMENT_URL = "http://localhost:8001";
4.都写死了怎么搞?当然是要修改了,但是修改成什么呢?这个时候啊,我们就不能再用写死的服务端口号了,我们该用服务的名称来访问。
public static final String PAYMENT_URL = "http://CLOUD-SPRING-PAYMENT"
CLOUD-SPRING-PAYMENT为你注册的微服务名,可以直接去打开的eureka复制,粘贴过来。
5.修改完成后,8001、8002测试通过的情况下测试80.此时哎呀,出现了错误:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sun Mar 07 21:01:11 CST 2021
There was an unexpected error (type=Internal Server Error, status=500).
I/O error on GET request for "http://CLOUD-SPRING-PAYMENT/payment/getPaymentById/1": CLOUD-SPRING-PAYMENT; nested exception is java.net.UnknownHostException: CLOUD-SPRING-PAYMENT
org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://CLOUD-SPRING-PAYMENT/payment/getPaymentById/1": CLOUD-SPRING-PAYMENT; nested exception is java.net.UnknownHostException: CLOUD-SPRING-PAYMENT
这是什么呢?错误指明->找不到服务名称为: CLOUD-SPRING-PAYMENT 的服务。
- 为什么呢?这个我们服务名称为:CLOUD-SPRING-PAYMENT 的里边有两个支付模块,8001、8002,他不知道你要访问的是哪一个端口号的模块。此时,我们就要使用@LoadBalanced 注解来开启我们的负载均衡功能。负载均衡主要是使用轮询的方式来访问。在80模块的ApplicationContextConfig类修改为:
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
7.此时再去访问:http://localhost/consmuer/payment/getPaymentById/1 结果:
第一次:
{"code":200,"message":"查询数据库成功+serverPost:8001","data":{"id":1,"serial":"202103041827"}}
刷新:
{"code":200,"message":"查询数据库成功+serverPost:8002","data":{"id":1,"serial":"202103041827"}}
可以看到我们访问的端口号改变了,也就证明我们的负载均衡生效了,8001、8002端口交替使用。
四、总结
Eureka集群服务,主要原理就是通过注册与发现,来使我们的服务的容错率更高,不会发生一个服务宕机,全体崩盘的事情。使用负载均衡来降低我们单个服务的承载量。
学无以致用,学之可惜。学习的时间是弥足珍贵的,不可浪费一丝一毫。
人天性是懒惰的,但也是勤劳的。这一切的一切,都只在我们的一念之间。