日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

tomcat装死原因汇总

發(fā)布時(shí)間:2023/12/20 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 tomcat装死原因汇总 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

http://www.myexception.cn/open-source/921974.html


Tomcat 假死原因分析

Tomcat 假死原因分析報(bào)告


最近監(jiān)控服務(wù)發(fā)現(xiàn)有臺(tái)tomcat 的應(yīng)用出現(xiàn)了無(wú)法訪問(wèn)的情況由于已做了集群,基本沒有影響線上服務(wù)的正常使用。下面來(lái)簡(jiǎn)單描述該臺(tái)tomcat當(dāng)時(shí)具體的表現(xiàn):客戶端請(qǐng)求沒有響應(yīng),查看服務(wù)器端tomcat 的java 進(jìn)程存活,查看tomcat 的catalina.log ,沒有發(fā)現(xiàn)異常,也沒有error 日志.查看localhost_access.log 也沒有最新的訪問(wèn)日志,該臺(tái)tomcat 已不能提供服務(wù)。

? ?根據(jù)前面的假死表象,最先想到的是網(wǎng)絡(luò)是否出現(xiàn)了問(wèn)題,于是開始從請(qǐng)求的數(shù)據(jù)流程開始分析。由于業(yè)務(wù)的架構(gòu)采用的是nginx + tomcat 的集群配置,一個(gè)請(qǐng)求上來(lái)的流向可以用下圖來(lái)簡(jiǎn)單的描述。


從上圖可以看出,如果是網(wǎng)絡(luò)的原因,可以從兩個(gè)點(diǎn)進(jìn)行分析。

? ?1、從前端到nginx的網(wǎng)絡(luò)情況;

分析nginx上的access.log ,在其中一臺(tái)上可以查出當(dāng)時(shí)該條請(qǐng)求的訪問(wèn)日志,也就是說(shuō)可以排除這段網(wǎng)絡(luò)的問(wèn)題。

? ?2、從nginx 到tomcat 的網(wǎng)絡(luò)情況。

分析tomcat 的訪問(wèn)日志localhost_acess.log 上無(wú)法查出該條請(qǐng)求的訪問(wèn)日志。可以懷疑是否網(wǎng)絡(luò)有問(wèn)題。就該情況,從該臺(tái)nginx ping 了一下tomcat server ,均為正常,沒有發(fā)現(xiàn)問(wèn)題。既然網(wǎng)絡(luò)貌似沒有問(wèn)題,開始懷疑是tomcat本身的問(wèn)題,在tomcat本機(jī)直接curl 調(diào)用該條請(qǐng)求,發(fā)現(xiàn)仍然沒有響應(yīng)。到此基本可以斷定網(wǎng)絡(luò)沒有問(wèn)題,tomcat 本身出現(xiàn)了假死的情況。

基于tomcat 假死的情況,開始分析有可能的原因。造成tomcat假死有可能的情況大概有以下幾種:

一、tomcat jvm 內(nèi)存溢出

? ? ? ? ?分析當(dāng)時(shí)的gc.log ?,


7581861.927: [GC 7581861.927: [ParNew
Desired survivor size 76677120 bytes, new threshold 15 (max 15)
- age ? 1: ? ?5239168 bytes, ? ?5239168 total
: 749056K->10477K(898816K), 0.0088550 secs] 1418818K->680239K(8238848K), 0.0090350 secs]

? ? 沒有發(fā)現(xiàn)有內(nèi)存溢出的情況

? ?直接grep catalina.sh 也沒有結(jié)果,證明沒有發(fā)生內(nèi)存溢出的情況 ,,這種假死可能可以排除。

? ?grep OutOfMemoryException catalina.sh



二、jvm GC 時(shí)間過(guò)長(zhǎng),導(dǎo)致應(yīng)用暫停

? ? ? 7581088.402: [Full GC (System) 7581088.402: [CMS: 661091K->669762K(7340032K), 1.7206330 secs] 848607K->669762K(8238848K), [CMS Perm : 34999K->34976K(58372K)], 1.7209480 secs] [Times: user=1.72 sys=0.00, real=1.72 secs]

? ? ?最近的一次full gc 顯示,也不應(yīng)該會(huì)暫停幾分鐘的情況,這種假死可能可以排除。


三、load 太高,已經(jīng)超出服務(wù)的極限

? ? ? ? 當(dāng)時(shí)top一下linux

? ? ? ? top

load average: 0.02, 0.02, 0.00
Tasks: 272 total, ? 1 running, 271 sleeping, ? 0 stopped, ? 0 zombie
Cpu(s): ?0.2%us, ?0.2%sy, ?0.0%ni, 99.6%id, ?0.0%wa, ?0.0%hi, ?0.0%si, ?0.0%st
Mem: ?32950500k total, 23173908k used, ?9776592k free, ?1381456k buffers
Swap: 33551744k total, ? ? ?236k used, 33551508k free, 12320412k cached

? ? ? ? load 并不是高,,這種假死可能可以排除。

四、應(yīng)用本身程序的問(wèn)題,造成死鎖。

? ? ? ? 針對(duì)這種情況,做了一下jstack,有少量線程處于TIMED_WAITING。


