什麼是Apache Access Log中的OPTIONS *的含義

roc_guo發表於2023-10-11
訪問日誌

在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的文件的說明

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 Access Log中的OPTIONS *的含義什麼是Apache Access Log中的OPTIONS *的含義

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

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


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69901823/viewspace-2988055/,如需轉載,請註明出處,否則將追究法律責任。

相關文章