一般處理線上問題的三板斧是重啓-回滾-擴容
,可以快速有效的解決問題,可是根據我多年的線上經驗,這三個操做略微有些簡單粗暴,解決問題的機率也很是隨機,並不老是有效。這邊總結下一般我處理應用中遇到的故障的解決方案。mysql
處理故障的時候必須遵循的一些原則redis
提前發現問題,避免故障擴散
故障的出現鏈路通常以下圖所示
每一層都有可能出現問題,越底層出現問題,影響面越大。因此每個層次都須要有相應的問題監控機制,這樣越早發現問題,越能儘早解決故障,避免問題的擴散。好比服務依賴的一個數據庫主庫有問題了,若是等到用戶報過來,這時候可能服務已經掛了幾分鐘了。再等你分析問題,解決問題,切換主備什麼的,可能幾分鐘又過去了。影響訪問比較大了。若是在數據庫出問題時,就已經收到警報,迅速解決,可能沒等用戶報過來,問題解決了。sql
迅速廣播
當收到一個P0警報,判斷應用出現問題了,第一時間在組內廣播。所有人員進入一級戰鬥狀態,發現可能和其餘依賴的服務/中間件/運維/雲廠商有關,當即通知相關責任人,要求進入協同做戰。數據庫
快速恢復
保留現場很重要,有助於發現root cause。可是發生故障了,必需要爭分奪秒,不能爲了保留現場浪費幾分鐘的時間去幹什麼dump內存,jstack線程狀態的事。必須第一時間內先恢復服務,以後再根據當時監控數據,去找root cause架構
持續觀察
爲了解決問題,可能須要在線上進行了重啓/回滾/mock/限流等操做,必定要查看是否達到了預期效果。
須要持續觀察一段時間,服務是否真的正常。 有時候可能只是短暫下去了,還會反撲。運維
處理手段無非是重啓、擴容、回滾、限流、降級、hotfixjvm
如下是我通常處理線上問題的流程
主要分爲四大塊性能
和形成大部分車禍的緣由是因爲變化致使同樣,線上故障一般也是因爲變化致使的。外部的變化很難感知到,可是服務自身的變化很容易感知,當有服務發佈、配置變動等變化時。那麼首先判斷是否可回滾,可回滾的立馬回滾。線程
如今通常是集羣部署,服務高可用。若是隻是一臺機器有問題,在服務可摘除的狀況下當即摘除。不可當即摘除的,先擴容再摘除。日誌
整個服務集羣都出問題了,問題就相對比較複雜一些了,須要分爲單個API與多個API錯誤。
當即找到相關團隊,一塊兒看問題。若是是自身服務不正常的請求引發的,再作相應的fix。若是是正常操做引發的,那須要緊急擴容,升級配置。
從上述操做能夠看出,故障發生時須要作的判斷仍是不少的,若是經驗不夠豐富,處理不得當,很容易引起故障升級、資產損失。
因此須要提早預防。
像哲學家剖析本身同樣去了解你的服務。通常包含如下內容
須要包含如下模塊,
系統是如何部署的,部署在什麼環境。如何登錄、擴容、升配。
哪些模塊是核心的,哪些模塊是沒那麼重要的,能夠降級的。
當前系統可以支持的單機QPS是多少,可能存在的性能瓶頸是什麼,須要經過壓測來得出來。
當前應用的API讀寫比是多少,對應到各個存儲層面的比例是多少。當應用QPS上升,哪一個依賴最早掛掉。redis/mysql 仍是依賴的服務,仍是應用自己。
不管是用戶反饋故障,仍是監控警報,基本都晚了,由於這時候已經累積了必定錯誤量的調用了。因此須要再搶先一步,按期盤點應用。衡量的指標通常圍繞使用率、飽和度、吞吐量以及響應時間
盤點的內容包括全部的依賴。
應用層面
磁盤cpu,內存,load數,jvm gc狀況
系統層面
qps
依賴的存儲
磁盤,cpu, IOPS, qps。
消息隊列
消費速度是否正常
另外系統日誌是第一手的故障信息來源,應用owner須要按期對錯誤日誌進行查詢,可以有效的將潛在問題扼殺在搖籃裏。
監控警報有助於提前發現故障,因此確保監控項完備,警報可以有效報出來。
如下是經常使用的一些監控項
類型 | 監控項 |
---|---|
主機狀態 | 磁盤使用率>85 |
主機狀態 | 5分鐘load > 核數*1.5 |
主機狀態 | 5分鐘內存使用率 > 80 |
主機狀態 | 5分鐘CPU > 50 |
API | 5分鐘API錯誤率>0.1 |
SQL | 慢查詢 耗時>100ms |
日誌 | 1分鐘錯誤數>10 |
日誌 | 5分鐘錯誤數>50 |