Archives mensuelles : mars 2011

Simplicité des mises en production : Pourquoi les war/ear ?

Voilà, vous avez donné des mois de votre vie, sept, huit, neuf, dix heures par jour pour un projet, et aujourd’hui c’est le grand jour : la mise en prod.
La mise en production d’un projet, qu’il s’agisse d’une MEP initiale, d’une mise à jour majeure ou d’un patch de corrections est un moment important. Cela doit-il pour autant une aventure interminable, épique et pleine d’incertitudes ?

La mise en production devrait être simple.
Déployer sur le serveur de prod ne doit pas être plus compliqué que les vingt ou trente déploiements quotidiens du développeur sur son poste. Le déploiement en lui même doit pouvoir être fait sans stress excessif, et avec le moins de sources d’erreurs possibles.

La mise en production doit pouvoir se faire sans coupure de service
Pour ne pas avoir à se caler sur un horaire particulier (la nuit, le week end), même dans le cadre d’un Intranet, il faut pouvoir mettre en production sans couper le service. Cela peut se faire en ayant au moins deux serveur, avec réplication de sessions : on peut basculer sur un seul, mettre en prod sur l’autre, basculer sur le noeud mis à jour, mettre en prod sur le second, puis revenir au load balancing.
Quelque dizaines de minutes de travail pour un administrateur peuvent donc sauver les soirées et les week-end de toute l’équipe.

Des livrables indépendants de l’environnement
Le même livrable (jar, war, ear, zip, …) doit pouvoir être utilisé sur tous les environnements, de la machine du développeur à la prod, en passant par l’intégration et la preprod.
Ainsi le comportement de l’application ne changera pas d’une plateforme à l’autre (en tout cas pas du fait du contenu du livrable).
De plus si une erreur se produit sur un environnement (au hasard la prod), le développeur peut récupérer le livrable incriminé pour reproduire le problème sur son poste.
Dans cette optique, la mise en place de profils maven pour spécialiser les livrables n’est pas souhaitable (même si les profils peuvent être utiles pour autre chose). Cela évite également de surcharger le repository avec 4 versions quasiment identiques du même war, de trente Mo chacune, séparées par uniquement par les qualifiers « integ », « preprod », et quelques lignes qui varient dans un fichier de config.

Des livrables validés, sauvegardés et reproductibles
C’est une bonne pratique d’avoir les livrables de l’application sauvegardés sur un repository d’entreprise (de type nexus), plutôt que sur le poste de l’administrateur système, du développeur en chef, ou sur la clef USB de la responsable marketing. Cela permet de les récupérer facilement (avec un wget par exemple), même des mois après.
Cependant cela ne suffit pas. Tout ce qui va en prod doit pouvoir être reproduit à partir du gestionnaire de version en quelque minutes. C’est à dire que tout ce qui va en prod doit être taggé, même le plus petit patch.

War; Ear, pourquoi des archives ?
Pourquoi le format de déploiement standard d’une application est-il une archive ? Pourquoi ne pas laisser le développeur faire ce qu’il veut avec plein de fichiers (comme en php) ?
Cela permet d’avoir un seul livrable ! Lors de la livraison on livre un et un seul fichier et poum, fini. Pas besoin de se demander s’il manque une propriété CSS ou si une dépendance n’est pas à jour : si le war a été validé en preprod, il marchera en prod.
Il faut éviter autant que possible d’avoir des fichiers à livrer en dehors du war. Pour la plupart des applications, une ou deux datasources et un fichier de propriétés sufisent. Si une entorse est faite à ce principe (ressources externes comme des modèles de documents, fichiers de configuration xml, …), il faut la voir comme de la dette technique à corriger.
Moins il y a d’éléments à livrer, moins il y a d’erreurs possibles.

Externaliser proprement
Les propriétés peuvent avantageusement être mise dans une table de la base de donnée : c’est plus pratique pour tout le monde (développeur, AMOA, admins, …).

