記一次最近生產環境項目中發生的兩個事故及處理方法



前言

  年前放假的幾個月內,公司項目發生了兩次事故,雖然與我無關,但事故發生后整個團隊都受到影響,主管需要給客戶寫事故報告,客戶甚至打電話給公司領導嚴肅批評,我想經歷過這種事的朋友不在少數,但很多剛入行的朋友可能不太清楚其中利害,這里我分享出來希望對大家有所幫助。


事故經過

  三個月內一共發生兩次生產環境事故,一個是接口超時導致服務雪崩,一個是鎖表導致核心功能停滯一小時。


1、接口超時事故

1)、現象

  2021年12月某周一上午,負責管理網絡的同事(俗稱網管)一大早巡檢過程中發現有一個服務掛掉了,他當時沒在意,直接重啟就好了,但到了10點左右,忽然三四個服務:掛號服務、門診服務、檢查報告服務等一起掛掉了,而且重啟十幾分鍾后又會掛掉,瞬間公司就炸鍋了,網管、開發人員、技術主管集體冒汗,在緊急處理過程中,還不斷有院方電話打給主管、總經理直到大老板,領導就站在我們背后着急的等待我們處理,我想很多人應該有畫面了。

2)、原因

  大概到中午都沒解決,因為沒有日志平台的情況下,定位問題是一件不容易的事情,后來在中午休息時間技術主管和我們終於發現了門診服務中調用某軟his接口出現超時,而周一上午的流量又很大,平常偶爾超時也沒問題沒人在意,這次一個小小的接口超時竟然直接把服務全部堵塞,調用該接口的掛號和門診服務全部掛掉,而和門診服務有一點耦合的檢查報告服務也在瘋狂的超時等待又超時又等待中掛掉了。

  最終,緊急聯系院方找廠商服務團隊查找該接口問題,同時我們臨時把幾個服務全部重啟,總算在所有人惶惶不安的努力下3點之前恢復了正常。

3)、總結及處理

  事后,老板大發雷霆,並召開批斗大會點出了團隊沒有危機處理預案等等種種問題,據說是被院方碉堡了。我們懷着謙虛忐忑的心情在小本上瘋狂做筆記(做樣子),算是挺過去了,唯獨主管比較難受,要親自寫好幾個事故報告給甲方,懂的都懂。

  接口超時時間之后發現設置為60秒,真特么離譜啊,之前竟沒一個人關注(包括我),沒問題的情況下自然萬事大吉,但凡出了問題,60秒的超時時間這是人干的事么,有什么接口若需要60秒,那本身就是一枚定時炸彈,必須一開始就拆掉。

  很多公司的項目其實都存在這個問題,礙於調用第三方接口難以預估超時時間,所以就設置的比較長,可實際上,這會給項目帶來莫大的隱患,處理方式很簡單:

  i)、一定要和對接的廠商確定接口的大概超時時間,有個基本的范圍,因為你很難要求其他公司給你做好接口的完善,很多是不會搭理你的,你也看不見人家接口怎么寫的,那么就要知道個大概,然后自己這邊才好設置;

  ii)、在預估項目上線后流量會成倍增長的情況下,一定要對項目主要接口做壓測,這是公司的測試團隊必須要做的事情,我們公司這次就是測試人員不會壓測,也沒人重視,所以功能沒問題就上線了,事后所有測試人員都被要求參加壓測培訓;

  iii)、只要是微服務,請一定引入熔斷機制 ,這次事故過后,團隊深刻反思,明明用了SpringCloud,但調用第三方接口的位置都沒有做熔斷處理,如果一開始做了,那么這次事故至少我們可以抽身,服務熔斷降級后,既不會出現雪崩影響到其他服務,主要責任也在某軟,給自己公司更多彈性處理的空間,而不是現在反而擔負了主要責任。


2、鎖表事故

1)、現象

  這個事故和前面的相比算是小事故了,但依然令人心驚膽戰,畢竟快過年了,誰也不想出問題。墨菲定律講過,越是你害怕的事情越是會到來,果不其然,年前大概就是前一兩周的樣子,某天下午一家三甲醫院的掛號服務未響應,在前端的效果就是,你打開了小程序,點擊了掛號服務,然后某個功能一直加載中,最后頁面未響應或假死。

2)、原因

  鎖表,因為負責維護該醫院的同事,在下午四點中的時候給掛號表新增了一個可以為空的字段,而掛號表是百萬數據的大表,直接執行SQL新增字段還附帶部分條件,直接導致整個表都鎖掉了,前端發來的請求就一直無法對該表執行其他操作,最終未響應及假死。

  既然鎖了就要解,操作很簡單,但集成同事剛好一時聯系不上,開發人員又不熟悉內網環境,前后花了一個小時時間才解鎖恢復正常,在一堆病患使用過程中,一個小時時間內都無法掛號,這背后的凶殘你可想而知。

3)、總結及處理

  給該表迅速解鎖,有條件的話最好讓本公司專業DBA或集成同事來操作,他們更熟悉數據庫服務及項目部署,操作更安全,如果公司沒有這樣的同事,只能百度一下咯。



MySQL解鎖方式:

# 1. 查看當前數據庫鎖表的情況 
SELECT * FROM information_schema.INNODB_TRX; 
# 2. 殺掉查詢結果中鎖表的trx_mysql_thread_id 
kill trx_mysql_thread_id

Oracle解鎖方式:

# 查看被鎖的表ct
select b.owner, b.object_name, a.session_id, a.locked_mode
from v$locked_object a, dba_objects b where b.OBJECT_ID = a.OBJECT_ID

# 查看連接的進程
select sid, serial#, username, osuser from v$session;

# 殺掉進程 sid, serial#
alter system kill session '678,983';

切記,給大表新增字段以及其他操作,一定要選擇流量最小的時間段,比如凌晨以后,這樣可以避免造成生產環境事故。


總結

1)、首先,接口超時時間的設置不是小問題,希望大家引以為戒,一是要充分和對接廠商溝通,對接口情況有底,一個接口的響應時間理論上是毫秒級的,大廠甚至對接口超時時間都有明確規范,小廠因為身不由己,只能曲線救國,設置一個合理的范圍;

    其次,一定要在測試階段進行核心接口的壓測,某種程度上可以提前暴露問題;

    最后,微服務一定要引入熔斷機制,並且重視使用;

2)、大表操作要謹慎,要么選擇合適的工具來實時操作大表(可以百度非常多),要么就選擇流量最少的時間去操作,無非也就是凌晨,因為沒啥人用,而且執行SQL操作大表時最好不要附帶條件比如設置默認值之類的,這樣會明顯提升速度,把復雜的語句分段執行效果更佳,大家可以試試。



  本人文章從來都是純手打,且都來自實際工作中的經驗及分享,如果覺得有一滴滴幫助,就點個推薦吧!(o..o)~


其他文章推薦
Springboot+Redisson自定義注解一次解決重復提交問題(含源碼):https://www.cnblogs.com/fulongyuanjushi/p/15883067.html



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM