tomcat7关键配置和线程

来源:互联网 发布:淘宝上的车秒贷靠谱吗 编辑:程序博客网 时间:2024/04/28 05:04

1. tomcat 7的一些关键参数配置

官方文档 http://tomcat.apache.org/tomcat-7.0-doc/config/http.html

配置文件conf/server.xml

<Connector port="8080" protocol="HTTP/1.1"               connectionTimeout="20000"               redirectPort="8443" />

没有指定Executor,则使用internal executor,使用的是jdk的线程池。本文讨论internal executor。

maxThreads – 默认200,最大线程数,为线程池最大大小(ThreadPoolExecutor的maximumPoolSize)

maxConnections – 最大连接数,默认为maxThreads

acceptCount – 默认100,监听socket的 backlog。

minSpareThreads – 默认min(10,maxThreads) ,等同于ThreadPoolExecutor的corePoolSize

maxKeepAliveRequests – 默认100,一条长连接服务的http请求最大数目(超过了关闭之),-1表示不受数目影响。

connectionTimeout – 默认60000ms,accept一个连接后,等URI的最长时间。

keepAliveTimeout – 默认为connectionTimeout,一个连接等待下一个http请求到来的最长时间(过期关闭该连接)

2. 主要线程

2.1 http监听线程

代码为:JIoEndpoint$Acceptor.run\
线程名为:http-bio-监听端口-Acceptor-0

关键逻辑

public void run() {    while (running) {        // 连接数到了maxConnections则等待,否则计数器加1        countUpOrAwaitConnection();        Socket socket = accept();        封装socket为runnable对象(JIoEndpoint$SocketProcessor对象)提交给线程池;    }}

注: 线程池使用的队列为TaskQueue extends LinkedBlockingQueue,其重载了offer方法。所以线程池的行为与JDK里的稍有不同:连接数小于minSpareThreads,来一个连接建个线程;minSpareThreads<=连接数<maxThreads, 有空闲线程则新连接用空闲线程,无则建个线程; 连接数>=maxThreads,则新连接进入队列。

分析: accept了maxConnections个连接后,1. 如果有新连接过来,则进入监听套接字的backlog; 2.如果maxConnections>maxThreads,那么maxConnections-maxThreads个连接进入线程池的队列里。

分析: nginx反向代理到tomcat时,出现过这么个情况:nginx部分日志显示上游响应时间很长,但是tomcat access log显示处理时间都很短,这是为什么呢? 一个可能的原因是socket连接数满了(并且每个长连接服务100个http后关闭,才处理新连接),新连接进入backlog,nginx的时间表现为backlog呆的时间+线程池队列呆的时间+处理时间即accesslog里的时间,而tomcat access日志里的时间为请求接收直到响应发送完毕的时间。

conf/server.xml文件里,

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"               prefix="localhost_access_log." suffix=".txt"               pattern="%h %l %u %t &quot;%r&quot; %s %b %D" />

%D为毫秒,即为access log里的时间

2.2 工作线程(线程池)

线程池在在AbstractEndpoint中创建。

AbstractEndpoint<Socket>        |    JIoEndpoint

工作线程代码:JIoEndpoint$SocketProcessor.run() \
线程名:http-bio-端口号-exec-

关键逻辑

public void run() {    try {        处理socket(一次http请求)    } finally {        不关闭socket(长连接),则封装socket为runnable对象(JIoEndpoint$SocketProcessor对象)提交给线程池;    }}

从单个线程来看:服务一个http请求后,将socket放到线程池,自己再去任务队列里取任务。 这种方式的好处是 连接数多于线程数时,所有连接都公平的轮询得到处理;缺点是socket任务不断的入队出队在频率极高下也会是个瓶劲。

2.3 命令监听线程

conf/server.xml文件里

<Server port="8005" shutdown="SHUTDOWN"></Server>

接收shutdown 之类的命令

0 0
原创粉丝点击