通过监控线程状态来保证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服务器。

时间: 2024-08-02 15:37:08

通过监控线程状态来保证socket服务器的稳定运行的相关文章

使用pm2来保证Spring Boot应用稳定运行

Spring Boot开发web应用就像开发普通的java程序一般简洁,因为其内嵌了web容易,启动的时候只需要一条命令java -jar server.jar即可,非常方便.但是由此而来的问题是万一应用挂了怎么办? 别担心,有pm2进程管理工具可以帮到你. PM2简介 pm2原先是nodejs应用的进程管理工具,不过其良好的设计以及扩展性可以手动执行执行进程. PM2安装 1.安装NodeJs npm install pm2 -g PM2基本命令 pm2 list 查看所有被PM2管理的进程列

C#高性能Socket服务器SocketAsyncEventArgs的实现(IOCP)

原创性申明 本文作者:小竹zz  博客地址:http://blog.csdn.net/zhujunxxxxx/article/details/43573879转载请注明出处 引言 我一直在探寻一个高性能的Socket客户端代码.以前,我使用Socket类写了一些基于传统异步编程模型的代码(BeginSend.BeginReceive,等等)也看过很多博客的知识,在linux中有poll和epoll来实现,在windows下面 微软MSDN中也提供了SocketAsyncEventArgs这个类来

001-多线程基础-进程线程、线程状态、优先级、用户线程和守护线程

一.进程与线程 1.DOS系统[单进程系统] 最早的时候DOS有一个特点:只要电脑有病毒,那么电脑就死机了. 原因:传统的DOS系统属于单进程系统,即:在同一时间段内只允许有一个程序运行. 2.Windows系统[多进程多线程] 电脑中毒也可以运行,但是会变慢 原因:因为在一个cpu.一块资源的情况下,程序利用一些轮转算法,可以让一个资源在一个时间段可以同时处理多个程序(进程),但是在一个时间点上只允许一个进程去执行. windows:任务管理器 linux:ps 在每一个进程上可以划分出若干个

利用ScktSrvr打造多功能Socket服务器

Socket服务端编程中最重要的也是最难处理的工作便是客户请求的处理和数据的接收和发送,如果每一个Socket服务器应用程序的开发都要从头到尾处理这些事情的话,人将会很累,也会浪费大量时间.试想,如果有一个通用的程序把客户请求处理和数据的接收.发送都处理好了,程序员只需要在不同的应用中对接收到的数据进行不同的解析并生成返回的数据包,再由这个通用程序将数据包传回客户端,这样,程序设计的工作将会轻松许多.  用Delphi进行过三层数据库应用开发的程序员一定对Borland公司的Borland So

.Net socket服务器编程之为何也高效

说到Socket编程,肯定大部分人举手c,c++.可惜现在已没有机会去追随并达到写服务器的水平,所以将就下还是考虑c#版的Socket服务器吧. 经过一番查询,试用.一些数据和事实还是浮出水面,同时对c#版的服务器也有很大信心,下面慢慢列出. 基础知识: 1,首先socket按平台来分有两种一种是源自unix的和源自微软平台的winsock,句资料显示,winsock借鉴unix下的socket. 2,从编程模式来看有两种,同步和异步 3,按tcp协议又有短链接,长链接. 在unix中,sock

Java NIO 非阻塞Socket服务器构建

部分内容引用自xpbug的Blog. 说到socket服务器,第一反应是java.net.Socket这个类.事实上在并发和响应时间要求不高的场合,是可以用java.net.Socket来实现的,比如写一个局域网聊天工具.发送文件等.但它的缺点也很明显,需要自行对接受的线程进行维护,管理缓冲区的分配等,我尝试过用java.net.Socket完成一个瞬时负载在千人左右的服务器,却因后期改动和维护异常麻烦而放弃. Java自1.4以后,加入了新IO特性,这便是本文要介绍的NIO.下面是一段服务器的

VisualVM监控线程

VisualVM是JDK的一个集成的分析工具,自从JDK 6 Update 7以后已经作为Sun的JDK的一部分. VisualVM可以做的:监控应用程序的性能和内存占用情况.监控应用程序的线程.进行线程转储(Thread Dump)或堆转储(Heap Dump).跟踪内存泄漏.监控垃圾回收器.执行内存和CPU分析,保存快照以便脱机分析应用程序:同时它还支持在MBeans上进行浏览和操作.尽管 VisualVM自身要在JDK6以上的运行,但是JDK1.4以上版本的程序它都能被它监控. Visua

(IOCP)-C#高性能Socket服务器的实现

C#高性能Socket服务器的实现(IOCP) https://www.jianshu.com/p/c65c0eb59f22 引言 我一直在探寻一个高性能的Socket客户端代码.以前,我使用Socket类写了一些基于传统异步编程模型的代码(BeginSend.BeginReceive,等等)也看过很多博客的知识,在linux中有poll和epoll来实现,在windows下面 微软MSDN中也提供了SocketAsyncEventArgs这个类来实现IOCP 地址:https://msdn.m

[Swift通天遁地]四、网络和线程-(13)创建一个Socket客户端

请点击Socket服务端文章:[Swift通天遁地]四.网络和线程-(14)创建一个Socket服务端 本文将演示Socket(套接字)客户端的使用. 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. 在Github中下载项目:[SwiftSocket] 在[Source]文件夹,按下[Shift]选择多个文件. [yudpsocket.c] [ytcpsocket.c] [UDPClient.swift] [TCPClient.swift] [Swif