在Windows下异常后iisnode失败请求?

时间:2016-10-30 17:26:37

标签: node.js iis httpserver iisnode

最近我一直在尝试使用nodejs创建一个简单的文件服务器,看起来我遇到了一些我似乎无法克服的问题。

简而言之:

我将iisnode配置为有4个工作进程(web.config中有一个名为nodeProcessCountPerApplication =“4”的设置)。它平衡了这些工人之间的负担。

当有8个请求进入时,每个工作者有2个处理请求,但是当正在处理的一个请求中发生异常时,另一个正在等待的请求也会失败。

例如:

worker 1 handling request 1, request 5 waiting 
worker 2 handling request 2, request 6 waiting
worker 3 handling request 3, request 7 waiting
worker 4 handling request 4, request 8 waiting

如果在处理请求3时发生异常,服务器将使用我的自定义错误代码进行响应,关闭并由iisnode重新启动。但问题是请求7也会失败,即使它尚未处理。

我尝试设置maxConcurrentRequestsPerProcess="1",以便一次只有一个请求发送给一个工作者,但它不能按我想要的方式工作。即使将排队的最大请求数设置为1000(默认为iis),请求5,6,7,8也将被拒绝,并且503 Service Unavailable响应。

问题

这些请求彼此之间没有任何关系,因此一个失败不应该取消另一个。

IIS中是否有一个设置可以启用我之后的行为?或者这甚至可以用于节点和IIS吗?

长期

为什么吗

我正在使用节点,因为我有一些其他要求(比如日志记录等),我可以在JavaScript中轻松完成。 由于我有一个ASP.NET MVC背景,而且我正在运行Windows,经过几次搜索,我发现了IIS的iisnode模块,可用于托管带有IIS的节点应用程序。这使我可以轻松管理和部署应用程序。我还在许多网站上看到,节点服务器由于其异步特性而具有良好的性能。

如何吗

我从一个非常基本的异常处理逻辑开始,它使用节点的域对象捕获异常:

var server = http.createServer(function (request, response) {
    var d = domain.create();
    d.on('error', function (err) {
        try {
            //stop taking new requests.
            serverShutdown();
            //send an error to the request that triggered the problem
            response.statusCode = 500;
            response.end('Oops, there was a problem! ;) \n');
        }
        catch (er2) {
            //oh well, not much we can do at this point.
            console.error('Error sending 500!', er2.stack);
            process.exit(1);
        }
    });

    d.add(request);
    d.add(response);

    d.run(function () {
        router.route(request, response);
    });
}).listen(process.env.PORT);

由于我找不到任何最佳实践来优雅地关闭服务器,当存在未处理的异常时,我决定编写自己的逻辑。所以在调用server.close()之后,我会通过套接字唤醒它们,以便服务器可以关闭:

function serverShutdown() {
    server.close();
    for (var s in sockets) {
        sockets[s].setTimeout(1, function () { });
    }
}

这也很棒!

什么吗

当我试图对此进行压力测试时,问题就来了。由于某种原因,iisnode不支持群集模块,但它具有类似的功能。我将iisnode配置为有4个工作进程(web.config中有一个名为nodeProcessCountPerApplication="4"的设置)。它平衡了这些工人之间的负担。

我不完全确定这是如何工作的,但这是我从测试中发现的:

当有8个请求进入时,每个工作者有2个处理请求,但是当正在处理的一个请求中发生异常时,另一个正在等待的请求也会失败。

例如:

worker 1 handling request 1, request 5 waiting 
worker 2 handling request 2, request 6 waiting
worker 3 handling request 3, request 7 waiting
worker 4 handling request 4, request 8 waiting

如果在处理请求3时发生异常,服务器将使用我的自定义错误代码进行响应,关闭并由iisnode重新启动。但问题是请求7也会失败,即使它尚未处理。

我尝试设置maxConcurrentRequestsPerProcess="1",以便一次只有一个请求发送给一个工作者,但它不能按我想要的方式工作。即使将排队的最大请求数设置为1000(默认为iis),请求5,6,7,8也将被拒绝,并且503 Service Unavailable响应。

问题再次

这些请求彼此之间没有任何关系,因此一个失败不应该取消另一个。

IIS中是否有一个设置可以启用我之后的行为?或者这甚至可以用于节点和IIS吗?

感谢任何帮助!

更新

我设法排除了iisnode,并使用集群和工作进程创建了相同的服务器。

问题仍然存在,并且使用502 Bad Gateway返回排队到具有异常的worker的请求。

同样,我不知道进入服务器的请求发生了什么,以及在异常时它们是哪个级别。我似乎无法找到任何关于此的信息......

有人能指出我正确的方向吗?至少在哪里搜索解决方案?

0 个答案:

没有答案