Erkennen, wann das ordnungsgemäße Neuladen von Apache abgeschlossen ist

Erkennen, wann das ordnungsgemäße Neuladen von Apache abgeschlossen ist

Es scheint, dass Apache Graceful Reload (apachectl graceful) ein asynchroner Vorgang ist. Wenn ich es von einem Skript aus aufrufe, wird das Skript fortgesetzt, während Apache seine Arbeit erledigt, was eine unbestimmte Zeit dauern kann (z. B. langsame Clients, lange Downloads).

Ich möchte programmgesteuert erkennen, wann das Neuladen abgeschlossen ist und Apache nun mit der neuen Konfiguration ausgeführt wird. Mit anderen Worten, ich möchte eine Möglichkeit finden, es wie einen synchronen Aufruf zu behandeln, der erst fortgesetzt wird, wenn Apache fertig ist.

Wie würden Sie das in meiner Lage machen?

Hinzugefügt am 09.12.: Es scheint, dass Apache inaktive Threads mit der neuen Konfiguration neu startet, Threads mit offenen Verbindungen jedoch die alte Konfiguration beibehalten, bis die Verbindung beendet wird. Daher könnte die Frage vielleicht genauer formuliert werden, um zu bestimmen, wann Apache mit der neuen Konfiguration beginnt, neue Verbindungen anzunehmen.

Antwort1

Ich denke, ich muss mein eigenes Problem lösen ...

Hier ist ein Stück Perl, das ich mir ausgedacht habe. Im Grunde suche ich das Ende der Apache-Protokolldatei und merke es mir. Dann führe ich einen Apache-Neustart/Neuladen aus und schaue, welcher Text seitdem in die Protokolldatei geschrieben wurde. Wenn der Text „Wiederaufnahme des normalen Betriebs“ enthält, betrachte ich den Neustart/Neuladen als abgeschlossen. (Ich bin nicht sicher, ob das stimmt, aber auf der Apache-Seite zum Thema „Anhalten und Neustarten“ hier klingt es so:http://httpd.apache.org/docs/2.2/stopping.html)

Verbesserungen sind willkommen.

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

verwandte Informationen