6

我正在尝试在 nginx 和 fastcgi-mono-server 下使用 ServiceStack 运行 Web 服务 API。

服务器启动正常,API 启动并运行。我可以通过 ServiceStack 分析器在浏览器中查看响应时间,它们的运行时间不到 10 毫秒。

但是,一旦我使用“围攻”(只有 500 个请求使用 10 个连接)进行小型负载测试,我就开始收到 502 Bad Gateway。为了恢复,我必须重新启动 fastcgi-mono-server。

nginx服务器很好。fastcgi-mono-server 是在这个小负载后停止响应的服务器。

我尝试过同时使用 tcp 和 unix 套接字(我知道 unix 套接字存在权限问题,但我已经解决了这个问题)。

这是我的配置:

server {
    listen       80;
    listen       local-api.acme.com:80;
    server_name  local-api.acme.com;

    location / {
        root   /Users/admin/dev/acme/Acme.Api/;
        index index.html index.htm default.aspx Default.aspx;
        fastcgi_index Default.aspx;
        fastcgi_pass unix:/tmp/fastcgi.socket;
        include /usr/local/etc/nginx/fastcgi_params;            
    }
}

启动 fastcgi-mono-server:

sudo fastcgi-mono-server4 /applications=local-api.acme.com:/:/Users/admin/dev/acme/Acme.Api/ /socket=unix:/tmp/fastcgi.socket /multiplex=True /verbose=True /printlog=True

编辑:我忘了提到一个重要的细节:我在 Mac OS X 上运行它。

我还测试了 Mono 的所有可能的 Web 服务器配置:控制台应用程序、apache mod_mono、nginx fast_cgi 和 proxy_pass 模块。在 Mono 3.2.3 + Mac OS X 下几次请求后都出现了相同的崩溃问题。

我能够在 Linux 机器上测试相同的配置并且在那里没有任何问题。

因此,在 Mac OS X 上运行时,这似乎是 Mono/ASP.NET 问题。

4

1 回答 1

17

编辑:我确实在原始问题中看到在 Linux 下运行没有问题,但是,在“高负载”场景(即 +50 个并发请求)下,我在 Linux 上也面临困难,因此这可能适用于 OS X出色地...

我对这个问题进行了更深入的研究,并找到了我的设置的解决方案 - 在负载测试我的简单 hello world 应用程序时,我不再收到 502 Bad Gateway 错误。我在 Ubuntu 13.10 上测试了一切,并在 /opt/mono 中安装了新的 Mono 3.2.3 编译。

当您使用 "/verbose=True /printlog=True" 启动 mono-fastcgi-4 服务器时,您会注意到以下输出:

Root directory: /some/path/you/defined
Parsed unix:/tmp/nginx-1.sockets as URI unix:/tmp/nginx-1.sockets
Listening on file /tmp/nginx-1.sockets with default permissions
Max connections: 1024
Max requests: 1024

重要的几行是“最大连接数”和“最大请求数”。这些基本上告诉了 mono-fastcgi 服务器将能够处理多少活动 TCP 连接和请求 - 在本例中为 1024。

我的 NGINX 配置如下:

worker_processes 4;
events {
    worker_connections  1024;
}

所以我有 4 个工人,每个工人可以有 1024 个连接。因此,NGINX 愉快地接受 4096 个并发连接,然后将其发送到 mono-fastcgi(它只希望处理 1024 个连接)。因此,mono-fastcgi 是“自我保护”并停止服务请求。有两种解决方案:

  1. 降低 NGINX 可以接受的请求数量
  2. 增加你的 fastcgi 上游池

1 通过更改 NGINX 配置可以轻松解决,例如:

worker_processes 4; # <-- or 1 here
events {
    worker_connections  256; # <--- if 1 above, then 1024 here
}

但是,这很可能意味着您无法最大限度地利用机器上的资源。

2. 的解决方案有点棘手。首先,mono-fastcgi 必须多次启动。为此,我创建了以下脚本(在应该启动的网站内):

function startFastcgi {
    /opt/mono/bin/fastcgi-mono-server4 /loglevels=debug /printlog=true  /multiplex=false /applications=/:`pwd` /socket=$1 &
}
startFastcgi 'unix:/tmp/nginx-0.sockets'
startFastcgi 'unix:/tmp/nginx-1.sockets'
startFastcgi 'unix:/tmp/nginx-2.sockets'
startFastcgi 'unix:/tmp/nginx-3.sockets'

chmod 777 /tmp/nginx-*

它启动了 4 个可以接受 1024 个连接的 mono-fastcgi 工作人员。然后 NGINX 应该配置如下:

upstream servercom {
    server unix:/tmp/nginx-0.sockets;
    server unix:/tmp/nginx-1.sockets;
    server unix:/tmp/nginx-2.sockets;
    server unix:/tmp/nginx-3.sockets;
}
server {
    listen 80;
    location / {
        fastcgi_buffer_size 128k;
        fastcgi_buffers 4 256k;
        fastcgi_busy_buffers_size 256k;
        fastcgi_pass servercom;
        include fastcgi_params;
    }
}

这为 NGINX 配置了一个包含 4 个“上游工作人员”的池,它将以循环方式使用。现在,当我用Boom以并发 200 敲击我的服务器 1 分钟时,一切都很好(也就是根本没有 502)。

我希望你能以某种方式将它应用到你的代码中并使东西工作:)

PS:

你可以在这里下载我用来测试的 Hello World ServiceStack 代码。

你可以在这里下载我完整的 NGINX.config 。

虽然有一些路径需要调整,但它应该作为一个良好的基础。

于 2013-11-11T12:27:22.087 回答