高性能httpserver的架构和惊群问题

我做了个简单实现,一个主线程负责accept,然后塞给一个epoll set;每个epoll set有一个单独的线程负责处理。epollset配置为1的时候,qps在开发机和线上机器分别跑到14000/18000; epollset配置为4,分别跑到30000/70000;再往上调整个数,qps没有明显提升。 硬件配置:8核cpu,千兆网卡。

 

如果仔细调整系统配置,程序极致优化,听说可以达到20wqps,一般项目用不到。

 

 

1. 为了提高网络利用率,提高httpserver的qps:

在主进程listen一个端口,然后fork出多个子进程,每个子进程内部都accept主进程listen的fd,然后建立自己的epoll_fd,对接收到的链接进行处理。 这样就实现了多个进程,从同一个端口accept链接,并行处理的目的;apache应该也是这么做的。

2. 惊群效应:指一个fd的事件被触发后,等候这个fd的所有线程/进程都被唤醒。

低版本的linux内核在accept这边有所谓的“惊群效应”,是指一个链接过来,会把堵塞在accept上的所有子进程都唤醒;但是只有一个子进程都读取到链接,其他子进程唤醒后发现没有数据,继续睡觉去了;这样就产生了大量的进程切换开销。 但目前的内核版本已经修复了这个问题,一个链接过来,内核只会唤醒一个子进程出来accept,这样就不用担心惊群效应了。

但是对于其他类型的fd,惊群效应还是存在的,而且是必须的;比如多个进程wait在一个pipe的读事件上,有数据过来后,多个进程都会被唤醒,因为内核也不知道这些数据就给一个进程读的,还是每个进程都读一点,这个逻辑是应用层控制的;而accept也相当于一个读事件,但内核确认一个进程接受一个链接就可以了。

同理,如果多个子进程把同一个listen的fd添加到各自的epoll_wait中,有链接过来会导致所有的子进程唤醒,这也会导致惊群效应;但这个是应用层面需要解决的问题。

关于httpserver惊群效应和如何处理: http://bbs3.chinaunix.net/viewthread.php?action=printable&tid=1676724

不知道这样是否正确 (目前主流高效的做法
1.创建listenfd监听并设置非阻塞
2.fork()一定数量的子进程
3.子进程创建epollfd并注册从父进程继承的listenfd
4.子进程等待在epoll_wait()上

当有链接来的时候所有的子进程都从epoll_wait()上返回了

这样会不会有性能问题


//这样是有惊群效应,lighthttpd也是这样处理的,accept时你判断一下判断值errno是不是EAGAIN; lighthttpd的做法,说明还是有效的


但是这样的情况
1.创建listenfd监听并设置非阻塞
2.fork()一定数量的子进程
3.子进程等待accept()上
当有链接来的时候就只有一个子进程从accept()上返回了,这个应改是正常的现象吧(不唤醒不必要的进程).

//accept这个最新的内核已经不会有惊群效应了

请教如何让epoll_wait()在这种情况下能像accept()的行为一样.

谢谢   必然不能,因为epoll_wait要处理普通的事件

//你可以使用线程池或进程池,也就是主线程或主进程负责accept,有连接来以后分给下面的进程或线程池去处理,各进程或线程epoll_wait他自己的就不会有了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值