天天看點

Spring+SpringMVC+MyBatis+easyUI整合進階篇(七)一次線上Mysql資料庫崩潰事故的記錄

先來簡單的介紹一下發生這次事故的項目,當時所在的公司是一家小型的電商公司,公司主要的線上産品也就是一個商城項目,上線運作了一段時間,還處于繼續開發和優化的階段,使用者界面就是很雷同的一些電商屬性:商品、購物車、訂單、支付,背景則是一些營運資料,倉庫系統(商品的入庫和出庫),訂單管理等,使用者量和訂單量還算不錯吧。

作者:13

GitHub:https://github.com/ZHENFENG13

版權聲明:本文為原創文章,未經允許不得轉載。

文章簡介

工作這幾年,技術棧在不斷更新,項目管理心得也增加了不少,寫代碼的速度也在提升,感覺很欣慰,畢竟是在一直進步,但是過程中也有許許多多的曲折,也踩過了數不盡的坑坑窪窪,從一個連百度都不知道用的萌新到一個悠哉悠哉的老油子也不容易,很多人應該都有類似的經曆和感受,是以部落格中也會整理一些曾經碰到過的事故和問題給自己提個醒。

由于接下來要在perfect-ssm項目中引入緩存子產品,恰好在翻看日記時看到了這次事故的記錄,是以整理了這篇文章,根據事件發生時的日記來回顧一下這次事件,通過這次資料庫事故的真實案例及後續的事故處理作為引子來講講緩存,為什麼要這麼做呢,因為我覺得網上關于緩存使用的重要性和必要性的文章已經很多了,一個又一個的原因及使用緩存的益處都寫的很清晰,我再去寫一遍有些多餘,不如通過這種親身經曆的案例來得好。

雖然當時也知道緩存的重要性,也想去在項目中使用,但是由于當時太菜了也不知道怎麼去在項目中整合緩存,是以使用緩存的事情就一拖再拖,而這次事件及後續的處理也是我第一次在項目開發中使用緩存,這也是為什麼我選擇使用這篇日記來寫這篇文章并作為緩存接入的引子,其實還有很多日記,不過這篇就顯得比較特殊了,剛好要在perfect-ssm裡用到,是以結合這篇日記整理了一篇文章。

項目介紹

前面寫了三個段落,不能再繼續寫了,主角該出場了,先來簡單的介紹一下發生這次事故的項目,當時所在的公司是一家小型的電商公司,公司主要的線上産品也就是一個商城項目,上線運作了一段時間,還處于繼續開發和優化的階段,使用者界面就是很雷同的一些電商屬性:商品、購物車、訂單、支付,背景則是一些營運資料,倉庫系統(商品的入庫和出庫),訂單管理等,使用者量和訂單量還算不錯吧,比上不足比下有餘,馬馬虎虎可以讓公司正常運轉,OK,基礎資訊介紹完畢。

Spring+SpringMVC+MyBatis+easyUI整合進階篇(七)一次線上Mysql資料庫崩潰事故的記錄

第一次崩潰

這次事故發生的時間點是在某天的上午(額...又是發生在上午),事發比較突然,客服陸陸續續接到幾個使用者的回報電話,起初并沒有在意,以為隻是某些使用者的誤操或者某些商品在倉庫裡沒貨了,這些都經常遇到也就沒放在心上(處于萌新階段的自己最大的優點應該就是心比較大,什麼事情都覺得無所謂,哈哈哈哈),但是接下來的投訴越來越多,老大就讓我趕緊去看看是怎麼回事,我這時候才打開網站開始查問題(心大不大?或者說楞不楞?)。

詭異的事情也發生了,網站打開一切正常,網站首頁好好的,搜尋功能也正常,商品詳情頁也可以用,當時心裡一緊,這是發生了什麼事情啊?伺服器卡了?tomcat叢集挂了其中的一台?趕緊去看伺服器,結果所有執行個體的運作一切正常,看到這個結果心裡的緊張又多了幾分,和平時的劇情不太一樣,這個時候不應該是伺服器挂掉然後重新開機的橋段嗎?答案是no...

又去找客服,到底是什麼事情,客服說基本上都是說無法下單,我又趕緊去下單,走一下訂單流程,果然,卡在頁面上一動也不動了

Spring+SpringMVC+MyBatis+easyUI整合進階篇(七)一次線上Mysql資料庫崩潰事故的記錄

無法生成訂單,陸陸續續點了其他頁面,發現都是正常的,訂單清單和訂單删除都能用,隻有訂單生成不行,趕緊去查日志,也沒有報錯(這個我有點記不清了,到底報沒報錯以及報了什麼錯,隻是記得查了日志也沒查出什麼問題),我趕緊去找老大,報!伺服器沒問題!日志也沒問題!資料庫也可以正常的查詢!訂單表也正常!就是無法生成訂單,可能是訂單接口有問題!(可以腦補一下當時的愣頭青場景),這個時候我也懵了,到底是什麼情況呢?什麼都正常怎麼會出現這種情況,以我當時的水準隻能在旁邊喊666,然後就把事情推到了老大身上(美滋滋...),沒辦法,我真的不會,也想不明白是什麼問題。

