在处理大并发的请求是,用 epoll 管理多个 socket,一次循环中返回 10 个可读的 socket,每一个都得 read,然后处理数据,然后 send,这样 10 个串行执行下来,黄花菜都凉了,这一块怎么优化呢,有种说法: 把这 10 个可读的套接字扔到一个 io 线程里面读取,计算线程处理逻辑,然后注册的 epoll,关注可写事件,这样返给用户。有没有正规的做法,有没有相关的权威的文档
1
sen506 2018-02-01 23:21:47 +08:00 via iPhone 1
你这是错觉,非阻塞 socket 性能是很不错的,并不是你说的那样 10 个 read/write 就不行了。。
|
2
thomaswang OP @sen506 首先是 read(有可能一次 read 不能读完客户端发的请求,需要多次), read 完了,知道用户要读 index.html 文件,要处理数据(比如压缩一下), 然后把压缩的 send 给客户端,这样 1 个处理完了,然后同样的情况处理 2, 然后是 3, .... 然后是 10,好 都处理完了,再去用 epoll 里面拿活跃的请求,这样不慢 ? 还是我理解的有问题
|
3
thomaswang OP @thomaswang 补充一下,send 的时候,可能阻塞住,内核发送缓存区可能是满的,客户端内核接受缓存区可能一直是满的,这要要阻塞...
|
4
sen506 2018-02-01 23:37:14 +08:00 via iPhone 1
压缩这个会耗 cpu,其他的,读还有写,还真的不慢的,读的话你需要实现一个断包的函数,每次数据 ready 了,用你的断包函数 check 下,ok 了,就做业务处理,否则就继续挂 epoll 上,写也是一样的,系统缓冲区空闲了就写,否则挂着。。。可以参考下 reator 模式。。
|
5
byaiu 2018-02-01 23:50:55 +08:00 via Android 1
muduo 那本书里记得有探讨这个问题
|
6
thomaswang OP @sen506 明白你的意思了,多谢
|
7
thomaswang OP @byaiu 多谢,我下单了
|
8
htfy96 2018-02-02 00:11:38 +08:00
楼主可以看看 proactor/reactor 模式 + 最近的一些基于协程的网络库是怎么搞的
|
9
sryanyuan 2018-02-02 11:04:57 +08:00
lz 可以参考下 libevent 的处理方式
所有的 socket 设为 nonblock 的,假设满了,直接返回,等待下次可写继续写。 单线程+epoll 性能是不错的,假设需要高并发,可以通过一个线程 accept,然后把 fd 扔到多个工作线程中,每个工作线程一个 epoll 来处理 accept 线程丢过来的 fd,这样就可以多个线程分担多个 socket 了。这个也是 memcache 使用 libevent 的方式。 |
10
thomaswang OP @htfy96 多谢
|
11
thomaswang OP @sryanyuan 多谢
|