【问题标题】:How non-blocking web server works?非阻塞网络服务器如何工作?
【发布时间】:2014-02-03 20:03:49
【问题描述】:

我正在尝试理解非阻塞 Web 服务器的概念,但似乎有些我想念的东西。

我可以理解“阻止”网络请求(伪代码)有几个原因:

  1. CPU 限制

    字符串 on_request(arg)
    {
    DO_SOME_HEAVY_CPU_CALC
    返回“完成”;
    }

  2. IO 绑定

    字符串 on_request(arg)
    {
    DO_A_CALL_TO_EXTERNAL_RESOURCE_SUCH_AS_WEB_IO
    返回“完成”;
    }

  3. 睡觉

    字符串 on_request(arg)
    {
    睡眠(VERY_VERY_LONG_TIME);
    返回“完成”;
    }

    • 这三个都可以从非阻塞服务器中受益吗?
    • 确实受益于非阻塞 Web 服务器的情况如何真正做到这一点? 我的意思是,在查看 Tornado 服务器文档时,似乎 喜欢它“释放”线程。我知道可以让线程进入睡眠状态 并等待来自操作系统的信号(至少在 Linux 中), 这是“释放”线程的含义吗?这是不是更高一些 水平执行?实际上创建一个新线程的东西 是在等待新请求而不是“休眠”请求?
    • 我在这里遗漏了什么吗?

谢谢

【问题讨论】:

    标签: asynchronous operating-system tornado nonblocking


    【解决方案1】:

    要从非阻塞服务器中受益,您的代码也必须是非阻塞的 - 您不能只在非阻塞服务器上运行阻塞代码并期望获得更好的性能。例如,您必须删除所有对 sleep() 的调用,并将它们替换为非阻塞等效项,例如 IOLoop.add_timeout(这反过来又涉及重组代码以使用回调或协程)。

    【讨论】:

      【解决方案2】:

      如何在 Python 中使用 Linux epoll http://scotdoyle.com/python-epoll-howto.html 可能会给你一些关于这个话题的观点。

      【讨论】:

        【解决方案3】:

        基本上,非阻塞套接字 I/O 的工作方式是使用轮询和状态机。所以你的许多连接方案是这样的:

        • 创建多个套接字并使其非阻塞
        • 将它们的状态切换为“连接”
        • 对它们中的每一个启动connect 操作
        • 轮询所有这些,直到某些事件触发
        • 处理触发的事件(连接建立或连接失败)
        • 将已建立的状态切换为“正在发送”
        • 在缓冲区中准备 Web 请求
        • 轮询“发送”套接字以进行 WRITE 操作
        • send 获得 WRITE 事件集的数据
        • 对于已发送所有数据的用户,将状态切换为“正在接收”
        • 轮询“接收”套接字以进行 READ 操作
        • 对于设置了READ事件的,执行read,按照协议处理读取的数据
        • 如果协议是双向的则重复,否则关闭套接字

        当然,在每个阶段你都需要处理错误,并且每个套接字的状态是不同的(一个可能正在连接而另一个可能已经在读取)。

        关于轮询,我在这里发布了一篇关于不同轮询方法如何工作的文章:http://www.ulduzsoft.com/2014/01/select-poll-epoll-practical-difference-for-system-architects/ - 我建议你查看它。

        【讨论】:

        • 您可能会考虑接受答案,这样当人们希望回答更多问题时它不会显示为“未回答”:) 谢谢!
        猜你喜欢
        • 2015-04-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-25
        • 1970-01-01
        • 2014-03-18
        • 2018-06-14
        • 1970-01-01
        相关资源
        最近更新 更多