当前位置 主页 > 服务器问题 > Linux/apache问题 >

    令Apache中沉睡的无用进程自动退出的方法

    栏目:Linux/apache问题 时间:2018-11-04 14:03

    这篇文章主要介绍了令Apache中沉睡的无用进程自动退出的方法,利用OPTIONS请求得以实现清理完成任务后的进程,需要的朋友可以参考下

    在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 -
    在Apache Prefork模式下, 启动的时候,Apache就会fork出一些worker进程, 来准备接受请求, 这些worker进程,在完成准备工作以后, 就会进入block模式的监听沉睡中, 等待请求到来而被唤醒。

    另外一方面, 在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: ",