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

在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: “,

                               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 well 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;

            }

    //…有省略

       }

    //…有省略

    }

于是, 它就做完清理工作, 然后自我消亡了~~~

声明: 猿站网有关资源均来自网络搜集与网友提供,任何涉及商业盈利目的的均不得使用,否则产生的一切后果将由您自己承担! 本平台资源仅供个人学习交流、测试使用 所有内容请在下载后24小时内删除,制止非法恶意传播,不对任何下载或转载者造成的危害负任何法律责任!也请大家支持、购置正版! 。本站一律禁止以任何方式发布或转载任何违法的相关信息访客发现请向站长举报,会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。本网站的资源部分来源于网络,如有侵权烦请发送邮件至:2697268773@qq.com进行处理。
建站知识

小知识:不能在本地计算机启动 apache2.2解决方法

2023-3-16 17:44:55

建站知识

小知识:配置fail2ban对Apache服务器进行安全防护的方法

2023-3-16 17:59:24

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索