宋一凡,谢正源,宣 科,李 川,王季刚,刘功发
(中国科学技术大学 国家同步辐射实验室,安徽 合肥 230029)
基于可调谐红外激光的能源化学研究大型实验装置(Tunable Infrared Laser for Fundamentals of Energy Chemistry, FELiChEM)是由国家自然科学基金委员会支持的一个重大科研项目,由厦门大学、复旦大学、中国科学技术大学和中国科学院大连化学物理研究所共建。FELiChEM主要由可调谐红外自由电子激光光源(IR-FEL)和3个实验站组成[1-2]。实验物理和工业控制系统(Experimental Physics and Industrial Control System, EPICS)是20世纪90年代初发展起来的大型分布式控制系统的软件运行环境和开发平台,广泛应用在国内外的大科学装置上[3-6]。IR-FEL装置控制系统是基于EPICS的分布式控制系统[7-8]。
装置在其运行过程中会产生大量与装置运行相关的历史数据,这些存档数据可用于装置的性能分析和故障诊断,对装置的性能提升和运行维护具有重要意义。EPICS社区发布了一系列历史数据存档软件,如Channel Archiver、RDB Channel Archiver[9-10]和Archiver Appliance。其中Archiver Appliance是最新发布的数据存档软件,已应用在国内外多个加速器装置中,如SLAC、NSLS-Ⅱ、ESS、HLS-Ⅱ等[11-13]。与EPICS社区其他数据存档软件相比,Archiver Appliance数据查询性能更高,软件管理更方便。因此,本文以Archiver Appliance作为数据存档工具,设计和开发IR-FEL装置数据存档和查询系统,以满足装置调试和运行的需求。
Archiver Appliance由SLAC、BNL和MSU合作开发。Archiver Appliance的核心设计理念是数据多级存储,即根据数据产生时间将历史数据划分为3个不同的数据存储级别(表1)。内置的数据迁移功能将采集到的数据首先存入位于读写速度最快的内存中(短期存储,short term store, STS),随着时间的推移,逐步迁移至位于读写速度稍慢的本地硬盘(SSD)中(中期存储,medium term store, MTS),最后数据全部存入读写速度最慢的网络存储(SAN)中(长期存储,long term store, LTS)。一般,距离越近的数据检索越频繁,因此这样的架构可有效提升技术人员查询历史数据的效率。
表1 Archiver Appliance存储级别Table 1 Storage level of Archiver Appliance
图1 IR-FEL装置数据存档和查询系统架构图Fig.1 Architecture of data archiving and query system of IR-FEL facility
IR-FEL装置数据存档和查询系统采用了前、后端分离的架构,前端为客户端,运行在浏览器中,负责网页的内容展示;后端为服务端,运行在服务器上,负责提供页面动态渲染需要的数据,系统架构如图1所示。系统初始数据源是控制系统中的IOC,但经过了不同的处理流程。在后端,Archiver Appliance中数据采集引擎(Engine)将采集到的数据保存在磁盘中,内置的迁移模块完成了不同存储级别之间的数据自动迁移,数据检索模块(Data Retrieval)为前端提供了数据查询的HTTP/JSON接口。此外,开发实时数据推送(Status Push)程序,通过WebSocket协议将IOC中记录值推送至前端网页,实现记录值的实时显示。在前端,基于Vue.js等框架开发单页应用(Single Page Application,SPA),该页面提供了丰富的数据查询功能,具有良好的用户体验。
Archiver Appliance的Data Retrieval模块内置数据查询接口,该接口提供强大的查询功能,包括丰富的查询参数、多样的数据格式,并支持数据处理。以如下请求为例:
http:∥irfel_aa_host:17668/retrieval/data/getData.json
?pv=IRFEL:DM:G1:ai
&from=2019-04-07T08:34:30.000Z
&to=2019-04-08T08:34:53.222Z
这一请求用于查询IR-FEL装置中1 d的G1剂量探测器数据,其中http:∥irfel_aa_host:17668是IR-FEL Archiver Appliance中DataRetrieval模块的HTTP地址,/retrieval/data/getData是数据查询接口,.json指明返回数据格式为JSON,pv=IRFEL:DM:G1:ai指明查询PV名,from=2019-04-07T08:34:30.000Z&to=2019-04-08T08:34:53.222Z指明查询起止时间,时间格式遵循ISO 8601标准,.json可换为其他数据格式,满足不同应用程序的需要。本文直接使用Archiver Appliance作为历史数据查询的服务端程序,为方便与前端交互,使用JSON格式作为返回数据格式。
在装置运行过程中,操作人员一般关心一些物理量的实时状态,如束流流强、辐射剂量等,在控制系统中,这些物理量均对应于EPICS的1个记录,现有的数据存档软件为提高性能,一般设计有数据库写入缓冲区(缓冲时间默认值一般为30 s),在采集IOC内数据后并不会将其实时存入数据库,而是先存入缓冲区,依照写入周期将缓冲区内数据写入数据库。因此,若客户端中的Operation Status页面的数据读取自数据库,那么会存在至多30 s的延时,运行人员无法从网页获得装置的实时状态。为解决这一问题,开发Status Push程序,通过WebSocket的方式把IOC的数据直接推送给网页客户端,消除时间延时。
WebSocket是一在单个TCP连接上进行全双工通信的协议,允许服务端主动向客户端推送数据,简化了两者之间的数据交换。客户端(浏览器)与服务端进行通信时,在使用HTTP协议的情况下,每次必须由浏览器主动发起数据请求,浏览器返回响应,连接存续时间短;在使用WebSocket协议的情况下,两者完成1次握手后一直保持连接,在连接存续期间,可相互进行数据传输,直至一端关闭连接。
实时数据推送程序的核心是基于Websocketd的WebSocket服务器,Websocketd可将标准输入(stdin)转化为 WebSocket的输入,标准输出(stdout)转化为WebSocket的输出,不限制后台脚本语言[14-15]。采用Python语言基于PyEPICS库开发了Status Push程序,该程序与给定列表中的PV建立Channel Access连接,当PV中数据更新时,将其打印至标准输出(stdout),Websocketd将其转化为WebSocket消息,推送给前端。
此外,系统在服务端上层加入Nginx作为反向代理服务器,这一设计主要实现了以下功能:便于实现客户端浏览器的跨域资源请求;整合了多个服务端程序,为数据查询提供统一的接口,便于客户端程序开发,也便于服务端与客户端的横向扩展;通过Nginx中的geo模块实现了不同访问者IP的返回内容控制,提高了系统的安全性。
网页客户端提供了数据查询与可视化的功能,是技术人员与存档系统最便捷的交互方式。Archiver Appliance已提供基于plotly的Web客户端,但其网页功能和UI设计均无法满足要求。因此,本文基于Vue.js框架开发了一单页应用,其中包含了数据的显示、查询、统计和下载功能。
当用户切换单页应用中的子页面时,浏览器通过AJAX的方式向后端请求数据,并刷新该子页面,无需刷新整个页面,提升了页面响应速度,优化了用户使用体验。Vue.js是一渐进式的JavaScript框架,用于开发单页应用。与其他同类框架相比,Vue.js更易用、灵活和高效。Vue.js采用单文件组件的形式划分网页应用,每个单文件组件的Vue文件中同时包含HTL、JavaScript和CSS代码,实现了网页应用的模块化开发。此外,Vue.js生态系统中还包括大量第三方库,丰富了Vue.js的功能。
历史数据查询页面包含了两种不同的查询方式,分别是定制查询和自由查询,分别对应了两个子页面,如图2、3所示。定制查询子页面左侧显示PV分组树,用于PV的查找和勾选;自由查询子页面中,用户可在左侧文本框内自由输入PV名称进行查询。两个子页面右侧是相似数据可视化部分,展示给定时间范围的数据变化曲线,并提供了原始数据查看、统计信息显示和数据下载功能。
图2 历史数据定制查询页面Fig.2 Customized query page of historical data
图3 历史数据自由查询页面Fig.3 Free query page of historical data
定制查询子页面中的PV分组树是根据PV名自动生成的,无需手动配置。IR-FEL控制系统中,所有PV名遵循严格的分级分段命名规则,即“系统名:设备名:通道名(可选):参量名:记录类型”。定制查询子页面被加载后,首先调用Archiver Appliance的getAllPVs接口获得所有PV列表,按照符号对PV名分段,各段名称标识了该PV所属的系统,根据从属关系组成PV分组树。图2中的树状结构有共同的根节点IRFEL,表明所有的PV均来自IRFEL控制系统,下级是各子系统,如IRFEL:DM为辐射剂量检测系统,IRFEL:VA为真空系统,IRFEL:BD为束流诊断系统。将根节点到底层叶节点路径上的节点名连接,即为完整的PV名。在每个底层节点左侧均有一复选框,用于勾选PV名。如图2中用户勾选了IRFEL:DM:G1:ai、IRFEL:DM:G2:ai和IRFEL:DM:N1:ai 3个PV,之后点击Draw Line Chart按钮,右侧将显示这3个PV一段时间内的PV变化曲线。
由于不同子系统被控变量值量级差异较大,如真空值常小于10-5Pa,而磁铁电源值常大于1 A,若在同一坐标轴中显示,则不易观察量级较小的变量值的变化特征。针对这一问题,设计自由查询子页面,用户可手动配置PV并根据需要进行分组。分组输入框上方的“Add”和“Remove”按钮用来添加和删除分组,每个group中的“+”和“-”按钮用来添加和删除组中的PV,“log”单选框用来将对应分组的纵轴设置为对数轴。每个group中的所有PV共享同一纵轴。如在图3中建立Group1和Group2两个分组,分别在两个坐标轴中显示束流流强和辐射剂量的变化曲线。
图4为运行状态显示页面,页面上方显示了IR-FEL装置的运行参数和状态,目前主要显示后端服务器通过WebSocket协议推送的束流流强和束流能量实时值,页面下方显示最近24 h的束流流强的变化。IR-FEL装置使用流强变压器(current transformer,CT)测量直线加速器中束流流强,控制系统中IRFEL:BD:CT:CT1:I和IRFEL:BD:CT:CT2:I两个记录分别表示电子枪出口的流强和直线加速器末端的流强。图中红色曲线和蓝色曲线分别表示这两个记录最近24 h的数据变化曲线,图中时刻两处流强实时值CT-1和CT-2分别为0.025 A和0.005 A,两段直线加速器的束流能量实时值分别为16.25 MeV和46.00 MeV。
图4 实时数据显示页面Fig.4 Display page of real-time data
本文描述了IR-FEL装置数据存档和查询系统的设计与开发。系统使用了前、后端分离的软件架构风格,使用Archiver Appliance作为历史数据存档软件。在后端,设计了历史数据查询和实时数据推送两种服务端程序,并使用Nginx反向代理服务器提供了统一的数据查询接口。在前端,基于Vue.js开发了单页应用,提供了丰富的数据查询功能,页面中包含了PV分组树和自由查询功能,优化了用户使用体验。系统性能稳定、功能完善,满足了IR-FEL装置调试和运行的需求。