它运行良好,但是当我计算每个工作人员处理的连接数(或每个工人消耗的CPU工具数)时,我发现它根本不平衡。
例如:
一个忙碌的工人:处理10k连接,消费者20%CPU; 一个空闲工作者:处理300个conenctions,消费者4%CPU;
我的服务器在RHEL6.5操作系统(2.6.32内核)上运行。
有人可以帮我解决这个问题吗?
编辑:
在挖掘了一些内核代码(2.6.32.x)后,我发现了为什么会出现平衡。
1 * MasterProcess:创建并绑定Listen套接字;
n * WorkerPrecess:创建epfd并监视来自master的listen socket。
当WorkProcess epoll_ctl(...,listen_sock,...)时,内核将监视文件添加到epoll结构的rbtree(@see fs / eventpoll.c ep_insert)并将epoll结构添加到wait_queue listen_sock通过回调(ep_ptable_queue_proc)
static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead,
poll_table *pt) {
...
add_wait_queue(whead, &pwq->wait);
...
}
//whead is the waitqueue of listen socket,
//and the *pt is a container of epfd's releated resource.
当一个新连接进入(SYN_REC)时,监听套接字的事件已被更改,内核将迭代等待等级通过epoll给出的回调将该事件通知给套接字上的所有epoll监视器。回调是 ep_poll_callback (@see fs / eventpoll.c),回调将唤醒epoll_wait系统调用的进程(或线程)等待。
在通知过程之后,listen socket的waitqueue序列不会改变。并且将通过修复订单通知事件等待进程。提前唤醒的进程应该有更多的连接来处理与最后一个进程得到通知。这导致了失衡。
1 * MasterProcess为所有WorkerProcess创建一个epfd; 2 * WorkerProcess通过epoll_wait等待同一个epfd;
在这种情况下,我们在内核级别只有一个 epoll结构。当事件发生时,将仅调用一个 epoll结构的等待call_back。
epoll结构的唤醒回调是:static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *key)
现在,所有WorkerProcess的boss线程都在epoll_wait上等待,而ep_poll_callback只会 唤醒其中一个。
当一个WorkerProcess被epoll唤醒时,它将从wait_queue中删除自己,如果调用了epoll_wait,则将它们重新添加到wait_queue的尾部。所以,我们可以逐个唤醒WorkerProcess。
答案 0 :(得分:0)
没有问题。
拥有多名工作人员的目的是至少有一名工作人员可以使用,即使其他工作人员很忙。
但是当多个工作人员在等待时,哪个人获得该事件并不重要。进程/线程不会因为它运行较长时间而耗尽。
没有平衡,因为内核不关心。你也不应该。