第一次獨立上手多線程高並發的項目的心路歷程


  這個項目是進入新公司的第一個項目,需求比較簡單,后續做起來越發麻煩,中間涉及到並發的一系列的問題,難倒是不難,但是很有參考價值,讓我對並發的理解加深了很多!

       需求:向Bloomberg發起請求,獲取各個國家股票市場的實時交易數據,然后每分鍾將當前時刻的數據記錄下來,生成CSV文件備份。

    剛拿到項目,我理了一下邏輯,業務的主要需求就是兩塊,一個是將最新的數據實時更新,一個是定時的將數據記錄下來,最簡單的實現方式就是兩個線程處理,一個線程用來實時更新數據,一個線程定時去生成記錄文件,第一版代碼應運而生。

    第一版代碼的設計思路:全部業務分為兩個線程去處理,也沒太多面相對象的思想在里面。主線程負責部分包括:連接Bloomberg,請求數據,解析數據,更新數據;生成文件使用定時任務,每隔一分鍾執行一次。

    接上Bloomberg后,數據會不斷的傳過來,對傳來的原始數據(Bloomberg設定的element類型)進行解析過后,將股票的id作為主鍵,存儲到hashmap中,根據id對hashmap進行更新;定時任務每隔一分鍾,對hashmap進行一個深拷貝,得到一個tem,然后對這個tem進行生成CVS文件處理。大致流程如圖所示:

      

  這種實現方式是比較粗暴的,基本沒有什么面相對象的思想,按部就班的把流程實現,第一版只是想着把數據跑通,看看會出現什么問題,后續再去優化。在接入歐洲市場后,大概1500支股票的實時交易,在當前代碼中是沒有問題,緊跟着接入日本市場2000支股票時,開始出現延時和部分數據丟失的情況,在開盤和休盤時間很明顯,因為在那個時間點數據的量比較大,一分鍾大概有7W筆交易,優化勢在必行。

  對第一版優化的主要有兩點,一是將現有代碼進行重構,按照面向對象的方式去實現,增加代碼的可讀性;二是針對數據量大時出現數據丟失的問題,通過多線程來處理數據。

  main線程里只保留部分核心代碼,將對數據的處理業務的實現封裝到數據處理的對象中,這樣main方法中代碼量少了很多,主要是連接Bloomberg的方法,生成文件的定時任務的啟動,解析數據任務的啟動。

  考慮到數據丟失的情況,對該問題進行定位,發現是在由於數據量太大,單線程處理不過來,導致數據阻塞甚至丟失,解決的思路就是解析和更新數據過程使用多線程,結合業務的具體場景,決定使用類hash的方式進行處理,根據線程個數對指定市場的所有股票進行均分,每個線程只處理給定的股票集合,通過這種方式可以極大的提升數據處理速率。大致流程圖如下圖所示:

  其間還做了一些別的小優化,將解析和更新的步驟合並為一步,解析出來的數據直接存到hashmap中,之前分成兩步是考慮代碼的可讀性,讓代碼邏輯更清晰;重寫了官方提供的解析element的方法,因為通過閱讀源代碼發現官方代碼自己有對解析步驟加鎖,會影響速率,索性自己重寫了該方法。

  整個過程耗時還是有點長的,大概有2個月,沒有提供什么文檔,獲取數據的方式都需要自己去嘗試,還有期間測試生成的大量文件,需要寫自己腳本,對歐洲、日本和美國三個市場進行實時測試,又是要熬夜去搞,整體下來,收獲還是很多的,加深了面相對象思想的理解,同時對多線程處理業務的理解也深刻了。

 

 

 

 


免責聲明!

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



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