La MEP idéale
– wget http://monserveurderepo/…/mon-appli-1.0.1.war
– Arret du noeud 1 du cluster (la prod tourne uniquement sur le noeud 2)
– scp mon-appli-1.0.1.war user@serveur1:/path.to/wars/
– Re démarrage du noeud 1 du cluster
– Arret du noeud 2 du cluster (la prod tourne uniquement sur le noeud 1, à jour)
– scp mon-appli-1.0.1.war user@serveur2:/path.to/wars/
– Re démarrage du noeud 2 du cluster
– Champagne et buffet au service commercial

Frameworks : Laissez moi écrire du HTML.

Certaines technologies permettant de créer des pages webs, comme JSF ou GWT, cachent le code html final généré, le développeur déléguant celui-ci à l’API. A partir de là, certains pensent qu’il n’est pas nécessaire au développeur de connaître les technologies sous-jacentes pour développer les pages. Ce n’est pas mon avis.

D’abord, dans tout les cas, il faut comprendre ce que l’on fait pour faire du bon travail. Pour moi on ne devrait pas écrire des pages webs toute la journée (même pour un intranet), sans avoir des connaissances correctes en html, css, javascript; http. Pour les même raisons, toute formation sérieuse à la programmation inclut des cours d’assembleur et de compilation.

D’ailleurs, comparer le web (html, css & JS) à l’assembleur est intéressant, mais plutôt inapproprié :

  • L’assembleur est figé au moment de sa sortie à quelques dizaines d’instructions. Le html est en constante évolution, et est beaucoup plus riche, ce qui le rend beaucoup plus difficile à générer correctement par des outils.
  • L’assembleur est le langage du processeur. Il s’agit d’instructions pour une machine, difficilement digérables par un humain. Personne ne s’attend, sur les architectures modernes, à que ce que de nombreux développeurs utilisent directement l’assembleur. Ceux qui le font codent des noyaux systèmes et des drivers.  A l’opposé, le html est fait par et pour des humains. Le w3c s’attend à ce que des humains utilisent directement ses standards.
  • Le html n’est pas bas niveau. On ne dit pas au navigateur quels pixels dessiner, quel registre mettre sur la pile. On lui dit qu’on veut un lien, un champ texte, voire maintenant, en html 5, un champ date ou URL, une section, un menu.

Ces outils ne font de toute façon pas toujours correctement les choses. Par exemple, beaucoup de balises standard de JSF utilisent des tableaux de présentation. Il y a aussi des bugs, et des bibliothèques de tags pas forcement bien écrites (j’ai déjà vu un attribut style=”width : 100%” écrit en dur dans le code généré par une balise d’une API JSF).

Par essence, ces outils ne sont pas à jour. Le web ne s’est jamais aussi bien porté, et les innovations d’HTML 5 et CSS 3 sont passionnantes à suivre. Il est impossible pour un outil de génération de code d’inclure convenablement les dernières nouveautés.

De plus, en ne connaissant pas bien le html, on risque de rater une version plus simple et plus élégante de réaliser ce que l’on souhaite (voyez donc ces pages truffées de widgets pour deux menus et un tableau de données, …), et on risque de ne pas prévoir de dégradation élégante de la page (qu’est-ce qui se passe sans Javascript ? Sans CSS ?), de mettre en péril l’accessibilité, …

Il y a pourtant un bon argument en faveur de ces outils : la compatibilité entre les navigateurs. Il est vrai qu’il y a ne serait-ce que deux ans, c’était un vrai problème, il fallait que le site tourne sur IE 6, voir IE 5.5, et c’était dur, … Mais dans le paysage actuel des navigateurs l’argument est moins valable. De plus JQuery et consorts aident à se défaire de ces problèmes tout en laissant visible le html final.

Enfin ces technologies ne sont pas inaccessibles. Un développeur dont le quotidien est fait de REST, de SOAP et de Scala, qui lit la JSR de JPA avant de se coucher, aurait peur de CSS ?