李水龍,周躍勇,周施文,于偉恒
(福建省地震局,福建 福州 350003)
地震預警利用震中周圍少量觸發臺站的信息,估算地震基本參數,基于預警目標及時發出告警信息,以減輕人員傷亡,減少經濟損失,因此對地震預警系統的處理時效提出了較高的要求。
地震預警處理涉及的環節較多,包括數據接收、仿真變換、震相撿拾、幅值量算、特征周期計算、地震事件判定、震中定位、震級估算、可靠度計算、預警烈度預測、預警時間估算等多個環節。傳統的處理方式是以串行的方式從數據接收開始按流程依次處理,由于各個環節計算復雜度不同,計算量存在較大差異,整個過程的處理效率容易受計算較為復雜環節的影響,從而降低地震預警處理的時效性。
在地震預警系統的研發過程中,必須從技術上尋求能夠解耦不同處理環節的密切關聯、探索從串行處理向并行處理轉變的途徑,從而有力地保證地震預警系統的時效性。
生產者—消費者模式是并發、多線程編程中一種經典的設計模式,將串行處理變成并行處理,實現了流程解耦,提升了整個系統的處理效率。生產者—消費者模型通過“找出需要做什么”和“執行需要做什么”的分離,簡化了開發模型。生產者和消費者能夠以不同的速度生產和消費數據。
軟件開發經常會遇到這樣的情況:一個模塊負責生成由另一個模塊處理的數據(這里的模塊是通用的,它們可以是類、函數、線程、進程等)。產生數據的模塊被形象地稱為生產者,處理數據的模塊稱為消費者。為了匹配生產者和消費者之間的速度差異,通常會在兩者之間插入一個倉庫充當中介。生產者將數據放入倉庫,消費者從倉庫中取出數據,完成一次數據傳輸過程。
因此,生產者—消費者模式包含三類參與者:生產者——負責生產產品;倉庫——負責存放產品;消費者——負責消耗產品。生產者—消費者模式結構如圖1所示。

圖1 生產者—消費者模式結構示意圖
生產者在倉庫有空位時生產,倉庫滿倉時便停止生產。只有倉庫不是空無一物并且處于等待狀態時,消費者才能消費。當消費者發現倉庫中沒有產品可以消費時,他們會通知生產者生產。生產者在生產消耗性產品時,應通知等待的消費者進行消費。生產者—消費者運行流程如圖2所示。

圖2 生產者消費者運行流程圖
生產者—消費者模式能為系統研發帶來以下好處:(1)支持流程解耦——通過引入共享倉庫,實現生產者與消費者之間的解耦,隔離生產者與消費者各自變化導致的連鎖反應。(2)支持并發執行——通過把生產者活動和消費者活動分別放入獨立的并發主體中,把活動環節從串行轉變為并行。(3)支持忙閑不均——根據共享倉庫的容量,可以支持生產者和消費者以不同的速度完成各自的工作。
在地震預警系統中引入生產者—消費者模式,可以實現各個地震預警處理環節的流程解耦,提升地震預警處理的并行化程度,對提高地震預警處理效率起到至關重要的作用。
通過對地震預警各個具體處理環節的歸納抽象,可知地震預警處理過程在較高層面包含以下環節:數據接收、數據派發、通道處理、綜合處理、控制網關、外圍應用,等等。把生產者—消費者模式應用到上述各個環節,形成地震預警系統的并行化解決方案,如圖3所示。

