apache 的任务分配模型

我们知道,Apache可以同时接受很多请求,在Apache的pre-fork模型中,有m个Apache的子进程随时等待着处理请求,这时,有n个请求过来了,那么,这n个请求是如何分配到m个进程来处理的呢?

首先,即使是n个请求同时到达,到操作系统层也会串行化后再提交到应用程序的。

情况一:
假设我们的Apache只listen一个IP:port, 则:
第一步:
父进程在fork子进程之前,会:
socket(…) = s;
listen(s,…) = 0;
这样就产生了一个listen指定ip:port 的文件描述符fd(s); Apache父进程在fork子进程时会将该fd(s)遗传给每一个子进程
第二步:
每个子进程都会处于:  accept(s,…) 状态,等待接受请求,这些子进程在s上排队,先到先得,得到请求后,开始处理请求,处理完请求后继续accept(s,…) 等待请求; 这样,如果每个请求的处理时间相同,则,每个子进程能处理的任务基本是平均分配的。

情况二:
假设我们的Apache同时listen了同一个IP上的80和443端口,则:
第一步:
父进程在fork子进程之间,会:
socket(…) = s80;
listen(s89,…) = 0;

socket(…) = s443;
listen(s443,…) = 0;

semget(…) = semaphore;
产生s80, s443 两个fd (如果是epoll模型,则是创建一个epoll)和一个信号量semaphore

第二步:
因为accept不能同时在两个socket上排队,所以直接进入accept状态就不行了,所以就用到了“同步IO多路技术”,一般有三种实现: select、poll、epoll,其中epoll是最为高效的一种,这里已epoll为例说明。因为epoll只能同时accept多个socket,但是没法让多个进程在epoll的多个socket上排队;所以还得引入一个信号量的概念,信号量是解决同步与互斥问题的,常用的一种实现为semop(…); 这样多个Apache的子进程通过semop在父进程产生的信号量semaphore上排队,这样,保证同时只有一个进程处于可以接受请求的状态,接受到请求之后,退出队列,然后由下一个子进程接受请求。基本流程如下:

留下评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据