在Apache的Access Log中会看到很多如下的访问日志:
127.0.0.1 - - [05/May/2011:10:54:07 +0800] "OPTIONS * HTTP/1.0" 200 - 127.0.0.1 - - [05/May/2011:10:54:08 +0800] "OPTIONS * HTTP/1.0" 200 - 127.0.0.1 - - [05/May/2011:10:54:09 +0800] "OPTIONS * HTTP/1.0" 200 - 127.0.0.1 - - [05/May/2011:10:54:10 +0800] "OPTIONS * HTTP/1.0" 200 -
另外一方面, 在Prefork模式下, 当请求很多, 目前的worker进程数不够处理的时候, 就会额外再fork一些worker进程出来, 以满足当前的请求。
而在这些请求高峰过后, 如果额外fork出来的进程数大于了MaxSpareServers, Apache就会告诉这些worker进程退出, 那么问题就来了。
这些进程都在沉睡中啊, 怎么告诉他们, 并且让他们自我退出呢?
Apache会首先发送一个退出状态字(GRACEFUL_CHAR !)给这些Work进程:
static apr_status_t pod_signal_internal(ap_pod_t *pod) { apr_status_t rv; char char_of_death = '!'; apr_size_t one = 1; rv = apr_file_write(pod->pod_out, &char_of_death, &one); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, "write pipe_of_death"); } return rv; }
但此时, Worker进程不会去读这些状态字, 因为他们还在沉睡。
这个时候Apache就会发送一个OPTIONS请求给自己, 唤醒这些沉睡的进程:
static apr_status_t dummy_connection(ap_pod_t *pod) { //...有省略 /* Create the request string. We include a User-Agent so that * adminstrators can track down the cause of the odd-looking * requests in their logs. */ srequest = apr_pstrcat(p, "OPTIONS * HTTP/1.0\r\nUser-Agent: ", ap_get_server_banner(), " (internal dummy connection)\r\n\r\n", NULL); //...有省略 }
这些进程在处理完当前请求以后(OPTIONS请求), 就会发现, oh, 主进程让我退出。
static void child_main(int child_num_arg) { //...有省略 while (!die_now && !shutdown_pending) { //...有省略 //1. listen //2. accept //3. process request /* Check the pod and the generation number after processing a * connection so that we'll go away if a graceful restart occurred * while we were processing the connection or we are the lucky * idle server process that gets to die. */ if (ap_mpm_pod_check(pod) == APR_SUCCESS) { /* selected as idle? */ die_now = 1; } //...有省略 } //...有省略 }
于是, 它就做完清理工作, 然后自我消亡了~~~
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:notice#nhooo.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。