nginx - FastCGI中的“多路复用”是什么意思?
问题描述
FastCGI 规范的附录 B给出了一个多路复用的例子,其中未缩进的行是由客户端(例如 Nginx)发送的,而缩进的行是由 FastCGI 服务器发送的:
{FCGI_BEGIN_REQUEST, 1, {FCGI_RESPONDER, FCGI_KEEP_CONN}}
{FCGI_PARAMS, 1, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}
{FCGI_PARAMS, 1, ""}
{FCGI_BEGIN_REQUEST, 2, {FCGI_RESPONDER, FCGI_KEEP_CONN}}
{FCGI_PARAMS, 2, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}
{FCGI_STDIN, 1, ""}
{FCGI_STDOUT, 1, "Content-type: text/html\r\n\r\n"}
{FCGI_PARAMS, 2, ""}
{FCGI_STDIN, 2, ""}
{FCGI_STDOUT, 2, "Content-type: text/html\r\n\r\n<html>\n<head> ... "}
{FCGI_STDOUT, 2, ""}
{FCGI_END_REQUEST, 2, {0, FCGI_REQUEST_COMPLETE}}
{FCGI_STDOUT, 1, "<html>\n<head> ... "}
{FCGI_STDOUT, 1, ""}
{FCGI_END_REQUEST, 1, {0, FCGI_REQUEST_COMPLETE}}
据我了解,在上述的非多路复用版本中,FastCGI 客户端(例如 Nginx)将在发送与请求 2 相关的任何内容之前发送请求 1:
(图2):
{FCGI_BEGIN_REQUEST, 1, {FCGI_RESPONDER, FCGI_KEEP_CONN}}
{FCGI_PARAMS, 1, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}
{FCGI_PARAMS, 1, ""}
{FCGI_STDIN, 1, ""}
{FCGI_STDOUT, 1, "Content-type: text/html\r\n\r\n"}
{FCGI_STDOUT, 1, "<html>\n<head> ... "}
{FCGI_STDOUT, 1, ""}
{FCGI_END_REQUEST, 1, {0, FCGI_REQUEST_COMPLETE}}
{FCGI_BEGIN_REQUEST, 2, {FCGI_RESPONDER, FCGI_KEEP_CONN}}
{FCGI_PARAMS, 2, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}
{FCGI_PARAMS, 2, ""}
{FCGI_STDIN, 2, ""}
{FCGI_STDOUT, 2, "Content-type: text/html\r\n\r\n<html>\n<head> ... "}
{FCGI_STDOUT, 2, ""}
{FCGI_END_REQUEST, 2, {0, FCGI_REQUEST_COMPLETE}}
我的理解正确吗?
我在几个地方读到 Nginx 不支持 FastCGI 的多路复用:
但是,这似乎与多线程 FastCGI App相矛盾,其中提到 Nginx 在发送第二个请求之前不会等待第一个请求的响应,如下所示:
(图 3):
{FCGI_BEGIN_REQUEST, 1, {FCGI_RESPONDER, FCGI_KEEP_CONN}}
{FCGI_PARAMS, 1, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}
{FCGI_PARAMS, 1, ""}
{FCGI_STDIN, 1, ""}
{FCGI_BEGIN_REQUEST, 2, {FCGI_RESPONDER, FCGI_KEEP_CONN}}
{FCGI_PARAMS, 2, "\013\002SERVER_PORT80\013\016SERVER_ADDR199.170.183.42 ... "}
{FCGI_PARAMS, 2, ""}
{FCGI_STDIN, 2, ""}
在这一点上我很困惑,因为据我了解,非多路复用版本一次只能处理一个请求(即接收请求,并在处理下一个请求之前发送该请求的响应)。多路复用的具体含义是什么?尤其是:
非多路复用是否允许在对旧请求做出响应之前接受新请求?(例如,参考下面的片段,在给出响应 A 之前查看请求 B 的接受)。
(图 4):
{Request A} {Request B} {Response A} {Request C} {Response C} {Response B}
非多路复用是否允许以与请求不同的顺序给出响应?(例如请求顺序:A、B、C;响应顺序:A、C、B)。
多路复用是否意味着请求的一部分可以与其他请求和响应的一部分混合?例如
(图 5):
{Small part of request A} {Small part of request B} {Small part of request A} {Small part of request B} {Small part of response A} {Small part of request B} {Small part of response B} ...
请注意,我是网络和 FastCGI 的新手。
解决方案
在没有多路复用的情况下,nginx在收到新请求时只是简单地与 fastcgi 侦听套接字建立新连接。多个请求以任何顺序并行处理,但每个连接一次只承载一个请求的数据。这与 HTTP/1 和许多其他协议的处理方式完全相同。
推荐阅读
- java - 如何使用我在 java 的 main 中创建的类?
- java - 映射器函数空参数检查
- php - 我如何将注册重定向到另一个页面?
- react-native - React Native - 使用代码推送 (OTA) 推送新组件
- rest - OrderSummary 创建失败(ConnectApi、Record-Triggered Flow、REST API)
- c++ - C++:退格字符未显示在标准输出中?
- c - 如何简化 if 语句
- flume-ng - EmbeddedAgent org.apache.flume.sink.http.HttpSink 的组件类型不在 [AVRO] 的允许类型中
- java - 如何使用 XML 签名 API 验证 Jaxb 签名元素?
- flutter-web - 如何将 Flutter 包转换为 JavaScript