生产者—消费者模式在地震预警系统中的应用
2022-08-26李水龙周跃勇周施文于伟恒
李水龙,周跃勇,周施文,于伟恒
(福建省地震局,福建 福州 350003)
0 引 言
地震预警利用震中周围少量触发台站的信息,估算地震基本参数,基于预警目标及时发出告警信息,以减轻人员伤亡,减少经济损失,因此对地震预警系统的处理时效提出了较高的要求。
地震预警处理涉及的环节较多,包括数据接收、仿真变换、震相捡拾、幅值量算、特征周期计算、地震事件判定、震中定位、震级估算、可靠度计算、预警烈度预测、预警时间估算等多个环节。传统的处理方式是以串行的方式从数据接收开始按流程依次处理,由于各个环节计算复杂度不同,计算量存在较大差异,整个过程的处理效率容易受计算较为复杂环节的影响,从而降低地震预警处理的时效性。
在地震预警系统的研发过程中,必须从技术上寻求能够解耦不同处理环节的密切关联、探索从串行处理向并行处理转变的途径,从而有力地保证地震预警系统的时效性。
1 生产者—消费者模式
生产者—消费者模式是并发、多线程编程中一种经典的设计模式,将串行处理变成并行处理,实现了流程解耦,提升了整个系统的处理效率。生产者—消费者模型通过“找出需要做什么”和“执行需要做什么”的分离,简化了开发模型。生产者和消费者能够以不同的速度生产和消费数据。
软件开发经常会遇到这样的情况:一个模块负责生成由另一个模块处理的数据(这里的模块是通用的,它们可以是类、函数、线程、进程等)。产生数据的模块被形象地称为生产者,处理数据的模块称为消费者。为了匹配生产者和消费者之间的速度差异,通常会在两者之间插入一个仓库充当中介。生产者将数据放入仓库,消费者从仓库中取出数据,完成一次数据传输过程。
因此,生产者—消费者模式包含三类参与者:生产者——负责生产产品;仓库——负责存放产品;消费者——负责消耗产品。生产者—消费者模式结构如图1所示。
图1 生产者—消费者模式结构示意图
生产者在仓库有空位时生产,仓库满仓时便停止生产。只有仓库不是空无一物并且处于等待状态时,消费者才能消费。当消费者发现仓库中没有产品可以消费时,他们会通知生产者生产。生产者在生产消耗性产品时,应通知等待的消费者进行消费。生产者—消费者运行流程如图2所示。
图2 生产者消费者运行流程图
生产者—消费者模式能为系统研发带来以下好处:(1)支持流程解耦——通过引入共享仓库,实现生产者与消费者之间的解耦,隔离生产者与消费者各自变化导致的连锁反应。(2)支持并发执行——通过把生产者活动和消费者活动分别放入独立的并发主体中,把活动环节从串行转变为并行。(3)支持忙闲不均——根据共享仓库的容量,可以支持生产者和消费者以不同的速度完成各自的工作。
2 地震预警应用
在地震预警系统中引入生产者—消费者模式,可以实现各个地震预警处理环节的流程解耦,提升地震预警处理的并行化程度,对提高地震预警处理效率起到至关重要的作用。
通过对地震预警各个具体处理环节的归纳抽象,可知地震预警处理过程在较高层面包含以下环节:数据接收、数据派发、通道处理、综合处理、控制网关、外围应用,等等。把生产者—消费者模式应用到上述各个环节,形成地震预警系统的并行化解决方案,如图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参数实现了对不同数据对象的统一封装,它的简要定义为:
3 结 论
在实际的测试和在线运行过程中,当接入的台站数量较多时,生产者产生数据多而且快,而消费者却无法及时处理消费完毕,会产生“快生产者-慢消费者”问题,实时数据流服务器将会把预警系统当作“慢消费者”,进而强制断开其连接,导致预警系统无法接收到台站数据,因此,在引入生产者—消费者模式的同时,在台站数量足够庞大时,还需引入高性能并发处理框架,解决“快生产者—慢消费者”的瓶颈问题。