2014-02-10

结合IO多路复用的多线程服务器模型

Views: 32621 | 3 Comments

IO 多路复用技术, 就是常说的 select/epoll/kqueue 等处理文件描述符相关的函数. 在高性能高并发网络服务器的实现时, IO 多路复用技术可以用来处理多个 socket 连接的读写 IO 操作, 避免了传统的每一个 socket 连接分配一个单独的线程的低效的多线程技术.

虽然多线程在处理高并发网络 IO 方面是低效的, 但是, 多线程在处理业务相关的逻辑方面是有优势的, 而且多线程能利用多核 CPU.

所以, 一个高性能高并发的网络服务器, 应该是结合了 IO 多路复用技术和多线程技术的.

IO 多路复用技术用于处理网络 IO, 而多线程用于处理业务逻辑. 那么, 这两种技术是如何结合的呢?

整个服务器的流程是这样的: IO 多路复用接口层从客户端 socket 中读取了完整的请求报文之后, 便将请求报文转交给线程池, 线程处理完业务逻辑, 生成响应报文, 转交给 IO 多路复用接口层, 发送给客户端. 示意图如下:

        bytes                         packet
Client ------- IO Multiplexing Layer -------- Thread Pool

这样, 一个重要的问题就来了. 线程池和 IO 多路复用层之间的交互是报文(其实就是内存操作), 但是, IO 多路复用层只能处理文件描述符, 也就是 read()/write() 系统调用. 因此, 两者的交互必须从报文传递转换成文件描述符的操作. 所以, 我们需要一个可以 select/epoll/kqueue 的队列.

为此, 我用管道(pipe)封装了一个 SelectableQueue 类, 可以和 IO 多路复用层无缝结合. 这个技术已经在 SSDB 数据库服务器中使用了, 感兴趣的朋友可以获取 SSDB 的源码看看.

唯一的不足是, 管道通信在 10us 左右的延时, 所以会影响单个请求的处理时间, 但是, 对于高并发的网络服务器来说, 单个请求的处理时间的微小增加, 并不会对整个服务器的吞吐量有明显影响, 所以整个服务器的处理能力仍然非常高.

Related posts:

  1. Master-Workers 模式处理高负载
  2. Windows Python select标准输入输出
  3. fdevent – 方便的跨平台IO多路复用接口
  4. SSDB 双主(多主)同步模式现在 beta
  5. 汽车之家, 比亚迪等成为开源数据库SSDB的用户!
Posted by ideawu at 2014-02-10 10:54:31

3 Responses to "结合IO多路复用的多线程服务器模型"

Leave a Comment