业务高峰期部分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
相关推荐
当当网 dubbox 基于rest 方式调用的工程代码,能运行
Spring整合dubbox框架编写rest风格,项目使用maven构建,需要编译dubbo-2.8.4到本地的maven资源仓库,然后使用当前代码测试,不需要相应的web容器,将浏览器作为一个客户端访问URL。
jfinal 与dubbox 和 rest的 简单列子,不过jfinal 在其中使用的比较少,大多是基于java写的,dubbox 则是在 dubbo的基础上进行的扩展,运行示例的话,必须要有 dubbo admin的管理服务和zookeeper 服务。注意 这是个...
基于Spring-boot和dubbox的API接口和后台管理系统
管理系统系列--基于Spring-boot和dubbox的API接口和后台管理系统
dubbox
决策支持系统 (DSS):辅助决策者分析复杂问题,提供数据驱动的决策建议。 网络系统: 包括局域网 (LAN)、广域网 (WAN)、互联网 (Internet) 等,通过路由器、交换机、调制解调器等网络设备,以及通信协议(如TCP/...
Dubbox源码及资源,
dubbox分布式服务框架源码和使用实例,对于入门和学习是一个非常好的资料
最近在研究rest接口,无意发现了dubbox,感谢当当网开源,下载源码,自己编译通过,然后写了两个不连数据库的接口,又写了一个连数据库的接口,共享出来给想学习的小白做参考,源码是个maven项目,前提是要编译好...
dubbox2.8.4版本,增强dubbox功能,由当当网开源出来,maven构建!
dubbox 源码
dubbox spring集成. dubbox spring集成.dubbox spring集成.
dubbox.2.8.4.rar在阿里库中不存在的rar费劲千辛万苦终于找到了,特意分享给大家
Dubbox介绍 V1.0
java源码 仅供学习和参考 禁止一切商业用于
Dubbox框架搭建的Demo,本资源为Maven构建项目,本地测试通过。
Dubbox环境搭建,安装包dubbox-master,dubbox-master,以及详细dubboxDemo和详细配置文档