fragen stichworte

Elastische Beanstalk-Protokollrotation, die Apache-Neustart verursacht

Ich habe bereits durchgearbeitet. AWS Elastic Beanstalk - Apache wird ständig neu gestartet.

Unsere elastischen Beanstalk-Instanzen melden die folgende Meldung in error_log

[Mon Jun 26 22:01:01.878892 2017] [mpm_prefork:notice] [pid 8595] AH00173: SIGHUP received.  Attempting to restart
*** Error in (wsgi:wsgi)    ': double free or corruption (out): 0x00007f564cced560 ***

Manchmal sieht die Fehlerfolge wie folgt aus:

[Tue Jun 27 00:01:01.215260 2017] [:error] [pid 6429] [remote XX.XXX.XX.195:29773] mod_wsgi (pid=6429): Exception occurred processing WSGI script '/opt/python/current/app/site/settings/wsgi/__init__.py'.
[Tue Jun 27 00:01:01.215320 2017] [:error] [pid 6429] [remote XX.XXX.XX.195:29773] OSError: failed to write data
[Tue Jun 27 00:01:01.222407 2017] [:error] [pid 6430] [remote XX.XXX.XX.60:53313] mod_wsgi (pid=6430): Exception occurred processing WSGI script '/opt/python/current/app/site/settings/wsgi/__init__.py'.
[Tue Jun 27 00:01:01.222460 2017] [:error] [pid 6430] [remote XX.XXX.XX.60:53313] OSError: failed to write data
[Tue Jun 27 00:01:04.554810 2017] [core:warn] [pid 8595] AH00045: child process 7614 still did not exit, sending a SIGTERM
[Tue Jun 27 00:01:04.554850 2017] [core:warn] [pid 8595] AH00045: child process 7615 still did not exit, sending a SIGTERM
[Tue Jun 27 00:01:05.555958 2017] [mpm_prefork:notice] [pid 8595] AH00173: SIGHUP received.  Attempting to restart
*** Error in (wsgi:wsgi)    ': double free or corruption (out): 0x00007f5640cae900 ***
*** Error in (wsgi:wsgi)    ': double free or corruption (out): 0x00007f78649b7970 ***

Das geht fast jede Stunde weiter. Die allgemeine Nachricht lautet:

[Mon Jun 26 22:01:01.878892 2017] [mpm_prefork:notice] [pid 8595] AH00173: SIGHUP received.  Attempting to restart

Ich habe nach dem mpm_prefork -Modul conf-Block gesucht ... und es gibt keinen, also werden alle Standardeinstellungen verwendet.

Ich habe nach dem Befehl logrotation gesucht, der von elastic beanstalk

