背景
这篇文章主要讲服务器软件的线程池。
cpu密集还是io密集?
程序按消耗资源的类型分类,
1.cpu密集 //业务程序,即自己写的程序,比如定时任务+线程池
2.io密集 //服务器程序,例如,tomcat/jetty,dubbo
jdk 线程池
默认的顺序是:core——队列——max //适合cpu密集。线程数量比较少,所以上下文切换比较少,那么就能更好的利用cpu。
如果要io密集,怎么办?增大线程数量。如何增大?顺序改为:core——max——队列。说白了,就是在第二步,校验线程数量的时候,是创建新的线程,而不是添加到队列。
解决方案
1.自己实现 //太复杂。比如,jetty。
2.基于jdk //最佳实践。比较简单。比如,tomcat,dubbo。
开源项目
网上有开源项目。专门修改队列和max的顺序。
线程数量
1.自己写的程序
cpu*2 + 1 //适合cpu密集
2.服务器软件
因为是服务器,所以一般至少几百个线程。具体是多少?
tomcat,1.线程数量是百位数级别。默认200。2.最大连接数量是1万。//为什么可以那么大?因为客户端请求连接都是io密集型,大部分请求连接都是在等待网络io,所以线程数量要远远大于cpu数量。
最佳实践
最小线程数量(默认各位数)——最大线程数量(默认200,最好不要超过1000)——最大连接数量(1万)——队列(1000)——connection refuse
连接数量和线程数量
线程数量不能太大,1000就很大了,因为线程需要上下文切换,很耗费资源,数量再多,也没用。而连接数量,可以放队列,所以连接数量最多可以1万。
如何配置?
tomcat
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxThreads="800" acceptCount="1000"/>
这两个值如何起作用,请看下面三种情况
情况1:接受一个请求,此时tomcat起动的线程数没有到达maxThreads,tomcat会起动一个线程来处理此请求。
情况2:接受一个请求,此时tomcat起动的线程数已经到达maxThreads,tomcat会把此请求放入等待队列,等待空闲线程。
情况3:接受一个请求,此时tomcat起动的线程数已经到达maxThreads,等待队列中的请求个数也达到了acceptCount,此时tomcat会直接拒绝此次请求,返回connection refused
程序
server:
#tomcat配置
tomcat:
# 线程池维持最小线程数,默认10
min-spare-threads: 4 //core
# 最大线程数,默认200
max-threads: 1000 //max
# 允许最大连接数,默认10000,当达到临界值时,系统可能会基于accept-count继续接受连接
max-connections: 10000
# 当所有线程都在使用时,建立连接的请求的等待队列长度,默认100
accept-count: 1000 //队列
官方文档
1.maxThreads
The maximum number of request processing threads to be created by this Connector, which therefore determines the maximum number of simultaneous requests that can be handled. If not specified, this attribute is set to 200. If an executor is associated with this connector, this attribute is ignored as the connector will execute tasks using the executor rather than an internal thread pool. Note that if an executor is configured any value set for this attribute will be recorded correctly but it will be reported (e.g. via JMX) as -1 to make clear that it is not used.
2.maxConnections
The maximum number of connections that the server will accept and process at any given time. When this number has been reached, the server will accept, but not process, one further connection. This additional connection be blocked until the number of connections being processed falls below maxConnections at which point the server will start accepting and processing new connections again.Note that once the limit has been reached, the operating system may still accept connections based on the acceptCount setting.The default value varies by connector type. For BIO the default is the value of maxThreads unless an Executor is used in which case the default will be the value of maxThreads from the executor. For NIO the default is 10000. For APR/native, the default is 8192.
Note that for APR/native on Windows, the configured value will be reduced to the highest multiple of 1024 that is less than or equal to maxConnections. This is done for performance reasons.
If set to a value of -1, the maxConnections feature is disabled and connections are not counted.
3.acceptCount
The maximum queue length for incoming connection requests when all possible request processing threads are in use. Any requests received when the queue is full will be refused. The default value is 100.
tomcat.apache.org/tomcat-8.5-…
dubbo
线程数量和连接数量
和tomcat差不多。只要是服务器软件,接受连接的数量和线程池的数量,都差不多。
线程数量,默认200,最好不要超过1000。
队列,最大连接数量,1万。
参考
xiajunhust.github.io/2018/09/07/…
sanshengshui.github.io/2018/05/28/…