Apache Access Log 中的 OPTIONS * 的含义

发布于 2024-11-25 08:04:25 字数 3220 浏览 11 评论 0

在 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 的文档中, 有如下的说明:

When the Apache HTTP Server manages its child processes, it needs a way to wake up processes that are listening for new connections. To do this, it sends a simple HTTP request back to itself. This request will appear in the access_log file with the remote address set to the loop-back interface (typically 127.0.0.1 or ::1 if IPv6 is configured). If you log the User-Agent string (as in the combined log format), you will see the server signature followed by “(internal dummy connection)” on non-SSL servers. During certain periods you may see up to one such request for each httpd child process.

可是,为什么要唤醒呢? 唤醒是为了做什么呢?

在 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 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;
        }
//...有省略
   }
//...有省略
}

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

莫相离

暂无简介

文章
评论
27 人气
更多

推荐作者

李珊平

文章 0 评论 0

Quxin

文章 0 评论 0

范无咎

文章 0 评论 0

github_ZOJ2N8YxBm

文章 0 评论 0

若言

文章 0 评论 0

南…巷孤猫

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文