圖3 生產者—消費者模式在地震預警中應用的示意圖
在地震預警處理的生產活動和消費活動之間,常常將數據單元作為交換數據的基準。每一項生產活動都被存入倉庫緩沖區(一個數據單元),每個消費活動都從倉庫緩沖區中取出一個數據單元。數據單元必須與業務對象相關聯,因此數據單元的設計受到特定業務邏輯的影響。
在設計數據單元時,要滿足以下要求:(1)整體性。在生產活動和消費活動之間交換數據單元時,要么將整個數據單元傳遞給消費活動,要么根本不傳遞數據單元,部分傳遞的情況是不被允許的。(2)獨立性。數據單元之間不相互依賴。某個數據單元傳輸失敗不影響已完成傳輸和尚未傳輸的數據單元。(3)顆粒度。業務對象與數據單元對應關聯的程度。粒度粗細的權衡基于眾多因素,出于一些經驗上的考慮,是一個綜合權衡的結果。
以數據接收和通道處理兩個處理環節的流程解耦為例,解釋說明生產者—消費者模式在地震預警系統中的具體應用。原來數據接收環節與通道處理環節直接相連,兩者之間存在著較強的流程綁定關系。在新的設計里,引入數據派發,作為數據接收和通道處理之間的緩沖。數據派發從數據接收中獲取實時波形數據,內部緩存后再將波形數據轉發給通道處理,進行仿真變換和特征提取。通過這種方式,較好地解決了連續不斷的海量波形數據到達與復雜多變的特征處理效率不一致引起的堵塞問題,從整體上保證了地震預警處理的高效穩定,具體應用示例如圖4所示。

圖4 生產者—消費者模式的具體應用示例
上述處理的部分核心代碼為:
生產活動——把陸續到達的二進制字節數據流轉化為一個個MiniSeed對象,存入緩沖隊列中。

倉庫——阻塞式、以先入先出方式訪問的緩沖隊列。MiniSeed對象是基本的數據單元,存儲miniseed格式的波形數據。
miniSeedQueue = new ArrayBlockingQueue<MiniSeed>(c apac
ity,true);
消費活動——啟動一個新線程,從緩沖隊列中依次獲取MiniSeed對象,遞交給通道處理器進行仿真變換和特征提取等處理。



地震預警波形數據接收主要負責從多個實時流服務器接收獲取臺站的實時波形數據流,根據波形數據格式,自動產生符合格式要求的波形數據包并進行解析,生成對應的波形數據對象,為后續的波形數據質量檢測提供數據來源。另外,實現自動重連實時波形流服務器的功能,以提高實時波形數據的連續性和系統的可靠性。下面是地震預警數據接收的主要流程,流程圖如圖5所示。

圖5 地震預警波形數據接收流程
(1)當有新的波形數據到達時,本項功能就會啟動。
(2)系統置位對應的實時波形流服務器的數據到達標記。
(3)系統把接收到的波形數據的字節數組存放到波形數據字節緩沖區中。
(4)系統根據波形數據包大小從緩沖區中提取所需字節的數據。
(5)系統根據波形數據格式解析出波形數據對象,并存放到臨時波形數據對象列表中。
(6)重復步驟4,直至波形數據緩沖區中的內容符合要求為止。
(7)系統輸出臨時波形數據對象列表的全部內容。
(8)本項功能執行結束。
下面是輔助流程,流程圖如圖6所示。

圖6 地震預警波形數據接收輔助流程
針對每個連接的實時波形流服務器,建立一個定時監控過程:
(1)設定時間間隔到達時,本項功能就會啟動。
(2)檢查對應的實時波形流服務器的數據到達標記。
(3)如果數據到達標記已被置位,則清空數據到達標記,并轉到步驟5。
(4)如果數據到達標記并未置位,則重新與對應的實時波形流服務器建立連接。
(5)本項功能執行結束。
內部信息傳遞接口通過封裝使不同數據對象以規范統一樣式在系統的各個部分之間無礙流通。該接口的簡要定義為:
public interface IDataArrive{

當有新的數據對象到達時,dataArrive方法會被激活以實現對數據對象的進一步加工處理。dataContainer參數實現了對不同數據對象的統一封裝,它的簡要定義為:

在實際的測試和在線運行過程中,當接入的臺站數量較多時,生產者產生數據多而且快,而消費者卻無法及時處理消費完畢,會產生“快生產者-慢消費者”問題,實時數據流服務器將會把預警系統當作“慢消費者”,進而強制斷開其連接,導致預警系統無法接收到臺站數據,因此,在引入生產者—消費者模式的同時,在臺站數量足夠龐大時,還需引入高性能并發處理框架,解決“快生產者—慢消費者”的瓶頸問題。