关于使用Spring Cloud Gateway网关网络连接的4个重要的参数配置

整理出这四个重要的参数,说起来很不易,来源于一次网络故障事故后的调查,对于平时使用Spring Cloud Gateway(简称scg)来说这些参数几乎很少会关注到,从网上也很少能看到讲解的文章,表面上是SCG的问题,实则都是和SCG的底层网络通信框架Netty有关系。

率先曝光一下这4个参数

System.setProperty("reactor.netty.pool.leasingStrategy", "lifo");
spring.cloud.gateway.httpclient.pool.max-idle-time=PT1S

spring.cloud.gateway.httpclient.connect-timeout=2000
spring.cloud.gateway.httpclient.response-timeout=PT30S

是不是略感陌生,平时的网关使用的都是默认配置,使用起来也没有问题,因为使用了WebFlux异步非阻塞的框架,底层基于Netty,NIO的异步非阻塞的处理SOCKET,可以让少量的线程处理大量的业务请求。

所以如果你使用端点监控去查看网关的线程数,网关中暴露的线程数都不会很高

system_cpu_count{application="i5xforyou-service-gateway",} 4.0
jvm_threads_live_threads{application="i5xforyou-service-gateway",} 123.0
jvm_threads_states_threads{application="i5xforyou-service-gateway",state="new",} 0.0
jvm_threads_states_threads{application="i5xforyou-service-gateway",state="runnable",} 21.0
jvm_threads_states_threads{application="i5xforyou-service-gateway",state="blocked",} 0.0
jvm_threads_states_threads{application="i5xforyou-service-gateway",state="waiting",} 70.0
jvm_threads_states_threads{application="i5xforyou-service-gateway",state="timed-waiting",} 32.0
jvm_threads_states_threads{application="i5xforyou-service-gateway",state="terminated",} 0.0

事情的起源还是从一次网络故障说起,由于机房网络的LBC网关出现问题,导致整体系统的内网网络出现延迟,各服务内部调用,接口间调用以及连接数据库等所有节点都发生了超时,延迟拥塞,导致外部反馈用户在页面上卡死,所有服务都出现了延迟请求,请求调用非常慢,致使整个系统出现了雪崩效应,故障持续了相当长的时间,而且找不到原因,只知道网络问题却无从定位,也不知道何时恢复。从日志看网关报各种错,CPU的负载也相当高,呈现忽高忽低的抖动的状态。

scg中各种报错,主要是 Connect reset by peer 和 Connection prematurely closed BEFORE response,

说来也巧,因为事故前上线给部分服务及网关加了Alibaba的Sentinel的的限流降级组件,其中就各分配了50%的流量分别到2个隔离的服务集群中,虽然当时2个集群都发生了网络问题,因为同属于一个网络分区内,但是加了sentinel的这部分集群的网关及服务的资源并没有配置足够,有问题的这部分scg,当时配置了8台,而没有问题的scg配置了18台,后端服务的资源也是没有按1:1的比例配足,最碰巧的是后来重启了后端服务及这8台scg, 也没有恢复问题,而关掉了这8台网关请求居然恢复了。就是这种种的巧合以至于后来的百思不得其解及事故调查分析。甚至一度被怀疑是Sentinel把请求阻塞了,虽然事故原因是由于机房网络引起的,但是重启网关服务恢复这一表象却难以说服。最后可以解释的原因就是故障最后网络问题已经缓解,同时进入到8台scg的流量因为伴随着scg关闭,而流量都进入到了18台scg中。哪一部分集群的资源比较充足。

和网关相关的调查及分析也就引出了这个4个重要的参数,首先要说明的是,这些参数的配置不会导致真正发生网络问题的时候能够快速解决故障的问题,因为网络故障是非常致命及难易管控的,除非具备相应的容灾处理方案,例如多机房双活多活等,否则难易做到对业务的无损操作。所以这些参数的作用不能解决和杜绝网络问题,只能说是让网关性能或者功能得到进一步优化的效果,从而快速定位问题并配合降级保护等策略使服务及scg网关可以得到一些保护。

首先我们调查了网关报错,Connection prematurely closed BEFORE response,通过日志监控发现,报错的出现都是在重启8台scg的期间发生的

时间点比较吻合,通过查找网上文章 https://blog.csdn.net/rickiyeat/article/details/107900585

里面描述了报错的问题及解决方法,虽然我们后端没有使用tomcat,使用的undertow,但是原理应该是一样的就是后端服务主动断开了连接,因为当时怀疑是服务故障所以就重启了后端服务,而这时scg中的连接依然使用了和后端保持的连接,而请求发送的时候后端连接已经断开而导致的报错。

请求报错reactor.netty.http.client.PrematureCloseException

就会抛出Connection prematurely closed BEFORE response的异常

和这个相关的配置参数有2个:

spring.cloud.gateway.httpclient.pool.max-idle-time=PT1S # 这个参数的作用就是scg的空闲连接超时回收时间

System.setProperty("reactor.netty.pool.leasingStrategy", "lifo"); #这个参数的作用是先使用后回收的连接,而不是先使用先回收的连接。所以这2个参数的配合使用,可以让网关始终能够取到一个比较新鲜的连接。而不会导致后端连接中断而Scg的连接取到的是一个是比较旧的并且很可能是一个后端已经主动断开的连接。

还有2个重要的参数

spring.cloud.gateway.httpclient.connect-timeout=2000 # 全局的TCP连接超时时间默认时间是45秒,所以也就是发生网络故障的时候,连接时间要等待45秒,而网络连接是同步阻塞的 ,The connect timeout in millis, the default is 45s. 所以就会导致请求非常慢,从网关就卡死了。
spring.cloud.gateway.httpclient.response-timeout=PT30S  #全局的响应超时时间,网络链接后,后端服务多久不返回网关就报错 The response timeout. 

当网络连接到达指定的时间,比如默认的45秒后,网关会报错,日志中会显示一个 connection timed out的500异常

这也就是当天日志显示的大量的一个连接超时的报错

实际就是由于网络连接发生了大量的超时,而因为默认超时时间是45秒,所以网关也一直在等待,理论上说,这个时间45秒还是比较长的,如果网络连接问题调成2秒超时,如果这期间大量的出现 connection reset by peer  connection timed out,就可以断定是网络发生了抖动或者故障。

请求响应时间也同样,如果后端服务30秒内仍然未返回任何回复信息就会直接超时报错,可以说正常响应超过1秒就已经难以忍受了。通过配置超时时间,如果超过超时时间,网关会直接报错,

如果出现了,504 GATEWAY_TIMEOUT "Response took longer than timeout: ", Gateway Timeout 这样的504错误,那么就可以快速认定是由于后端服务问题导致的请求响应超时问题。

所以合理的配置对于快速定位分析问题能够起到一定的促进作用。如果你还没有配置,那么就请留意这些参数的使用吧。

 

  • 13
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值