Spring Gateway syscall:read(..) Connection reset by peer

最近花了一段时间完成了从zuul迁移到 Spring Cloud Gateway 的工作,记录一下遇到的一个问题。

访问结构

SLB -> HaProxy -> SpringGateway

现象

  • 当haproxy配置为:
mode http
retries 3
option http-pretend-keepalive
option srvtcpka  
option clitcpka
option http-keep-alive
timeout client 30s
timeout server 120s
timeout http-keep-alive 900s
  • 这个配置在我们之前使用zuul的时候是完全OK的。
  • 当切换为spring cloud gateway后,会频繁的抛出以下异常,通过查看日志,几乎是每一秒一条:
io.netty.channel.unix.Errors$NativeIoException: syscall:read(..) failed: Connection reset by peer
io.netty.channel.unix.Errors$NativeIoException: syscall:read(..) failed: Connection reset by peer
io.netty.channel.unix.Errors$NativeIoException: syscall:read(..) failed: Connection reset by peer
io.netty.channel.unix.Errors$NativeIoException: syscall:read(..) failed: Connection reset by peer
io.netty.channel.unix.Errors$NativeIoException: syscall:read(..) failed: Connection reset by peer
io.netty.channel.unix.Errors$NativeIoException: syscall:read(..) failed: Connection reset by peer
io.netty.channel.unix.Errors$NativeIoException: syscall:read(..) failed: Connection reset by peer
io.netty.channel.unix.Errors$NativeIoException: syscall:read(..) failed: Connection reset by peer

这里初步怀疑是spring gateway的问题,然而测试服务器环境下的使用的nginx从未出现该问题,so,这里将问题注意力切换到HAproxy上。

首先想到的是,是不是配置不兼容,这里我清空了所有的haproxy配置,让haproxy使用默认配置。

果然,功夫不负有心人,打印的异常数量,从没秒一条,变成了一分钟几条。这进一步加强了我们定位问题的正确性。

由于spring cloud gateway本质上是使用的reactor-netty作为服务器,那就去github看看。缘分总是那么巧合,刚好遇到了有其他老铁提的ISSUES

看到有老铁问了,我接着在后面问到 我前端使用Haproxy,后端使用reactor-netty,遇到同样的问题

果然github的gay老们还是很热心的。不一会儿,就有老哥给到了我Stack Overflow的一个讨论,这个讨论已经给出了很完美的解决方案。

结论

  • 修改haproxy配置,新配置如下:
defaults
mode http
option prefer-last-server
balance leastconn
timeout server 600s

更新HAProxy后,世界恢复了宁静。


原文:https://qingmu.io/2019/01/10/HAProxy-Spring-Gateway-Connection-reset-by-peer/