Soudain, que faites-vous avec le déploiement Java?
Bien sûr, il existe de nombreuses façons de se déployer à la fin. Il y a, mais dans le langage de script, un projet léger qui peut être cloné git avec gem, pip, npm, etc. pour résoudre certaines dépendances, mais en ce qui concerne Java, la graisse du fat jar est étonnamment supprimée, ou le fichier jar Ce sera un style un peu subtil, tel que le générer et le remplacer manuellement. (Ce n'est pas le cas! Faites-moi savoir si vous avez une bonne solution)
En premier lieu, il semble que vous ne devriez pas écrire en Java avant un tel moment, mais on dit que Java (ou langage JVM) est légèrement requis, comme la réutilisation des actifs de code avec des outils périphériques ou la volonté d'effectuer un calcul parallèle avec un peu de multithreading. Existe encore.
Tout d'abord, considérons la méthode de déploiement Java existante.
C'est une méthode pour essayer de faire quelque chose avec la même idée que le langage de script. Copiez le code source avec git ou un outil, résolvez les dépendances avec gradle (ci-après incluant maven / sbt / etc.) sur le serveur d'exécution, et construisez localement. Dans certains cas, il sera exécuté tel quel avec gradle.
Ce n'est pas une mauvaise méthode, mais cela ressemble plus à un serveur de développement qu'à une destination de déploiement car il contient l'ensemble complet. En outre, il est difficile d'affirmer qu'il n'a pas été modifié dans le serveur. Je crains que si j'apporte des modifications, que je construis et que quelqu'un essaie de faire quelque chose et de passer à une autre branche, je ne sais pas.
Il s'agit d'une méthode pour transférer un fichier .class qui est une compilation d'un fichier .java vers un serveur et l'exécuter.
Est-ce une méthode? J'avais l'habitude de le faire lorsque j'ai commencé à utiliser Java. C'est facile car il vous suffit de copier le fichier créé par l'EDI. Plutôt que de le déployer, c'est juste un moyen de l'exécuter sur un serveur. Si c'est un langage de script, c'est comme copier avec .zip ou .tar. C'est la pire méthode lorsqu'on considère le fonctionnement réel, comme ne pas avoir toutes les .classes, bien sûr ne pas bien connaître la version, ou les mélanger.
Collectez les fichiers .class avec la commande IDE ou jar, ou transférez les fichiers .jar générés par gradle vers le serveur. Transférez également les fichiers .jar des bibliothèques dépendantes.
C'est une méthode légitime pour sa nature primitive. En termes de mise en œuvre, cela revient à envoyer un fichier .class au format zip, mais il est extrêmement facile à gérer car divers outils Java le prennent en charge.
Vous pouvez inclure du code source, des mémos, des documents, n'importe quoi, donc je pense que c'est toujours utile lorsque vous ne pouvez pas le gérer. Cependant, il est difficile de collecter tous les fichiers .jar qui ont des dépendances. Et différentes versions de .jar sont mélangées et cela devient Jar Hell au lieu de DLL Hell ...
La méthode royale. Reconstruisez toutes les bibliothèques dépendantes en un fichier jar exécutable. Puisque nous définissons main, nous pouvons faire ce qui suit:
> java -jar xxxx.jar arg1 arg2
Récemment (?) Semble être appelé uber jar ou shadow jar.
C'est une technique courante. La bonne chose est que vous ne pouvez transférer qu'un seul fichier. Tout est dedans, vous n'avez donc pas à vous soucier du fait qu'il soit partiellement mis à jour et terrible, et vous n'avez pas à vous soucier d'oublier la classe principale.
Personnellement, c'est trop gros (putain de gros), et quand je ne regarde que l'environnement de production, je ne connais pas tout de suite le nom de la bibliothèque utilisée ou la classe principale que j'utilise, donc je ne peux rien dire à moins de la décompresser. Cela ne convient pas vraiment à mon goût lors de l'exécution sur un serveur. Il vaut peut-être mieux fonctionner selon des règles de dénomination appropriées.
C'est un peu triste car je choisis parfois gros pot car il est difficile de collecter des fichiers de dépendance .jar tels que gradle. Cela ne semble pas être si courant, mais la bibliothèque de dépendances est [par ici](https://stackoverflow.com/questions/23109276/gradle-task-to-put-jars-from-maven-repository-into-project- Il est collecté par lib-folder).
Vous pouvez faire de même avec de gros pots avec des fichiers war et ear, que vous voyez rarement en dehors du Web. war peut être plus approprié car il permet un contrôle plus fin tel que l'inclusion du fichier de paramètres d'application mais son exclusion du chemin de classe.
Je pense que le fichier war est utile si vous avez de nombreux environnements Java EE. S'il s'agit d'un fichier war, cela peut être acceptable même si la taille du fichier est un peu grande (biais)
Créez une image en créant un environnement d'exécution dans le conteneur Docker. L'image Java Docker est-elle lourde? Non, Alphine Linux / musc libc / Jigsaw le rend raisonnablement compact.
De nos jours, vous pouvez également créer une image Docker avec Maven / Gradle en une seule fois avec Google / Jib.
Ce sera désormais le favori. Le support Docker de Java progresse également, et on peut dire que les problèmes faciles à comprendre ont presque disparu. Il gère également les versions et vous n'avez pas à vous soucier d'être lié au comportement Java local.
Cependant, d'un autre côté, c'est Docker ... Il y a pas mal de situations qui ne conviennent pas à Docker, et c'est dommage de mettre une JVM capable de contrôler la mémoire de manière relativement simple dans un conteneur.
En examinant diverses choses, nous voulons résoudre les problèmes suivants pour un déploiement idéal.
Quel outil répond à cette exigence? En passant, si vous regardez d'autres langages, vous pouvez généralement déployer avec gem, pip, npm, etc. Le code principal peut être cloné git ou déployé à partir d'un référentiel privé. Les versions sont gérées dans le référentiel et vous pouvez voir ce qui s'est passé d'un seul coup en regardant l'environnement de production.
N'est-ce pas le cas avec Java? Compte tenu de cela, au moins le référentiel a un référentiel Maven. Je ne peux pas faire de git clone, qui nécessite une compilation, mais je pense que le support des référentiels privés est plus puissant que les autres langages. Après cela, ce serait bien s'il y avait un outil. .. ..
C'est pourquoi je l'ai fait.
marun https://github.com/nishemon/marun
Un outil pour télécharger les artefacts cibles à partir du référentiel Maven tout en résolvant les dépendances.
> marun install com.example:example:1.0.1
gradle et maven peuvent résoudre les dépendances, mais ils sont magnifiques car ils ne sont que des outils de construction, et ils ont la capacité de résoudre les dépendances dans les bibliothèques de dépendances (artefacts), mais ils ont la capacité de les gérer. Il n'y a aucune fonctionnalité permettant de télécharger uniquement les artefacts. Il existe un outil appelé Apach Ivy qui est spécialisé uniquement pour la résolution des dépendances dans le référentiel Maven, mais c'est aussi pour la construction en combinaison avec Apache Ant. Il est principalement considéré comme utilisé pour Ivy seul, et Ivy.xml doit être écrit pour l'utiliser seul.
J'ai donc utilisé Apache Ivy pour créer un outil qui télécharge uniquement les artefacts cibles et leurs dépendances.
J'ai besoin d'un référentiel privé, mais maintenant, par exemple, plugin maven-publish et [plugin aws-maven](https://qiita.com/ suzutt / items / bf1e8a8e425a9077b96c) facilite la création d'un référentiel Maven sur Amazon S3.
Il n'est pas bon d'être difficile à utiliser au début, il est donc installé avec pip. La partie ligne de commande est Python2 afin qu'elle fonctionne autant que possible avec le système Python.
> sudo pip install marun
init Initialisez pour le moment. Java est requis pour l'exécution, veuillez donc l'installer d'abord.
> sudo marun init
configuration file is not found!
Your Maven Repository URL []: s3://your_repository
S3 Access Key []:(Entrez la clé d'accès)
S3 Secret Key []:(Entrez la clé secrète)
En plus de s3, il peut également être utilisé avec http / https. Lorsque vous le saisissez, un fichier de paramètres * /etc/marun.conf * sera créé.
À propos, Ivy fera de son mieux pour télécharger les dépendances de marun lui-même comme ça. En raison d'Amazon S3, il existe de nombreuses dépendances de fichiers JAR. Trempez dans * / var / lib / marun *.
Ivy travaille dur
Download: 130982 / 130982
Download: 1282424 / 1282424
Download: 241622 / 241622
:: loading settings :: url = jar:file:/var/lib/marun/lib/ivy-2.4.0.jar!/org/apache/ivy/core/settings/ivysettings.xml
:: resolving dependencies :: caller#all-caller;working
confs: [runtime]
found jp.cccis.marun#marun;0.1.1 in maven.cccis.jp.s3.amazonaws.com
found com.amazonaws#aws-java-sdk-s3;1.11.475 in bintray/jcenter
[1.11.475] com.amazonaws#aws-java-sdk-s3;1.11.+
found com.amazonaws#aws-java-sdk-kms;1.11.475 in bintray/jcenter
found com.amazonaws#aws-java-sdk-core;1.11.475 in bintray/jcenter
found commons-logging#commons-logging;1.1.3 in bintray/jcenter
found org.apache.httpcomponents#httpclient;4.5.5 in bintray/jcenter
found org.apache.httpcomponents#httpcore;4.4.9 in bintray/jcenter
found commons-codec#commons-codec;1.10 in bintray/jcenter
found software.amazon.ion#ion-java;1.0.2 in bintray/jcenter
found com.fasterxml.jackson.core#jackson-databind;2.6.7.2 in bintray/jcenter
...
commons-logging#commons-logging;1.1.3 from bintray/jcenter in [runtime]
joda-time#joda-time;2.8.1 from bintray/jcenter in [runtime]
jp.cccis.marun#marun;0.1.1 from maven.cccis.jp.s3.amazonaws.com in [runtime]
org.apache.httpcomponents#httpclient;4.5.5 from bintray/jcenter in [runtime]
org.apache.httpcomponents#httpcore;4.4.9 from bintray/jcenter in [runtime]
software.amazon.ion#ion-java;1.0.2 from bintray/jcenter in [runtime]
:: evicted modules:
commons-logging#commons-logging;1.2 by [commons-logging#commons-logging;1.1.3] in [runtime]
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| runtime | 16 | 2 | 0 | 1 || 17 | 1 |
---------------------------------------------------------------------
C'est une bonne idée de télécharger et d'exécuter quelque chose dans votre référentiel privé, mais ici, je vais essayer de télécharger le Google Closure Compiler.
> sudo marun install com.google.javascript:closure-compiler:+
:: loading settings :: url = jar:file:/var/lib/marun/lib/ivy-2.4.0.jar!/org/apache/ivy/core/settings/ivysettings.xml
:: resolving dependencies :: caller#all-caller;working
confs: [runtime]
found com.google.javascript#closure-compiler;v20181210 in repo1.maven.org
[v20181210] com.google.javascript#closure-compiler;+
found com.google.javascript#closure-compiler-externs;v20181028 in bintray/jcenter
found args4j#args4j;2.0.26 in bintray/jcenter
found com.google.errorprone#error_prone_annotations;2.3.1 in bintray/jcenter
found com.google.guava#guava;25.1-jre in bintray/jcenter
found org.checkerframework#checker-qual;2.0.0 in bintray/jcenter
found com.google.j2objc#j2objc-annotations;1.1 in bintray/jcenter
found org.codehaus.mojo#animal-sniffer-annotations;1.14 in bintray/jcenter
found com.google.protobuf#protobuf-java;3.0.2 in bintray/jcenter
found com.google.code.gson#gson;2.7 in bintray/jcenter
found com.google.code.findbugs#jsr305;3.0.1 in bintray/jcenter
found com.google.jsinterop#jsinterop-annotations;1.0.0 in bintray/jcenter
found com.google.auto.value#auto-value;1.4.1 in bintray/jcenter
found org.apache.ant#ant;1.9.7 in bintray/jcenter
downloading https://repo1.maven.org/maven2/com/google/javascript/closure-compiler/v20181210/closure
...
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| runtime | 16 | 14 | 14 | 2 || 16 | 16 |
---------------------------------------------------------------------
Je me sens comme cela.
> ls -l
total 8
drwxr-xr-x 1 racine racine 512 23 décembre 21:37 lib
-rw-r--r--1 racine racine 4438 23 décembre 21:37 marun.json
> ls -l lib
total 18980
-rw-r--r--2 racine racine 3482 26 février 2015 animal-sniffer-annotations-1.14.jar
-rw-r--r--2 racine racine 2036195 12 avril 2016 fourmi-1.9.7.jar
-rw-r--r--2 root root 74703 3 novembre 2013 args4j-2.0.26.jar
-rw-r--r--2 racine racine 1504726 7 avril 2017 auto-value-1.4.1.jar
-rw-r--r--2 racine racine 343222 6 mai 2016 vérificateur-qual-2.0.0.jar
-rw-r--r--2 racine racine 189289 31 octobre 04:55 closure-compiler-externs-v20181028.jar
-rw-r--r--2 root root 10248761 13 décembre 03:35 closure-compiler-v20181210.jar
-rw-r--r--2 root root 13162 21 avril 2018 erreur_prone_annotations-2.3.1.jar
-rw-r--r--2 root root 231952 15 juin 2016 gson-2.7.jar
-rw-r--r--2 racine racine 2734339 24 mai 2018 goyave-25.1-jre.jar
-rw-r--r--2 root root 8764 27 juillet 2016 j2objc-annotations-1.1.jar
-rw-r--r--2 root root 4075 29 juillet 2016 jsinterop-annotations-1.0.0.jar
-rw-r--r--2 root root 19943 9 octobre 2015 jsr305-3.0.1.jar
-rw-r--r--2 racine racine 1304415 7 septembre 2016 protobuf-java-3.0.2.jar
Vous pouvez également l'exécuter avec marun run
. Closure Compiler exécute, par exemple, com.google.javascript.jscomp.CommandLineRunner
, mais c'est un peu intelligent, vous pouvez donc le faire pour trouver main avec le nom abrégé.
> marun run CommandLineRunner
The compiler is waiting for input via stdin.
Comme vous pouvez le voir dans le message affiché, il s'agit presque de Apache Ivy. Cela ne semblait pas si difficile à écrire par moi-même juste pour résoudre les dépendances, mais le facteur décisif était qu'il semblait y avoir des pièges et que gradle l'utilisait dans le passé. (Il semble qu'ils résolvent leurs propres dépendances maintenant)
J'ai téléchargé le fichier jar minimum requis pour démarrer Ivy avec Python, puis j'ai inclus Ivy avec Ivy et essayé de résoudre à nouveau la dépendance.
De plus, le contenu de marun.json est comme ça, seules quelques données d'analyse sont incluses.
marun.json
{
"1545568648": {
"mains": [
"com.google.javascript.jscomp.CommandLineRunner",
"com.google.javascript.jscomp.LinterMain",
"org.kohsuke.args4j.Starter",
"org.apache.tools.ant.Diagnostics",
"org.apache.tools.ant.taskdefs.KeySubst",
"org.apache.tools.ant.taskdefs.optional.ejb.IPlanetEjbc",
"org.apache.tools.ant.taskdefs.optional.jlink.jlink",
"org.apache.tools.ant.util.ProcessUtil"
],
"dependencies": {
"com.google.code.gson:gson": {
"cache": "/var/lib/marun/ivy/com.google.code.gson/gson/jars/gson-2.7.jar",
"name": "gson-2.7.jar",
"revision": "2.7"
},
...
},
"install": [
"com.google.javascript:closure-compiler:+"
]
},
"context": [
1545568648
]
}
Comme vous pouvez le voir dans le fichier json, il permet également de sauvegarder et d'exécuter la version de la bibliothèque, mais il télécharge essentiellement tous les jars dans lib, vous pouvez donc l'exécuter avec java -cp lib / *
.
Donc, je m'inquiétais de la façon de déployer Java, alors j'ai essayé de créer un outil de déploiement qui comble le vide. Je pense qu'il y a des situations addictives, alors utilisez-le si vous le souhaitez. Ne vous attendez pas à la perfection pour le moment. (Je veux faire de mon mieux)
Aussi, si vous n'avez pas à créer un tel outil, ou si vous souhaitez le faire, veuillez nous en informer!
Recommended Posts