系統上線那點事續
話說距離周五上線后第一天的數據庫故障已經好幾天了,上次的緊急恢復過程中也沒來得及復現現場問題,用戶微信入口的代碼邏輯并不復雜,也沒有什么明顯漏洞。
海創園的辦公場地已經跟夏日的游泳池一樣了,所有的邊邊角角都放滿了桌子和人。各個部門負責安排新人座位的人肯定已經頭很大了,要在如此緊張的空 間中再挖掘出來能坐人的地方簡直就是門藝術~ 不堪重負下終于開始啟用新辦公地點,周一部門從“鄉下”搬到西溪路的“城里”,轉身做了城里人。
周一開了第二個屏幕專門盯了一天系統監控,流量和負載都較平穩,到下班也沒發現什么異常,可以愉快的回家了。
周二也盯了半天,一切正常,活動將在周四晚間結束。看看沒什么大問題,由于之前太累,周三開始調休。但,墨菲定律又生效了,這東西是看星際穿越從諾蘭那學的,用在這里正合適。
周三4點多合作方又通知5點鐘計劃另一個公眾號要推圖文引入用戶進入游戲,雖然在家休著但閑著無事打開監控系統看著有啥問題沒。到了時間,應用服 務器cpu和數據庫負載確實有所上升,但看起來問題不大,于是打開愛奇藝準備欣賞道士出山,后面證明這是個悲劇,跟林志玲的道士下山沒半點關系。
看了沒幾分鐘,運維同學打電話來,說“上次你說想要的現場來了,連接數又上來了”,馬上登上數據庫機器查看,cpu usage, load average值跟上次故障如出一轍;但這次有所不同,一是已經有了上次的經驗,二是運維同學這次沒在高速的半路上,可以一起及時處理。
數據庫的配置是8核虛機,上次已經知道負載大是tomcat應用嘗試建立更多的jdbc連接,而數據庫的最大連接已經配成了3000,但操作系統文件句柄沒放開,所以仍只能開到1024個連接。
階段一:降級應用
既然是14個tomcat應用嘗試開更多連接,那首先要降低數據庫壓力就從關tomcat開始,關了一半tomcat機器,觀察數據庫連接仍然是 1024,考慮到TCP的close wait可能需要部分時間,所以又等了一會,確認沒有降低后決定繼續關tomcat。做這個動作時有個疑問,上次單個tomcat連接數據庫的參數應該已 經調成了60,數據庫端的連接數最大應該只有840,為何這次又到了1000多?
tomcat關到只剩兩個時,數據庫連接數開始降下來了,到了300,此時系統負載雖然CPU仍然是99%,但load average已經從500降到了基本安全的1點幾。這個機的生產庫雖然有些配置問題導致數據庫的sql query log沒有輸出,但根據上次另一臺機的經驗,慢查詢都在查單條用戶表數據上,這個操作是在每個用戶進入頁面時,如果session中不存在此用戶信息時做 的操作。
階段二:加數據庫
此時的現象似乎單個數據庫不能承受這個業務邏輯上進行的查詢,所以此時做的第二個動作就是開始準備用多個數據庫給前端業務分流。在運維同學給我準 備數據庫的時候,抽空查了一下連接池配置,發現設置的最大連接數量不是之前設想的60,而是150,可能是由于上次問題時臨時改的,所以之前應用連接到 1000+到正常的。
此時兩個數據庫已經準備好,將之前備份的主庫dump到新數據庫,重新修改war包的數據庫ip地址,啟動3個tomcat對應一個數據庫并重新 發布;后又啟動3個tomcat對應另一個數據庫。再看監控,分流數據庫訪問似乎并不能緩解問題,起的數據庫都馬上CPU 99%,想讓用戶正常訪問頁面仍然困難。
階段三:遷移緩存
既然數據庫hold不住,只能臨時改程序將所有用戶數據放在redis緩存里,由于是集群部署所以將原jedis連接池配置從1000改為 100。改好上傳正要發布時,電話那邊幾個哥們居然喊著火了,剛搬去的新辦公室就著火了?我不在現場只能聽到電話免提里的背景音,背景人聲里似乎有物業要 讓他們斷電撤退,但聽到運維的哥們鎮定的說等等先別斷,讓我把這個程序先布上去。。。
這個著火算是個小插曲,過了一會這幾個哥們似乎沒動地方,繼續在處理問題,估計不是要緊的大火,生命沒啥危險。此項更改先在一個單實例 tomcat上測試,前端nginx已改為指向此單個tomcat。緩存上來需要預熱,用戶第一次進來還是需要找下數據庫,后面就不需要了。確認功能沒問 題后,開始將新的war包部署到所有tomcat并全部啟動。10幾分鐘過去后,緩存連接在最開始時有個峰值到了1000,之后穩定在了600,查看應用 服務log開始正常了。
8點多應用基本正常后,電話那邊幾個哥們開始叫全家桶外賣了,咱也終于能把吃了一半的飯吃完。
遇到線上故障,首要的是開發自己要冷靜,頂住各方面的壓力。如你這里正忙著嘗試恢復,那邊上級領導一個個的打電話來詢問情況,這還不算完,還有合 作方的人看到服務不可用了也來打電話找你,這時開發哪有精力理會這些,自己要知道輕重緩急,不能lost focus,集中精力做自己該做的事情。
上次參加杭州Oracle用戶組時一個DBA說過,做這行,要能承受很大壓力,因為每天接觸的都是業務方最核心的數據庫,一旦遇到數據庫崩潰,你 在恢復的時候自己決不能慌,這時可能有很多人(領導,同事,焦急的客戶)圍在你身后看著你,這時你要打鍵盤手都要抖那可不行。這句話對處理線上故障的開發 人員也是一樣,想必攜程的事故處理的當事人也會有同感。
最后送上百度百科里墨菲定律的解釋,祝各位周末愉快。
“墨菲定律”(英文:Murphy’s theorem)主要內容有四個方面:一、任何事都沒有表面看起來那么簡單;二、所有的事都會比你預計的時間長;三、會出錯的事總會出錯;四、如果你擔心某種情況發生,那么它就更有可能發生。
“墨菲定律”的根本內容是“凡是可能出錯的事有很大幾率會出錯”,指的是任何一個事件,只要具有大于零的機率,就不能夠假設它不會發生。
在科學和算法方面,它與英文所謂的“worst-case scenario(最劣情形)”同義,數學上用大O符號來表示。例如,對插入排序來說,最劣情形即是要排序的陣列完全倒置,必須進行 n*(n-1) 次的置換才能完成排序。在實驗上,證明了最劣情形不會發生,并不代表比它輕微的情形就不可能,除非能夠很有信心的推論事件的概率分布是線型的。