it-swarm.com.de

Aktualisieren einer Web-App ohne Ausfallzeiten

Es ist eine PHP App. Wie kann ich die Ausfallzeit minimieren, während ich die gesamte Codebasis aktualisiere?

31
gAMBOOKa

Was wir im Allgemeinen bei der Arbeit tun, ist:

  • bevor wir aktualisieren, lautet der Dokumentenstamm des Servers:
    • in /www/app-2009-09-01
    • der Zugriff erfolgt jedoch über eine symbolische Verknüpfung namens /www/application.
  • wir setzen die gesamte neue Codebasis auf /www/app-2009-09-08
  • sobald die gesamte Codebasis vorhanden ist:
    • wir entfernen den alten symbolischen Link
    • wir erstellen einen neuen symbolischen Link, der immer noch /www/application heißt, aber auf die neuen Quellen verweist: /www/app-2009-09-08
  • wir laden Apache neu, um die Berücksichtigung der Änderung zu erzwingen.

All dies geschieht über ein automatisches Skript (das einzige, was nicht automatisch geschieht, ist, dass wir es bei Bedarf starten). Das heisst :

  • Alles geht schnell (besonders das Umschalten der symbolischen Verbindung, was der wichtige Teil ist)
  • Kein Risiko, einen Fehler zu machen: Das Skript ist gut getestet und funktioniert seit Monaten/Jahren


Ein weiterer Vorteil dieser symbolischen Link-Prozedur ist, dass es sehr einfach ist, ein Update zurückzusetzen, wenn wir einen katastrophalen Fehler erst feststellen, nachdem wir die neue Version der Quellen in Betrieb genommen haben: Wir müssen nur die symbolischen Links wechseln zurück.

Das hindert Sie natürlich nicht daran, die neue Version auf Ihrem Staging-Server zu testen, bevor Sie sie in Betrieb nehmen - aber wer weiß ... Manchmal gibt es einen wirklich großen Fehler, den niemand gesehen hat testen :
Zum Beispiel, weil auf der Staging-Maschine keine regelmäßigen Belastungstests durchgeführt werden.
--- ((Ich habe gesehen, dass das "Rollback" -Ding 4 oder 5 Mal in 3 Jahren verwendet wurde - jedes Mal, wenn es den Tag rettete - und die Websites ^^)


Hier ist ein kurzes Beispiel: Angenommen, ich habe diesen VirtualHost in meiner Apache-Konfiguration:

<VirtualHost *>
        ServerName example.com
        DocumentRoot /www/application
        <Directory /www/application>
            # Whatever you might need here (this example is copy-pasted from a test server and test application ^^ )
            Options Indexes FollowSymLinks MultiViews +SymLinksIfOwnerMatch
            AllowOverride All
            php_value   error_reporting 6135
            php_value short_open_tag  on
        </Directory>
</VirtualHost>

Ziemlich "Standard" ... Das einzige, was ist /www/application ist kein richtiges Verzeichnis: Es ist nur eine symbolische Verknüpfung zur aktuellen Version der Quellen.
Das heißt, wenn Sie die Quellen auf den Server gestellt, aber noch nicht umgestellt haben, haben Sie ungefähr Folgendes:

[email protected]:/www
# ll
total 8
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-01
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-08
lrwxrwxrwx 1 root root   19 2009-09-08 22:08 application -> /www/app-2009-09-01

Beachten Sie, dass das Symbol auf die "alte Version" verweist

Nachdem die neue Version vollständig auf den Server hochgeladen wurde, wechseln wir:

[email protected]:/www
# rm /www/application
[email protected]:/www
# ln -s /www/app-2009-09-08 /www/application

Und jetzt zeigt der /www/application auf die neue Version der Quellen:

[email protected]:/www
# ll
total 8
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-01
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-08
lrwxrwxrwx 1 root root   19 2009-09-08 22:09 application -> /www/app-2009-09-08

Und wir müssen nur Apache neu starten:

[email protected]:/www
# /etc/init.d/Apache2 restart
 * Restarting web server Apache2

Die drei Schritte "Link entfernen; neuen Link erstellen; Apache neu starten" sollten schnell erledigt sein; dh durch ein automatisiertes Skript und nicht durch einen Menschen.

Verwendung dieser Lösung:

  • sie können so viel Zeit in Anspruch nehmen, wie Sie zum Hochladen der neuen Version der Quellen benötigen: Apache verwendet sie nicht, solange das Symbol nicht geändert wurde
  • wenn alles in Ordnung ist, wechseln Sie einfach den Symlink: Es geht schneller als das Ändern von 1 oder 2 Dateien ... Das bedeutet praktisch keine Ausfallzeit :-)

