21 Stimmen

Fehlerbehebung bei der Langsamkeit einer Website auf einem Nginx + Gunicorn + Django Stack

Problem, das ich hatte

Ich hatte ein Problem, bei dem einige Websites sehr lange zum Laden brauchten (mit "sehr lange" meine ich bis zu 16 Sekunden). Manchmal kam es zu einer vollständigen Zeitüberschreitung, die einen Nginx 504-Fehler erzeugte. Normalerweise konnte ich die Seite nach einer Zeitüberschreitung neu laden und sie wurde schnell geladen. Die Website, mit der ich Probleme hatte, hat ein sehr geringes Besucheraufkommen. Ich teste die Site, indem ich die Django-Admin-Indexseite lade, um zu versuchen, jegliche Langsamkeit auszuschließen, die durch schlechten Code verursacht werden könnte. Es sollte auch angemerkt werden, dass diese spezielle Website nur den Django-Admin verwendet, weil es sich um eine Intranet-Site nur für Mitarbeiter handelt.

Hosting-Einrichtung

Alle Websites, die ich hoste, befinden sich auf zwei Rackspace-Cloud-Servern. Der erste Server ist mein App-Server, der 1024 MB RAM hat, und mein zweiter Server ist mein Datenbankserver, der 2048 MB RAM hat. Der App-Server ist bis jede Website mit Nginx, die alle statischen Dateien dient und Proxys alles andere auf die Django Gunicorn Arbeiter für jede Website.

Wenn man sich den RAM und die CPU-Last des Datenbankservers ansieht, scheint alles in Ordnung zu sein.

$ free -m
             total       used       free     shared    buffers     cached
Mem:          1999       1597        402          0        200       1007
-/+ buffers/cache:        389       1610
Swap:         4094          0       4094

Top shows a CPU load average of: 0.00, 0.01, 0.05

Um zu versuchen, das Problem zu beheben, habe ich ein kleines Programm geschrieben Skript die den Speicherverbrauch auf dem Anwendungsserver ausgibt.

Beispielausdruck mit anonymisierten Standortdomänen:

Celery:     23 MB
Gunicorn:  566 MB
Nginx:       8 MB
Redis:     684 KB
Other:      73 MB

             total       used       free     shared    buffers     cached
Mem:           993        906         87          0         19         62
-/+ buffers/cache:        824        169
Swap:         2047        828       1218

Gunicorn memory usage by webste:
site01.example.com    31 MB
site02.example.com    19 MB
site03.example.com     7 MB
site04.example.com     9 MB
site05.example.com    47 MB
site06.example.com    25 MB
site07.example.com    14 MB
site08.example.com    18 MB
site09.example.com    27 MB
site10.example.com    15 MB
site11.example.com    14 MB
site12.example.com     7 MB
site13.example.com    18 MB
site14.example.com    18 MB
site15.example.com    10 MB
site16.example.com    25 MB
site17.example.com    13 MB
site18.example.com    18 MB
site19.example.com    37 MB
site20.example.com    30 MB
site21.example.com    23 MB
site22.example.com    28 MB
site23.example.com    80 MB
site24.example.com    15 MB
site25.example.com     5 MB

Beispiel einer Gunicorn-Konfigurationsdatei:

pidfile = '/var/run/gunicorn_example.com.pid'
proc_name = 'example.com'
workers = 1
bind = 'unix:/tmp/gunicorn_example.com.sock'

Beispiel Nginx-Konfiguration:

upstream example_app_server {
    server unix:/tmp/gunicorn_example.com.sock fail_timeout=0;
}

server {

    listen       80;
    server_name  example.com;
    access_log   /var/log/nginx/example.com.access.log;
    error_log    /var/log/nginx/example.com.error.log;

    location = /favicon.ico {
        return  404;
    }

    location  /static/ {
        root  /srv/sites/example/;
    }

    location  /media/ {
        root  /srv/sites/example/;
    }

    location  / {
        proxy_pass            http://example_app_server;
        proxy_redirect        off;
        proxy_set_header      Host             $host;
        proxy_set_header      X-Real-IP        $remote_addr;
        proxy_set_header      X-Forwarded-For  $proxy_add_x_forwarded_for;
        client_max_body_size  10m;
    }

}

Wie Sie sehen können, wird eine Menge Speicher ausgelagert. Um meine Probleme zu beheben, habe ich den Arbeitsspeicher des App-Servers aufgerüstet, was die Langsamkeit der Seiten vollständig behoben hat. Obwohl ich das Problem beheben konnte, hat es viel länger gedauert, als mir lieb war, und ich habe immer noch das Gefühl, dass ich im Grunde nur raten konnte, was die Ursache für die Langsamkeit der Website war. All dies führt mich zu meinen Fragen...

Fragen

  1. Wie kann man feststellen, dass die Langsamkeit einer Website mit geringem Datenverkehr nicht durch Inaktivität der Website verursacht wird, was wiederum dazu führt, dass Gunicorn die Website erneut laden muss, nachdem die Website inaktiv geworden ist? Gibt es eine Einstellung, die verhindert, dass eine Website inaktiv wird?
  2. Ich habe den Eindruck, dass einige meiner Websites zu viel Speicherplatz benötigen. Welche Tools kann ich verwenden, um den Speicherbedarf einer Website zu verringern? Sollte ich einige Python-Profiling-Tools verwenden?
  3. Welche Instrumente und Schritte sind erforderlich, um festzustellen, auf welcher Ebene des Stacks der Engpass auftritt?
  4. Wie lässt sich am besten feststellen, ob es Ihre Gunicorn-Prozesse sind, die ausgelagert werden, oder ob es andere Prozesse sind, die ausgelagert werden?
  5. Die meisten der von mir gehosteten Websites haben nicht viel Traffic, daher verwende ich nur einen Gunicorn Worker. Gibt es eine wissenschaftlichere Methode, um zu bestimmen und anzupassen, wie viele Gunicorn-Mitarbeiter Sie auf einer Website haben?
  6. Gibt es beim Hosten mehrerer Websites auf demselben Server Möglichkeiten, die Konfiguration so vorzunehmen, dass weniger Speicherplatz benötigt wird?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X