nginx,fastcgi和开放套接字

sim*_*sjo 28 sockets d nginx

我正在尝试在nginx上使用fastcgi,但我遇到了一些问题.Nginx不重用连接,它在BeginRequest标志中给出0,因此应用程序应在请求完成后关闭连接.

我有以下代码用于结束:

socket.shutdown(SocketShutdown.BOTH);
socket.close();
Run Code Online (Sandbox Code Playgroud)

问题是连接实际上没有关闭..它们在TIME_WAIT上停留,而nginx(或其他东西)不会继续打开新连接.我的猜测是我在关闭套接字时做错了什么,但我不知道是什么..在相关的说明 - 我如何让nginx保持连接打开?

这是使用nginx 1.0.6和D 2.055

编辑:没有更近,但我也检查了逗留选项,它是关闭的:

linger l;
socket.getOption(SocketOptionLevel.SOCKET, SocketOption.LINGER, l);
assert(l.on == 0); // off
Run Code Online (Sandbox Code Playgroud)

getOption虽然返回4 ..不知道这意味着什么.返回值未记录.

编辑:我也尝试在发送的最后一条消息上使用TCP_NODELAY,但这也没有任何影响:

socket.setOption(SocketOptionLevel.SOCKET, SocketOption.TCP_NODELAY, 1);
Run Code Online (Sandbox Code Playgroud)

编辑:nginx 1.1.4支持保持活跃的连接.虽然这没有按预期工作.正确报告服务器负责连接生命周期管理,但它仍然为每个请求创建一个新套接字.

Yar*_*hiy 5

NGINX 代理保持活动状态

关于 fastcgi 的 nginx (v1.1) keepalive。正确的配置方法如下:

upstream fcgi_backend {
  server localhost:9000;
  keepalive 32;
}

server {
  ...
  location ~ \.php$ {
    fastcgi_keep_conn on;
    fastcgi_pass fcgi_backend;
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

时间的等待

TCP TIME_WAIT 连接状态与 lingers、tcp_no_delays、超时等无关。它完全由操作系统内核管理,并且只能受系统范围配置选项的影响。一般来说,这是不可避免的。这就是 TCP 协议的工作方式。请阅读此处此处

避免 TIME_WAIT 的最根本方法是通过设置 linger=ON 和 linger_timeout=0 在关闭时重置(发送RST数据包)TCP 连接。但在正常操作中不建议这样做,因为您可能会丢失未发送的数据。仅在错误情况下(超时等)重置套接字。

我要尝试的是以下内容。发送完所有数据后,调用 socket.shutdown(WRITE) (这将向对方发送FIN数据包)并且不要关闭套接字。然后继续从套接字读取数据,直到收到另一端关闭连接的指示(在 C 中,通常由 0 长度的 read() 指示)。收到此指示后,关闭套接字。在这里阅读更多相关信息。

TCP_NODELAY 和 TCP_CORK

如果您正在开发任何类型的网络服务器,您必须研究这些选项,因为它们确实会影响性能。如果不使用这些,您可能会在发送的每个数据包上遇到大约 20 毫秒的延迟( Nagle 延迟)。尽管这些延迟看起来很小,但它们可能会对您的每秒请求统计数据产生不利影响。这里有一篇关于它的好读物。

另一个阅读套接字的好参考是这里

关于 FastCGI

我同意其他评论者的观点,即在后端使用 FastCGI 协议可能不是一个好主意。如果您关心性能,那么您应该实现自己的 nginx 模块(或者,如果这看起来太困难,则可以实现其他服务器的模块,例如NXWEB)。否则使用 HTTP。它比 FastCGI 更容易实现并且用途更广泛。我不会说 HTTP 比 FastCGI 慢很多。


Lar*_*rsB 0

你好西门德舍

\n\n

以下建议可能完全偏离目标。

\n\n

我自己使用 NginX 进行开发;然而,我\xe2\x80\x99m绝对不是NginX的专家。

\n\n

NginX 工作人员

\n\n

尽管如此,你的问题还是让我想起了NginX 中的工作进程和工作进程

\n\n

除此之外, NginX 中的工作人员和工作进程用于减少工作人员在磁盘 I/O 上阻塞时的延迟,以及在使用 select()/poll() 时限制每个进程的连接数

\n\n

您可以在这里找到更多信息

\n\n

NginX Fcgiwrap 和套接字

\n\n

另一个指针可能是以下代码,尽管此示例特定于 Debian。

\n\n
#!/usr/bin/perl\n\nuse strict;\nuse warnings FATAL => qw( all );\n\nuse IO::Socket::UNIX;\n\nmy $bin_path = \'/usr/local/bin/fcgiwrap\';\nmy $socket_path = $ARGV[0] || \'/tmp/cgi.sock\';\nmy $num_children = $ARGV[1] || 1;\n\nclose STDIN;\n\nunlink $socket_path;\nmy $socket = IO::Socket::UNIX->new(\n    Local => $socket_path,\n    Listen => 100,\n);\n\ndie "Cannot create socket at $socket_path: $!\\n" unless $socket;\n\nfor (1 .. $num_children) {\n    my $pid = fork;\n    die "Cannot fork: $!" unless defined $pid;\n    next if $pid;\n\n    exec $bin_path;\n    die "Failed to exec $bin_path: $!\\n";\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

您可以在此处找到有关此解决方案的更多信息。

\n