測(cè)試環(huán)境問題排查的那些事兒
作者|劉寶成
筆者在轉(zhuǎn)轉(zhuǎn)主要負(fù)責(zé)環(huán)境治理相關(guān)的工作,本篇主要和大家分享,測(cè)試環(huán)境問題排查的一些經(jīng)驗(yàn)。
相對(duì)于線上環(huán)境,測(cè)試環(huán)境的問題往往更為復(fù)雜,主要有以下幾個(gè)方面的原因:
環(huán)境組成的復(fù)雜性。轉(zhuǎn)轉(zhuǎn)的測(cè)試環(huán)境,是由一套基礎(chǔ)的穩(wěn)定環(huán)境,和若干套動(dòng)態(tài)環(huán)境組成的。動(dòng)態(tài)環(huán)境部署需求涉及變更的服務(wù),而穩(wěn)定環(huán)境提供給所有動(dòng)態(tài)環(huán)境共同調(diào)用。如下:

在多個(gè)項(xiàng)目并行的情況下,同一個(gè)服務(wù),會(huì)在測(cè)試環(huán)境同時(shí)部署多個(gè)不同的版本;穩(wěn)定環(huán)境的同一個(gè)服務(wù),會(huì)根據(jù)上游環(huán)境的不同,調(diào)用不同的下游服務(wù)節(jié)點(diǎn)。
由上可見,測(cè)試環(huán)境鏈路拓?fù)涞膹?fù)雜性,遠(yuǎn)遠(yuǎn)高于線上環(huán)境。
服務(wù)器性能差。轉(zhuǎn)轉(zhuǎn)的測(cè)試環(huán)境組成,是基于運(yùn)維同學(xué)自研KVM的虛擬化系統(tǒng)。測(cè)試環(huán)境服務(wù)器本身相對(duì)于線上服務(wù)器性能更差,再加上長(zhǎng)時(shí)間高負(fù)荷運(yùn)轉(zhuǎn),出現(xiàn)故障的概率也更大。
服務(wù)穩(wěn)定性差。部署在測(cè)試環(huán)境的服務(wù),大多仍處在開發(fā)、聯(lián)調(diào)、測(cè)試的流程中,服務(wù)可能會(huì)存在更多的Bug,穩(wěn)定性較差。
筆者將常見的問題原因,分為了以下幾類:
機(jī)器問題:比如測(cè)試環(huán)境虛擬機(jī)的負(fù)載過高、內(nèi)存不足、磁盤空間不足、宿主機(jī)IO過高等等,經(jīng)常會(huì)造成服務(wù)啟動(dòng)失敗、響應(yīng)超時(shí)等。在大的項(xiàng)目,部署服務(wù)較多時(shí),這類問題經(jīng)常出現(xiàn)。像Linux內(nèi)核的OOM Killer機(jī)制,就經(jīng)常造成服務(wù)的意外終止,不了解的話往往會(huì)令人非常困惑。
?外部依賴問題:
比如數(shù)據(jù)庫連接是否正常、是否有對(duì)應(yīng)數(shù)據(jù)庫的權(quán)限、連接池大小設(shè)置是否合理等。
比如外部服務(wù)異常,包括調(diào)用的業(yè)務(wù)方服務(wù)、緩存、公共服務(wù)等。微服務(wù)架構(gòu)下,服務(wù)調(diào)用關(guān)系錯(cuò)綜復(fù)雜,一個(gè)關(guān)鍵服務(wù)的異常,往往會(huì)引發(fā)一串連鎖反應(yīng)。
再比如node版本不正確。前端服務(wù),不同的node版本間,差異還是比較大的,需要提前確認(rèn)清楚。
服務(wù)自身問題:測(cè)試環(huán)境部署的代碼,很可能是未經(jīng)測(cè)試,甚至是沒有經(jīng)過調(diào)試和自測(cè)的。因此,服務(wù)本身出現(xiàn)問題的概率也非常大。常見的比如代碼邏輯問題、配置不正確、pom文件依賴沖突等等。
細(xì)心的讀者可能已經(jīng)發(fā)現(xiàn),上述的很多問題,其實(shí)是會(huì)反復(fù)出現(xiàn)的。對(duì)于這類問題,我們首先想到的,應(yīng)該是:這個(gè)問題為什么會(huì)重復(fù)出現(xiàn)?有沒有什么辦法能夠徹底解決?比如是不是系統(tǒng)有Bug?是不是流程不合理?是不是缺乏規(guī)范?如果能夠徹底解決,就應(yīng)該采取相應(yīng)的措施,徹底解決問題,避免再次出現(xiàn),而不是等問題出現(xiàn)了再去查找之前的文檔。
比如前面提到的機(jī)器問題,我們可以對(duì)機(jī)器的資源進(jìn)行監(jiān)控、對(duì)部署的服務(wù)進(jìn)行限制等,避免出現(xiàn)負(fù)載、使用率過高的問題;
比如依賴問題,我們可以通過對(duì)服務(wù)可用性的監(jiān)控,及時(shí)發(fā)現(xiàn)并處理,避免在調(diào)用時(shí)才發(fā)現(xiàn)問題,影響項(xiàng)目進(jìn)度;
而一些配置、規(guī)范類的問題,則可以制定并推動(dòng)規(guī)范的落地,在編譯或者部署階段,增加相應(yīng)的校驗(yàn),將問題盡早暴露出來。問題發(fā)現(xiàn)的越早,解決的成本越低;
解決了這些重復(fù)性的問題,剩下的就是一些個(gè)性化的問題了,只能挨個(gè)排查。接下來就說說問題排查的一些思路和方法。
1、分析思路
歷史問題回歸
古人云:“鑒以往而知未來”,遇到的很多問題,往往能從之前的經(jīng)驗(yàn)中找到靈感。針對(duì)這類問題,如果能夠有效檢索歷史問題,能夠極大縮短問題排查的時(shí)間,提高解決效率。這就要求我們?cè)谌粘5墓ぷ髦?,?duì)于遇到的問題進(jìn)行詳盡的記錄,便于日后查找。甚至可以基于這些常見問題,形成一套排查流程,類似下面這樣:

