SpringCloud - 服务注册与发现组件Eureka的使用详解5(区域配置、重试机制)
五、区域配置、重试机制
1,指定区域 Zone
我们可以通过 Eureka 实例的元数据配置来实现区域化的实例配置方案。比如:将处于不同机房的实例配置成不同的区域值,以作为跨区域的容错机制实现。
(1)服务提供者方面,只需要在服务实例的元数据中增加 zone 参数来指定自己所在的区域即可。下面通过 java -jar 命令行的方式启动两个不同端口、不同 zone 的 hello-service 服务:
java -jar hello-service.jar --server.port=8081 --eureka.instance.metadata-map.zone=beijing java -jar hello-service.jar --server.port=8082 --eureka.instance.metadata-map.zone=nanjing
(2)同样地,在服务消费者方面也在元数据中增加 zone 参数来指定自己所在的区域:
eureka.instance.metadata-map.zone=nanjing
(3)由于 Spring Cloud Ribbon 默认实现了区域亲和策略,消费者这边我们用同样用前文的方式(点击查看)调用 hello-service 里的服务。可以发现无论调用多少次,调用的都是同样属于 nanjing 这个 zone 的服务实例:
(4)当然也不是说其他区域的服务完全无法调用到。这里我们把区域为 nanjing 的服务实例关闭,再次让消费者调用 hello-service 里的服务,可以发现这次请求的是区域为 beijing 的服务:
Ribbon 内部会有一些专门的负载策略算法,虽然优先请求的是同一个 Zone 区域的服务实例。但在一些情况下:比如当不存在同区域的服务、活着同区域的服务负载过高...等等,仍会自动切换成其他区域的服务。
2,重试机制
由于 Spring Cloud Eureka 实现的服务治理机制强调了 CAP 原理中的 AP,即可用性与可靠性,牺牲了一定的一致性(在极端情况下它宁愿接受故障实例也不要丢掉"健康"实例)。但不论是由于触发了保护机制还是服务剔除的延迟,引起服务调用到故障实例的时候,我们还是希望能够增强对这类问题的容错。所以,我们在实现服务调用的时候通常会加入一些重试机制。
从 Camden SR2 版本开始,Spring Cloud 就整合了 Spring Retry 来增强 RestTemplate 的重试能力,对于开发者来说只需通过简单的配置,原来那些通过 RestTemplate 实现的服务访问就会自动根据配置来实现重试策略。
从 Camden SR2 版本开始,Spring Cloud 就整合了 Spring Retry 来增强 RestTemplate 的重试能力,对于开发者来说只需通过简单的配置,原来那些通过 RestTemplate 实现的服务访问就会自动根据配置来实现重试策略。
注意:spring.cloud.loadbalancer.retry.enabled 参数用来开启重试机制,因为默认是 true(开启)。因此只要引入 spring-retry 依赖就可以自动实现重试功能。如果要将其关闭,只要将其设为 false 即可。
<!-- 重试机制--> <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency>
(2)当然我们也可以在 application.properties 中对 ribbon 重试相关参数进行设置,这里还是以对 hello-service 服务的调用为例:
配置说明:当访问到故障请求的时候,它会再尝试访问一次当前实例(次数由 MaxAutoRetries 配置),如果不行,就换一个实例进行访问,如果还不行,再换一次实例访问(更换次数由 MaxAutoRetriesNextServer 配置),如果依然不行,返回失败信息。
#断路器的超时时长需要大于Ribbon的超时时间,不然不会触发重试
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000
#请求连接超时时间
hello-service.ribbon.ConnectTimeout=500
#请求处理的超时时间
hello-service.ribbon.ReadTimeout=1000
#对所有请求都进行重试(是否所有操作都重试,若false则仅get请求重试)
hello-service.ribbon.OkToRetryOnAllOperations=true
#切换实例的重试次数
hello-service.ribbon.MaxAutoRetriesNextServer=2
#对当前实例的重试次数
hello-service.ribbon.MaxAutoRetries=1
(3)上面仅仅是针对访问 hello-service 服务进行配置,我们也可以对 Ribbon 进行全局配置,这样就会对所有服务都有效:
#断路器的超时时长需要大于Ribbon的超时时间,不然不会触发重试
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000
#请求连接超时时间
ribbon.ConnectTimeout=500
#请求处理的超时时间
ribbon.ReadTimeout=1000
#对所有请求都进行重试(是否所有操作都重试,若false则仅get请求重试)
ribbon.OkToRetryOnAllOperations=true
#切换实例的重试次数
ribbon.MaxAutoRetriesNextServer=2
#对当前实例的重试次数
ribbon.MaxAutoRetries=1