快、狠、準(zhǔn)排查各類系統(tǒng)故障的運(yùn)維套路
今天準(zhǔn)備談下對(duì)于IT人員面對(duì)技術(shù)類問(wèn)題分析和解決的一些思路和實(shí)踐總結(jié),在很早以前我就談到過(guò),對(duì)于開(kāi)發(fā)人員在后期需要的不是簡(jiǎn)單的新業(yè)務(wù)功能的設(shè)計(jì)和開(kāi)發(fā)能力,而是問(wèn)題分析和解決能力。這類問(wèn)題分析和解決本身又包括了兩個(gè)方面內(nèi)容:
- 其一是IT系統(tǒng)運(yùn)行類問(wèn)題和故障的分析和解決;
- 其二是面對(duì)復(fù)雜業(yè)務(wù)問(wèn)題時(shí)候?qū)⑵滢D(zhuǎn)化為技術(shù)解決方案能力。
在前面我講思維類文章的時(shí)候就專門(mén)談到IT人員應(yīng)該關(guān)注自己思維能力的提升,這個(gè)思維能力實(shí)際上包括了分析和認(rèn)知事物,獨(dú)立的問(wèn)題分析和解決兩個(gè)層面的內(nèi)容。
- 對(duì)于第一個(gè)層面在IT領(lǐng)域更多的就是架構(gòu)設(shè)計(jì)的能力,將現(xiàn)實(shí)的業(yè)務(wù)需求和場(chǎng)景轉(zhuǎn)化為抽象的架構(gòu)設(shè)計(jì)語(yǔ)言和架構(gòu)模型的能力;
- 而第二個(gè)層面在IT領(lǐng)域里面即是面對(duì)問(wèn)題或故障的時(shí)候進(jìn)行問(wèn)題分析診斷,假設(shè)和驗(yàn)證,快速解決的能力。
而對(duì)我們當(dāng)前很多IT人員來(lái)說(shuō),實(shí)際上兩個(gè)方面的能力都欠缺,既不能獨(dú)立的進(jìn)行整體架構(gòu)設(shè)計(jì),對(duì)負(fù)責(zé)的業(yè)務(wù)進(jìn)行自頂向下,分而治之的建模和設(shè)計(jì)。也不能在面對(duì)生產(chǎn)環(huán)境關(guān)鍵故障或問(wèn)題的時(shí)候快速定位,并找到根源快速解決。而是將自己大量的時(shí)間花費(fèi)在重復(fù)的事務(wù)性工作上,花費(fèi)在對(duì)各類新技術(shù)的狂熱追求上。
實(shí)際上自己也從不反對(duì)保持對(duì)新技術(shù)的學(xué)習(xí)興趣。但是任何新技術(shù),如果你實(shí)際的工作環(huán)境沒(méi)有實(shí)踐的機(jī)會(huì),那么大量新技術(shù)下應(yīng)該出現(xiàn)的類似性能,安全,可靠性等問(wèn)題你都無(wú)法真正得到實(shí)踐驗(yàn)證和解決。
在這種情況下對(duì)新技術(shù)也只能夠停留在理論階段而無(wú)太大意義。
對(duì)于問(wèn)題分析和解決的核心邏輯,可以先參考我前面發(fā)布的文章:《問(wèn)題分析和解決邏輯-麥肯錫七步成詩(shī)僅是開(kāi)始》(http://blog.sina.com.cn/s/blog_493a84550102z8l9.html) 在前面這篇文章里面,結(jié)合麥肯錫問(wèn)題分析七步法,對(duì)問(wèn)題分析核心邏輯進(jìn)行了詳細(xì)的描述。
一、技術(shù)問(wèn)題解決的關(guān)鍵點(diǎn)
我寫(xiě)過(guò)不少的關(guān)于技術(shù)問(wèn)題分析和診斷的文章,這些問(wèn)題基本也是來(lái)源于真實(shí)的項(xiàng)目實(shí)踐。
即使到現(xiàn)在有些問(wèn)題也沒(méi)有完全得到定位和最終解決,包括我們找了Oracle專家和顧問(wèn),也不是說(shuō)馬上就能夠滿足我們解決掉該技術(shù)問(wèn)題。
簡(jiǎn)單來(lái)說(shuō),如果一個(gè)技術(shù)問(wèn)題,你能夠直接快速的根據(jù)異?;騿?wèn)題關(guān)鍵字在網(wǎng)上搜索到相關(guān)的答案,這種問(wèn)題都談不上真正有挑戰(zhàn)的技術(shù)問(wèn)題。
對(duì)于技術(shù)問(wèn)題的解決,基于前面實(shí)踐的問(wèn)題定位、分析和解決的思路,我還是想談下在解決技術(shù)問(wèn)題中的一些關(guān)鍵點(diǎn)和思考邏輯方面的內(nèi)容。
1、個(gè)人前期大量實(shí)踐經(jīng)驗(yàn)的積累
這點(diǎn)相當(dāng)重要,任何知識(shí)庫(kù),搜索都代替不了個(gè)人已有的知識(shí)經(jīng)驗(yàn)積累。
為什么說(shuō)工作經(jīng)驗(yàn)很值錢(qián)?
往往就是因?yàn)槟阍谝粋€(gè)專業(yè)領(lǐng)域有大量實(shí)踐積累,大量問(wèn)題分析解決經(jīng)驗(yàn)積累。這些經(jīng)驗(yàn)可以幫助你在遇到問(wèn)題的時(shí)候快速地對(duì)問(wèn)題進(jìn)行預(yù)判和定位,包括提出最可能的假設(shè)路徑。
當(dāng)前解決問(wèn)題,很多都是非結(jié)構(gòu)化解決問(wèn)題方法,即是優(yōu)先提出最可能的假設(shè),然后再去驗(yàn)證假設(shè)是否能夠真正解決問(wèn)題。
那么有經(jīng)驗(yàn)的人往往就最容易提出最可能的假設(shè)路徑,而減少對(duì)各種不可能彎路的嘗試。一個(gè)問(wèn)題本身有A到E五個(gè)獨(dú)立假設(shè)路徑,而最可能路徑是A,你解決問(wèn)題速度慢的原因往往就是你最后才假設(shè)和嘗試到A路徑并解決問(wèn)題,而有經(jīng)驗(yàn)的人往往一開(kāi)始就選擇了假設(shè)A進(jìn)行驗(yàn)證。
要積累這種經(jīng)驗(yàn),必須在問(wèn)題解決后及時(shí)復(fù)盤(pán),將其抽象為經(jīng)驗(yàn)和方法論。
問(wèn)題定位的重點(diǎn)就是縮小范圍和確定邊界。一個(gè)問(wèn)題出現(xiàn)之后最重要的就是快速的定位。
比如一個(gè)業(yè)務(wù)系統(tǒng)查詢故障,要快速的定位是基礎(chǔ)設(shè)施資源的問(wèn)題,還是數(shù)據(jù)庫(kù)和中間件的問(wèn)題,還是說(shuō)程序的問(wèn)題。
如果是程序的問(wèn)題,又需要馬上定位到究竟是前端的問(wèn)題,還是邏輯層的問(wèn)題或數(shù)據(jù)庫(kù)的問(wèn)題。
只有快速的確定邊界和定位問(wèn)題,才能夠有針對(duì)性的去解決問(wèn)題。任何問(wèn)題的定位都是追溯到引發(fā)問(wèn)題的根源,而不是解決問(wèn)題的表象,類似頭痛醫(yī)頭腳痛醫(yī)腳。
那么如何縮小范圍和快速的確定邊界?
比如我們假設(shè)一個(gè)最簡(jiǎn)單的場(chǎng)景:?jiǎn)栴}的產(chǎn)生經(jīng)歷了A-》B的兩個(gè)過(guò)程。那么如何快速的確定問(wèn)題是在A階段產(chǎn)生的還是在B階段產(chǎn)生的呢?
對(duì)于這個(gè)問(wèn)題,我們有如下的問(wèn)題定位方法和思路可以參考和借鑒:
- 替換法:比如將A替換為A1,如果問(wèn)題消失,那么說(shuō)明問(wèn)題出在A階段;
- 斷點(diǎn)法:在A和B之間設(shè)置斷點(diǎn)監(jiān)控輸出,判斷A輸出是否正常;
- 假設(shè)法:假設(shè)A階段有問(wèn)題,對(duì)A階段的參數(shù)進(jìn)行調(diào)整,觀察問(wèn)題是否解決。
當(dāng)然還有其他很多的問(wèn)題定位方法,但是對(duì)于所有問(wèn)題定位和確定邊界的方法中,最有效的仍然是類似于快速查找中的二分法,通過(guò)二分法可以快速的幫助我們縮小范圍和定位問(wèn)題。
我們進(jìn)一步對(duì)上面邏輯舉例說(shuō)明,比如一個(gè)軟件應(yīng)用出現(xiàn)Bug的場(chǎng)景,如下圖:
可以看到看到要分析和定位Bug為何困難?
引入問(wèn)題既可能是我們的輸入出現(xiàn)錯(cuò)誤,我們面對(duì)的軟硬件環(huán)境運(yùn)行狀態(tài)有問(wèn)題,也可能是我們實(shí)際程序處理構(gòu)成出現(xiàn)問(wèn)題。
即使你定位到程序處理問(wèn)題,那么還可能是邏輯層,數(shù)據(jù)訪問(wèn)層或數(shù)據(jù)庫(kù)多個(gè)點(diǎn)導(dǎo)致的問(wèn)題。
2、善用搜索引擎
要明白,任何你遇到過(guò)的技術(shù)問(wèn)題,往往都有前人遇到過(guò),踩過(guò)坑,并總結(jié)和分享到互聯(lián)網(wǎng)上面。因此善用互聯(lián)網(wǎng)和搜索引擎,進(jìn)行基于問(wèn)題關(guān)鍵字的技術(shù)檢索仍然是解決技術(shù)問(wèn)題的關(guān)鍵途徑。
即使搜索引擎沒(méi)有幫助我們解決最終的問(wèn)題,往往也會(huì)幫助我們?cè)谒阉鞯倪^(guò)程中學(xué)習(xí)與該技術(shù)問(wèn)題相關(guān)的很多知識(shí)。
要搜索,一個(gè)重點(diǎn)就是選擇搜索的關(guān)鍵字,對(duì)于關(guān)鍵字的選擇沒(méi)有一次就選擇準(zhǔn)確的話,自己就要多次嘗試和迭代,直到能夠準(zhǔn)確的描述問(wèn)題為止,同時(shí)在搜索的過(guò)程中搜索的答案往往也可以幫助你進(jìn)一步的細(xì)化關(guān)鍵字。
比如對(duì)于系統(tǒng)運(yùn)行故障或問(wèn)題,對(duì)于關(guān)鍵字的描述,應(yīng)該包括:
- 從數(shù)據(jù)庫(kù),中間件和業(yè)務(wù)系統(tǒng)錯(cuò)誤日志中提取關(guān)鍵字信息;
- 從你產(chǎn)生問(wèn)題的環(huán)境,背景,場(chǎng)景中增加縮小檢索范圍的關(guān)鍵字信息;
- 從搜索到的網(wǎng)頁(yè)中挖掘更加有意義的描述類似問(wèn)題的關(guān)鍵字信息。
同時(shí)對(duì)于搜索而言,特別是技術(shù)問(wèn)題的搜索,有官方知識(shí)庫(kù)的要優(yōu)先搜索官方的知識(shí)庫(kù):比如對(duì)于Oracle產(chǎn)品相關(guān)的技術(shù)問(wèn)題,我們也會(huì)先搜索Oracle官方的Support網(wǎng)站,同時(shí)搜索類似StackOverFlow網(wǎng)站,這些網(wǎng)站往往有更加全部的技術(shù)問(wèn)題解決文章。
搜索技術(shù)文章,那么國(guó)外的技術(shù)網(wǎng)站相對(duì)來(lái)說(shuō)更加全面,而對(duì)于百度這塊相對(duì)弱,很多國(guó)外技術(shù)網(wǎng)站內(nèi)容甚至都搜索不到,這時(shí)候可以嘗試Google或Bing搜索。
3、技術(shù)問(wèn)題解決和復(fù)盤(pán)
在前期我們實(shí)施Oracle SOA項(xiàng)目的時(shí)候,遇到了將服務(wù)封裝和注冊(cè)接入到OSB后,客戶端消費(fèi)和調(diào)用服務(wù)出現(xiàn)消息報(bào)文內(nèi)容被截?cái)嗟膯?wèn)題。
由于該問(wèn)題出現(xiàn)概率不高,并且消費(fèi)端系統(tǒng)本身有重試機(jī)制,也暫時(shí)不影響到具體的OSB服務(wù)運(yùn)行和使用。雖然到現(xiàn)在為止,造成該問(wèn)題的原因究竟是客戶端服務(wù)器配置,負(fù)載均衡,網(wǎng)絡(luò),報(bào)文本身,OSB套件本身的Bug缺陷等哪方面還沒(méi)有最終確認(rèn),但是整個(gè)問(wèn)題排查和分析過(guò)程還是有意義的。
在問(wèn)題排查和分析過(guò)程中,對(duì)于各類超時(shí)時(shí)間的含義,OSB的一些關(guān)鍵配置,報(bào)文解析,Http Post報(bào)文發(fā)送長(zhǎng)短連接,Tomcat的一些配置都進(jìn)行了了解,同時(shí)通過(guò)該問(wèn)題的分析,也發(fā)現(xiàn)了在技術(shù)問(wèn)題分析過(guò)程中的一些問(wèn)題,供后面在分析問(wèn)題中借鑒和參考。
4、確定問(wèn)題邊界始終是最重要的
客戶端發(fā)送報(bào)文到服務(wù)器端接收?qǐng)?bào)文,當(dāng)前現(xiàn)象是客戶端Log日志報(bào)文是完整的,而OSB上Log的日志報(bào)文不完整。
那么究竟是客戶端,服務(wù)端,還是網(wǎng)絡(luò)傳輸過(guò)程中出現(xiàn)的問(wèn)題?這個(gè)問(wèn)題邊界的確定相當(dāng)重要。
實(shí)際上在幾天的問(wèn)題分析和排查中對(duì)于問(wèn)題邊界一直沒(méi)有最終確認(rèn),導(dǎo)致問(wèn)題也一直沒(méi)有很肯定的得到定位究竟在哪里,也導(dǎo)致最終問(wèn)題沒(méi)有得到明確的解決和排查。
比如上面說(shuō)的消息報(bào)文不完整這個(gè)問(wèn)題,要確定邊界實(shí)際上常規(guī)思路也就兩種,
- 一種就是修改程序代碼進(jìn)行更加詳細(xì)的日志記錄;
- 另外一種就是增加Trace監(jiān)控。
比如該問(wèn)題可以在客戶端進(jìn)行Http或TCP Trace,同時(shí)在服務(wù)器端也進(jìn)行Http TCP Trace,通過(guò)兩邊的Trace信息才能夠最終確定問(wèn)題的邊界在哪里。
但是在生產(chǎn)環(huán)境很難這樣去做,
- 一個(gè)是接口服務(wù)調(diào)用并發(fā)量大導(dǎo)致Trace日志的量也巨大,而且不止這一個(gè)接口服務(wù)在調(diào)用;
- 一個(gè)是協(xié)調(diào)的需要配合的資源也太多,很難去聯(lián)合排查和跟蹤。
5、問(wèn)題復(fù)現(xiàn)很重要
故障的復(fù)現(xiàn)是我們分析和定位問(wèn)題的一個(gè)基礎(chǔ),問(wèn)題如果隨機(jī)偶然發(fā)生往往是最難解決的。當(dāng)你面對(duì)問(wèn)題的時(shí)候,你需要定位,那就需要問(wèn)題能夠復(fù)現(xiàn)才方便不斷地去Debug或Trace。
在該問(wèn)題的解決過(guò)程中,由于該異常是偶然出現(xiàn),不定時(shí)而且是沒(méi)有規(guī)律出現(xiàn),所以也給我們排查問(wèn)題造成了很大的麻煩。
雖然在問(wèn)題排查過(guò)程中,我將出現(xiàn)問(wèn)題的異常日志,和前后正常的實(shí)例都進(jìn)行了導(dǎo)出分析,對(duì)出現(xiàn)問(wèn)題的服務(wù)器Server節(jié)點(diǎn)、調(diào)用方、調(diào)用時(shí)間段都進(jìn)行了分析,但是沒(méi)有明顯的發(fā)現(xiàn)出現(xiàn)問(wèn)題的規(guī)律究竟在哪里。
同時(shí)該問(wèn)題具有很高的隨機(jī)性,往往是第一次調(diào)用不成功,但是同樣的報(bào)文在第二次或第三次就調(diào)用成功,同時(shí)每次對(duì)于報(bào)文的截?cái)嚅L(zhǎng)度都不相同。這導(dǎo)致很難分析具體什么場(chǎng)景下調(diào)用不成功。
即由于問(wèn)題不能在特定的輸入條件下重現(xiàn),導(dǎo)致我們很難對(duì)問(wèn)題進(jìn)行進(jìn)一步的分析和定位,也導(dǎo)致我們很難去進(jìn)行特定的跟蹤和邊界確定。同時(shí)也很難在測(cè)試環(huán)境對(duì)該問(wèn)題進(jìn)行進(jìn)一步的分析,和各種參數(shù)條件修改后的測(cè)試和驗(yàn)證。
即由于問(wèn)題不能在特定的輸入條件下重現(xiàn),導(dǎo)致我們很難對(duì)問(wèn)題進(jìn)行進(jìn)一步的分析和定位,也導(dǎo)致我們很難去進(jìn)行特定的跟蹤和邊界確定。同時(shí)也很難在測(cè)試環(huán)境對(duì)該問(wèn)題進(jìn)行進(jìn)一步的分析,和各種參數(shù)條件修改后的測(cè)試和驗(yàn)證。
以上都導(dǎo)致問(wèn)題很難快速定位和分析,只能夠大范圍的場(chǎng)景+異常的關(guān)鍵字搜索,然后搜索到相關(guān)的可能解決方案后,一個(gè)個(gè)的去嘗試看是否能夠解決。
但是,這種方式帶來(lái)巨大的問(wèn)題,即:
由于測(cè)試環(huán)境問(wèn)題不復(fù)現(xiàn),我們無(wú)法在測(cè)試環(huán)境做這個(gè)事情。那么搜索到的解決方案驗(yàn)證只能夠在生產(chǎn)環(huán)境做,但是生產(chǎn)環(huán)境根據(jù)規(guī)定是絕對(duì)不允許隨意去修改配置和調(diào)整參數(shù)的。
這也正是我們看到很多大型IT項(xiàng)目上線,往往會(huì)預(yù)留3個(gè)月左右的試運(yùn)行期間的原因,在試運(yùn)行期間生產(chǎn)環(huán)境的日常運(yùn)維和配置修改不會(huì)嚴(yán)格受控管理,也方便及時(shí)分析和解決問(wèn)題。
6、網(wǎng)上搜索很難搜索到完全一致的異常場(chǎng)景
由于項(xiàng)目采用的Oracle SOA Suite 12c套件產(chǎn)品,當(dāng)前在國(guó)內(nèi)并沒(méi)有大范圍的應(yīng)用,所以如果用百度搜索基本搜索不到有用信息,改用Google或Bing很多信息也無(wú)法搜索到。
因此在該問(wèn)題的排查過(guò)程中,我們基本都在Oracle Support網(wǎng)站進(jìn)行了所有相關(guān)知識(shí)點(diǎn)的排查,同時(shí)選擇各類關(guān)鍵字進(jìn)行搜索引擎的搜索,其中包括了:
- Weblogic Tomcat Post Timeout KeepAliveOSB-;
- 長(zhǎng)連接 超時(shí) OSB-382030;
- Failed to parse XML text等。
但是并沒(méi)有搜索到完全一致的場(chǎng)景。
對(duì)于一個(gè)最相似的關(guān)于Failed to parse XML document的場(chǎng)景,我們進(jìn)行了相關(guān)的調(diào)整,即將KeepAlive設(shè)置為False,同時(shí)對(duì)Post Timeout設(shè)置為120秒,但是仍然出現(xiàn)在120秒超時(shí)時(shí)間到達(dá)后任何沒(méi)有Post到完整的請(qǐng)求而導(dǎo)致超時(shí)的問(wèn)題。
由于無(wú)法搜索到完全類似的場(chǎng)景,也導(dǎo)致我們很難根據(jù)網(wǎng)上給出的方法進(jìn)行進(jìn)一步測(cè)試和驗(yàn)證。并且Oracle顧問(wèn)對(duì)于該問(wèn)題也只能給出進(jìn)行Tcp Trace的無(wú)用建議。
7、關(guān)鍵基礎(chǔ)技術(shù)知識(shí)缺乏,導(dǎo)致問(wèn)題分析和提出假設(shè)不合理
在原來(lái)問(wèn)題的分析和解決中,由于搜索引擎往往會(huì)給出完全類似的場(chǎng)景,我們只需要根據(jù)搜索引擎給出的排查思路對(duì)問(wèn)題進(jìn)行排查即可。
因此解決起來(lái)效率很高,對(duì)于具體底層原理性的內(nèi)容我們并不需要掌握和了解,只需要能夠選擇合適的關(guān)鍵字,通過(guò)搜索引擎搜索到最合適的內(nèi)容然后進(jìn)行排查即可。
但是這次問(wèn)題,特殊點(diǎn)就在于搜索引擎根本無(wú)法給出完全類似的文章。這就導(dǎo)致需要基于問(wèn)題提出各種合理的假設(shè),并對(duì)假設(shè)進(jìn)行逐一驗(yàn)證。
那么如何提出合理的假設(shè)?
這里就涉及到對(duì)于TCP底層協(xié)議,各個(gè)超時(shí)值的含義和原理,Tomcat Server的參數(shù)配置,OSB代理服務(wù)的解析過(guò)程,Weblogic的關(guān)鍵參數(shù)配置和含義,負(fù)載均衡策略,乃至Docker容器和IP映射等很多內(nèi)容都有技術(shù)積累才可能提出最合理的思路。
比如在排查過(guò)程中,我會(huì)想到是否需要將Tomcat 的MaxPostSize值調(diào)大的假設(shè),但是該異常是Tomcat向Weblogic Server進(jìn)行Post請(qǐng)求發(fā)送數(shù)據(jù),對(duì)于Tomcat 的MaxPostSize根本不會(huì)影響到這個(gè)Post請(qǐng)求,而只有Weblogic上的Post Size才會(huì)有影響。這個(gè)假設(shè)本身就不合理。而要快速的判斷這些假設(shè)不合理,你就必須提前有這些關(guān)鍵的基礎(chǔ)技術(shù)知識(shí)和背景積累。
包括對(duì)于Keep Alive長(zhǎng)連接,Keep Alive的Time out超時(shí)時(shí)間設(shè)置是否會(huì)對(duì)該服務(wù)異常調(diào)用操作影響,實(shí)際上由于對(duì)Keep Alive長(zhǎng)連接和各類Timeout的具體含義理解的并不深入,也使得很難判定究竟是否有影響,也只能是注意嘗試去排除可能性,這些也都導(dǎo)致了很難快速的定位出問(wèn)題根源究竟在哪里。
8、涉及到外圍干系人協(xié)同時(shí)問(wèn)題解決困難
這個(gè)也是解決服務(wù)接口問(wèn)題的一個(gè)關(guān)鍵影響。對(duì)于接口服務(wù)運(yùn)行問(wèn)題,往往涉及到業(yè)務(wù)系統(tǒng)消費(fèi)方,業(yè)務(wù)系統(tǒng)提供方,OSB服務(wù)總線,網(wǎng)絡(luò),負(fù)載均衡設(shè)備等多個(gè)相關(guān)因素和廠商。
對(duì)于一個(gè)問(wèn)題的排查往往需要協(xié)調(diào)多方的資源在約定的時(shí)間相互配合才能夠完成,這些都直接導(dǎo)致排查難度很大,很難依靠個(gè)人一方力量就完成。
在原來(lái)類似大項(xiàng)目實(shí)施過(guò)程中,也經(jīng)常會(huì)遇到這些接口問(wèn)題的分析和排查,往往也都是問(wèn)題造成嚴(yán)重影響后,各方才會(huì)真正重視該問(wèn)題,并各自協(xié)調(diào)資源形成聯(lián)合的問(wèn)題排查團(tuán)隊(duì)進(jìn)行問(wèn)題分析和排查,最終才能夠解決問(wèn)題。
雖然截止現(xiàn)在問(wèn)題沒(méi)有得到最終解決,但是整個(gè)分析過(guò)程仍然有意義,特進(jìn)行本文總結(jié)。
二、問(wèn)題復(fù)盤(pán)-文件句柄打開(kāi)過(guò)多
在前面已經(jīng)談到,問(wèn)題分析解決后需要及時(shí)復(fù)盤(pán),對(duì)于問(wèn)題復(fù)盤(pán)不是簡(jiǎn)單的問(wèn)題解決總結(jié),而是對(duì)整個(gè)問(wèn)題分析思考過(guò)程進(jìn)行梳理,包括在問(wèn)題解決中究竟踩了哪些坑,走了哪些彎路,這些經(jīng)驗(yàn)教訓(xùn)對(duì)后續(xù)問(wèn)題的解決有哪些參考意義等。
問(wèn)題描述:服務(wù)器響應(yīng)很慢,服務(wù)調(diào)用出現(xiàn)超時(shí),接著查詢相關(guān)的錯(cuò)誤日志信息。在錯(cuò)誤日志信息里面包括了IO Exception的too many open files信息,也包括了socket receive time out的socket連接超時(shí)的信息。
1、應(yīng)用服務(wù)器監(jiān)控情況檢查
在拿到這個(gè)問(wèn)題后,由于原來(lái)也出現(xiàn)過(guò)服務(wù)響應(yīng)慢和調(diào)用超時(shí)的問(wèn)題,所以首先排查的是應(yīng)用服務(wù)器本身的健康狀況,因此開(kāi)始用jstat檢查服務(wù)器本身的cpu和內(nèi)存的使用情況,經(jīng)過(guò)檢查服務(wù)器本身完全正常。
2、數(shù)據(jù)庫(kù)連接池和線程池檢查
在檢查這個(gè)后接著檢查數(shù)據(jù)庫(kù)連接池和線程池的情況,經(jīng)過(guò)檢查雖然有排隊(duì)情況,但是連接池本身都還有大量剩余,也不存在連接池超了的情況。
3、錯(cuò)誤日志檢查
在這個(gè)檢查完后回到問(wèn)題錯(cuò)誤日志,由于當(dāng)前有兩個(gè)錯(cuò)誤,即:
- 問(wèn)題A文件打開(kāi)過(guò)多,問(wèn)題B服務(wù)連接超時(shí),那現(xiàn)在有一個(gè)關(guān)鍵問(wèn)題就是究竟是A問(wèn)題導(dǎo)致了問(wèn)題B,還是B問(wèn)題導(dǎo)致了問(wèn)題A,還是A和B本身就是在同一時(shí)間導(dǎo)致的兩個(gè)本身不相關(guān)的問(wèn)題,在這個(gè)時(shí)候其實(shí)并沒(méi)有完全肯定的結(jié)論。
這就導(dǎo)致我們需要從兩條問(wèn)題路徑去查找問(wèn)題的根源,然后再進(jìn)行總結(jié)和收斂。
要知道對(duì)于問(wèn)題B連接超時(shí),Oracle官方的Support網(wǎng)站知識(shí)庫(kù)包括問(wèn)題解決的6到7個(gè)場(chǎng)景的排查,整個(gè)排除起來(lái)是相當(dāng)困難的。
而且該問(wèn)題是老服務(wù)器出現(xiàn)的新問(wèn)題,而不是完全新增加服務(wù)器出現(xiàn)的問(wèn)題。那必須就要考慮是否和新部署和上線的服務(wù)和應(yīng)用有關(guān)系。
4、回溯近期所做的代碼變更
現(xiàn)在回到文件打開(kāi)數(shù)過(guò)多的問(wèn)題,經(jīng)過(guò)基本問(wèn)題查看,發(fā)現(xiàn)的就是文件句柄打開(kāi)太多,那么我們要做的就是對(duì)新增加的修改和變更進(jìn)行查看,還是否存在文件句柄沒(méi)有關(guān)閉的情況。
5、異常-》文件打開(kāi)太多-》進(jìn)一步定位是哪些文件
經(jīng)過(guò)代碼的Review我們沒(méi)有發(fā)現(xiàn)這種情況。那接著很自然就是要進(jìn)一步去定位和分析究竟哪些文件句柄打開(kāi)沒(méi)有關(guān)閉?
而查這個(gè)問(wèn)題的方法是lsof進(jìn)行l(wèi)og數(shù)據(jù),有發(fā)現(xiàn)我們的hpunix小型機(jī)居然這個(gè)命令無(wú)法使用,沒(méi)有辦法我們先單純的調(diào)高的最大文件打開(kāi)數(shù)現(xiàn)狀但是問(wèn)題依然存在。
注意在這個(gè)時(shí)候我們停在這里了,沒(méi)有進(jìn)一步去想如何解決這個(gè)問(wèn)題,而轉(zhuǎn)到去分析服務(wù)超時(shí)問(wèn)題。
注:當(dāng)我們?cè)谶M(jìn)行問(wèn)題分析診斷的時(shí)候,選擇的沒(méi)有問(wèn)題的標(biāo)準(zhǔn)解決路徑,不要輕易因?yàn)樽璧K而放棄,你會(huì)發(fā)現(xiàn)最終你又會(huì)回到這個(gè)關(guān)鍵路徑上。
在面對(duì)服務(wù)超時(shí)的問(wèn)題的時(shí)候,我們又走了彎路,即直接根據(jù)metalink排查方式對(duì)各個(gè)問(wèn)題場(chǎng)景進(jìn)行分析和排除,對(duì)中間件的參數(shù)和設(shè)置進(jìn)行了大量的修改,但是最終該問(wèn)題還是沒(méi)有解決。
之所以說(shuō)走了彎路的原因主要在于沒(méi)有很好地去分析當(dāng)前服務(wù)器出現(xiàn)服務(wù)超時(shí)的具體原因,對(duì)應(yīng)當(dāng)前場(chǎng)景沒(méi)有做具體的分析。
6、進(jìn)一步分析問(wèn)題產(chǎn)生的場(chǎng)景和邊界
所以后續(xù)還是回到當(dāng)前場(chǎng)景的分析,在當(dāng)前服務(wù)器我們新增加部署了哪些服務(wù),這些服務(wù)是否需要逐個(gè)進(jìn)行排除,我們實(shí)際的服務(wù)運(yùn)行是都超時(shí),還是個(gè)別服務(wù)超時(shí)?這個(gè)服務(wù)超時(shí)究竟是發(fā)生在哪邊?具體的邊界在哪里這些問(wèn)題都需要進(jìn)一步搞清楚才能有后續(xù)行動(dòng)。
1)邊界確認(rèn):不是所有服務(wù)調(diào)用都超時(shí)
第一個(gè)情況就是不是所有的服務(wù)都出現(xiàn)超時(shí)的問(wèn)題,主要出現(xiàn)超時(shí)的服務(wù)都是某種類型的服務(wù),然后我們對(duì)超時(shí)的服務(wù)和服務(wù)超時(shí)日志進(jìn)行排除,包括具體的防火墻設(shè)置,長(zhǎng)事務(wù)運(yùn)行的服務(wù)本身等。
2)邊界確認(rèn):不止是新增加的服務(wù)超時(shí),老服務(wù)也超時(shí)
現(xiàn)超時(shí)的服務(wù)并不是都是新增加的服務(wù),也包括了已經(jīng)有的老的服務(wù)運(yùn)行,確實(shí)是一個(gè)很奇怪的現(xiàn)象。在服務(wù)超時(shí)設(shè)置參數(shù)都進(jìn)行調(diào)整后,繼續(xù)觀察服務(wù)器的健康狀況和錯(cuò)誤日志記錄,發(fā)現(xiàn)繼續(xù)出現(xiàn)too many files open的錯(cuò)誤。
在這個(gè)時(shí)候發(fā)現(xiàn)還是得回到too many file open這個(gè)異常日志上進(jìn)行進(jìn)一步的分析原因。
7、回歸到在hpunix上安裝lsof組件
要詳細(xì)分析必須有詳細(xì)的log日志以進(jìn)行定位,到這個(gè)時(shí)候發(fā)現(xiàn)還是必須首先得安裝上lsof組件,接著就是查找資料重新在hpunix上安裝上lsof組件,組件安裝后進(jìn)行詳細(xì)的lsof日志。
然后每1個(gè)小時(shí)左右新取一次lsof的數(shù)據(jù),通過(guò)對(duì)lsof數(shù)據(jù)的分析發(fā)現(xiàn)確實(shí)存在文件句柄不斷的增加而無(wú)法釋放的情況。
到了這一步后出現(xiàn)兩個(gè)小問(wèn)題分支:
- 一個(gè)是對(duì)lsof數(shù)據(jù)發(fā)現(xiàn)對(duì)oracle數(shù)據(jù)庫(kù)連接使用的是1524后門(mén)端口,開(kāi)始懷疑是這個(gè)端口使用有問(wèn)題,但是后面否定了該假設(shè);
- 那還是回到文件句柄問(wèn)題上。
那這個(gè)問(wèn)題的關(guān)鍵就是:究竟是哪些文件句柄不算在增加?
后面對(duì)lsof日志進(jìn)行詳細(xì)分析,發(fā)現(xiàn)了總是60多個(gè)文件句柄不斷的在增加和打開(kāi),這些文件句柄反復(fù)打開(kāi)多次,而且file inode值也是一樣的,到了這個(gè)時(shí)候關(guān)鍵的想法就是如何通過(guò)file inode查找到具體是哪些文件?
因?yàn)樵趯?shí)際的日志記錄中只有文件的路徑而沒(méi)有文件的名稱,一時(shí)在這個(gè)地方停滯。
到了這一步,沒(méi)有辦法,要做的還是詳細(xì)的研究lsof日志中的每一個(gè)字段的具體含義,找尋如何通過(guò)file inode找尋到具體文件的方法。
那先想到的就是文件系統(tǒng)中的文件本身是否有inode的說(shuō)法,后面看到通過(guò)ls命令是可以查找到每個(gè)文件的文件句柄的。那自然我們可以對(duì)所有的文件通過(guò)ls查找并導(dǎo)出inode信息,然后和lsof中的文件句柄進(jìn)行比對(duì)找到具體的文件。
根據(jù)該思路我們到處所有文件屬性信息進(jìn)行比對(duì),最終找到文件句柄不斷打開(kāi)的文件是哪些。
一看到這些文件在不斷的打開(kāi),問(wèn)題根源點(diǎn)基本就找到了,這些文件都是和我們的底層一個(gè)服務(wù)組件有關(guān)系的,那么接著看打開(kāi)這些文件的方法,在打開(kāi)這些文件的使用完成后釋放及時(shí)進(jìn)行了資源的釋放。
8、源碼最終定位-saxReader類文件處理
經(jīng)過(guò)源代碼分析,發(fā)現(xiàn)了具體的問(wèn)題就是文件不斷的打開(kāi),但是不是手工對(duì)文件句柄進(jìn)行關(guān)閉。
但是我們的生產(chǎn)環(huán)境為何沒(méi)有出現(xiàn)通用的問(wèn)題,這個(gè)是和saxReader類處理文件的方法是有關(guān)系的,saxReader類對(duì)文件是會(huì)進(jìn)行關(guān)閉,但是具體時(shí)間我們并不清楚。
那生產(chǎn)環(huán)境為何沒(méi)有出現(xiàn)同樣的問(wèn)題,是否是在fgc的時(shí)候會(huì)進(jìn)行回收,這個(gè)也只是一個(gè)假設(shè),暫時(shí)沒(méi)有做進(jìn)一步的驗(yàn)證,但是至少分析出對(duì)于文件的大量持續(xù)打開(kāi)肯定是需要修改的。
在對(duì)代碼進(jìn)行修改后重新部署,部署完成后進(jìn)行觀察,沒(méi)有再進(jìn)一步出現(xiàn)過(guò)too many files的文件IO異常。但是接著還是繼續(xù)出現(xiàn)一些服務(wù)超時(shí)異常。
9、問(wèn)題因果要分清
但是任何服務(wù)超時(shí)異常都不會(huì)再引起too many files打開(kāi)的異常,突然發(fā)現(xiàn)剛開(kāi)始出現(xiàn)的問(wèn)題A和問(wèn)題B,實(shí)質(zhì)是反應(yīng)出了我們當(dāng)前應(yīng)用存在兩個(gè)偏獨(dú)立的問(wèn)題,雖然兩個(gè)問(wèn)題間可能存在相互影響,但是問(wèn)題本身偏獨(dú)立,都有各自的問(wèn)題導(dǎo)致根源。
在進(jìn)一步分析服務(wù)超時(shí)問(wèn)題的時(shí)候,我們對(duì)服務(wù)調(diào)用調(diào)用詳細(xì)日志數(shù)據(jù)進(jìn)行分析,發(fā)現(xiàn)大多數(shù)服務(wù)都是正常的,而僅僅是個(gè)別服務(wù)出現(xiàn)了服務(wù)調(diào)用超時(shí)的問(wèn)題,那么接著還是對(duì)單獨(dú)的個(gè)別服務(wù)進(jìn)行原因查找。
由于是個(gè)別服務(wù)的問(wèn)題,我們完全可以懷疑是服務(wù)提供方系統(tǒng)出現(xiàn)了問(wèn)題,那么就需要對(duì)服務(wù)提供方提供的服務(wù)能力進(jìn)行原因定位和查找,最終找到了一個(gè)原因即對(duì)方的操作導(dǎo)致了對(duì)方數(shù)據(jù)庫(kù)出現(xiàn)死鎖而服務(wù)一直處于等待和鎖定狀態(tài),基于這個(gè)假設(shè)我們后續(xù)進(jìn)行了證實(shí)確實(shí)是該原因。
到這一步基本所有的問(wèn)題根源點(diǎn)和原因都基本確認(rèn)清楚,通過(guò)該次問(wèn)題定位,分析和解決,進(jìn)一步完善了對(duì)應(yīng)服務(wù)應(yīng)用性能和問(wèn)題定位的分析和解決方法,從CPU內(nèi)存再到IO,從服務(wù)異常日志再到服務(wù)詳細(xì)的調(diào)用日志信息,基本形成了一個(gè)完整的診斷方法。
三、問(wèn)題復(fù)盤(pán)-服務(wù)調(diào)用超時(shí)
最近跟蹤OSB服務(wù)運(yùn)行超時(shí),發(fā)現(xiàn)一個(gè)很奇怪的現(xiàn)場(chǎng),即在調(diào)用業(yè)務(wù)系統(tǒng)的時(shí)候出現(xiàn)1500秒超時(shí)返回的情況。而在OSB本身做服務(wù)封裝設(shè)置的時(shí)候,我們會(huì)設(shè)置兩個(gè)時(shí)間,如下:
- Socket Read Time out : 該超時(shí)設(shè)置為600s;
- Connectoin Time out:連接超時(shí)設(shè)置為30s。
也就是說(shuō)實(shí)際在OSB配置里面并沒(méi)有出現(xiàn)過(guò)1500秒超時(shí)的任何配置情況。
后面詢問(wèn)業(yè)務(wù)系統(tǒng),得到的答復(fù)是業(yè)務(wù)系統(tǒng)那邊有5分鐘,即300s的超時(shí)設(shè)置。但是即使如此,也應(yīng)該是返回300s的超時(shí)錯(cuò)誤,而不是1500s。
一開(kāi)始我們始終在分析,是否是300s超時(shí),重試了5次,導(dǎo)致看到的最終超時(shí)設(shè)置是1500s,因此我們將OSB的所有配置參數(shù)又全部檢查了一遍,結(jié)果沒(méi)有檢查到任何的有5分鐘的超時(shí)配置項(xiàng),同時(shí)也沒(méi)有檢查到有任何的重試次數(shù)是5次的檢查項(xiàng)。
在OSB業(yè)務(wù)服務(wù)配置的時(shí)候,確實(shí)可以配置重試,但是我們當(dāng)前的設(shè)置為:
- 最大重試次數(shù)為 0;
- 是否支持應(yīng)用程序重試,這個(gè)是true。
但是既然最大重試次數(shù)為0,即使后面的這個(gè)checkbox為true,也不應(yīng)該去進(jìn)行重試。
因?yàn)閺恼{(diào)用其它的業(yè)務(wù)系統(tǒng)的接口服務(wù)返回情況來(lái)看,都沒(méi)有發(fā)生過(guò)相應(yīng)的重試操作。同時(shí)后續(xù)在和業(yè)務(wù)系統(tǒng)測(cè)試的過(guò)程中,將該checkbox取消選擇,同樣會(huì)發(fā)生1500秒的錯(cuò)誤,因此暫時(shí)確定和該參數(shù)關(guān)系并不大。
后面詳細(xì)查看日志,會(huì)發(fā)現(xiàn)整體過(guò)程為:
- 2018-10-24 11:25:38開(kāi)啟調(diào)用
- Oct 24, 2018 11:35:49,172 AM GMT+08:00 報(bào)600s掛起
- Oct 24, 2018 11:50:46,140 AM GMT+08:00 報(bào)Connection Reset
- 在600s即到了我們?cè)O(shè)置的Read out timeout的實(shí)際,會(huì)報(bào)出如下異常信息:
- WatchRule: (log.severityString == 'Error') and ((log.messageId == 'WL-000337') or (log.messageId == 'BEA-000337'))
- WatchData: MESSAGE = [STUCK] ExecuteThread: '7' for queue: 'weblogic.kernel.Default (self-tuning)' has been busy for "610" seconds working on the request "Workmanager: SBDefaultResponseWorkManager, Version: 0, Scheduled=false, Started=true, Started time: 610222 ms
- ", which is more than the configured time (StuckThreadMaxTime) of "600" seconds in "server-failure-trigger". Stack trace:
- java.net.SocketInputStream.socketRead0(Native Method)
這個(gè)異常是和600s超時(shí)相關(guān)的一個(gè)異常信息,即Socket Read timeout,同時(shí)在報(bào)出這個(gè)異常信息后,該線程在60秒后又進(jìn)行了一次重試,即:
- <[STUCK] ExecuteThread: '7' for queue: 'weblogic.kernel.Default (self-tuning)' has been busy for "670" seconds working on the request "Workmanager: SBDefaultResponseWorkManager, Version: 0, Scheduled=false, Started=true, Started time: 670227 ms
- ", which is more than the configured time (StuckThreadMaxTime) of "600" seconds in "server-failure-trigger". Stack trace:
而后續(xù)在日志中搜索不到線程7的相關(guān)記錄,同時(shí)在間隔900秒后出現(xiàn)Connection Reset的報(bào)錯(cuò)。
- javax.ws.rs.ProcessingException: java.net.SocketException: Connection reset
- at org.glassfish.jersey.client.internal.HttpUrlConnector$3.run(HttpUrlConnector.
即初步分析很可能的原因是服務(wù)調(diào)用本身在5分鐘在業(yè)務(wù)系統(tǒng)端超時(shí)了,但是業(yè)務(wù)系統(tǒng)端沒(méi)有對(duì)連接進(jìn)行處理或關(guān)閉,導(dǎo)致在OSB側(cè)這個(gè)連接被并沒(méi)有感知到。
因此一直等待到600s的時(shí)候出現(xiàn)超時(shí),而這個(gè)時(shí)候超時(shí)本身不是檢測(cè)到業(yè)務(wù)系統(tǒng)端出現(xiàn)問(wèn)題的超時(shí),或其它原因?qū)е逻@個(gè)thread被stuck,連接被掛起。因此又等待了900秒后出現(xiàn)了連接重置。
基于上面的分析我們進(jìn)一步查找900s相關(guān)的設(shè)置,在Weblogic的DataSource連接池里面有一個(gè)900s收縮頻率的設(shè)置,該900s的含義為:在收縮為滿足需要而增大了的連接池前需等待的秒數(shù)。如果設(shè)置為 0,則將禁用收縮。而現(xiàn)在這個(gè)值我們?cè)O(shè)置為900s。
進(jìn)一步查找資料,找到進(jìn)一步信息為:
在Weblogic Server日志中可以觀察到大量的Connection for pool "SCDS" closed信息,表示系統(tǒng)在某一時(shí)刻會(huì)批量關(guān)閉一批連接,一般斷掉物理連接會(huì)這么做(WebLogic 配置池收縮也會(huì)這么做,如果未配置的話默認(rèn)為900s檢查一次,從您的配置文件發(fā)現(xiàn)未配置池收縮)。從線程名稱看,是應(yīng)用程序的線程關(guān)閉了連接。
即在600s連接出現(xiàn)掛起的時(shí)候,一直等待900s,在weblogic連接池檢查和收縮的時(shí)候才將該連接正式關(guān)閉和回收掉,從而返回Connection Reset的錯(cuò)誤。
該假設(shè)還沒(méi)有得到進(jìn)一步的驗(yàn)證,但是從整個(gè)過(guò)程和日志分析來(lái)看,基本能夠說(shuō)得通。
在該問(wèn)題分析中,我們最大的一個(gè)錯(cuò)誤分析就是根據(jù)300s和1500s想當(dāng)然的判斷是重試了5次導(dǎo)致,而一直在查找為何會(huì)進(jìn)行重試,而對(duì)重試配置進(jìn)行檢查和驗(yàn)證。
簡(jiǎn)單來(lái)說(shuō)就是前面的假設(shè)本身就是錯(cuò)誤的,但是驗(yàn)證假設(shè)上走太多彎路。因此還得重新回到問(wèn)題本身。
前面分析了在600秒出現(xiàn)線程阻塞和掛起的時(shí)候,再等待了900秒出現(xiàn)連接超時(shí),因此從時(shí)間上看是1500秒超時(shí)。
為了印證這個(gè)假設(shè),我們將Read Time out的時(shí)間修改為400秒,那么就應(yīng)該是1300秒報(bào)出服務(wù)超時(shí)的異常錯(cuò)誤,但是最終測(cè)試的結(jié)果仍然是1500秒超時(shí)。
因此前面這個(gè)假設(shè)不成立。
對(duì)于該超時(shí),在OSB集群側(cè)沒(méi)有任何5分鐘超時(shí)的設(shè)置,而檢查F5負(fù)載均衡的超時(shí)配置文檔可以看到,F(xiàn)5負(fù)載均衡設(shè)備上有一個(gè)idle time out的超時(shí)設(shè)置,默認(rèn)就是300秒。
任何問(wèn)題的診斷分析,往往無(wú)法提出明確合理的假設(shè)時(shí)候,仍然需要回歸到問(wèn)題產(chǎn)生過(guò)程和鏈路,然后通過(guò)分而治之的方式確定具體的問(wèn)題點(diǎn)和邊界。
因此為了解決該問(wèn)題,首先還是要確定是否和負(fù)載均衡設(shè)備有關(guān)系。對(duì)于當(dāng)前的服務(wù)調(diào)用,需要通過(guò)經(jīng)過(guò)ESB服務(wù)集群,業(yè)務(wù)系統(tǒng)的服務(wù)集群,才能夠完成。如下:
即整個(gè)服務(wù)請(qǐng)求的調(diào)用過(guò)程是為1->2->3->4的順序,需要同時(shí)經(jīng)過(guò)1和3兩個(gè)負(fù)載均衡設(shè)備。那么整個(gè)服務(wù)調(diào)用超時(shí)就和1,2,3,4四個(gè)節(jié)點(diǎn)的配置都會(huì)相關(guān)。
因此為了進(jìn)一步進(jìn)行驗(yàn)證,我們嘗試對(duì)如下路徑直接調(diào)用以排查問(wèn)題:
- 不走業(yè)務(wù)系統(tǒng)的負(fù)載均衡 1-2-4路徑調(diào)用
在該模式下通過(guò)管控系統(tǒng)和通過(guò)SOAPUI分別進(jìn)行調(diào)用測(cè)試。發(fā)現(xiàn)整體調(diào)用能夠成功,有成功的實(shí)例返回。
對(duì)于通過(guò)管控調(diào)用的時(shí)候會(huì)出現(xiàn)有重試的現(xiàn)象,但是通過(guò)SOAPUI調(diào)用的時(shí)候沒(méi)有發(fā)現(xiàn)重試。
其次對(duì)于客戶端調(diào)用仍然會(huì)出現(xiàn)5分鐘調(diào)用超時(shí),返回Connection Reset的錯(cuò)誤。但是這個(gè)時(shí)候?qū)嶋H上服務(wù)仍然還運(yùn)行,即2-4的連接仍然在運(yùn)行并能夠成功運(yùn)行完,因此可以看到成功的服務(wù)運(yùn)行實(shí)例數(shù)據(jù)。
- 不走ESB和業(yè)務(wù)系統(tǒng)兩邊的集群,走2-4直接進(jìn)行接口服務(wù)調(diào)用
在該模式下,我們通過(guò)SOAPUI對(duì)接口服務(wù)進(jìn)行調(diào)用測(cè)試,能夠成功調(diào)用,有成功的實(shí)例返回,同時(shí)對(duì)于客戶端也可能得到成功的返回信息。
即既有成功的實(shí)例,客戶端也返回成功。即我們希望達(dá)到的一個(gè)結(jié)果。
- 走兩邊的集群模式 1-2-3-4路徑進(jìn)行調(diào)用
這個(gè)即是最初的調(diào)用模式,我們還是使用SOAPUI進(jìn)行調(diào)用,發(fā)現(xiàn)會(huì)出現(xiàn)調(diào)用重試,同時(shí)最終服務(wù)運(yùn)行失敗,報(bào)1500秒的超時(shí)錯(cuò)誤。
在客戶端也會(huì)報(bào)出連接超時(shí)錯(cuò)誤。即和我們最初看的現(xiàn)象是一致的。但是具體為何會(huì)發(fā)起5分鐘后的重試,以及是否該重試是由負(fù)載均衡設(shè)備發(fā)起的暫時(shí)不明確。
在負(fù)載均衡上面,我們看到有tcp_tw_recycle參數(shù)配置,但是暫時(shí)不確定自動(dòng)觸發(fā)重試是否和該參數(shù)的設(shè)置有關(guān)系,從網(wǎng)上文章來(lái)看是不建議對(duì)該參數(shù)配置進(jìn)行啟用。
該超時(shí)問(wèn)題經(jīng)過(guò)分析,基本確定是負(fù)載均衡的超時(shí)設(shè)置引起的。因此解決就簡(jiǎn)單的,即對(duì)兩個(gè)集群對(duì)應(yīng)的負(fù)載均衡超時(shí)設(shè)置都進(jìn)行調(diào)整,同時(shí)確保該超時(shí)時(shí)間>OSB服務(wù)配置中的Read Time out時(shí)間即可。
最終問(wèn)題得以解決。
四、JVM內(nèi)存溢出問(wèn)題分析
網(wǎng)上有很多關(guān)于Java JVM內(nèi)存溢出的問(wèn)題和解決方案,實(shí)際上對(duì)于這類問(wèn)題已經(jīng)屬于一種很常見(jiàn)的問(wèn)題,已經(jīng)形成了一種標(biāo)準(zhǔn)的問(wèn)題解決和診斷方法論。
最佳方法就是按照這個(gè)步驟去診斷,而不是靠你自己經(jīng)驗(yàn)去提出各種假設(shè),因?yàn)樵谶@種情況下你提出的假設(shè)很可能都是瞎猜,反而浪費(fèi)了大量時(shí)間。
既對(duì)于問(wèn)題在你沒(méi)有足夠經(jīng)驗(yàn)的時(shí)候一定遵循通用方法論步驟去解決。
再回到內(nèi)存溢出問(wèn)題,這個(gè)問(wèn)題通用步驟如下:
到了這里,我們基本回歸到通用問(wèn)題解決方法論。
由于是生產(chǎn)環(huán)境問(wèn)題,而且由于是商用產(chǎn)品,我無(wú)法在測(cè)試環(huán)境重現(xiàn),也無(wú)法進(jìn)行靜態(tài)代碼檢查。因此首先還是需要進(jìn)行Java GC的內(nèi)存回收日志分析。
對(duì)于JVM內(nèi)存溢出問(wèn)題詳細(xì)分析可以參考:《從表象到根源-一個(gè)軟件系統(tǒng)JVM內(nèi)存溢出問(wèn)題分析解決全過(guò)程》。(http://blog.sina.com.cn/s/blog_493a84550102z8m1.html)
五、業(yè)務(wù)系統(tǒng)性能問(wèn)題分析診斷
如果一個(gè)業(yè)務(wù)系統(tǒng)上線前沒(méi)有性能問(wèn)題,而在上線后出現(xiàn)了比較嚴(yán)重的性能問(wèn)題,那么實(shí)際上潛在的場(chǎng)景主要來(lái)自于以下幾個(gè)方面:
- 業(yè)務(wù)出現(xiàn)大并發(fā)的訪問(wèn),導(dǎo)致出現(xiàn)性能瓶頸;
- 上線后的系統(tǒng)數(shù)據(jù)庫(kù)數(shù)據(jù)日積月累,數(shù)據(jù)量增加后出現(xiàn)性能瓶頸;
- 其它關(guān)鍵環(huán)境改變,比如我們常說(shuō)的網(wǎng)絡(luò)帶寬影響。
正是由于這個(gè)原因,當(dāng)我們發(fā)現(xiàn)性能問(wèn)題的時(shí)候,首先就需要判斷是單用戶非并發(fā)狀態(tài)下本身就有性能問(wèn)題,還是說(shuō)在并發(fā)狀態(tài)才存在性能問(wèn)題。
對(duì)于單用戶性能問(wèn)題往往比較容易測(cè)試和驗(yàn)證,對(duì)于并發(fā)性能問(wèn)題我們可以在測(cè)試環(huán)境進(jìn)行加壓測(cè)試和驗(yàn)證,以判斷并發(fā)下的性能。
對(duì)于詳細(xì)的業(yè)務(wù)系統(tǒng)性能問(wèn)題分析和診斷可以參考:《業(yè)務(wù)系統(tǒng)性能問(wèn)題診斷和優(yōu)化分析》。(http://blog.sina.com.cn/s/blog_493a84550102z8t2.html)