业务高峰期部分rest接口超时有一段时间了,之前一直怀疑是kafka、nginx、log4j、网络等原因并进行优化,一直没有太大改观。我们生产共有四台nginx反向代理网关,运维在某台nginx中通过日志grep看到,高峰期 nginx反向代理到后端某台tomcat,每秒达到100+,4台nginx则为400+,已超过tomcat设置的并发连接数和完全连接队列的大小(200+100=300)。前两天运维说把tomcat线程数调大到600之后(原来是200),超时问题就没有再出现了。
事后考虑原因分析如下:
tomcat配置中有一个参数叫acceptCount,这个参数在tomcat中指server端监听端口的完全连接队列的socket上限(backlog)。这个值在dubbox中是不能设置的,默认100。
另一个参数叫threadCount,这个参数指tomcat工作线程池大小。tomcat线程池每次从队列头部取线程去处理请求,请求完结束后再放到队列尾部,也就是说前后两次请求处理不会用同一个线程。如下:
换句话说,之前threadCount=200、acceptCount=100时,tomcat能接受的最大并发数就是200,如果并发数>200时,只会有额外的100个并发请求会在完全连接队列中排队,其他并发请求则根本进入不了完全连接队列中,会被服务端拒绝处理(详见注1)。还有三种情况:
1、半连接队列满了:详见注2
2、在完全连接队列中超时:出现这种情况,主要因为接口处理响应慢,导致tomcat工作线程池没有空闲的线程处理完全连接队列中的请求,完全连接队列中的请求在到达超时时间(20s)时,被nginx主动关闭了tcp连接(nginx日志中http ressponse code:504)。有一点要注意,已经进入完全连接队列中的请求,最终会被tomcat处理,只不过此时连接已经断开,nginx不会收到tomcat的响应。
3、接口处理超时:出现这种情况,说明请求已经在tomcat的工作线程中处理了,确实由于接口处理响应慢,而最终被nginx主动关闭了tcp连接。
结论:
治标的方法是增加tomcat工作线程池(threadCount)的数量,而治本的方法还是要提高接口的响应速度(rt:response time)。试想如果我们的所有接口都能控制在100ms之内,tomcat工作线程池设置为200,单机也能承受峰值2000(200 / 0.1)的并发量请求量(当然mem和cpu不能太差)。
注1:当accept队列满了之后,即使client继续向server发送ACK的包,也会不被响应,此时ListenOverflows+1,同时server通过/proc/sys/net/ipv4/tcp_abort_on_overflow来决定如何返回,0表示直接丢弃该ACK,1表示发送RST通知client;相应的,client则会分别返回read timeout
或者 connection reset by peer
。
注2:对于SYN半连接队列的大小是由(/proc/sys/net/ipv4/tcp_max_syn_backlog)这个内核参数控制的,有些内核似乎也受listen的backlog参数影响,取得是两个值的最小值。当这个队列满了,不开启syncookies的时候,Server会丢弃新来的SYN包,而Client端在多次重发SYN包得不到响应而返回(connection time out
)错误。但是,当Server端开启了syncookies=1,那么SYN半连接队列就没有逻辑上的最大值了,并且/proc/sys/net/ipv4/tcp_max_syn_backlog设置的值也会被忽略。
最后再附录一张tcp连接建立 和 半连接队列和完全连接队列的图,很经典!
参考链接:
tcp的半连接与完全连接队列
https://segmentfault.com/a/1190000008224853
tomcat的acceptCount与maxConnections
https://segmentfault.com/a/1190000008064162
相关推荐
- **API增强**:Dubbox提供了更丰富的API接口,如异步调用、超时重试等,增强了服务调用的灵活性。 - **协议扩展**:除了支持原生的Dubbo协议,还增加了REST、Hessian2等更多通信协议,扩大了服务集成的可能性。 ...
这个压缩包包含了Dubbox的jar包以及关于如何安装和使用Dubbox源码的文档,对于想要深入理解或者开发基于Dubbox的应用的开发者来说是非常宝贵的资源。 首先,让我们了解一下Dubbox的核心功能。Dubbox支持多种通信...
`ReferenceConfig`是服务消费者的主要配置类,包含了服务接口、版本、超时等信息;`ExportConfig`则对应服务提供者,负责服务的发布。`ProxyFactory`如JavassistProxyFactory,生成服务接口的代理对象,使得调用服务...
9. **版本兼容性**:由于是 Dubbo 的增强版,Dubbox 兼容 Dubbo 的大部分特性,使得已有的 Dubbo 应用能够平滑升级到 Dubbox。 10. **社区支持**:Alibaba 的开源项目通常拥有活跃的社区,Dubbox 也不例外,开发者...
Dubbox 是一款基于 Spring 和 Dubbo 的微服务框架,它扩展了 Dubbo 的功能,提供了更丰富的特性,比如 REST 支持、Zookeeper 注册中心等。在这个例子中,我们有三个主要的组件:一个消费者工程(UConsumer)和两个...
5. **版本兼容性**:Dubbox 2.8.4与早期版本相比,可能修复了一些已知问题,增加了新的功能,同时也保持了与Dubbo原生接口的兼容性,使得升级更为平滑。 综上所述,Dubbox的admin和monitor组件对于实现高效、可靠的...
Dubbox是阿里巴巴开源的一个基于Java的RPC框架,它由dubbo升级而来,增加了对REST、Hessian2等协议的支持,并且在配置和使用上更加灵活。这次分享的是未经Maven编译的原始Git克隆资源,这意味着用户可以深入理解框架...
Dubbox 是 Dubbo 的升级版,增加了对 HTTP、REST、WebSocket 等协议的支持。 总结来说,Dubbo 是一款强大的分布式服务框架,它简化了分布式系统中的服务调用、服务治理等复杂问题,同时也提供了丰富的扩展机制,...
- **与 Dubbox 的区别**:Dubbox 是 Dubbo 的一个分支,增加了对 HTTP 和 REST 协议的支持,以及更多的负载均衡策略。 7. **注册中心** - **Dubbo 支持的注册中心**:如 ZooKeeper、Eureka、Consul 等。 - **...
- **接口级别超时设置**:在接口级别的配置文件中设置。 - **方法级别超时设置**:在具体的接口方法调用时设置。 4. **服务调用超时会怎么样?** 当服务调用超时时,Dubbo会根据配置的容错策略来处理,比如抛出...