文献标识码: A
DOI:10.16157/j.issn.0258-7998.2016.02.020
中文引用格式: 吕海东,陆永林. 异步响应式集群实时监控系统设计[J].电子技术应用,2016,42(2):74-77.
英文引用格式: Lv Haidong,Lu Yonglin. Design of asynchronous reactive cluster real-time monitoring system[J].Application of Electronic Technique,2016,42(2):74-77.
0 引言
大型的工业过程监控系统一般都采用分布式控制系统(Distributed Control System,DCS[1])模式,上位控制主机和下位机都采用价格高昂的工业控制计算机。监控系统的软件通常选用专门的组态软件,这些软件价格不菲,导致系统投资过大,增加了企业的经济负担。当系统性能难以满足实时性需求,需进行系统的升级改造时,原有主机基本被淘汰,造成极大的浪费。
如何用最少的投资实现超高性能,以满足工业过程控制的实时性要求,是当今所有监控系统设计的终极目标。
树莓派[2]的出现以及性能的不断提升,在硬件上为实现低成本监控系统提供了可能。尤其是最新推出的树莓派第2代B型,配置了ARM结构的Cortex-A7 64位4核处理器及1 GB内存,单价在200元以内,配置16 GB存储卡,散热器和金属外壳也不超过300元,性能比原有B型提升6倍,其使用Debain Linux操作系统,可运行大部分Linux应用程序。
软件方面,使用传统的多进程和多线程软件技术无法满足当今应用面临高并发请求和实时性能要求,全新的Node.js[3]服务器平台技术应运而生。
Node.js采用了全新的单线程、非阻塞和异步驱动模式[4],能在使用很少内存的情况下,高性能处理超大量的客户并发请求,完美解决了传统软件技术难以逾越的C10K+问题。
Node.js支持多种集群技术[5],可简单地实现横向和纵向伸缩技术,能适应超大规模应用的需求。
本文将树莓派与Node.js结合,并利用Node.js的集群技术,完美实现了一个超低成本、高性能的全新模式的集群式过程监控系统,并在大连高新园区广源热力有限公司供热管网监控中实施。
1 系统总体架构设计
为减少系统的投资,此监控系统集群中的主机没有使用传统的工业控制计算机,均采用树莓派第2代B型,使用其Linux操作系统,安装Node.js,构成如图1所示的过程监控系统。为提高系统的可靠性和高性能,系统采用分层的架构。
现场数据采集层依然使用传统的PLC完成,采用西门子S7-300实现对供热管网温度、压力和流量的监测。
数据采集传输层采用多块树莓派构成集群,通过TCP协议实时读取PLC的数据,并使用socket.io模块将数据实时推送到客户端的Web页面上。
监控数据的显示层使用高性能的Nginx[6]发布HTML页面和JavaScript代码到客户端浏览器上。浏览器的JavaScript利用socket.io客户端直接接收数据采集层推送的监测数据,并集成jQuery框架技术显示在Web页面的指定位置。由于使用了socket.io的数据推技术,克服了传统Web监控系统使用HTTP协议时AJAX的请求/响应模式低效率和大延迟的缺陷,极大提高了系统的传输性能,满足了监控系统对实时性的苛刻要求。
按照此架构设计的高性能监控系统,主机部分采用了5块树莓派,按每块300元计算(已包含核心板和辅助的配件),共计1 500元。如果采用较普及的天迪工控机,即使双核的最低型也要4 200元,如果使用4核CPU版,则要5 600元左右,要组成本系统的集群,则至少3万元,可见本系统的成本优越性。
2 监控数据采集传输模块设计
数据采集传输模式是系统设计的关键,其向下实时读取PLC监测的监控数据,向上使用Node.js的socket.io模块采用推技术直接将数据发送到客户端。客户连接成功后,不再需要客户端发送数据请求,传输层定时将数据发送到客户端进行显示。
为提高系统的性能和可靠性,系统采用2块树莓派组成集群,将来可以随时增加更多的板子,以适应更高性能的要求,这也是此系统的最核心优势。
树莓派内部有一个4核64位的CPU A7,系统采用cluster集群模块,单板可运行4个Node.js实例,集群模块内置了均衡负载功能实现请求的均衡处理。如此2块树莓派可运行8个Node.js实例,使系统处于超高性能数据处理和传输状态。
Cluster模块只是单主机内部集群,为解决跨主机间的Node.js的socket.io模块的消息处理集群,系统采用socket.io-proxy代理模块构成主机集群,实现2块树莓派之间的消息处理的均衡负载,未来可根据需求增加更多的Node.js主机,以满足更高的性能需求。
2.1 现场监控数据采集实现
西门子S7-300支持TCP协议通信[7],可实现数据的直接相互传输。系统使用Node.js的TCP Client核心模块读取PLC的监测数据,节省了购买昂贵的西门子数据采集组件的费用。
西门子S7-300内置TCP FETCH WRITE通信方式,该模式下通过TCP协议,Node.js使用内置的net模块创建TCP客户端实现与PLC的数据交换,其示意代码如下所示:
var net = require("net");
var MonoteData=function(){};
MonoteData.prototype.monitor =function(){
var io = require('socket.io')(9000);
io.on('connection',function (socket){
var client=new Array();
for(var i=0;i<plcs.length;i++){
client[i] = net.connect(plc[i].port, plc[i].ip);
client[i].on('data', function(data) {
var plcdate=convertToReal(data);
iosocket.broadcast.emit("plcdata",plcdata);
});
}
});
}
数据读取程序使用JavaScript的面向对象特性封装在对象构造函数中,以便进行集群处理。在数据采集程序之前,使用Node.js的文件模块fs,将保存所有PLC设备IP和端口的配置文件plc.json读入到数组plcs对象中,通过Node.js创建TCP客户端,连接到所有的PLC,使用Socket对象的on事件以异步响应模式接收监测数据。接收到PLC监测数据后,使用专门的转换函数转换为JSON格式的数据,其中包含监控点的编号、监测的数据类型(温度、流量或压力)和数据值,使用socket.io模式实时推送到Web客户端。
2.2 数据传输集群设计实现
针对树莓派4核64位CPU的特性,系统使用Node.js的cluster[8]模块,在每块树莓派内部运行与CPU核数对应的Node.js实例,实现数据监测和传输层的集群,以满足监控系统的高性能需求。其核心的示意代码如下所示:
var cluster = require('cluster');
var numCPUs = require('os').cpus().length;
if(cluster.isMaster) {
for(var i = 0; i < numCPUs; i++) {
cluster.fork();
}
}
if(cluster.isWorker){
new MonoteData().monitor();
}
代码在每个树莓派内部创建4个Node.js实例,并且cluster模块自动具备动态负载均衡功能,实现采集任务处理的均衡分配。
由于cluster模块不具备跨不同树莓派的集群功能,只能在单个主机内多CPU内核实现纵向的可伸缩性,为实现跨不同主机Node.js的横向可伸缩性,本系统采用集群模块node-http-proxy[9]。
服务器端与客户端通过Socket.io模块与其底层使用的WebSocket协议实时通信,此协议在连接初期依然使用HTTP协议,待握手成功后,升级为WebSocket协议,以实现全双工的实时通信。因此为实现多主机集群,原则上可以使用任何支持HTTP协议的动态均衡负载的集群服务器产品,如著名的Nginx,同时Node.js也提供了多种模块实现相同的功能。为与Node.js模块更好地融合,系统选择了node- http-proxy实现横向集群,其简化示意代码如下所示:
var httpProxy = require('http-proxy');
var addresses = [
{ host: '172.30.39.230',port:9000},
{ host: '172.30.39.231',port:9000}
];
httpProxy.createServer(function(req, res, proxy) {
var target = addresses.shift();
proxy.proxyRequest(req, res, target);
addresses.push(target);
}).listen(9000);
如果要增加新的Node.js主机,在addresses变量定义中增加新主机的配置项即可,极其简便。
3 数据发布Web服务器实现
本系统的Web客户端全部采用纯的HTML和JavaScript实现,通过socket.io的客户端与Node.js进行数据传输。虽然使用Node.js的express模块也能实现静态Web站点的发布,但Nginx是此类应用的最佳选择,在所有静态Web内容的请求处理上,Nginx性能是最佳的。为提高系统的请求处理性能,本系统采用1块单独的树莓派运行Nginx服务器,使用其默认的配置,将监控系统的Web客户端文件保存在Nginx的html目录下即可,该Nginx监听80端口上的HTTP请求。
4 数据显示客户端设计与实现
监控系统的客户端采用Web方式,可以使用PC、手机、平板等访问监控页面。客户端使用HTML、JavaScript、jQuery和socket.io客户端实现。页面上的显示数据使用绝对位置的div实现,每个div通过id属性与特定的监控点对应。socket.io客户端监听Node.js服务器广播的数据事件,从中解析出监控点编号和监测数据,使用jquery显示在指定的div中。
页面HTML的主div定义指定的监控区域,将监控设备图作为其背景图片,定义每个监控数据div,并通过CSS进行绝对位置定义,并悬浮在监控点上,其简化示意代码如下:
<link rel=”stylesheet” type=”text/css” href=”main,css”>
<script type="text/javascript" src="../socketio/socket. io.js"></script>
<script type="text/javascript" src="main.js"></script>
<div id="area01">
<div id="t01"></div>
<div id="p01"></div>
<div id="l01"></div>
</div>
其中area01为第1个监控区域,每个监控区域使用不同的页面,用户可以选择查看不同监控区域的数据。t01表示第1个温度检测数据,p01为压力数据,l01为流量检测数据。
页面元素的定位采用CSS进行控制,其示意代码如下(为简化只演示一个显示元素,其余相似):
div#area01{
background-image:url(../images/area01.jpg);
width:960px;
heighty:650px; }
div#t01 {
position:fixed;
top:212px;
left:467px;
width:12px;
height:11px;
}
客户端接收服务器发送的监控数据和显示,通过JavaScript结合jQuery和socket.io客户端实现。通过接收异步响应式事件,取得采集服务器发送的数据,显示在指定的div元素上,其简化示意代码如下:
$(document).ready(function(){
var socket = io.connect("http://172.30.39.100:8082");
socket.on("plcdata",function(data){
var dataid=data.plc.id;
var value=data.plc.data;
$("div"+dataid).html(value);
});
});
这里socket.io客户端连接的是node-http-proxy代理Node.js主机,该代理按照负载均衡算法转发到数据采集主机,实现高并发请求的处理。系统显示的监控页面截图如图2所示。
5 结论
此系统的设计与实施是低成本监控系统的创新实践,极大减轻了企业的经济负担,提高了企业投入技术改造的积极性。使用全新的异步响应式编程模式和高性能的Node.js结合,极大简化了监控系统的编程和维护,加快了系统的建设和实施效率,通过集群技术,提供了监控系统的性能,更好地满足了监控系统对处理速度和实时性的需求。
参考文献
[1] 张士超,仪垂杰,郭健翔,等.集散控制系统的发展及应用现状[J].微计算机信息,2007(1):94-96.
[2] Samarth Shah.Learning raspberry PI[M].Birmingham:Packt Publishing,2015.
[3] 陆凌牛.Node.js权威指南[M].北京:机械工业出版社,2014.
[4] Diogo Resende.Node.js high performance[M].Birmingham:Packt Publishing,2015.
[5] Pedro Teixeira.Professional Node.js[M].Indianapolis:John Wiley&Sons,Inc,2013.
[6] Rahul Sharma.Nginx high performance[M].Birmingham:Packt Publishing,2015.
[7] 席英杰,刘文丽.简述西门子S7-300/400的通讯功能及工业应用[J].自动化与仪表,2007(1):37-40.
[8] TILKOV S,VINOSKI S.Node.js:using JavaScript to build high-performance network programs[J].Internet Computing,IEEE,2010,14(6):80-83.
[9] 姚立.IBM云计算平台下NodeJS应用支持环境的设计与实现[D].哈尔滨:哈尔滨工业大学,2013.