"Ice.ThreadPool.Client-75" daemon prio=10 tid=0x000000005c5ed800 nid=0x4cde in Object.wait() [0x0000000047738000]
? java.lang.Thread.State: TIMED_WAITING (on object monitor)
? ? ? ?at java.lang.Object.wait(Native Method)
? ? ? ?- waiting on <0x00002aab14336a10> (a IceInternal.ThreadPool)
? ? ? ?at IceInternal.ThreadPool.followerWait(ThreadPool.java:554)
? ? ? ?- locked <0x00002aab14336a10> (a IceInternal.ThreadPool)
? ? ? ?at IceInternal.ThreadPool.run(ThreadPool.java:344)
? ? ? ?- locked <0x00002aab14336a10> (a IceInternal.ThreadPool)
? ? ? ?at IceInternal.ThreadPool.access$300(ThreadPool.java:12)
? ? ? ?at IceInternal.ThreadPool$EventHandlerThread.run(ThreadPool.java:643)
? ? ? ?at java.lang.Thread.run(Thread.java:619)

? ? ? ?"ContainerBackgroundProcessor[StandardEngine[Catalina]]" daemon prio=10 tid=0x00002aacc4347800 nid=0x651 waiting on condition [0x00000000435f7000]
? java.lang.Thread.State: TIMED_WAITING (sleeping)
? ? ? ?at java.lang.Thread.sleep(Native Method)
? ? ? ?at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1378)
? ? ? ?at java.lang.Thread.run(Thread.java:619)

"version sniffer" daemon prio=10 tid=0x00002aacc4377000 nid=0x645 in Object.wait() [0x0000000040f3c000]
? java.lang.Thread.State: TIMED_WAITING (on object monitor)
? ? ? ?at java.lang.Object.wait(Native Method)
? ? ? ?- waiting on <0x00002aaaee20b7b8> (a java.lang.Boolean)
? ? ? ?at com.panguso.map.web.service.LocateServiceFactory$IpDataVersionSniffer.run(LocateServiceFactory.java:351)
? ? ? ?- locked <0x00002aaaee20b7b8> (a java.lang.Boolean)
? ? ? ?at java.lang.Thread.run(Thread.java:619)

"ReplicaSetStatus:Updater" daemon prio=10 tid=0x000000005d070800 nid=0x636 waiting on condition [0x0000000044001000]
? java.lang.Thread.State: TIMED_WAITING (sleeping)
? ? ? ?at java.lang.Thread.sleep(Native Method)
? ? ? ?at com.mongodb.ReplicaSetStatus$Updater.run(ReplicaSetStatus.java:428)


? ?從jvm 堆棧信息可以看出,其中有可能出現(xiàn)線程鎖死的情況為:IceInternal 和訪問(wèn)mongdb 的客戶端 com.mongodb.ReplicaSetStatus$Updater類。針對(duì)這兩種情況,看了一下源碼,基本排除。



五、大量tcp 連接CLOSE_WAIT

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

TIME_WAIT 48

CLOSE_WAIT 2228

ESTABLISHED 86


常用的三個(gè)狀態(tài)是:ESTABLISHED 表示正在通信,TIME_WAIT 表示主動(dòng)關(guān)閉,CLOSE_WAIT 表示被動(dòng)關(guān)閉。



CLOSE_WAIT 從上面的圖可以看出來(lái),如果一直保持在CLOSE_WAIT 狀態(tài),那么只有一種情況,就是在對(duì)方關(guān)閉連接之后,服務(wù)器程序自己沒有進(jìn)一步發(fā)出ack 信號(hào)。換句話說(shuō),就是在對(duì)方連接關(guān)閉之后,程序里沒有檢測(cè)到,或者程序壓根就忘記了這個(gè)時(shí)候需要關(guān)閉連接,于是這個(gè)資源就一直被程序占著。個(gè)人覺得這種情況,通過(guò)服務(wù)器內(nèi)核參數(shù)也沒辦法解決,服務(wù)器對(duì)于程序搶占的資源沒有主動(dòng)回收的權(quán)利,除非終止程序運(yùn)行。

由于咱們自己使用的是HttpClient ,并且遇到了大量CLOSE_WAIT 的情況。所以懷疑這個(gè)點(diǎn)可能出了問(wèn)題。

查看了咱們的httpClient 的寫法需要改正:

HttpGet get = newHttpGet(url.toString());

InputStream ins = null;

try{

HttpResponse response = excuteHttp(httpClient, get);

// HttpResponse response = httpClient.execute(get);


if(response.getStatusLine().getStatusCode() != 200) {

thrownewMapabcPoiRequestException(

"Http response status is not OK");

}


這種寫法意味著一旦出現(xiàn)非200 的連接,InputStream ins 根本就不會(huì)被賦值,這個(gè)連接將永遠(yuǎn)僵死在連接池里頭.

解決方法:

if(response.getStatusLine().getStatusCode() != 200) {

get.abort();

thrownewMapabcPoiRequestException(


"Http response status is not OK");

}

應(yīng)該改為顯示調(diào)用HttpGetabort ,這樣就會(huì)直接中止這次連接,我們?cè)谟龅疆惓5臅r(shí)候應(yīng)該顯示調(diào)用,因?yàn)闊o(wú)法保證異常是在InputStream in 賦值之后才拋出。但是這種情況也是發(fā)生在httpClient 后端的服務(wù)出現(xiàn)了沒有響應(yīng)的情況,


轉(zhuǎn)載于:https://blog.51cto.com/liuer/1338758

總結(jié)

以上是生活随笔為你收集整理的tomcat装死原因汇总的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。