今天小戚發出一封郵件,說由於線上系統中tomcat的鏈接超時(connectionTimeout)設置成60ms,形成第三方訪問公司的服務,老是502異常。html
這個設置在$tomcat/conf/server.xml中web
<!-- Define a non-SSL HTTP/1.1 Connector on port 8080 -->
<Connector port="8080" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="2000" disableUploadTimeout="true" />
http://tomcat.apache.org/tomcat-5.5-doc/config/http.htmlapache
connectionTimeout :瀏覽器
The number of milliseconds this Connector will wait, after accepting a connection, for the request URI line to be presented. The default value is 60000 (i.e. 60 seconds).tomcat
以上中文是通過以下分析過程得出的。服務器
寫了一個servlet,doGet先sleep一段時間,再寫一個輸出,直接用瀏覽器訪問。cookie
通過測試,發現和這個時間無關。session
寫客戶端模擬超時,多是由於API直接實現到提交URI了,另外還懷疑底層有自動保持鏈接的動做,反正怎麼Sleep都不超時,得換個寫法了。app
明天連上TCPMon看看後臺有沒有自動保持鏈接的動做。socket
def sURL='http://localhost:8080/index.jsp'
URL url = new URL(sURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
直接用telnet連上tomcat,若是什麼都不輸入,socket很快回斷開,輸入完整GET。。。,可以得到輸出。若是不保持輸入,則鏈接很快會斷開。若是一直不停輸入,鏈接繼續保持。
$ telnet localhost 8080
GET /index.jsp HTTP/1.1
Accept-Language: zh-cn
Connection: Keep-Alive
Host: 192.168.0.53
Content-Length: 36
仍是2s超時,睡一秒可以正確得到輸出,睡2秒,輸出爲空。
如下是Groovy代碼
content ='''GET /index.jsp HTTP/1.1
Accept-Language: zh-cn
Connection: Keep-Alive
Host: 192.168.0.53
Content-Length: 36
'''
def sleepTime=1000
Socket socket = new Socket('localhost',8080)
println 'is keep alive? ' + socket.getKeepAlive()
println 'sleep ' + sleepTime + ' ms.'
Thread.sleep(sleepTime)
println 'is closed? ' + socket.isClosed()
println 'sleep ' + sleepTime + ' ms.'
//Thread.sleep(sleepTime)
println 'write socket begin======'
writeStream(content, socket.getOutputStream())
println 'read socket begin======'
println readStream(socket.getInputStream())[0..300]
void writeStream(content, stream) {
OutputStream buf = new BufferedOutputStream(stream);
OutputStreamWriter out = new OutputStreamWriter(buf, "UTF-8");
out.write(content)
out.flush();
print content
//out.close();
}
String readStream(stream){
String sResult=''
byte[] buffer = new byte[1024];
int readCount = stream.read(buffer);
while (readCount != -1) {
sResult += new String(buffer, 0,
readCount, "utf-8");
readCount = stream.read(buffer);
}
stream.close()
return sResult
}
用Groovy寫測試代碼真舒服,呵呵。
JBoss使用Tomcat做爲Web容器,所以在JBoss中對於Web容器的配置也相似於在Tomcat中的配置,主要就是對於server.xml文件的編輯,在JBoss 5.x中,這個文件位於${JBOSS.HOME}\server\${confifure}\deploy\jbossweb.sar下,其中configure的值能夠是all,
default,web,standard, minimal等。下面的代碼展現了一個JBoss default配置下的server.xml,因爲篇幅緣由,將其中的註釋都已經去掉了。
<Server> <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> <Listener className="org.apache.catalina.core.JasperListener" /> <Service name="jboss.web"> <Connector protocol="HTTP/1.1" port="8080" address="${jboss.bind.address}" connectionTimeout="20000" redirectPort="8443" compression="on" compressionMinSize="1" compressableMimeType="text/html,text/xml" /> <Engine name="jboss.web" defaultHost="localhost"> <Realm className="org.jboss.web.tomcat.security.JBossWebRealm" certificatePrincipal="org.jboss.security.auth.certs.SubjectDNMapping" allRolesMode="authOnly" /> <Host name="localhost"> <Valve className="org.jboss.web.tomcat.service.jca.CachedConnectionValve" cachedConnectionManagerObjectName="jboss.jca:service=CachedConnectionManager" transactionManagerObjectName="jboss:service=TransactionManager" /> </Host> </Engine> </Service> </Server>
在上面的配置文件中,Server是根節點,一個Server就表明一個Servlet容器,所以在server.xml中,這個節點只能有一個,在Server節點下,能夠存在一個或者多個Service節點。
一個Service節點表明了一個或者多個Connector和一個Engine,而Connector和Engine是在server.xml中兩個重要的配置項,Connector的主要功能是接受、響應用戶請求。經常使用的Connector有HTTP/1.1 Connector和AJP Connector,HTTP/1.1 Connector主要用於處理用戶的HTTP請求,須要注意的是雖然它名叫HTTP/1.1 Connector,可是是徹底兼容HTTP/1.0協議的。AJP Connector主要使用AJP協議和Web
Connector通訊,一般用於集羣中。
HTTP/1.1 Connector的實例監聽在用戶配置的端口上,當應用服務器啓動時,HTTP/1.1 Connector負責建立若干線程,用於處理用戶請求,建立的線程數目取決於用戶配置的minThreads值,默認爲5,當有更多的用戶請求到來時,HTTP/1.1 Connector將會建立更多的線程用於處理請求,建立線程的最大值由maxThreads定義,默認值爲20,當全部的線程都在忙於處理用戶請求時,新到來的請求將會放入HTTP/1.1 Connector建立的Socket隊列中,隊列的長度由acceptCount屬性定義,當等待隊列也被佔用滿了,新來的用戶請求將會收到connection
refused錯誤。
全部的Connector提供的配置項(不徹底版scheme, isSecure, xpoweredBy, useIPVHosts ):
Http/1.1 Connector提供的配置項: