看來 Apache 的優雅重載(apachectl Graceful)是一個非同步操作。如果我從腳本呼叫它,腳本將在 Apache 執行其操作時繼續,這可能需要不確定的時間(例如緩慢的客戶端、長時間的下載)。
我想以程式設計方式檢測重新載入何時完成以及 Apache 現在正在使用新組態運行。換句話說,我想找到某種方法將其視為同步調用,只有在 Apache 完成後才會繼續。
如果你是我,你會怎麼做?
12/09 新增:Apache 似乎使用新配置重新啟動空閒線程,但具有打開連接的線程保留舊配置,直到連接終止。因此,也許可以更準確地提出關於確定 Apache 何時開始接受具有新配置的新連線的問題。
答案1
我想我需要解決我自己的問題...
這是我想出的一段 Perl 程式碼。基本上,我找到 Apache 日誌檔案的末尾,並記住它。然後我發出 Apache 重新啟動/重新載入命令,並查看此後日誌檔案中寫入了哪些文字。如果文字包含“恢復正常操作”,我認為重新啟動/重新載入已完成。 (我不確定這是真的,但這聽起來像是來自 Apache 頁面上的“停止和重新啟動”:http://httpd.apache.org/docs/2.2/stopping.html)
改進表示讚賞。
my $lastPos;
sub textSinceLast {
my $logF = '/var/log/httpd/error_log'; # or wherever your Apache log file is
open( FH, '<', $logF ) || die( "Cannot open $logF" );
my $pos = sysseek( FH, 0, SEEK_END );
my $ret = "Still at mark";
if( defined( $lastPos ) && $pos != $lastPos ) {
sysseek( FH, $lastPos, SEEK_SET );
sysread( FH, $ret, $pos - $lastPos, 0 );
}
close( FH );
$lastPos = $pos;
return $ret;
}
textSinceLast();
`systemctl reload httpd`; # or "service restart apache2", or whatever your distro wants
for( my $i=0 ; $i<1000 ; ++$i ) { # give up after 10sec
select( undef, undef, undef, 0.01 ); # apparently a tricky way of sleeping for 10ms
my $text = textSinceLast();
if( $text =~ /resuming normal operations/ ) {
print "Detected restart on $i\n";
last;
}
}