记调整SpringCloudGateway负载策略BestAvailableRule引发的事故

前言

因老信息流项目维护性太差及各种线程池乱用泛滥,原研发人员离职等等历史原因。导致信息流新研发人员中不断吐槽。当然吐槽老代码是程序员特点,看到别人写的不经意就想来一句 “我艹”,最后一看注释发现自己写的,默默修改中…。在不断的吐槽中,大家决定 “重构“,说干就干,don’t say too much。建项目、熟悉老业务逻辑、重构。

历程

经过一个星期小伙伴们的辛苦奋战,信息流核心接口完成提测,看样子一切都是如此的顺利。在测试环境中在测试周测一周期间修改一些细节问题,回归等等。在第二周部署上生产,在生产经过验证后的第三天,开始切流,切进来大概700多万流量。发现请求耗时要比之前的长,原老项目接口 99.99%(450ms),最大连接耗时 3000多毫秒, 新重构项目 99.99%(500多ms),最大连接耗时 8000多毫秒。我的天,什么情况,起初给自己心理安慰,新切流可能redis 缓存并没有刷的很完美,继续观察,连续3天,还是老样子,总量将近 2400多万流量进来,redis 缓存不可能命中还是那么低,然后怀疑人生,因为redis 集群归数据组维护,然后联系相关人员查看目前我们这个项目使用的redis占用情况,然后发现目前redis 占用80%多。又一次给自己心理安慰,永远不承认自己有问题(哈哈)。然后申请资源 切redis 集群。部署上线。一切还是如往常一样。上线后观察,发现耗时是降下来了。但是也不是很多,99.99%(470ms),和原来相比还是差点。这不瞎了吗?如果重构后还达不到老项目的标准重构的意义就没了呀。耗时这个问题也还好,在这期间通过监控发现很多的Failure 异常

org.apache.catalina.connector.ClientAbortException java.io.IOException: Broken pipe

看这错误估计大家也都遇到过(远程客户端的请求中止引起的。),官方解释
在这里插入图片描述

这个异常正常频率小的话,可以直接捕获打印日志就可,但是对于目前接口来说太多这个异常了。感觉不正常,什么情况下 “远程客户端的会请求中止”? 这次先怀疑到自己身上,可能是处理比较慢。并发打进来后,超时,客户端已经断开连接,服务端还往连接里边写数据,然后报错。自己也测了,这种情况确实会发生,包括 客户端超时断开、客户端主动取消这些确实都会引发以上错误。开始针对这个错误做一些tomcat 优化,

调整了几个参数maxConnections、maxThreads、acceptCount。

起初参数值:maxConnections:10000,maxThreads:500,acceptCount:1000

调整后参数值maxConnections:10000,maxThreads:800,acceptCount:1000

说一下这几个参数的意义

maxConnections:最大连接数,是指在同一时间,tomcat能够接受的最大连接数。对于Java的阻塞式BIO,默认值是maxthreads的值;如果在BIO模式使用定制的Executor执行器,默认值将是执行器中maxthreads的值。对于Java 新的NIO模式,maxConnections 默认值是10000。
对于windows上APR/native IO模式,maxConnections默认值为8192,这是出于性能原因,如果配置的值不是1024的倍数,maxConnections 的实际值将减少到1024的最大倍数。

如果设置为-1,则禁用maxconnections功能,表示不限制tomcat容器的连接数。
maxConnections和accept-count的关系为:当连接数达到最大值maxConnections后,系统会继续接收连接,但不会超过acceptCount的值。

maxThreads:最大线程数,每一次HTTP请求到达Web服务,tomcat都会创建一个线程来处理该请求,那么最大线程数决定了Web服务容器可以同时处理多少个请求。maxThreads默认200,肯定建议增加。但是,增加线程是有成本的,更多的线程,不仅仅会带来更多的线程上下文切换成本,而且意味着带来更多的内存消耗。JVM中默认情况下在创建新线程时会分配大小为1M的线程栈,所以,更多的线程异味着需要更多的内存。线程数的经验值为:1核2g内存为200,线程数经验值200;4核8g内存,线程数经验值800。
accept-count:当所有的请求处理线程都在使用时,所能接收的连接请求的队列的最大长度。当队列已满时,任何的连接请求都将被拒绝。accept-count的默认值为100。

详细的来说:当调用HTTP请求数达到tomcat的最大线程数时,还有新的HTTP请求到来,这时tomcat会将该请求放在等待队列中,这个acceptCount就是指能够接受的最大等待数,默认100。如果等待队列也被放满了,这个时候再来新的请求就会被tomcat拒绝(connection refused)。

调整后重新上线,发现错误依旧。没有降。这时,脑袋蹦出来一个“瞎比”想法,这个想法就是这次事故的“凶手”

因为这个异常可能是因为连接数过多然后超时导致客户端关闭连接发生异常,目前springcloud gateway网关的策略是轮询(RoundRobinRule),然后想着如果改成BestAvailableRule(最可用,选择负载最小的节点)是不是就会提高响应时间,说干就干。修改完测试也没什么问题(因为量不大),然后晚上上线。第二天早上,持续观察,发现系统耗时整体上涨,查看机器 当策略负载到目标机器时 cpu暴增,最大耗时达17s.

在这里插入图片描述

这就是我说的事故。发现后立马会滚。期间当然老大也口头说道说道,但是结果是好的。起码知道这个BestAvailableRule 策略在高并发,高流量业务场景下不适用。

轮询永远是最稳定的负载策略
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Spring Cloud Gateway是Spring Cloud生态中的一个API网关框架,可以实现请求的路由、限流、鉴权、监控等功能。其中,负载均衡是Spring Cloud Gateway中非常重要的功能之一。本篇文章就来介绍一下Spring Cloud Gateway负载均衡功能。 在Spring Cloud Gateway中,负载均衡是通过路由(Route)来实现的。每一个路由对应一个或多个服务实例,Spring Cloud Gateway会根据负载均衡策略,将请求转发到对应的服务实例。 Spring Cloud Gateway支持多种负载均衡策略,包括: 1. RoundRobinLoadBalancer:轮询负载均衡策略,每个服务实例轮流接收请求。 2. WeightedResponseTimeLoadBalancer:响应时间加权负载均衡策略,对每个服务实例的响应时间进行加权,响应时间短的服务实例接收更多的请求。 3. ZoneAvoidanceRule:区域避让负载均衡策略,对于不同区域的服务实例,Spring Cloud Gateway会尽量选择同一区域的服务实例来处理请求。 除了以上几种负载均衡策略之外,Spring Cloud Gateway还支持自定义负载均衡策略。在自定义负载均衡策略时,需要实现Spring Cloud Gateway的LoadBalancerClient接口和LoadBalancer接口。 下面是一个示例,展示了如何在Spring Cloud Gateway中使用RoundRobinLoadBalancer策略: ```java @Configuration public class GatewayConfig { @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route(r -> r.path("/foo/**") .uri("lb://service-foo") .id("service-foo") .lb(new RoundRobinLoadBalancer())) .build(); } } ``` 在上面的示例中,我们配置了一个路由,将请求转发到service-foo服务实例。并且指定了负载均衡策略为RoundRobinLoadBalancer。 除了在配置文件中配置负载均衡策略之外,Spring Cloud Gateway还支持通过请求头、请求参数等方式,动态设置负载均衡策略。这样可以在运行时根据实际情况,动态调整负载均衡策略。 总的来说,Spring Cloud Gateway负载均衡功能非常强大,支持多种负载均衡策略,并且支持自定义负载均衡策略。这为我们构建高可用、高性能的分布式系统提供了很大的便利。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值