變量對(duì)比
類似測(cè)試方法論中的“單一變量法”,遇到了問題,做一下變量的對(duì)比分析。
比如發(fā)生了“Class Not Found Exception”,可以看看最近有沒有改動(dòng)過pom,是否遺漏了jar包或者引發(fā)了jar包沖突;
比如某個(gè)分支的服務(wù)一直異常,那么可以同步下線上版本,確認(rèn)下是否是該服務(wù)分支的問題,再做進(jìn)一步分析;
比如某個(gè)方法或接口響應(yīng)很慢,那么同一服務(wù)的其他接口也慢嗎?是服務(wù)的問題還是接口邏輯的問題?等等
日志分析
在問題排查過程中,日志的價(jià)值是極其巨大的。應(yīng)該養(yǎng)成好的習(xí)慣,出現(xiàn)問題,第一反應(yīng)應(yīng)該就是查看日志。這里的日志,不僅僅包括服務(wù)本身的日志輸出,還包括環(huán)境管理平臺(tái)的日志、JVM日志、GC日志等。以下日志分析中的一些小建議:
異常日志,要學(xué)會(huì)定位到異常發(fā)生的起點(diǎn),確定根本原因;
不要放過任何一行日志,有些關(guān)鍵信息往往隱藏在不起眼的地方;
關(guān)注JVM日志,尤其是服務(wù)啟動(dòng)失敗的情況,常常有意外的驚喜;
學(xué)會(huì)手動(dòng)添加GC日志配置,對(duì)于分析GC相關(guān)問題非常有幫助;
?遠(yuǎn)程Debug
對(duì)于個(gè)別問題,本地環(huán)境難以復(fù)現(xiàn),又沒有明顯的線索,遠(yuǎn)程debug是排查的一個(gè)簡(jiǎn)單有效的手段。熟練運(yùn)用IDE進(jìn)行遠(yuǎn)程debug配置,是一個(gè)必備手段,這里就不贅述了。
2、排查工具
工欲善其事,必先利其器。借助于合適的工具,不僅能夠極大的提升排查問題的效率,還能防患于未然,及時(shí)發(fā)現(xiàn)環(huán)境中的問題,避免一些異常的產(chǎn)生。在轉(zhuǎn)轉(zhuǎn)測(cè)試環(huán)境管理中,主要用的的工具和平臺(tái)有以下幾種:
環(huán)境管理平臺(tái)Agent。在之前分享的文章《轉(zhuǎn)轉(zhuǎn)測(cè)試環(huán)境平臺(tái)解決方案》中提到過,轉(zhuǎn)轉(zhuǎn)的測(cè)試環(huán)境管理平臺(tái),是一個(gè)典型的master-slave分布式結(jié)構(gòu),每個(gè)測(cè)試環(huán)境上都部署有平臺(tái)的agent。Agent除了負(fù)責(zé)環(huán)境管理、服務(wù)部署等功能,還提供對(duì)環(huán)境的監(jiān)控和報(bào)警功能,包括環(huán)境的內(nèi)存使用、CPU負(fù)載、磁盤使用、服務(wù)狀態(tài)等。前文提到的機(jī)器問題,大多可以通過監(jiān)控及時(shí)發(fā)現(xiàn)并處理;
服務(wù)管理平臺(tái)。架構(gòu)部提供的服務(wù)治理平臺(tái),能夠?qū)ξ⒎?wù)的服務(wù)方進(jìn)行全方位的監(jiān)控,包括服務(wù)狀態(tài)、節(jié)點(diǎn)信息、函數(shù)的流量、耗時(shí)統(tǒng)計(jì)等等;
zzmonitor——立體化監(jiān)控平臺(tái)。提供對(duì)服務(wù)的個(gè)性化監(jiān)控,包括服務(wù)端口的探活、JVM監(jiān)控(GC/Thread/Mem)等。通過服務(wù)管理平臺(tái)和zzmonitor強(qiáng)大的監(jiān)控和報(bào)警能力,能夠?qū)Ψ?wù)的狀態(tài)、性能等異常情況,實(shí)時(shí)發(fā)送報(bào)警,便于及時(shí)發(fā)現(xiàn)服務(wù)自身問題,也能避免前文提到的相關(guān)依賴服務(wù)的異常;
天網(wǎng)、zzapm。這兩個(gè)平臺(tái)可以提供強(qiáng)大的服務(wù)拓?fù)浜玩溌纷粉櫟墓δ?,?duì)于定位調(diào)用異常、接口性能等問題,有非常大的幫助;
通用工具。常見的JDK工具,比如jps、jstat、jmap、jstack等;Arthas 是Alibaba開源的Java診斷工具,功能非常強(qiáng)大;
案例一 問題:測(cè)試環(huán)境一個(gè)查詢商品列表的接口,響應(yīng)非常慢,經(jīng)常超時(shí)。
排查過程:
Step 1:查看服務(wù)管理平臺(tái)。服務(wù)狀態(tài)正常,接口耗時(shí)統(tǒng)計(jì)中,部分接口耗時(shí)正常,個(gè)別接口超時(shí)嚴(yán)重,如下:

注:圖片僅供參考,圖中數(shù)據(jù)不一定與案例的數(shù)據(jù)對(duì)應(yīng),下同
Step 2:查看該服務(wù)的日志,有如下報(bào)錯(cuò),初步定位為服務(wù)數(shù)據(jù)庫連接池不足;

Step 3:通過zzapm,對(duì)超時(shí)的調(diào)用鏈路進(jìn)行追蹤,發(fā)現(xiàn)在“getConnection()”環(huán)節(jié)耗時(shí)非常嚴(yán)重;

Step 4:確認(rèn)服務(wù)的數(shù)據(jù)庫配置,設(shè)置的連接池大小為5~10,而該服務(wù)是一個(gè)基礎(chǔ)服務(wù),調(diào)用量非常大,因此連接池長(zhǎng)時(shí)間被占滿,導(dǎo)致大量調(diào)用在等待連接池釋放,而造成超時(shí);
Step 5:修改服務(wù)的連接池配置,重啟后恢復(fù)正常;
總結(jié):這個(gè)案例充分展示了合理使用工具的重要性。通過服務(wù)管理平臺(tái),能夠快速確認(rèn)服務(wù)是正常的,問題在于部分接口;通過zzapm強(qiáng)大的調(diào)用鏈追蹤能力,能準(zhǔn)確定位到耗時(shí)的節(jié)點(diǎn),確定問題原因。
案例二?問題:某RPC服務(wù),部署后啟動(dòng)失敗。
排查過程:
Step 1:查看服務(wù)進(jìn)程,發(fā)現(xiàn)進(jìn)程不存在;查看服務(wù)日志,發(fā)現(xiàn)沒有生成日志;
Step 2:查看Java虛擬機(jī)日志,發(fā)現(xiàn)在日志中間有一條異常輸出,表明服務(wù)的端口被占用了;

Step 3:查看服務(wù)端口配置,再通過ps、netstat等命令,確認(rèn)該服務(wù)的監(jiān)聽端口被另一個(gè)服務(wù)的連接端口占用;
Step 4:重啟占用方服務(wù),待端口釋放后,再重啟問題服務(wù),恢復(fù)正常;
總結(jié):端口沖突的問題,曾經(jīng)在測(cè)試環(huán)境頻繁出現(xiàn),給我們制造了很多麻煩。通過在排查過程中不斷分析和總結(jié),我們確定了問題的根本原因在于端口使用的不規(guī)范。進(jìn)而制定并推廣了服務(wù)端口的分配規(guī)范,只允許使用指定范圍內(nèi)的監(jiān)聽端口,并在測(cè)試環(huán)境中對(duì)這些端口進(jìn)行了預(yù)留,從而徹底解決了這一問題。
整體來說,測(cè)試環(huán)境的問題繁瑣而復(fù)雜,排查起來是一個(gè)勞心勞力的過程。這就需要我們?cè)谂挪檫^程中多思考、多總結(jié),形成一套完善的方法和流程,合理地使用各種工具,進(jìn)而提高排查問題的效率。
在這個(gè)過程中,我們始終不應(yīng)忘記自己的最終目的。一方面,作為測(cè)試人員,不能放過測(cè)試過程中的一絲異常,每一個(gè)問題都要排查出產(chǎn)生的根本原因。在線下它只是個(gè)bug,一旦漏到了線上,就可能造成一次事故。另一方面,作為測(cè)試環(huán)境的管理者,我們要經(jīng)常去思考,能否通過功能的改進(jìn)、流程的完善,避免同樣的問題再次出現(xiàn),將問題扼殺在搖籃之中。
此外,筆者一直有一個(gè)想法。既然我們能夠根據(jù)經(jīng)驗(yàn),總結(jié)出一套問題排查的方法論和排查流程,那么,是否能將這個(gè)過程自動(dòng)化、智能化,讓平臺(tái)來完成排查的過程,進(jìn)一步節(jié)約成本,提高排查效率?這將是筆者未來努力探索的一個(gè)方向。
道阻且長(zhǎng),行則將至。與諸君共勉。