Und wenn Sie einen Opcode-Cache wie APC mit der Option stat bei 0 verwenden, kann dies vermutlich sogar noch weniger Ausfallrisiko bedeuten.


Natürlich ist dies die "einfache" Version - wenn Sie zum Beispiel einige hochgeladene Dateien haben, müssen Sie irgendwo einen anderen Symlink oder einen anderen VirtualHost oder was auch immer verwenden ...


Hoffe das ist klarer :-)

44
Pascal MARTIN

Können Sie den vorhandenen Code nicht übernehmen und das Projekt in eine separate Test-PHP-Datei migrieren und diese verwenden, während Sie Ihre Updates vornehmen? Ich meine, Sie sollten einen Testserver und einen Produktionsserver haben, damit Sie keine Ausfallzeiten haben, wenn Sie ein Update durchführen müssen.

2
THE DOCTOR

Richten Sie einen zweiten Server mit der aktualisierten Codebasis ein und wechseln Sie diese so schnell wie möglich. :-)

Wenn dies nicht möglich ist, stellen Sie sicher, dass Ihre Codebasis in Dutzende kleinerer Teile unterteilt ist. Dann wäre die Ausfallzeit auf jeweils nur einen Unterbereich begrenzt. Die kleineren Codeblöcke lassen sich leichter austauschen und die meisten funktionieren problemlos weiter. Probieren Sie dies jedoch zunächst in einer Testumgebung aus!

1
Wim ten Brink

Zunächst einmal verwende und mag ich oft eine Methode, die der von Pascal MARTIN ähnelt.

Eine andere Methode, die ich auch mag, ist mein SCM zu verwenden, um neuen Code zu pushen. Der genaue Prozess hängt von Ihrem SCM-Typ ab (git vs svn vs ...). Wenn Sie svn verwenden, möchte ich einen "Online" - oder "Produktions" -Zweig erstellen, den ich als Dokumentstamm auf dem Server auschecke. Wann immer ich neuen Code von einem anderen Zweig/Tag/Trunk übertragen möchte, gebe ich den neuen Code einfach in den "Online" -Zweig ein und führe svn update im Dokumentenstamm aus. Dies ermöglicht sehr einfache Rollbacks, da es ein vollständiges Revisionsprotokoll darüber gibt, was auf dem Server hoch/runter gegangen ist und wer es wann getan hat. Sie können diesen "Online" -Zweig auch problemlos auf einer Testbox ausführen, um die App zu überprüfen, die Sie pushen möchten.

Der Prozess ist für Git und andere SCM-Stile ähnlich, wurde jedoch so modifiziert, dass er natürlicher für die Art des Arbeitsablaufs ist.

Möchten Sie Aktualisierungen abrufen oder abrufen, anstatt sie zu übertragen? Haben Sie einfach einen Cron-Job oder einen anderen, intelligenteren Mechanismus, mit dem svn update automatisch ausgeführt wird.

Extra: Sie können diesen Prozess auch zum Sichern von Dateien verwenden, die Ihre Anwendung auf die Festplatte geschrieben hat. Lassen Sie einfach einen Cron-Job oder einen anderen Mechanismus svn commit ausführen. Jetzt werden die von Ihrer Anwendung erstellten Dateien in Ihrem SCM gesichert, die Revision wird protokolliert usw. (Wenn beispielsweise ein Benutzer eine Datei auf dem Datenträger aktualisiert, aber Sie möchten, dass Sie sie zurücksetzen, drücken Sie einfach die alte Revision).

1
Sam Bisbee

Ähnlich gehe ich auch bei Pascal MARTIN vor. Anstatt jedoch mehrere Versionen meiner App auf den Produktionsserver hochzuladen, behalte ich die "Builds" hinter meiner Firewall in einem separaten Verzeichnis mit Build-Nummer und Datum. Wenn ich eine neue Version hochladen möchte, verwende ich ein einfaches Skript, das "rsync -avh --delay-updates" enthält. Mit dem Flag "delay = updates" wird alles (was anders ist) in einen temporären Ordner hochgeladen, bis alle Updates vorhanden sind. Anschließend wird am Ende der Übertragung alles auf einmal auf die richtigen Pfade verschoben, sodass sich die App niemals in einem befindet halb alter halb neuer Zustand. Dies hat den gleichen Effekt wie die oben beschriebene Methode, außer dass ich nur eine Version der App auf dem Produktionsstandort behalte (am besten nur die wichtigsten Dateien auf dem Produktionsserver, IMO).

0
scotts