ausgeführt wird
/var/log/httpd/* {
size 10M
missingok
notifempty
rotate 5
sharedscripts
compress
dateext
dateformat -%s
create
postrotate
   /sbin/service httpd reload >/dev/null 2>/dev/null || true
endscript
olddir/var/log/httpd/rotated
}

Ziemlich Standard. Nach meinem Verständnis von reload wird versucht, einen Neustart durchzuführen ...

Ich kann die Fehlermeldung manuell auslösen, indem Sie sudo apachectl -k restart ausführen, obwohl ich nicht finden kann, wo dies während der Protokollrotation laufen würde.

Wir haben nachgelagerte Dienste, die scheinbar Ausnahmen an dem Punkt auslösen, an dem dieser Server alle seine Verbindungen auflegt.

Nun, meine Frage ist, was sonst während logrotate das SIGHUP innerhalb des mpm_prefork verursachen könnte? Soweit ich das beurteilen kann, sollte dies nicht außerhalb einer Fehlerbedingung geschehen.

Apache/2.4.18 (Amazon) mod_wsgi/3.5 Python/3.4.3

antworten

Kurz gesagt sieht es so aus, als ob die aktuelle Konfiguration der Elastic Beanstalk-Logrotation fehlerhaft ist, was zu Ausfallzeiten führt, 504 Gateway Timeout. Lass uns einen Blick darauf werfen.

Wiedergabe

Wir erstellen eine einfachste Python-WSGI-Anwendung.

application.py

import time


def application(environ, start_response):
    # somewhat realistic response duration
    time.sleep(0.5)

    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers)
    return [b'Hello world!\n']

In application.zip packen. Erstellen Sie anschließend die Anwendung und Umgebung von Elastic Beanstalk Python. Laden Sie das Archiv hoch. Stellen Sie sicher, dass Sie ein Schlüsselpaar verwenden, das Sie besitzen. Behalten Sie die anderen Einstellungen bei. Warten Sie, bis es fertig ist (mehrere Minuten).

ssh in die zugrunde liegende EC2-Instanz (siehe Instanzkennung im EB-Protokoll). Geben Sie ein (logrotate nach Aktion httpd, siehe unten):

sudo/sbin/service httpd reload

Dann auf Ihrem Computer ausführen:

siege -v -b -c 10 -t 10S http://your-test-eb.you-aws-region.elasticbeanstalk.com/

Wiederholen Sie den reload-Befehl während der Ausführung einige Male.

Dann wird etwas wie das Folgende erwartet:

** SIEGE 3.0.8
** Preparing 10 concurrent users for battle.
The server is now under siege...
HTTP/1.1 200   0.63 secs:      13 bytes ==> GET /
HTTP/1.1 200   0.65 secs:      13 bytes ==> GET /
HTTP/1.1 200   0.64 secs:      13 bytes ==> GET /
HTTP/1.1 200   0.60 secs:      13 bytes ==> GET /
...

Folgendes passiert, wenn Sie reload verwenden.

HTTP/1.1 504   0.06 secs:       0 bytes ==> GET /
HTTP/1.1 504   0.07 secs:       0 bytes ==> GET /
HTTP/1.1 504   0.08 secs:       0 bytes ==> GET /
HTTP/1.1 504   0.10 secs:       0 bytes ==> GET /
HTTP/1.1 504   0.11 secs:       0 bytes ==> GET /
HTTP/1.1 504   0.66 secs:       0 bytes ==> GET /
HTTP/1.1 504   0.19 secs:       0 bytes ==> GET /
HTTP/1.1 504   0.20 secs:       0 bytes ==> GET /
HTTP/1.1 504   0.09 secs:       0 bytes ==> GET /

Dann erholt es sich.

HTTP/1.1 200   1.25 secs:      13 bytes ==> GET /
HTTP/1.1 200   1.24 secs:      13 bytes ==> GET /
HTTP/1.1 200   1.26 secs:      13 bytes ==> GET /
...

Lifting the server siege..      done.

Transactions:                 75 hits
Availability:              81.52 %
Elapsed time:               9.40 secs
Data transferred:           0.00 MB
Response time:              1.21 secs
Transaction rate:           7.98 trans/sec
Throughput:             0.00 MB/sec
Concurrency:                9.68
Successful transactions:      75
Failed transactions:          17
Longest transaction:        4.27
Shortest transaction:       0.06

Beachten Sie, dass ELB scheinbar keine Auswirkung auf das Problem hat, und dasselbe kann mit zwei SSH-Sitzungen zu EC2 und (Amazon AMI hat nicht siege):

ab -v 4 -c 10 -t 10 http://your-test-eb.you-aws-region.elasticbeanstalk.com/

Ursache

/etc/cron.hourly/cron.logrotate.elasticbeanstalk.httpd.conf

#!/bin/sh
test -x/usr/sbin/logrotate || exit 0
/usr/sbin/logrotate/etc/logrotate.elasticbeanstalk.hourly/logrotate.elasticbeanstalk.httpd.conf

/etc/logrotate.elasticbeanstalk.hourly/logrotate.elasticbeanstalk.httpd.conf

/var/log/httpd/* {
size 10M
missingok
notifempty
rotate 5
sharedscripts
compress
dateext
dateformat -%s
create
postrotate
   /sbin/service httpd reload >/dev/null 2>/dev/null || true
endscript
olddir/var/log/httpd/rotated
}

Hinweis postrotate. /sbin/service ist nur ein System V-Wrapper für Skripte in /etc/init.d/. Die Manpage sagt:

service runs a System V init script in as predictable environment as possible, removing most environment variables and with current working directory set to / .

Beachten Sie, dass reload kein Standardwartungsbefehl für Apache ist.. Es ist der Downstream-Zusatz der Distribution. Schauen wir uns das Init-Skript an: /etc/init.d/httpd. Relevanter Teil folgt:

reload() {
        echo -n $"Reloading $prog: "
        check13 || exit 1
        killproc -p ${pidfile} $httpd -HUP
        RETVAL=$?
        echo
}

Wie Sie sehen, sendet es ein HUP -Signal an Apache, das als Jetzt neu starten:

interpretiert wird

Sending the HUP or restart signal to the parent causes it to kill off its children like in TERM , but the parent doesn't exit. It re-reads its configuration files, and re-opens any log files. Then it spawns a new set of children and continues serving hits.

TERM erklärt 504 ziemlich gut. Wie es wahrscheinlich hätte geschehen sollen, ist Graceful Restart, da es auch Protokolle öffnet, aber die zugestellten Anfragen nicht beendet:

The USR1 or graceful signal causes the parent process to advise the children to exit after their current request (or to exit immediately if they're not serving anything). The parent re-reads its configuration files and re-opens its log files. As each child dies off the parent replaces it with a child from the new generation of the configuration, which begins serving new requests immediately.

...

The code was written to both minimize the time in which the server is unable to serve new requests (they will be queued up by the operating system, so they're not lost in any event) and to respect your tuning parameters.

Problemumgehung

Es ist möglich, .ebextensions zu verwenden, um /etc/logrotate.elasticbeanstalk.hourly/logrotate.elasticbeanstalk.httpd.conf zu ersetzen. Im Stammverzeichnis erstellen .ebextensions/10_logs.config mit folgendem Inhalt (ersetzen Sie "reload" grundsätzlich durch "graceful"):

files:
    "/etc/logrotate.elasticbeanstalk.hourly/logrotate.elasticbeanstalk.httpd.conf":
        mode: "000644"
        owner: root
        group: root
        content: |
           /var/log/httpd/* {
                size 10M
                missingok
                notifempty
                rotate 5
                sharedscripts
                compress
                dateext
                dateformat -%s
                create
                postrotate
                   /sbin/service httpd graceful >/dev/null 2>/dev/null || true
                endscript
                olddir/var/log/httpd/rotated
            }

Stellen Sie Ihre Elastic Beanstalk-Umgebung erneut bereit. Beachten Sie jedoch, dass es mir mit anschließenden feinen Neustarts im Unter-Sekundenbereich (sporadisch) möglich war, 503 Service Unavailable zu produzieren. Dies ist jedoch nicht der Fall bei Protokollrotationen, da bei gleichmäßig beabstandeten Neustarts kein Fehler aufgetreten ist .