老大當時也按照我的思路去查了(可能覺得我中間有偷懶以緻于沒查出來),當然他也什麼都沒查出來,然後就開始去看資料庫,查了也挺久的,我記得這個過程中我是很煎熬的,也幫不上什麼忙,還要聽客服那邊催,中間也僥幸的覺得是不是哪裡抽風了過會兒就好了,就去下了幾次單,結果都不行,最後隻能坐在老大旁邊看他敲代碼,最氣的是,很多sql指令和linux腳本也看不懂...

代碼沒問題,日志沒問題,叢集也好好的,基本也就可以猜到問題應該在資料庫了,不過我沒有檢視和操作的權限,是以具體是不是,當時我也不知道。

老大一直在查,我就隻能呆呆的等着,過了一會兒老大說是有兩張表鎖住了(我的内心OS:表鎖住了?什麼意思?怎麼會鎖住?等等...資料庫鎖是什麼東西),試着去解決但是沒有成功,一時也想不出好的辦法,客服那邊同僚催的也緊,氣氛有點僵,然後我就說出了我的"高見",老大,要不咱們重新開機資料庫吧,話一說完,老大看了我一眼,我猜眼神裡應該滿是贊善,然後對着我笑了笑,他可能覺得這是個很好的方案吧,他怎麼就沒想到呢?(ps:也可能是在心裡罵我,這個愣頭青,一出問題就知道重新開機,tomcat重新開機,nginx重新開機,伺服器重新開機....現在又要mysql重新開機)當然,由于比較混亂,我說了這個方案後,他也就有些妥協了,然後就去殺了一些程序,并重新開機了mysql服務,大概也就花了兩三分鐘左右的時間,雖然是線上環境,影響肯定是有一些的,但是也絕對不會太大,畢竟業務剛起步,系統也是在開發和完善中。重新開機後,果然就有了效果,可以正常下單了,我們也松了一口氣。又觀察了一段時間,發現系統一切正常,剛好也到了中午,也就去外面吃飯了,回來之後,繼續檢查并觀察了資料庫的情況,發現一切正常,于是就将這件事當做是一個偶然事件,沒有特别注意了,由于公司人員緊張(初創公司的技術部,算是什麼部門......),每個人的事情都很多,老大也就去忙其他事情去了,給的建議是讓我去查一下sql,是不是用了太多的聯查,或者建立的索引不合适之類的問題導緻了死鎖,由于沒有帶來特别大的影響,也就當成一個普通的偶然事件了,老大也說了,下個版本要加上緩存功能,不然随着業務的增長資料庫可能會有些撐不住。

又崩潰了

可能有些朋友心裡會有一些疑惑,事情就這麼結束了?怎麼這麼快?

肯定沒有!事情肯定不會就這麼完了的,不然我也不會單獨整理這麼一篇文章了,在下午的四點鐘之後,又出現了同樣的問題,不過這次就嚴重的多了。

依然跟上午的情況類似,在工位上開發的時候陸陸續續又收到了客服的資訊,與上午同樣的使用者回報,這下就不像上午似的手忙腳亂了,驗證了網站應用後發現問題和上午一樣,于是老大直接去查了資料庫,再接着就是重新開機了資料庫,網站又可以正常運作了,但是這個時候,傻子都能意識到網站出問題了,絕對不是偶然事件,雖然選擇了無奈的重新開機資料庫服務,但也不能每次都這麼做,必須把問題找到并解決,但是我了解到的資訊就是資料庫幾張表被鎖住了,關鍵是我也不知道怎麼做,去百度也百度不出個鳥兒來,當然,問題肯定是出在資料庫這裡,老大給我的建議也是去找下單邏輯的問題以及相關聯的sql是不是有問題......(肯定沒有找到問題啊,因為這次的事件根源并不在此)

Spring+SpringMVC+MyBatis+easyUI整合進階篇(七)一次線上Mysql資料庫崩潰事故的記錄

