前面介绍的springcloud相关组件,都是springcloude第一代的产品。 在使用过程中可能会遇到一些问题,下面介绍一下:
1、eureka注册中心服务发现不及时:
比如新上线了实例,或者下线了实例,不能及时发现。原因主要有两方面: eureka-server端缓存 和 eureka-client端缓存:
eureka-server:
server端有两层缓存:第⼀层缓存是readOnlyCacheMap,第二层是readWriteCacheMap。
- readOnlyCacheMap定时的和readWriteCacheMap进行数据同步,默认30s一次。
- readWriteCacheMap使用guava缓存实现,默认缓存时间180s,当服务有状态变更时,清除缓存。
client端获取实例时,先从readOnlyCacheMap获取,再从readWriteCacheMap获取,如果都没有,就会出发缓存的加载,从存储层拉数据到缓存中,返给client。 这样设计是为了提升server的响应速度,但是可能导致拿到的信息不是最新的。
解决方式:
- 1、缩短只读缓存的更新时间(eureka.server.response-cache-update-interval-ms) ,或者直接关闭只读缓存(eureka.server.use-read-only-response-cache=false )。
- 2、缩短失效检测的时间,及时更新缓存。
eureka-client:
客户端也会有缓存,一个是Eureka client的缓存,一个是Ribbon的缓存。 解决方式:
- Eureka client的缓存:client有个定时任务专门拉取server端的实例信息,可以缩短拉取的间隔时间(eureka.client.registryFetchIntervalSeconds),及时更新缓存 。
- Ribbon缓存:ribbon从eureka client获取信息,默认的实现是PollingServerListUpdater,通过线程定时去更新。 默认时间30s,可以缩小该时间,比如3s(ribbon.ServerListRefreshInterval = 3000)。
2、spring cloud各组件超时:
在SpringCloud中,应⽤的组件较多,只要涉及通信,就有可能会发⽣请求超时。在 Spring Cloud 中,超时时间只需要重点关注 Ribbon 和 Hystrix 即可。
ribbon超时:
- 全局配置:ribbon.ReadTimeout 和 ribbon.ConnectTimeout。
- 指定服务名配置如:user-service.ribbon.ReadTimeout。
hystrix超时:
Hystrix的超时时间要⼤于Ribbon的超时时间,因为Hystrix将请求包装了起来,特别需要注意的是,如果Ribbon开启了重试机制,⽐如重试3 次,Ribbon 的超时为 1 秒,那么 Hystrix 的超时时间应该⼤于 3 秒。
- 全局配置:Hystrix全局超时配置就可以⽤default来代替具体的command名称。
- hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3000
- 如果想对具体的 command 进⾏配置,那么就需要知道 command 名称的⽣成规则,才能准确的配置。
- 如使⽤ @HystrixCommand 的话,可以⾃定义 commandKeyhystrix.command.UserRemoteClient.execution.isolation.thread.timeoutInMilliseconds = 3000
- 也可以在FeignClient来指定hystrix的超时时间,还可以指定到具体接口hystrix.command.UserRemoteClient#getUser(Long).execution.isolation.thread. timeoutInMilliseconds = 3000
Feign超时:
Feign本身也有超时时间的设置,如果此时设置了Ribbon的时间就以Ribbon 的时间为准;如果没设置就以Feign的时间为准。Feign的时间同样也配置两种:
- 连接超时时间(feign.client.confifig.服务名称.connectTimeout)
- 读取超时时间(feign.client.confifig.服务名称.readTimeout)