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

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

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

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

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

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

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

