天天看點

Apache Access Log中的OPTIONS *的含義Apache Access Log中的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的文檔中, 有如下的說明:

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;

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

原文釋出時間:2014-11-09

本文來自雲栖合作夥伴“linux中國”

繼續閱讀