通过监控线程状态来保证socket服务器的稳定运行
2015-03-18 18:13
399 查看
云平台中使用的socket服务器是我们自己定义一套通信协议,并通过C#实现的一个socket服务。
该服务目前是和web服务一起运行在IIS容器中,通过启动一个永不退出的新线程来监听端口。
在开发的初期,由于服务内一些消息的异常未进行捕获,例如客户端发来的消息格式不对、试图去关闭一个已经被释放的连接 等操作,会导致监听线程意外退出。
后来随着系统的使用这些问题被一一修复,socket服务就稳定了很多,可是持续一个多周以后,socket服务还是会偶尔挂掉,查看系统日志没有发现任何系统异常。到网上查了一些关于IIS的资料,发现IIS有一套智能的进程回收机制,目的是为了提高服务器的性能,进程回收时内存中的session、cache以及正在运行的线程都会被清掉,所以采用IIS作为服务器,要保证session、cache等资源长期可用的话,要把他们放到数据库中,或者分布式的放到其他服务器中保存。进程回收后,IIS会启动新的线程,原来部署在IIS中站点的端口都会被重新监听,但是之前用户自己启动的那些线程IIS就不会给启动了。
网上有人给出一种解决方案,对IIS7进行配置:
回收——固定时间间隔(分钟) 改为 0
——虚拟/专用内存限制(KB) 改为 0
进程模型——闲置超时(分钟) 改为 0
这种方法会禁用IIS的进程回收,不过这样可能会导致长时间运行后服务器的性能下降。而且,经过多次尝试这样配置以后,经过很长时间的运行,IIS还是会对进程进行回收的。
想到IIS在进程回收之后会重启自己对运行在其上的站点的端口监听,我们自己也可以运行一个服务,来判断socket服务器的线程当前运行状态是否正常,如果不正常的话就重启服务。这个服务必须是运行在IIS之外的。
具体做法是:
web服务提供一个获取进程状态的接口
/SocketServer.ashx?action=getThreadStatus
提供一个重启socket服务的接口
/SocketServer.ashx?action=startSocketServer
在IIS外部通过其他方法启动一个服务,每隔10秒访问一次获取进程状态的接口,如果不正常则调用重启socket服务的接口。
现在的做法是启动了一个Nodejs服务:
这种做法目前有两个弊端:
1.每次IIS进程回收的时候,socket服务都会有几秒钟的时间不可用
2.socket服务运行在web服务器内,不利于以后web服务器或者socket服务器的扩展,连接到A服务器的设备无法被B服务器访问
以后的改进方向是:
把socket服务器独立出来,重新设计Web服务器与socket服务器的通信方法。
这样可以使socket服务不会受到IIS服务器配置的影响,而且可以随意扩展web服务器与socket服务器。
该服务目前是和web服务一起运行在IIS容器中,通过启动一个永不退出的新线程来监听端口。
在开发的初期,由于服务内一些消息的异常未进行捕获,例如客户端发来的消息格式不对、试图去关闭一个已经被释放的连接 等操作,会导致监听线程意外退出。
后来随着系统的使用这些问题被一一修复,socket服务就稳定了很多,可是持续一个多周以后,socket服务还是会偶尔挂掉,查看系统日志没有发现任何系统异常。到网上查了一些关于IIS的资料,发现IIS有一套智能的进程回收机制,目的是为了提高服务器的性能,进程回收时内存中的session、cache以及正在运行的线程都会被清掉,所以采用IIS作为服务器,要保证session、cache等资源长期可用的话,要把他们放到数据库中,或者分布式的放到其他服务器中保存。进程回收后,IIS会启动新的线程,原来部署在IIS中站点的端口都会被重新监听,但是之前用户自己启动的那些线程IIS就不会给启动了。
网上有人给出一种解决方案,对IIS7进行配置:
回收——固定时间间隔(分钟) 改为 0
——虚拟/专用内存限制(KB) 改为 0
进程模型——闲置超时(分钟) 改为 0
这种方法会禁用IIS的进程回收,不过这样可能会导致长时间运行后服务器的性能下降。而且,经过多次尝试这样配置以后,经过很长时间的运行,IIS还是会对进程进行回收的。
想到IIS在进程回收之后会重启自己对运行在其上的站点的端口监听,我们自己也可以运行一个服务,来判断socket服务器的线程当前运行状态是否正常,如果不正常的话就重启服务。这个服务必须是运行在IIS之外的。
具体做法是:
web服务提供一个获取进程状态的接口
/SocketServer.ashx?action=getThreadStatus
提供一个重启socket服务的接口
/SocketServer.ashx?action=startSocketServer
在IIS外部通过其他方法启动一个服务,每隔10秒访问一次获取进程状态的接口,如果不正常则调用重启socket服务的接口。
现在的做法是启动了一个Nodejs服务:
//此服务用来监控云平台的socket服务进程,若进程崩溃或重启,则重新启动socket服务、ws服务、任务超时检测 var http=require('http'); var moment = require('moment') //var host="http://xxx"; //本地调试 var host="http://xxxxxx"; //内网服务 //var host="http://xxxx";//公网服务 var statusCheck="xxx"; var startSocket= "xxx" ; var startWs= "xxx" ; var taskTimeout= "xxx"; var inteval; function start() { inteval = setInterval(checkStatus, 20000); } function end() { clearInterval(inteval); } start(); function checkStatus() { try { http.get(host + statusCheck, function (res) { res.on('data', function (data) { var socketStatus = JSON.parse(data.toString()); if (socketStatus.socketServer == '挂了' || socketStatus.socketServer == 'Stopped') { console.log(moment(new Date()).format('YYYY-MM-DD HH:mm:ss') + " socket服务不可用,正在重启") //重启服务 restartService(); } }) }).on('error', function (e) { console.log(moment(new Date()).format('YYYY-MM-DD HH:mm:ss') + "错误:" + e.message); }); } catch (e) { console.log(e.message); } } function restartService() { //end(); http.get(host + startSocket, function (res) { statusCode(res.statusCode, 'startSocket'); console.log(moment(new Date()).format('YYYY-MM-DD HH:mm:ss') + " 重启socketserver" + res.statusCode); res.resume(); }); http.get(host + startWs, function (res) { statusCode(res.statusCode, 'startWs'); console.log(moment(new Date()).format('YYYY-MM-DD HH:mm:ss') + " 重启wsserver" + res.statusCode); res.resume(); }); http.get(host + taskTimeout, function (res) { statusCode(res.statusCode, 'taskTimeout'); console.log(moment(new Date()).format('YYYY-MM-DD HH:mm:ss') + " 重启任务状态监控" + res.statusCode); res.resume(); }); var status = { startSocket: false, startWs: false, taskTimeout: false }; function statusCode(code, name) { if (code == 200) { status[name] = true; } if (status.startSocket && status.startWs && status.taskTimeout) { //start(); } } }
这种做法目前有两个弊端:
1.每次IIS进程回收的时候,socket服务都会有几秒钟的时间不可用
2.socket服务运行在web服务器内,不利于以后web服务器或者socket服务器的扩展,连接到A服务器的设备无法被B服务器访问
以后的改进方向是:
把socket服务器独立出来,重新设计Web服务器与socket服务器的通信方法。
这样可以使socket服务不会受到IIS服务器配置的影响,而且可以随意扩展web服务器与socket服务器。
相关文章推荐
- 通过线程监控socket服务器是否done机
- Haproxy做LB负载均衡集群的搭建和配置,可以通过web页面监控web服务器的运行状态
- 通过cacti+nagios监控服务器的运行--cacti篇
- spring通过annotation注解注册MBean到JMX实现监控java运行状态
- 写了一个简单的shell脚本监控mysql服务器运行状态
- spring通过annotation注解注册MBean到JMX实现监控java运行状态
- 通过cacti+nagios监控服务器的运行--nagios服务篇
- 通过crond自动运行Python脚本实现多台linux服务器的监控
- 使用Ganglia监控服务器运行状态
- 通过提高线程优先级保证高实时任务的运行平稳
- Windows监控进程服务器IIS进程状态解决CPU暴满造成服务器运行缓慢 Python版
- 如何通过其他主机查看Apahce服务器的运行状态
- 服务器运行状态监控工具
- 4006.Cacti集监控IBM刀片服务器温度和风扇运行状态
- 通过cacti+nagios监控服务器的运行―nagios nrpe
- 借助mosquitto“实时”远程监控服务器数据库运行状态
- 使用zabbix监控服务器运行状态-
- Socket异步服务器,可以监控客户端的状态,功能有,文字测试,服务端向客户端传输屏幕录像(UDP传输)、监控客户端屏幕(UDP传输),抖动用户窗体、发送文件给用户、扫描客户的C盘目录。
- ESP8266可以让LED发光,通过运行网络服务器驱动继电器检测按钮状态
- 使用apachetop实时监控日志、动态分析服务器运行状态