原創 記錄一次線上Mysql慢查詢問題排查過程
背景
前段時間收到運維回報,線上Mysql資料庫淩晨時候出現慢查詢的報警,并把原始sql發了過來:
--去除了業務含義的sql
update test_user set a=1 where id=1;
表資料量200W左右,不是很大,而且是根據主鍵更新。
問題排查
排查Mysql資料庫
我看到sql後第一反應就是是不是資料庫出問題了,每個小時都有業務,偏偏白天業務高峰時間段正常,淩晨業務量很少時候出問題,讓運維先檢查了資料庫的狀态,回報是資料庫正常。
排查業務代碼(第一次)
這塊業務代碼比較複雜,而且是别人寫的,第一次看都沒看完,直接在代碼裡列印了各個子產品執行的時間,然後上線。
排查業務代碼(第二次)
第二天又出現慢查詢了,我趕緊下載下傳了線上日志,發現整個方法執行時間很長,然後發現執行時間長的代碼有幾行調用其他服務的代碼,使用的是HttpClient,猜到了原因,應該是調用其他逾時導緻的。
說下系統整體流程,微信(A)回調我們的收銀台服務(B),收銀台更新訂單資訊并調用業務服務(C)。
出問題原因是:
第一次A調用B,B鎖住記錄行并調用C,這個時候C沒有響應,導緻A又發送了第二次請求。
第二次A調用B,B更新記錄時候發生死鎖,出現慢查詢。
解決方案
收銀台系統B接收回調的方法添加分布式鎖,保證同一時刻同一訂單隻能更新一次。
收銀台調用業務服務使用的是HttpClient4.4,預設逾時時間60秒,這麼長時間如果對方沒有響應就完了,改成了5秒,逾時立馬傳回,不影響其他業務。
HttpClient4.4版本設定逾時時間代碼如下:
HttpPost httpPost = new HttpPost(url);
RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000).setConnectionRequestTimeout(5000).build();
httpPost.setConfig(requestConfig);
上面設定了3個逾時時間,含義如下:
setConnectTimeout:設定連接配接逾時時間,機關毫秒。
setConnectionRequestTimeout:設定從connect Manager擷取Connection 逾時時間,機關毫秒。這個屬性是新加的屬性,因為目前版本是可以共享連接配接池的。
setSocketTimeout:請求擷取資料的逾時時間,機關毫秒。 如果通路一個接口,多少時間内無法傳回資料,就直接放棄此次調用。
最後,按照這兩個方案改造上線後,系統運作正常,問題解決。
推薦閱讀
1.使用者密碼到底要怎麼加密存儲?
2.徹底了解cookie、session、token
3.阿裡面試官:分别說說微信和淘寶掃碼登入背後的實作原理?
4.一分鐘帶你了解下MyBatis的動态SQL!
5.原創 | 我是如何解決POI解析Excel出現的OOM問題的?
原文位址
https://www.cnblogs.com/haha12/p/12580673.html