在大家檢查代碼檢查sql和在網上找解決方案的期間,同樣的問題又再次發生了,不過這次比前兩次更嚴重,不僅僅是下單流程,其他的功能也不能用了,接口大部分也挂掉了,資料庫的問題更嚴重了,下午這兩次事件發生的時間基本沒有隔太久,就是說剛重新開機沒多久,資料庫又崩了(這感覺像不像是被攻擊了?嘿嘿嘿),真的是爆炸,問題也沒定位到,當所有人都覺得我們是被人攻擊了甚至感到了絕望氣息的時候,巧了巧了,倉管那邊也過來回報,說無法錄入商品進行上架操作,還說上午也碰到了類似的情況,這個時候我們幾個開發才反應過來,倉庫背景是最近更新的,可能問題和這個有關,于是趕緊詳細地問了一下倉管,上架了多少商品,有幾個人在上架,得到的答案也很滿意,上午也入庫了,不過打電話之前入庫的比較多,是叫了幾個兼職一起做的,這個時候好像有點兒眉目了,想了一下更新的功能以及新的入庫代碼我們才恍然大悟,也漸漸地清楚了問題的根由!有問題的sql語句在這裡!于是我們與倉庫主管溝通,由于倉管系統剛更新,有些不穩定導緻了一些問題,先暫停一下入庫,我們趕緊把問題修複掉。

原來攻擊我們網站的是自己人!

乖乖隆叮咚,原來"攻擊"我們網站的是自己人!

具體的經過忘記了,總之是記得當天網站出現過三次事情,現在總結起來也就清晰了很多,基本上每次事情發生的時候,倉管都在做入庫操作,最後入庫的量比較大,根據倉管負責人的描述也就大緻能夠對應起來了。第一次第二次還好,隻是表鎖住了,但是第三次就比較嚴重了,資料庫服務資源耗盡了,根本連不上,隻有部分請求是正常的。當然根據倉管的說法再聯想一下大緻也就清楚了,由于前兩次入庫的商品并不多也不密集,是以雖然存在鎖表的情況以及下單失靈的問題,但是依然有部分下單請求是可以正常執行的,大部分接口也是可以正常運作的,但是第三次由于入庫的商品數量較大以及速度較頻繁,不僅僅導緻了鎖表,也導緻了資料庫連接配接被耗盡,進而導緻大部分接口也挂掉了。

看到這裡肯定有很多朋友會問,你們網站是怎麼做的,一入庫就會崩潰,那還玩什麼啊?先别激動,我們當時也是被搞得措手不及,以前也做過很多次的入庫操作,一切都是正常的,根本沒有過這種把資料庫拖垮的情況,是以發生這件事的時候,作為當事人的我們也都挺驚訝的,由于以前根本沒有過類似這種事件的發生,我們也想當然的忽略了,沒往倉管方面去考慮,而且下午兩次事件的發生時間又特别近,根本來不及排查問題。而這次事故的發生就是這麼巧合,因為倉管背景剛做了改版不久,加了一些功能,原來比較穩定的功能被要求修改,主要原因在于這次更新後的頁面設計以及對應的sql語句問題,與資料庫的配置沒有特别大的聯系,當然,資料庫配置高的話可能這個事故的發生會晚一些,但遲早還是會發生。

崩潰的部分結束了

不知不覺已經碼了這麼多的文字,粗略的估算了一下,大概有六千多字了,看來對那時候的自己以及當時經曆的事情還是有很多的感慨和想法的,有些場景依然曆曆在目,而當時自己的一些想法和反應現在還是有一些印象的,真的覺得當時的自己好傻好呆。

本來想将後續的原因分析和事件處理過程也一起寫進來的,但是如果加進來的話文章的篇幅确實有些太長了,這篇文章就已經回憶了這麼多事情,是以具體原因和後續的解決過程還是再整理整理放在後面一篇文章裡講吧,如果寫在一起真的就太長了,估計很多人要一拉到底了,哈哈哈哈。

結語

關于本次崩潰事故的記錄到這裡就告一段落了,糟糕的系統設計和拖垮系統的sql語句會在下一篇文章中再詳細介紹。

首發于我的個人部落格,新的項目示範位址:perfect-ssm,登入賬号:admin,密碼:123456

Spring+SpringMVC+MyBatis+easyUI整合進階篇(七)一次線上Mysql資料庫崩潰事故的記錄

如果有問題或者有一些好的創意,歡迎給我留言,也感謝向我指出項目中存在問題的朋友,本篇主要講述一次Mysql崩潰的事件。

如果你想繼續了解該項目可以檢視整個系列文章Spring+SpringMVC+MyBatis+easyUI整合系列文章,也可以到我的GitHub倉庫或者開源中國代碼倉庫中檢視源碼及項目文檔。

我曾七次鄙視自己的靈魂:

第一次,當它本可進取時,卻故作謙卑;

第二次,當它空虛時,用愛欲來填充;

第三次,在困難和容易之間,它選擇了容易;

第四次,它犯了錯,卻借由别人也會犯錯來寬慰自己;

第五次,它自由軟弱,卻把它認為是生命的堅韌;

第六次,當它鄙夷一張醜惡的嘴臉時,卻不知那正是自己面具中的一副;

第七次,它側身于生活的污泥中雖不甘心,卻又畏首畏尾。