今天同事在开发一个接口功能调用远端服务发email的适合,出现一次调用但远端服务接到两次请求的情况。

情况如下:

A服务接收到请求以后,处理了一些业务,然后调用B的接口处理业务。A从始至终只发了一次请求,B却能收到两次请求,且B端的日志看,两个前后几乎同时触发。

情况分析:在A只有一次请求的情况下,B会收到两次或者多次请求,那么说明A的底层帮忙调用了两次请求。在微服务的机制里面,确实会存在重试的策略。也就是底层框架收不到B的回复时,会自动发起一次请求。当然,重复尝试次数可配置。那么什么情况下会引起重试呢?一般情况下会有两种:

  • 1、B服务未在规定的时间内完成作业并回复给A服务的底层。
  • 2、B有返回结果,但因为网络原因导致A的底层没有收到。

明白了原理,那应该哪一种原因且如何解决呢?

A和B服务在同一个集群内,且是互通的内网,所以不可能是原因2,那么只剩下原因1。因为B端的业务是调用远端的邮件服务器,那么邮件服务器长时间没有返回的情况下,导致B没办法回复给A。

原因定位到后,解决的问题办法很简单,就是加大A发起请求的等待时间,让B有时间处理自己的业务后再返回,当然,另一个方式使用异步来发送邮件。

微服务之间增加等待时间的配置如下:

ribbon:
  connectTimeout: 60000 #请求连接的超时时间,默认时间为1秒
  readTimeout: 60000 #请求处理的超时时间

配置后,问题得到完满解决。