Question

Nous avons une application serveur Java qui fonctionne sur plusieurs ordinateurs, tous connectés à Internet, certains derrière des pare-feu. Nous devons mettre à jour à distance les fichiers JAR et les scripts de démarrage à partir d'un site central, sans interruption notable de l'application elle-même.

Le processus doit être sans surveillance et infaillible (c’est-à-dire que nous ne pouvons pas nous permettre de casser l’application en raison de pannes Internet inopportunes).

Dans le passé, nous utilisions une variété de scripts et d’utilitaires externes pour gérer des tâches similaires, mais comme ils ont leurs propres dépendances, le résultat est plus difficile à gérer et moins portable. Avant de créer quelque chose de nouveau, je souhaite obtenir l’avis de la communauté.

Quelqu'un a-t-il déjà trouvé une bonne solution? Avez-vous des idées ou des suggestions?

Juste pour préciser: cette application est un serveur, mais pas pour les applications Web (pas de conteneurs Webapp ni de fichiers WAR ici). C'est juste un programme Java autonome.

Était-ce utile?

La solution

Vous n’avez pas spécifié le type d’applications serveur - je vais supposer que vous n’exécutez pas d’applications Web (le déploiement d’un fichier WAR faisant déjà ce dont vous parlez, vous avez rarement besoin d’une application Web). Si vous parlez d'une application Web, la discussion suivante peut toujours s'appliquer - vous allez simplement implémenter la vérification de la mise à jour et le ping-pong pour le fichier WAR au lieu de fichiers individuels).

Vous voudrez peut-être jeter un œil sur jnlp - WebStart est basé sur ceci (il s’agit d’une technologie de déploiement d’applications client), mais je suis à peu près sûr que cela pourrait être personnalisé pour effectuer des mises à jour pour une application de type serveur. Quoi qu'il en soit, jnlp fournit assez de descripteurs qui peuvent être utilisés pour télécharger les versions requises des fichiers JAR requis ...

Quelques réflexions générales à ce sujet (nous avons plusieurs applications dans le même compartiment et envisage un mécanisme de mise à jour automatique):

  1. Envisagez de disposer d'un fichier bootstrap.jar capable de lire un fichier jnlp et de télécharger les fichiers JAR requis / mis à jour avant de lancer l'application.

  2. Les
  3. fichiers JAR peuvent être mis à jour même lorsqu'une application est en cours d'exécution (au moins sous Windows, et c'est le système d'exploitation le plus susceptible de bloquer les fichiers en cours d'exécution). Vous pouvez rencontrer des problèmes si vous utilisez des chargeurs de classes personnalisés ou si vous avez un ensemble de fichiers JAR pouvant être chargés ou déchargés à tout moment, mais si vous créez des mécanismes pour éviter cela, écrasez les fichiers JAR puis relancez l'application. suffisant pour la mise à jour.

  4. Même s'il est possible de remplacer les fichiers JAR, vous pouvez envisager une approche ping-pong pour votre chemin de bibliothèque (si vous ne disposez pas déjà de votre programme de lancement d'applicatifs configuré pour lire automatiquement tous les fichiers JAR du dossier). lib et ajoutez-les au chemin de classe automatiquement, c’est quelque chose que vous voulez vraiment faire). Voici comment fonctionne le ping-pong:

L'application se lance et examine lib-ping \ version.properties et lib-pong \ version.properties et détermine laquelle est la plus récente. Disons que lib-ping a une version plus récente. Le lanceur recherche lib-ping * .jar et ajoute ces fichiers au CP lors du lancement. Lorsque vous effectuez une mise à jour, vous téléchargez des fichiers jar dans lib-pong (ou copiez des fichiers jar à partir de lib-ping si vous souhaitez économiser de la bande passante et que le fichier JAR n'a pas été modifié - cela en vaut rarement la peine!). Une fois tous les fichiers JAR copiés dans lib-pong, la dernière chose à faire est de créer le fichier version.properties (ainsi, une mise à jour interrompue qui aboutit à un dossier partiel de lib peut être détectée et purgée). Enfin, vous relancez l’application et bootstrap détecte que lib-pong est le chemin de classe souhaité.

  1. ping-pong comme décrit ci-dessus permet un retour en arrière. Si vous le concevez correctement, vous pouvez tester un élément de votre application et ne jamais le modifier pour vérifier s'il doit restaurer une version donnée. Ainsi, si vous vous trompez et déployez quelque chose qui casse l'application, vous pouvez invalider la version. Cette partie de l'application doit simplement supprimer le fichier version.properties du mauvais dossier lib- *, puis le relancer. Il est important de garder cette partie simple, parce que c'est votre coffre-fort.

  2. Vous pouvez avoir plus de 2 dossiers (au lieu de ping / pong, ayez simplement lib-aaaammjj et purgez tout sauf les 5 plus récents, par exemple). Cela permet une restauration plus avancée (mais plus compliquée!) Des fichiers JAR.

