Une de mes premières impression à france billet etait le temps du build maven.
Voici l'etat de nos reflexions et exprimentations
Situation actuelle
- 364 projets
- 3 artefacts finaux
- 13 jobs Hudson pour builder, gérer les évolutions du schema de la base et déployer sur plusieurs environnements dont les premiers sont
- 1 Job Compilation + Tests Unitaires
- 1 Job Test IT avec appel à la base de données
- 1 Job Integration avec serveurs démarrés
- 33min pour un build complet en local sans les tests
- 1 intégrateur à plein temps pour gérer l'usine logicielle
Done
Bien connaître les options maven
Le réacteur contient le projet courant et l'ensemble de ses modules.
Les options utiles permettant de ne pas builder l'ensemble du réacteur sont:
- -pl, –projects Une fois placé à la racine des projets, cette option permet de sélectionner les projets à builder
- -am, –also-make Build également les dependances des projets selectionnés lorsque celles-ci sont dans le reacteur, ce qui permet de builder u produit à jour
- -amd, –also-make-dependents Build également les projets du réacteurs qui dépendent des projets selectionnés, ce qui permet de propager les modifications
- -rf, –resume-from Permet de reprendre un build sur un projet donné, après avoir effectué une correction
http://www.sonatype.com/people/2009/10/maven-tips-and-tricks-advanced-reactor-options/
http://blog.aheritier.net/construire-moins-pour-aller-plus-vite/
Régler les paramêtres de JVM
Sur le build, il y a 3 endroits où j'ai pu configurer la taille allouée pour la JVM
- Build Maven, avec la variable d'environnement MAVEN_OPTS (Maven indique gentiement la mémoire utlisée en fin de build)
- Compilation Java, avec la configuration maxmem du plugin maven-compiler-plugin
- Compilation GWT, avec la configuration extraJvmArgs du plugin gwt-maven-plugin
A manier avec précaution, car si le Xms est trop grand, la mémoire est allouée pour rien, s'il est trop petit, l'allocation progressive est plus coûteuese.
Si le Xmx est trop grand, il y a un risque de freezer la machine, et s'il est trop petit, c'est le java.lang.OutOfMemoryError
http://download.oracle.com/javase/6/docs/technotes/tools/windows/java.html
Spécifier le chemin du parent
Préciser un parent permet de faire de l'héritage et d'éviter de la duplication de configuration.
Lorsque l'on précise un parent, toujours ajouter le relativePath. Cela permet d'utiliser la dernière version du pom parent sans avoir à installer ce dernier.
Fixer les versions
Une grande partie de nos projets sont en SNAPSHOT. Nous ne passons pas par l'étape de version Fixe pour ces projets. L' ensemble des projets change de version en même temps.
Quelques projets dit 'ext' sont placés dans une autre arborescence avec des versions fixes car ils ne bougent plus.
Utiliser un build incrémental
Ce plugin permet de détecter si la recompilation est nécessaire. Ce plugin a été fait ici.
http://maven-incremental-build.java.net/site/index.html
Faire du TDD
Avec des tests unitaires, pas question de build, tout se passe dans l'IDE. Et je ne m'attarde pas sur les nombreux intérêts de cette pratique.
Mettre en places des circuits courts pour la partie présentation
Le build peut simplement être évité au cour du developement, suivant la technologie utilisée:
- jsp/js: Faire du war:inplace lorsque cela est possible, ou alors faire les modifications dans le repertoire de deploiment utilisé par le serveur (sans oublier de répercuter les modifs - OK ce n'est pas idéal)
- GWT: Se placer en mode dévelopement pour éviter la compilation GWT
- Code serveur/EJB: Se brancher en debug. Le code peut être remplacé à chaud tant que les signatures de méthode ne changent pas.
Détecter les modifications pour builder moins
Le job construit la commande maven en se basant sur le changelog, afin de ne builder que les projets qui ont changé, et les projets dépendants.
Mieux connaître l'avancement du build
Un plugin nommé progress-maven-plugin de mon cru permet d'ajouter un log de ce type:
Reactor Progress: 32/60 (53.33%) /workspace/module/subModule
Cela permet d'ajouter du feedback:
- sur un build local: un 53,33% permet de définir assez précisement la durée de la pause café :)
- sur le build hudson: Nous sommes sur des jobs de type FreeStyle, et pas Maven, donc nous n'avons pas l'avancement module par module. D'autres part, les calculs faits par hudson pour prédire la durée du job est faussé par l'aspect dynamique de nos jobs (voir 'détecter les modifications'). Cela est surtout utile lorsque le build est claimé et que la correction est en cours de build.
Générer le Mind Map des relations
Comme un dessin vaut 10 000 mots, il est interessant d'avoir le graphe des dépendances maven. IL existe plusieurs plugin qui génèrent une image, mais à partir d'une taille limite, l'image devient inutilisable. L'interêt de l'avoir sous forme de mindmap, c'est que l'on peut l'ouvrir avec l'outil de son choix, le parcourir, le modifier, afin d'en extraire l'information voulue.
http://blog.xebia.fr/2011/05/05/le-mind-mapping-applique-aux-dependances-des-projets-mavenises/
In Progress
Fixer les versions
Déplacer quelques projets en 'ext' et fixer la version pour ne plus les builder ni les télécharger plusieurs fois.
Casser des dépendances
Puisque notre build détecte le modifications et les propage, il devient critique de ne pas avoir de gros projet utilisés par de nombreux autres projets. Le risque est en effet de builder les projets qui ont une dépendance même s'il n'en utilise qu'une infime partie. Il faut donc continuer à découper, spécialiser les projets afin de builder juste.
Passer à Maven 3
C'est je pense un gros gain possible, mais quelques plugin maven ne sont pas compatibles, et n'ont pas encore été apadptés.
Essayer Jenkins
A ma connaissance, il n'y a pas de gain de performance particulier à obtenir. Ce qui fait la différence, c'est le nombre de plugin et l'activité de la communauté.
To Do
Parralléliser les tests
Cela nécessite d'avoir des tests bien indépendants, sans ordre, ni resources partagées, ni données en base réutilisées.
http://maven.apache.org/plugins/maven-surefire-plugin/test-mojo.html#parallel
Parralléliser le build
Une fois passé à Maven3, il est possible de parralléliser les builds à l'interieur du réacteur, en définnissant la taille du pool de threads.
https://cwiki.apache.org/confluence/display/MAVEN/Parallel+builds+in+Maven+3
Passer les jobs en type Maven
En supprimant la partie script non-maven du job, nous bénéficierons de la vue du build en cours avec le statut de chaque module.
Automatiser la génération du mind Map
Créer un job permettant de générer le mind map et le publier sur le serveur d'intégration continuer, afin de pouvoir consulter la version la plus récente sans le générer en local.
Atteindre le build incassable
Réaliser un build pre-commit.
http://blog.javabien.net/2009/12/01/serverless-ci-with-git/
http://blog.octo.com/integration-continue-performante-part-2/
Parralléliser le déploiement
Nos serveur d'intégration sont déployés en série, rendant la plateforme indisponnible pendant 15min à chaque déploiement (arrêt, copie, démarrage des 2 * 3 serveurs).
Faire du war:inplace partout
Mettre en place le mode de dévelopement inplace sur tous les projets web jsp.
Conclusion
Chouchoutez votre build pour vous faciliter la vie.
Aucun commentaire:
Enregistrer un commentaire
Feedback...