C'est une application PHP. Comment puis-je minimiser les temps d'arrêt lors de la mise à jour de toute la base de code?
Ce que nous faisons généralement au travail est:
/www/app-2009-09-01
/www/application
/www/app-2009-09-08
/www/application
, mais qui pointe vers les nouvelles sources: /www/app-2009-09-08
Tout ce processus se fait via un script automatique (la seule chose qui ne soit pas automatique, c'est que nous le lançons au besoin). Ça signifie :
Un autre avantage de cette procédure de lien symbolique est qu’il est très facile de "revenir en arrière" une mise à jour si nous remarquons un bogue catastrophique seulement après la mise en production de la nouvelle version des sources: il suffit de changer les liens symboliques. retour.
Bien entendu, cela ne vous empêche pas de tester la nouvelle version sur votre serveur de transfert avant de la mettre en production - mais, qui sait ... Parfois, il existe un très gros problème que personne n'a pu voir depuis le début. test :
Par exemple, car aucun test de charge n'est effectué régulièrement sur la machine de transfert.
--- ((J'ai vu la fonction "rollback" utilisée quelque chose comme 4 ou 5 fois en 3 ans - à chaque fois, cela a sauvé la journée - et les sites Web ^^)
Voici une sorte d’exemple rapide: supposons que je possède ce VirtualHost dans ma configuration Apache:
<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>
Joli "standard" ... La seule chose qui se passe est que /www/application
n'est pas un répertoire réel: c'est simplement un lien symbolique vers la version actuelle des sources.
Ce qui signifie que lorsque vous aurez placé les sources sur le serveur, sans avoir encore basculé, vous obtiendrez quelque chose comme ceci:
root@shark:/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
Notez que le symlinc pointe sur "l'ancienne version"
Maintenant que la nouvelle version a été totalement téléchargée sur le serveur, changeons:
root@shark:/www
# rm /www/application
root@shark:/www
# ln -s /www/app-2009-09-08 /www/application
Et maintenant, le /www/application
pointe vers la nouvelle version des sources:
root@shark:/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
Et il suffit de redémarrer Apache:
root@shark:/www
# /etc/init.d/Apache2 restart
* Restarting web server Apache2
Les trois étapes "supprimer le lien; créer le nouveau lien; redémarrer Apache" doivent être effectuées rapidement; c'est-à-dire par un script automatisé et non par un être humain.
En utilisant cette solution:
Et si vous utilisez un cache d'opcode comme APC avec l'option stat à 0, cela peut signifier encore moins de risque d'indisponibilité, je suppose.
Bien sûr, c'est la version "simple" - si vous avez des fichiers téléchargés, par exemple, vous devrez utiliser un autre lien symbolique quelque part, ou un autre VirtualHost ou autre chose ...
J'espère que c'est plus clair :-)
Ne pouvez-vous pas prendre le code existant et migrer le projet dans un fichier php de test séparé, et l'utiliser pendant vos mises à jour? Ce que je veux dire, c'est que vous devriez avoir un serveur de test et un serveur de production afin que, lorsque vous devez effectuer une mise à jour, vous n'ayez aucun temps d'arrêt.
Configurez un deuxième serveur avec la base de code mise à jour et basculez-les aussi rapidement que possible. :-)
Si ce n'est pas possible, assurez-vous que votre base de code est divisée en dizaines de parties plus petites. Ensuite, le temps d'arrêt serait limité à une sous-partie, une à la fois. Les plus petits blocs de code sont plus faciles à remplacer et la plupart continueront à fonctionner sans problèmes. Essayez simplement ceci sur un environnement de test d'abord!
Tout d’abord, j’utilise souvent et aime une méthode semblable à la réponse de Pascal MARTIN.
Une autre méthode que j'aime aussi consiste à utiliser mon GDS pour envoyer un nouveau code. Le processus exact dépend de votre type de SCM (git vs svn vs ...). Si vous utilisez svn, j'aime créer une branche "en ligne" ou "de production" que je récupère en tant que racine du document sur le serveur. Ensuite, chaque fois que je veux pousser le nouveau code depuis une autre branche/balise/tronc, je commets simplement le nouveau code dans la branche "en ligne" et exécute svn update à la racine du document. Cela permet des restaurations très faciles car il existe un journal de révision complet de ce qui est passé/descendu sur le serveur, qui l'a fait et quand. Vous pouvez également facilement exécuter cette branche "en ligne" sur une boîte de test, ce qui vous permet de contrôler l'application que vous êtes sur le point de pousser.
Le processus est similaire pour git et les autres styles de SCM, mais vient d'être modifié pour être plus naturel pour leur style de flux de travail.
Voulez-vous extraire/interroger au lieu d'envoyer des mises à jour? Juste un travail cron ou autre, un mécanisme plus intelligent lance automatiquement svn update.
Extra: Vous pouvez également utiliser ce processus pour sauvegarder les fichiers que votre application a écrits sur le disque. Juste un travail cron ou un autre mécanisme, exécutez svn commit. Maintenant, les fichiers créés par votre application sont sauvegardés dans votre GDS, les révisions enregistrées, etc. (par exemple, si un utilisateur met à jour un fichier sur le disque, mais veut que vous le restauriez, il suffit de pousser l'ancienne révision).
J'utilise une approche similaire à celle de Pascal MARTIN. Mais au lieu de télécharger plusieurs versions de mon application sur le serveur de production, je garde les "versions" derrière mon pare-feu, chacune dans un répertoire distinct avec le numéro et la date de la version. Lorsque je veux télécharger une nouvelle version, j'utilise un script simple qui inclut "rsync -avh - différé-mises à jour". L’indicateur "delay = updates" télécharge tout (ce qui est différent) dans un dossier temporaire jusqu’à ce que toutes les mises à jour soient disponibles, puis déplace tout à la fois, à la fin du transfert, dans le chemin approprié pour que l’application ne soit jamais dans un répertoire. Etat mi-ancien-mi-neuf. Cela a le même effet que la méthode ci-dessus, à la différence que je ne conserve qu'une version de l'application sur le site de production (il est préférable de ne disposer que des fichiers essentiels essentiels sur le serveur de production, IMO).