服务已经停止,但eureka server不会剔除服务。
eurekaServer默认约定client需要30s发送一次心跳通信进行续约。
引入下面两个名词:
Renews threshold:server期望在每分钟中收到的心跳次数
Renews (last min):上一分钟内收到的心跳次数。
ex:eurekaServer每分钟会自己发一次心跳
所以threshold值为 1+2n,n为client个数。
renews/renews threshold:eureka.server.renewalPercentThreshold,默认为0.85,也就是实际比率低于85%,eureka将会进入保护模式。
保护模式:
在此状态下,server不会删除注册信息,这就有可能导致在调用微服务时,实际上服务并不存在。这种保护状态实际上是考虑了client和server之间的心跳是因为网络问题,而非服务本身问题,不能简单的删除注册信息。进入保护模式之后就会报这个警告。
解决方案:
1、在生产上可以开自注册,部署两个server
2、在本机器上测试的时候,可以把比值调低,比如0.49
3、或者简单粗暴把自我保护模式关闭
ex:如何处理服务挂掉后或者手动关闭服务后,Ribbon负载均衡还是一直调用这个服务:
1.Hystrix,在fallback方法中shutdown指定的服务
2.让zuul只路由到活着的那个服务:
添加依赖:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.6.0</version>
</dependency>
配置文件:
ribbon.connectTimeout: 2000
ribbon.readTimeout: 10000
ribbon.maxAutoRetries: 1
ribbon.maxAutoRetriesNextServer: 2
ribbon.okToRetryOnAllOperations: true
ribbon.okhttp.enabled: true
3.重试机制(和上述一个道理)
spring.cloud.loadbalancer.retry.enabled=true
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000
hello-service.ribbon.ConnectTimeout=250
hello-service.ribbon.ReadTimeout=1000
hello-service.ribbon.OkToRetryOnAllOperations=true
hello-service.ribbon.MaxAutoRetriesNextServer=2
hello-service.ribbon.MaxAutoRetries=1
spring.cloud.loadbalancer.retry.enabled:该参数用来开启重试机制,它默认是关闭的。这里需要注意,官方文档中的配置参数少了enabled
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds:断路器的超时时间需要大于ribbon的超时时间,不然不会触发重试。
hello-service.ribbon.ConnectTimeout:请求连接的超时时间
hello-service.ribbon.ReadTimeout:请求处理的超时时间
hello-service.ribbon.OkToRetryOnAllOperations:对所有操作请求都进行重试
hello-service.ribbon.MaxAutoRetriesNextServer:切换实例的重试次数
hello-service.ribbon.MaxAutoRetries:对当前实例的重试次数