2013-02-07 9 views
9

Ich entwickle eine Facebook-Canvas-Anwendung, und ich möchte es laden. Ich bin mir der Facebook-Beschränkung für automatisierte Tests bewusst, also simulierte ich die Grafik-API-Aufrufe, indem ich eine gefälschte Webanwendung unter nginx erstellte und meine/etc/hosts auf Punkt graph.facebook.com auf 127.0.0.1 umstellte.Mit Nginx zu lange Reaktionszeit für Testzwecke zu simulieren

Ich benutze jmeter, um die Anwendung zu laden und die Simulation funktioniert ok. Jetzt möchte ich langsame Graph-API-Antworten simulieren und sehen, wie sie meine Anwendung beeinflussen. Wie kann ich Nginx so konfigurieren, dass es eine Verzögerung für jede Anfrage einfügt, die an die simulierte Anwendung graph.facebook.com gesendet wird?

Antwort

10

Sie können die Geschwindigkeit von localhost (Netzwerk) durch Hinzufügen von Verzögerung verlangsamen.
Verwenden Sie den Befehl ifconfig, um das Netzwerkgerät zu sehen: Auf localhost kann es lo und im LAN sein eth0 sein.

  • Dieser Befehl Verzögerungs Verwendung hinzuzufügen

    tc qdisc add dev lo root netem delay 1000ms

  • zur Verzögerung Verwendung verändern diese ein

    tc qdisc change dev lo root netem delay 1ms

  • (1000 ms Verzögerung auf lo Netzwerkgerät Zugabe) und entferne die Verzögerung

    tc qdisc del dev lo root netem delay 1000ms

+0

Leider ist 'tc' nur für Linux, aber nicht für OS X. – jiyinyiyong

2

Ich habe eine nginx Konfiguration geändert limit_req_zone und limit_req zu verwenden Verzögerungen einzuführen. Im Folgenden wird die Servicegeschwindigkeit auf 20 Anfragen pro Sekunde reduziert (rate=20r/s). Ich habe burst=1000 gesetzt, damit meine Anwendung 503 Antworten nicht erhalten würde.

http { 
    limit_req_zone $binary_remote_addr zone=one:10m rate=20r/s; 
    [...] 
    server { 
     [...] 
     location/{ 
      limit_req zone=one burst=1000; 
      [...] 
     } 
    } 
} 

Die Dokumentation ist here. Ich glaube nicht, dass es eine Möglichkeit gibt, mit dieser Methode eine einheitliche Verzögerung anzugeben.

1

Meine frühere Antwort funktioniert, aber es ist besser an einen Fall angepasst, in dem alle Anfragen verlangsamt werden müssen. Seitdem musste ich mir eine Lösung ausdenken, die es mir erlaubte, das Ratenlimit nur von Fall zu Fall zu aktivieren und die folgende Konfiguration zu erstellen. Stellen Sie sicher, dass Sie die gesamte Antwort lesen, bevor Sie diese verwenden, denn es gibt wichtige Nuancen zu wissen.

location/{ 
     if (-f somewhere/sensible/LIMIT) { 
      echo_sleep 1; 
      # Yes, we need this here too. 
      echo_exec /proxy$request_uri; 
     } 

     echo_exec /proxy$request_uri; 
    } 

    location /proxy/ { 
     internal; 
     # Ultimately, all this goes to a Django server. 
     proxy_pass http://django/; 
     proxy_set_header Host   $http_host; 
     proxy_set_header X-Forwarded-For $remote_addr; 
    } 

Wichtiger Hinweis: das Vorhandensein oder Fehlen von Schrägstrichen in den verschiedenen Pfaden macht einen Unterschied. Zum Beispiel proxy_pass http://django, ohne einen Schrägstrich, tut nicht tun Sie das gleiche wie die Zeile im obigen Code.

Das Prinzip der Bedienung ist einfach. Wenn die Datei somewhere/sensible/LIMIT vorhanden ist, werden Anforderungen, die mit location / übereinstimmen, für eine Sekunde angehalten, bevor Sie fortfahren. Wenn ich also eine Netzwerk-Verlangsamung möchte, erstelle ich die Datei in meiner Testsuite und wenn ich die Verlangsamung entfernen möchte, entferne ich sie. (Und ich habe Cleanup-Code, der es zwischen jedem Test entfernt.) Theoretisch würde ich lieber Variablen dafür als eine Datei verwenden, aber das Problem ist, dass Variablen mit jeder Anfrage neu initialisiert werden.Also können wir keinen location Block haben, der eine Variable zum Drehen des Limits und einen anderen zum Ausschalten setzen würde. (Das ist das erste, was ich versuchte, und es scheiterte aufgrund der Lebensdauer der Variablen). Es wäre wahrscheinlich möglich, das Perl-Modul oder Lua zu verwenden, um Variablen persistent zu machen oder an Cookies zu fummeln, aber ich habe mich entschieden, diese Routen nicht zu durchgehen.

Wichtige Hinweise:

  1. Es ist keine gute Idee, Richtlinien vom echo Modul zu mischen (wie echo_sleep und echo_exec) mit den Aktien Richtlinien von nginx, die bei der Herstellung einer Reaktion zur Folge hat. Ich hatte ursprünglich echo_sleep zusammen mit proxy_pass und bekam schlechte Ergebnisse. Deshalb haben wir den location /proxy/ Block, der die Aktiendirektiven von den echo Sachen trennt. (Siehe diese issue für einen ähnlichen Konflikt, der durch Aufteilen eines Blocks aufgelöst wurde.)

  2. Die beiden echo_exec Richtlinien, innerhalb und außerhalb des if, sind notwendig, da, wie if funktioniert.

  3. Die internal Direktive verhindert, dass Clients URLs /proxy/... direkt anfordern.