Autres conseils

Vous devez absolument jeter un coup d’œil à OSGi, il a été créé uniquement pour ces cas (en particulier pour les produits intégrés) et est utilisé par un grand nombre d’entreprises. Vous pouvez mettre à jour les "ensembles" de jar, les ajouter et les supprimer pendant l'exécution de l'application. Je ne l'ai pas utilisé moi-même. Je ne connais donc pas la qualité des infrastructures / serveurs Open Source, mais voici quelques liens utiles pour vous aider à démarrer:

http://www.osgi.org/Main/HomePage
http://www.aqute.biz/Code/Bnd
http://blog.springsource.com/2008/02/18 / creation-osgi-bundles /
http://blog.springsource.com/
http://www.knopflerfish.org/
http://felix.apache.org/site/index.html

Je recommanderais Capistrano pour un déploiement multi-serveur. Bien qu'il soit conçu pour déployer des applications Rails, je l'ai vu utilisé avec succès pour déployer des applications Java.

Lien: Capistrano 2.0 Pas seulement pour les rails

Les fichiers JAR ne peuvent pas être modifiés lorsque la machine virtuelle Java est en cours d'exécution et génèrent des erreurs. J'ai essayé des tâches similaires et le mieux que j'ai proposé est de faire une copie du fichier Jar mis à jour et de faire la transition du script de démarrage pour examiner ce fichier. Une fois que vous avez le bocal mis à jour, démarrez-le et attendez que l'ancien bocal se termine après lui avoir donné le signal. Malheureusement, cela signifie une perte de l'interface graphique, etc. pendant une seconde, mais la sérialisation de la plupart des structures en Java est simple et l'interface graphique actuelle pourrait être transférée à l'application mise à jour avant la fermeture (certaines choses peuvent ne pas être sérialisables!).

Il est très difficile de rendre la mise à jour atomique, en particulier si vous devez mettre à jour une base de données.

Mais si vous ne le faites pas, vous pouvez d’abord vous assurer que votre application peut s’exécuter à partir d’un chemin relatif. En d'autres termes, vous pouvez placer votre application dans un répertoire et tous les fichiers importants sont trouvés par rapport à cet emplacement, de sorte que l'emplacement d'installation réel n'est pas vraiment important.

Ensuite, dupliquez votre installation. Maintenant, vous avez le " en cours d'exécution " version et vous avez le " nouveau " version.

Mettez à jour le " nouveau " utilisez la technologie de votre choix (FTP, rsync, bande de papier, tout ce qui flotte sur votre bateau).

Vérifiez votre installation (sommes de contrôle, tests unitaires rapides, tout ce dont vous avez besoin - lancez-la même sur un port de test si vous le souhaitez).

Lorsque vous êtes satisfait de la nouvelle installation, renommez le répertoire d'origine (mv application application_old), renommez le répertoire NEW (nouvelle application mv) et démarrez-le.

Votre temps d'immobilisation est réduit à l'arrêt du serveur et au temps de démarrage (étant donné que le changement de nom est "gratuit").

Si, par hasard, vous détectez une erreur critique, votre version d'origine est toujours là. Arrêtez le nouveau serveur, renommez-le, redémarrez l'ancien. Très rapide retombée.

L’autre atout est que votre infrastructure de services est statique (comme vos scripts rc, vos tâches cron, etc.), car elles pointent vers l’application "Application". répertoire, et cela ne change pas.

Cela peut également être fait avec des liens symboliques au lieu de renommer des répertoires. de toute façon est bien.

Mais la technique est simple et à l'épreuve des balles si votre application coopère.

Maintenant, si vous avez des modifications dans la base de données, eh bien, c’est un problème complètement différent. Idéalement, si vous pouvez apporter des modifications de base de données "compatibles avec les versions antérieures", nous espérons que l'ancienne version de l'application pourra s'exécuter sur le nouveau schéma, mais ce n'est pas toujours possible.

Je pense que vous pouvez déployer à chaud les fichiers JAR si vous utilisez un serveur d'applications basé sur OSGi, tel que . Serveur dm SpringSource . Je ne l'ai jamais utilisé moi-même, mais connaissant la qualité générale du portefeuille Spring, je suis sûr que ça vaut le coup d'oeil.

Nous utilisons Eclipse, le système de mise à jour d’OSGi, et notre expérience est très bonne.

Recommandé!

La dernière version de Java Web Start permet d’injecter une application dans le cache local sans invoquer le programme. Elle peut également être marquée comme "hors connexion". Puisque le cache est ce qui est utilisé pour appeler le programme, il ne sera mis à jour que pour la prochaine exécution. Pour que cela fonctionne, vous aurez probablement besoin de bocaux dont le nom correspond au numéro de version (par exemple, our-library-2009-06-01.jar).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top