服务首次调用超时的问题
来源:5-10 优化服务间调用

RavenFeng
2019-07-12
视频中遇到的服务首次调用提示超时的情况, 工作中重构项目的时候我也遇到并解决了这个问题, 在这里分享一下, 之后老师也可以看情况更新到视频里去(我使用的SpringBoot版本是2.x, 不过这部分配置应该和1.x版本没太多区别)
这个问题非常关键, 因为从调用者(User)来看, 返回的结果是超时, 但如果观察提供者(Order)的日志, 会发现其实请求已经收到而且接口方法已经被执行,并且正常返回了结果, 只是调用者认为调用超时了忽略了返回结果.
如果首次调用的是查询类的接口, 返回个超时都还好说, 如果调的是个涉及复杂业务的接口, 就会引发后续一系列的问题
查阅了一些资料, 问题定位在了ribbon的负载均衡机制上, ribbon默认的方式为懒加载, 即服务首次被调用时, 才会触发加入ribbon的loadBalancer管理, 这个过程非常耗时, 通常会超过ribbon的默认超时时间, 然后再寻址到可用服务执行相应方法, 所以引起了这个问题.
观察gateway项目的日志可以发现, 在首次调用某个服务的时候会触发DynamicServerListLoadBalancer for client xxx initialized 的日志, 也印证了这一点.
解决问题的方法是在gateway项目中加入
ribbon.eager-load.enabled=true
ribbon.eager-load.clients=A,B,C…(service-id)
并且可以相应增加超时时间
ribbon.ConnectTimeout=1000
ribbon.ReadTimeout=1000
添加上述配置后,重启gateway项目观察日志可以发现, 加入了配置的A,B,C…服务在gateway启动过程中就已经被加载, 问题解决
1回答
-
大漠风
2019-07-17
非常好的分享。
有关这个spring cloud网关的超时,我再补充一点。这个ZULL网关的默认超时时间真的很短。
如果我们的spring cloud的微服务是使用服务间通过Rest API直接调用的方式,例如在我们的购票的spring cloud微服务系统中,初始的版本就是服务之间直接调用的。在这种情况下,一个请求由ZULL网关转发到服务A,服务A还要再调用服务B,在业务稍微复杂一点的情况下,也很容易超时。
至于为什么默认时间这么短,其实也是因为提醒开发者,如果要通过服务间调用实现跨服务的业务流程,一定要注意。默认设置这么短的时间,其实也是不推荐服务间有复杂的调用。
00
相似问题