最近在项目上遇到一个奇怪的问题:
我们有两个服务,服务A调用服务B发送邮件,但结果是重复发送了4封邮件,内容还是一样的。一开始以为是邮件服务器出问题,但通过本地调试发现发送邮件的方法是被重复调用了。
至于为什么会重复调用,这得先了解一下Spring Cloud 的重试机制。
Spring Cloud 整合了 Spring Retry实现重试逻辑。
可以通过Ribbon、Feign、Zuul中进行配置。
服务A中有如下Ribbon配置:
1 | ribbon: |
可以看到 OkToRetryOnAllOperations
属性控制了超时时是否自动重试所有请求,当为true
时会重试所有请求,包含POST
请求,可能会对服务器资源产生影响,如我遇到的重复发送多封邮件的问题。
因此,我将服务A 的 ReadTimeOut
更改为 40000
,重新部署测试重复调用的情况消失。
ribbon.retryableStatusCodes
属性列出希望客户端重试的响应代码。
Feign的重试功能被默认配置为永不启用
Zuul可以通过zuul.retryable
来控制是否开启重试。可以通过zuul.routes.routename.retryable
来为逐个路由禁用重试功能