zoukankan      html  css  js  c++  java
  • 通过监控线程状态来保证socket服务器的稳定运行

    云平台中使用的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服务:

    //此服务用来监控云平台的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服务器。

  • 相关阅读:
    Oracle SQL语句大全—查看表空间
    Class to disable copy and assign constructor
    在moss上自己总结了点小经验。。高手可以飘过 转贴
    在MOSS中直接嵌入ASP.NET Page zt
    Project Web Access 2007自定义FORM验证登录实现 zt
    SharePoint Portal Server 2003 中的单一登录 zt
    vs2008 开发 MOSS 顺序工作流
    VS2008开发MOSS工作流几个需要注意的地方
    向MOSS页面中添加服务器端代码的另外一种方式 zt
    状态机工作流的 SpecialPermissions
  • 原文地址:https://www.cnblogs.com/tzyy/p/4348084.html
Copyright © 2011-2022 走看看