无阻塞Web服务器如何工作? [英] How non-blocking web server works?
问题描述
我正在尝试理解非阻塞式Web服务器的想法,似乎我想念一些东西.
I'm trying to understand the idea of non-blocking web server and it seems like there is something I miss.
我了解阻止"网络请求(伪代码)的原因有以下几种:
I can understand there are several reasons for "block" web request(psuedocode):
-
CPU绑定
CPU bound
字符串on_request(arg)
{
DO_SOME_HEAVY_CPU_CALC
返回完成";
}
string on_request(arg)
{
DO_SOME_HEAVY_CPU_CALC
return "done";
}
IO绑定
字符串on_request(arg)
{
DO_A_CALL_TO_EXTERNAL_RESOURCE_SUCH_AS_WEB_IO
返回完成";
}
string on_request(arg)
{
DO_A_CALL_TO_EXTERNAL_RESOURCE_SUCH_AS_WEB_IO
return "done";
}
睡觉
字符串on_request(arg)
{
睡眠(VERY_VERY_LONG_TIME);
返回完成";
}
string on_request(arg)
{
sleep(VERY_VERY_LONG_TIME);
return "done";
}
- 这三者都能从非阻塞服务器中受益吗?
- 从无阻塞Web服务器中真正受益的情况是如何做到的? 我的意思是,当查看Tornado服务器文档时,似乎 喜欢它释放"线程.我知道线程可以入睡 并等待来自操作系统的信号(至少在Linux中), 这是释放"线程的意思吗?这高一些吗 级别的实施?实际上创建新线程的东西 正在等待新请求,而不是正在睡觉"的请求?
- 我在这里想念东西吗?
- are all the three can benefit from non-blocking server?
- how the situation that do benefit from the non-blocking web server really do that? I mean, when looking at the Tornado server documentation, it seems like it "free" the thread. I know that a thread can be put to sleep and wait for a signal from the operation system (at least in Linux), is this the meaning of "freeing" the thread? is this some higher level implementation? something that actually create a new thread that is waiting for new request instead of the "sleeping" one?
- Am I missing something here?
谢谢
推荐答案
基本上,无阻塞套接字I/O的工作方式是使用轮询和状态机.因此,您的许多连接方案都是这样的:
Basically the way the non-blocking sockets I/O work is by using polling and the state machine. So your scheme for many connections would be something like that:
- 创建许多套接字并使它们无阻塞
- 将它们的状态切换为连接"
- 对它们每个启动
connect
操作 - 对所有对象进行轮询,直到发生某些事件为止
- 处理激发的事件(连接建立或连接失败)
- 将已建立的状态切换为发送"
- 在缓冲区中准备Web请求
- 轮询发送"套接字以进行WRITE操作
-
send
获得WRITE事件集的人的数据 - 对于已发送所有数据的用户,将状态切换为正在接收"
- 轮询接收"套接字以进行READ操作
- 对于设置了READ事件的用户,请执行
read
并根据协议处理读取的数据 - 如果协议是双向的,请重复;如果不是双向的,请关闭套接字.
- Create many sockets and make them nonblocking
- Switch the state of them to "connect"
- Initiate the
connect
operation on each of them - Poll all of them until some events fire up
- Process the fired up events (connection established or connection failed)
- Switch the state those established to "sending"
- Prepare the Web request in a buffer
- Poll "sending" sockets for WRITE operation
send
the data for those who got the WRITE event set- For those which have all the data sent, switch the state to "receiving"
- Poll "receiving" sockets for READ operation
- For those which have the READ event set, perform
read
and process the read data according to the protocol - Repeat if the protocol is bidirectional, or close the socket if it is not
当然,在每个阶段,您都需要处理错误,并且每个套接字的状态都不同(一个可能正在连接,而另一个可能已经在读取).
Of course, at each stage you need to handle errors, and that the state of each socket is different (one may be connecting while another may be already reading).
Regarding polling I have posted an article about how different polling methods work here: http://www.ulduzsoft.com/2014/01/select-poll-epoll-practical-difference-for-system-architects/ - I suggest you check it.
这篇关于无阻塞Web服务器如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!