高并发服务端,如何高效的接受请求,然后响应结果

2018-02-01 21:14:34 +08:00
 thomaswang

在处理大并发的请求是,用 epoll 管理多个 socket,一次循环中返回 10 个可读的 socket,每一个都得 read,然后处理数据,然后 send,这样 10 个串行执行下来,黄花菜都凉了,这一块怎么优化呢,有种说法: 把这 10 个可读的套接字扔到一个 io 线程里面读取,计算线程处理逻辑,然后注册的 epoll,关注可写事件,这样返给用户。有没有正规的做法,有没有相关的权威的文档

2347 次点击
所在节点    问与答
11 条回复
sen506
2018-02-01 23:21:47 +08:00
你这是错觉,非阻塞 socket 性能是很不错的,并不是你说的那样 10 个 read/write 就不行了。。
thomaswang
2018-02-01 23:28:10 +08:00
@sen506 首先是 read(有可能一次 read 不能读完客户端发的请求,需要多次), read 完了,知道用户要读 index.html 文件,要处理数据(比如压缩一下), 然后把压缩的 send 给客户端,这样 1 个处理完了,然后同样的情况处理 2, 然后是 3, .... 然后是 10,好 都处理完了,再去用 epoll 里面拿活跃的请求,这样不慢 ? 还是我理解的有问题
thomaswang
2018-02-01 23:30:52 +08:00
@thomaswang 补充一下,send 的时候,可能阻塞住,内核发送缓存区可能是满的,客户端内核接受缓存区可能一直是满的,这要要阻塞...
sen506
2018-02-01 23:37:14 +08:00
压缩这个会耗 cpu,其他的,读还有写,还真的不慢的,读的话你需要实现一个断包的函数,每次数据 ready 了,用你的断包函数 check 下,ok 了,就做业务处理,否则就继续挂 epoll 上,写也是一样的,系统缓冲区空闲了就写,否则挂着。。。可以参考下 reator 模式。。
byaiu
2018-02-01 23:50:55 +08:00
muduo 那本书里记得有探讨这个问题
thomaswang
2018-02-01 23:58:44 +08:00
@sen506 明白你的意思了,多谢
thomaswang
2018-02-01 23:59:27 +08:00
@byaiu 多谢,我下单了
htfy96
2018-02-02 00:11:38 +08:00
楼主可以看看 proactor/reactor 模式 + 最近的一些基于协程的网络库是怎么搞的
sryanyuan
2018-02-02 11:04:57 +08:00
lz 可以参考下 libevent 的处理方式
所有的 socket 设为 nonblock 的,假设满了,直接返回,等待下次可写继续写。
单线程+epoll 性能是不错的,假设需要高并发,可以通过一个线程 accept,然后把 fd 扔到多个工作线程中,每个工作线程一个 epoll 来处理 accept 线程丢过来的 fd,这样就可以多个线程分担多个 socket 了。这个也是 memcache 使用 libevent 的方式。
thomaswang
2018-02-04 14:50:29 +08:00
@htfy96 多谢
thomaswang
2018-02-04 14:51:17 +08:00
@sryanyuan 多谢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/427822

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX