tomcat网络处理线程模型

虽然现在springboot微服务纵横都是用的jar包 , 但是还有很多使用的Tomcat 。tomcat是servlet的容器 , 也是springboot默认集成的容器 , 有必要对他的网络线程模型做一下了解 。

tomcat网络处理线程模型

文章插图
 
(一) tomcat网络处理线程模型
  • ① BIO同步Servlet
一个请求 , 一个工作线程 , CPU利用率低 , tomcat7以下才使用这种 , 新版本不再使用 , tomcat8默认NIO

tomcat网络处理线程模型

文章插图
 
  • ② APR 异步Servlet
apr(Apache Portable Runtime/Apache可以执行运行库) , Apache Http服务器的支持库 。JINI的行还是调用Apache Http服务器的核心动态链接库来处理文件读取或者网络传输操作 , tomcat 默认监听指定路径 , 如果有apr安全 , 则自动启用 。

tomcat网络处理线程模型

文章插图
 
  • ③ NIO异步Servlet
tomcat8开始 , 默认NIO方式 , 非阻塞读取请求信息 , 非堵塞处理下一个请求 , 完全异步 。

tomcat网络处理线程模型

文章插图
 
  • ④ NIO处理流程
  1. Acceptor接收器接受套接字 。
  2. 接收器从缓存中检索nioChannel对象 。
  3. Pollerthread将nioChannel注册到它的选择器IO事件中 。
  4. 轮询器将nioChannel分配给一个work线程来处理请求 。
  5. SocketProcessor完成对请求的处理和返回客户端 。

tomcat网络处理线程模型

文章插图
 
  • ⑤ 参数调优
不能靠经验猜测 , 需要不断调试 , 找出适应应用程序的合理配置 。
  1. ConnectionTime  , 默认 20s , 适当调整减少时间 。
  2. maxThreads处理连接的最大线程数 , 默认200 , 建议增大 , 但是不是越大越好的 。
  3. acceptCount(backlog)等待接收accept的请求数量限制 , 默认100 , 建议增大 , socket参数 min(accept , 、proc/sys/net/core/omaxconn) , 如果acceptCount设置是100.操作系统设置的10 , 就按照10来 , 请求限制就是10 。
  4. maxConnections最大连接处理器 , 默认 nio 1w , apr 8192 ,  建议不要调整 。
  • ⑥ 连接数调整
tomcat能够接受到的连接数 , acceptCount和connections , 一个用户请求连接到accept queue队列 , 代表捂手成功 , 通过tcp的形式 , 收到一个通知给tomcat 。tomcat收到请求数量是根据1万 , 这1万个请求正在处理 , 线程 , 如果tomcat已经满了 , 请求都堆积到操作系统里面 , 操作系统acceptCount就是控制堆积数量的 。windows这块 , 操作系统堆满了 , tcp这块也堆满了直接关闭了请求了 。
linux这块 , 不仅仅有队列 , 还有个tcp握手过程中的一个syn queue , linux也会在syn queue , 这属于系统内核 。

tomcat网络处理线程模型

文章插图
 
总共连接数 = acceptCount+ connections
connections: Tomcat能接收的请求限制 。
acceptCount: 超过Tomcat能接收的请求数以后 , 堆积在操作系统的数量(windows 和 linux 略有不同) 。
什么时候需要调整connections?如何调整?
connections小于maxThread的时候 , 需要调大 , 最好是比预期的最高并发数要大20%;反 正是堆积到tomcat的work处理线程池中(堆积占内存) 。举个简单的例子:cpu数量是5 maxThread是5 , 结果连接数据connections只有3 , 这不是浪费的了吗?直接调整connections的数量 。
什么时候需要调整acceptCount?
想受理更多用户请求 , 却又不想堆积在tomcat中 , 利用操作系统来高效的堆积 , 可以调整为 最高并发数 ­ connections; 实际上不需要调整 , tomcat默认100 , linux默认128;最好是把连接控制交给应用程序 , 这 样方便管理 。这是操作系统层面的 , 调整的比较少 。一般都是调整connections 。


推荐阅读