讀寫併發測試發現解決

       也許,你即使加了鎖,也未必能防止併發的出現,往往,驚喜就隱藏在背面,轉過身,你就會發現真實,不要讓表面美好現象蒙了你的雙眼 。

背景

       先說背景吧,我們是接收第三方數據,從數據過來到數據入庫經過三個服務,第一個服務是老大的數據接收在保存到文件中的同時Push給我,我經過初次解析,將需要的數據屬性發送給雷明的data-bus-java。

       在項目即將上線之前,老大讓我加大測試力度,因爲行業的緣故,我們的數據都是晚上數據異常的多,白天數據幾乎沒有,所以,我們都是晚上跑數據,白天的時候檢測項目的準確性和穩定性。所以,有天晚上,索性一次性預定了同一個時間點的10場數據。期待第二天能帶來驚喜。

發現

       果然,第二天,比較這10場數據,驗證正確性的時候,出現了異常。入庫的數據,有一個自定義的第三方id,這個第三方id是由固定的一些值產生的,正確性來說不應該重複,但是,現在數據中的數據重複了。查日誌吧,排除老大那裏可能產生的問題,比較我和雷明之間的問題,發現,我這裏發給雷明的數據是正確的,沒有異常。緊接着我和雷明找data-bus-java,排查它的入庫日誌,的確數據重複入庫了,這樣產生的問題可能在以下兩個方面。

分析

       第一個方面,入庫之前的過濾重複數據,沒有過濾掉,第二個方面,數據在插入時出現錯誤,在插入的時候,我們要先查詢,同要入庫的數據對比,過濾後,將非重複的數據入庫,難道是這裏出錯了?

       我們反覆檢查分析代碼,發現並沒有什麼問題。難道是Memcache出問題了,我又查了下其他兩場數據,也出現了數據明顯重複的問題,不可能一個晚上,Memcache出現錯誤這麼多次吧。我問雷明,是不是咱在讀寫的時候發生了併發啊,我記得當時雷明給準確的答覆是不可能,因爲那塊他已經做了限制,其實,我也看到了,的確是做了防止併發,做了相關的邏輯處理的。可是這個問題出現在哪裏呢?

       還好,不久,雷明就給我發來一張截圖,說,的確併發了,找不到截圖了,我就簡單描述下吧。

       先看下我們的代碼小部分截圖:

       

       如果不發生併發,我們這裏的日誌應該是連續的,類似這樣

        

      但是,我們看到的日誌卻是類似這樣的:(抱歉沒有截圖,只能描述)

      在exec-3下的開始過濾處理中,和exec-3下的保存完成中,夾帶了其他線程,比如exec-4的過濾處理或者exce-5線程的保存完成。

       原因找到了,如何解決,我看下這塊的代碼,分析了下,因爲用的是Lock加鎖,我們設置了鎖住的時間爲3s和鎖的請求時間30s。簡單分析下:

       exec-3線程通過查詢比較後需要保存數據1 2 3,三條數據,此時鎖住3秒,3秒過後,釋放鎖,此時1 2 3 三條數據還沒有入庫,這時exec-4拿到鎖,經過查詢比較還是需要入庫1 2 3 三條數據,就這樣,線程exec-3和exec-4的線程保存1 2 3 這三條數據的時候,保存了兩次,數據當然會重複。

      還好,沒有發現少數據的情況,說明我們設置的鎖的請求時間30s不會有問題。爲什麼呢?這還得詳細瞭解Lock的鎖機制。有興趣的自己看吧,或者,關注後面的博客,也許我會分析然後分享,嘻嘻。

      進一步分析,爲什麼鎖住3秒的時間不夠,也是因爲後面的邏輯,我們在入庫之前爲了保證數據一致性,我們有一個查詢並比較的過程,這個處理的時間比較長。

解決

      這些都是原因,剩下的就是優化了,我們採用的解決方案是:延長鎖時間,延遲鎖請求時間。

      至此,問題解決,也沒再發現這個情況了。

總結

       大量的測試暴露項目的真實情況,美好事務的背後隱藏着真實的內心,轉過身,發現事實,分析解決,又迴歸美好。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章