Tomcat
(一) tomcat网络处理线程模型
- ① BIO同步Servlet
一个请求,一个工作线程,CPU利用率低,tomcat7以下才使用这种,新版本不再使用,tomcat8默认NIO
- ② APR 异步Servlet
apr(Apache Portable Runtime/Apache可以执行运行库),Apache Http服务器的支持库。JINI还是调用Apache Http服务器的核心动态链接库来处理文件读取或者网络传输操作,tomcat 默认监听指定路径,如果有apr安全,则自动启用。
- ③ NIO异步Servlet
tomcat8开始,默认NIO方式,非阻塞读取请求信息,非堵塞处理下一个请求,完全异步。
- ④ NIO处理流程
- Acceptor接收器接受套接字。
- 接收器从缓存中检索nioChannel对象。
- Pollerthread将nioChannel注册到它的选择器IO事件中。
- 轮询器将nioChannel分配给一个work线程来处理请求。
- SocketProcessor完成对请求的处理和返回客户端。
- ⑤ 参数调优
不能靠经验猜测,需要不断调试,找出适应应用程序的合理配置。
- ConnectionTime ,默认 20s,适当调整减少时间。
- maxThreads处理连接的最大线程数,默认200,建议增大,但是不是越大越好的。
- acceptCount(backlog)等待接收accept的请求数量限制,默认100,建议增大,socket参数 min(accept,、proc/sys/net/core/omaxconn),如果acceptCount设置是100.操作系统设置的10,就按照10来,请求限制就是10。
- 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,这属于系统内核。
总共连接数 = acceptCount+ connectionsconnections: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。
SpringBoot的参数配置
java -jar webdemo1.1.0.jar --server.tomcat.maxconnections=1 -- server.tomcat.acceptCount=1
- ⑦ 线程数调整
并发处理线程数调整
线程太少,CPU利用率过低,程序的吞吐量变小,资源浪费,容易堆积。 线程太多,上下文频繁切换,性能反而变低。
线程数调为多少合适?
场景代入:服务器配置2核,不考虑内存问题。 收到请求,java代码执行耗时50ms,等待数 据返回50ms。 理想的线程数量= (1 + 代码阻塞时间/代码执行时间) * cpu数量 。 实际情况是跑起代码,压测环境进行调试。不断调整线程数,将CPU打到80~90%的利用率。
SpringBoot的参数配置
java -jar web-demo-1.1.0.jar --server.tomcat.maxThreads=500
Loading...