fastcgi 多路复用?
我正在实现 fastcgi 应用程序,在阅读 fastCGI 规范后,我发现了一个名为“请求多路复用”的功能。它让我想起 Adobe RTMP 多路复用协议是专有且封闭的时代。
据我了解,多路复用可以减少创建与 FCGI 客户端的新连接的开销,有效地交织请求块,同时启用连接的“保持活动”模型。后者允许通过单个连接发送多个请求。
第一个问题是我做对了吗?
下一个是 - 经过一些谷歌搜索后,我发现没有实现 FCGI 多路复用的服务器,我首先对“流行”服务器感兴趣,我的意思是 nginx 和 lighttpd。我什至发现了一些关于弃用 FCGI 请求多路复用的讨论。
那么问题来了——有没有服务器支持这个功能呢?
I'm in process of implementation of a fastcgi application, after reading fastCGI spec I've found a feature called "request multiplexing". It reminded me Adobe RTMP multiplexing back in the days that protocol was proprietary and closed.
As far as I understand, multiplexing allows to reduce overhead of creating new connections to FCGI clients effectively interweaving requests chunks, and at the same time enabling "keep-alive" model to connection. Latter allows sending several requests over a single connection.
First question is did I get it right?
Next one is - after some googling I've found there's no server that implements FCGI multiplexing, I was interested in "popular" servers in the first place, I mean nginx and lighttpd. I've even found some discussion about deprecation of FCGI request multiplexing.
So the question is - is there any server that supports this feature?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
问:多路复用可以减少创建与 FCGI 客户端的新连接的开销,有效地交织请求块
答:正确。但 keep-alive 也会减少新的连接。
问:同时启用连接的“保活”模型
答:保活不需要复用。
问:后者允许通过单个连接发送多个请求
答:keep-alive 允许多个请求相继发送。多路复用允许并行多个请求。
没有广泛使用的支持 FastCGI 的 Web 服务器支持多路复用。但nginx支持FastCGI keep-alive。
FastCGI 多路复用通常不是一个好主意,因为 FastCGI 不支持流量控制。这意味着:如果 FastCGI 后端发送数据,但 http 客户端无法足够快地接收数据,则 Web 服务器必须保存所有这些数据,直到它们可以发送到客户端。
当不使用多路复用时,如果 http 客户端太慢,Web 服务器可能无法从 fastcgi 后端读取数据,从而有效地积压了 fastcgi 后端。使用多路复用时,Web 服务器需要从 fastcgi 后端读取所有数据,即使其中一个客户端接收数据的速度不够快。
Q: multiplexing allows to reduce overhead of creating new connections to FCGI clients effectively interweaving requests chunks
A: True. But keep-alive is also reducing new connections.
Q: and at the same time enabling "keep-alive" model to connection
A: Multiplexing is not required for keep-alive.
Q: Latter allows sending several requests over a single connection
A: keep-alive allows several requests after each other. Multiplexing allows several requests in parallel.
There is no widely used FastCGI capable web server supporting multiplexing. But nginx supports FastCGI keep-alive.
FastCGI multiplexing is generally a bad idea, because FastCGI doesn't support flow control. That means: If a FastCGI backend sends data, but the http client can't receive data fast enough, the web server has to save all those data, until they can be sent to the client.
When not using multiplexing, the web server could just not read data from the fastcgi backend if the http client is too slow effectively backlogging the fastcgi backend. When using multiplexing the web server needs to read all data from the fastcgi backend, even though one of the clients isn't receiving data fast enough.
尝试更准确地陈述上面的答案(并纠正某些部分)......
与保持活动相反,它大大减少了新连接,特别是在高负载服务器或微服务(大量微请求)在使用中。此外,在跨网络平衡的情况下几乎是必需的(因此不能再使用unix套接字,并且连接建立过程获得越来越多的优先级)。
虽然keep-alive不需要多路复用,但是多路复用几乎需要keep-alive(否则意义不大)。
很少有服务器支持开箱即用的多路复用,但是...
我已经看到了其他开发人员的几个模块,并且我有自己的 nginx 的 fcgi 模块(作为替代),支持 FastCGI 多路复用请求。
它可以显示实践中的真实性能提升,特别是在上游通过网络连接的情况下。
如果有人需要,我会尽力抽出时间并在 github 等上提供。
这不是真的。通常,FastCGI 处理程序是完全异步的,工作人员池与交付工作人员分开,等等。
因此每个块都会获得一个 request-id,因此如果两个或多个上游工作线程同时写入单个连接,nginx 将获得的块会更小。这是唯一的缺点。
至于“Web 服务器必须保存所有这些数据”,它在任何情况下都会执行此操作(无论是否使用多路复用),因为否则如果有太多待处理数据可用于响应,则可能会出现内存不足的情况。因此,要么后端应该产生更少的数据(或者被阻止),要么网络服务器应该尽快接收它并将其传输到客户端或将其保存到某个临时存储(例如,如果待处理的数据大小超过了 nginx 的大小,nginx 就会执行此操作)使用 fastcgi_buffer_size 和 fastcgi_buffers 指令配置的值)。
这也是错误的。 Web 服务器必须只读取单个响应块到最后,并且好的工作池具有“智能”处理,因此会尽快自动将块发送到 Web 服务器(意味着如果它可用),因此如果多个内容提供者写入同一真实连接的所谓“反射”通道,则一旦响应数据可用,待处理的数据包将被分离,并从 nginx 接收块。
因此,几乎只有连接的吞吐量才是至关重要的,客户端接收数据的速度根本不重要。
同样,多路复用极大地节省了连接建立的时间,因此减少了待处理请求的数量以及公共请求执行时间(事务率)。
Trying to state the answers above more precisely (and correct some parts)...
In opposite to keep-alive it reduces new connections drastically, especially on high-load servers or if micro-servicing (a lot of micro requests) in usage. Futhermore it is almost required in case of balancing across network (so one cannot use unix-sockets anymore and the connection buildup process gaining more and more priority).
Although the multiplexing is not required for keep-alive, but keep-alive is almost required for multiplexing (otherwise it would make little sense).
There is few servers that supports multiplexing out of the box, but...
I saw already several modules of other devs and I have own fcgi-module for nginx (as replacement) that supports FastCGI multiplex requests.
It can show the real performance increase in the practice, especially if the upstreams are connected over the network.
If someone needs it, I will try to find time and make it available on github etc.
This is not true. Normally the FastCGI handlers are fully asynchronous, pool of workers is separated from the delivering workers, etc.
So each chunk gets a request-id, so if two or more upstream workers write to single connection simultaneously, the chunks that nginx will get are just smaller. That is the single cons.
As regards the "the web server has to save all those data", it does this in any case (regardless multiplexing used or not), because otherwise one can get out-of-memory situation if too many pending data available for response. So either the backend should produce fewer data (or be thwarted) or the web-server should receive it as soon as possible and transmit it to client or save it to some interim storage (and for example nginx does this if pending data size exceeds the values configured with fastcgi_buffer_size and fastcgi_buffers directives).
Also this is false. The web-server has to read only the single chunk of response to the end, and good worker pools have "intelligent" handling, so automatically sends the chunks to the web-server as soon as possible (means if it gets available), so if multiple content-providers write to so-called "reflected" channels of the same real connection, the pending packets will be separated and chunks received from nginx as soon as the response data is available.
Thereby almost only the throughput of the connection is crucial, and it does not matter at all how fast the clients will receive the data.
And again, multiplexing saves vastly the time of the connection buildup, so reduces number of pending requests as well as the common request execution time (transaction rate).
我不知道是否某些服务器实现了 FASTCGI 多路复用(我相信您理解正确,但详细信息在 FASTCTI 协议规范中),我不会打扰。
您很可能会通过 现有的 FASTCGI 库 使用 FASTCGI(例如 Ocamlnet(如果您使用 Ocaml 等进行编码)。如果该库能够实现多路复用,那么它就会进行多路复用。从您(该库用户)的角度来看,您不应该真正关心,除非您自己编写这样的库。
如果 FASTCGI 多路复用困扰您,您可以使用 SCGI 协议,它提供类似的功能,但更简单,效率稍低,并且非复用。
I don't know if some server implement FASTCGI multiplexing (which I believe you understood correctly, but the details are in the FASTCTI protocol specifications), and I would not bother.
You will very probably use FASTCGI thru an existing FASTCGI library (e.g. Ocamlnet if you code in Ocaml, etc.). And that library would do the multiplexing, if it does it. From your point of view (of that library user) you should not really care, unless you are coding such a library yourself.
If FASTCGI multiplexing bothers you, you might use the SCGI protocol, which offers similar functionality, but is simpler, a bit less efficient, and non-multiplexing.