Quelques retours sur la conférence BreizhCamp de fin mai. Cette année encore, deux jours de conférence multi-technos, dans une super ambiance, festive et sérieuse à la fois. La veille, il y avait également une journée “for kids”, où les intervenants apprenaient aux heureux et jeunes veinards comment programmer un NXT 3 (robot Lego), coder en Scratch, etc. J’aurais bien aimé pouvoir venir avec mes enfants…
Attention, les notes sont fournies “as is”. Pas de reprise de contenu, peu de remise en forme. C’est du brut…
Keynote jour 1
Présentation du changement de Microsoft, qui est de moins en moins vu comme le grand méchant loup. Comme quoi, ça met des années avant de se savoir, mais ça finit toujours par arriver.
Partie de cache-cache (Fred Bouchery)
A partir de 4 secondes de temps de chargement, on perd 25% d’utilisateurs.
On trouve des caches à tous les niveaux : navigateur, proxy, reverse-proxy, serveur applicatif, base de données ou systèmes externes. Et de tous types : cache de navigateur, d’OP code, partagé, etc.
Expires est trop vieux, et devrait être remplacé par Cache-control dans les entêtes http, même si le dernier est compatible avec tout. Utiliser ou le ETag ou le LastModified, mais les deux ensemble, cela n’a pas de sens. Le souci est surtout que les serveurs de cache, dans ces cas, n’auront pas un comportement normalisé.
Problème : l’empilement non maitrisé des caches. On a vite tendance à se retrouver avec un cache à tous les niveaux d’une architecture. C’est du gâchis, mais ça force aussi à des manipulations très complexes pour purger les caches lorsque c’est nécessaire pour le développement par exemple.
Conseil : mettre toujours un Cache-control et ne pas laisser les caches prendre leur comportement par défaut.
L’enfer du CRTL+F5 pour vider le cache.
F5 envoie un Cache-control : max-age = 0 et un If-Modified-Since et le serveur renverra un 304 pour dire que la page n’a pas changé depuis (sans contenu, bien sûr)
CTRL-F5 envoie un Cache-control : no-cache (et un pragma : no-cache, qui ne sert plus à rien depuis longtemps)
Problème : tout ça ne fonctionne pas avec AJAX. Après le window.onload, le navigateur prend dans son cache. Et il n’y a pas de moyen de gérer ça à part demander à l’utilisateur de purger manuellement son cache dans la configuration.
Conseil : toutes les ressources statiques devraient avoir un Cache-control, de préférence public de façon qu’une ressource soit mise en cache à destination de plusieurs personnes. Et si on fait une modification, il vaut mieux carrément changer le nom ou ajouter un paramètre pour être sûr que la nouvelle version sera prise (pour le navigateur, c’est une nouvelle URL).
Problème : les pages dynamiques doivent être associées à un Time To Live.
Le hit ratio se dégrade souvent la nuit car comme il y a moins de requêtes, donc le Time To Live fait que le cache a moins souvent la donnée nécessaire. Mais ce point n’est pas grave, car il n’a pas d’impact sur la performance. Si on augmente le TTL, on augmente le hit ratio, mais on congèle les données et ça prend beaucoup de mémoire.
Conseil : faire deux niveaux de cache, chaud et froid, respectivement pour les pages dynamiques et les pages qui ne changent que très peu.
Comment faire une politique d’éviction, de façon à purger le cache pour récupérer de la mémoire ? Il ne faut pas prendre que celles le plus demandées, car ça peut être juste un pic local dans le temps, mais aussi la taille, etc. Le mieux est finalement de sharder pour augmenter la mémoire totale du cache. Il faut aussi supprimer les paramètres qui font varier l’URL mais pas la page.
Conseil : le Vary : Accept-Encoding permet de spécifier les préférences d’algorithmes de compression des pages, mais du coup créent d’autant plus de variance. Il est donc recommandé de l’enlever et de demander tout le temps du gzip, supporté par tous les navigateurs.
Conseil : pour rafraîchir le contenu, ne pas effacer le cache, car ça provoque un phénomène de ruée (thundering herd), et tout le monde se retrouve d’un coup sur le serveur. Il vaut donc mieux périmer artificiellement le contenu avec un stale-cache, pendant qu’en même temps, on envoie le nouvel ordre au serveur. Une autre solution est de mettre des miss pour les adresses internes. Le développeur, du coup, ne passe pas par le cache, réalise le traitement sur le serveur, et remet de fait à jour le cache. On peut également mettre à jour de manière active le cache. La pré-construction du cache permet de s’assurer aussi que les crawlers robots d’indexation ne s’arrêteront pas d’indexer car ils se retrouvent à passer trop de temps à passer sur toutes les pages du site.
Modification de design : quand toutes les pages sont modifiées, il faut faire morceau par morceau, en faisant par exemple du crawling, en générant des miss, etc. de façon asynchrone. Il faut alors planifier complètement cette opération.
Edge Side Include (esi:include) permet de mettre en place des caches partiels. Du coup, chaque partie d’une page a une durée de cache différente.
Trois solutions se démarquent pour les caches partagés, de proxy : Varnish, Nginx et Squid (un peu plus vieux). Apache est un peu à la traîne, mais de nouvelles versions arrivent. Nginx est encore plus performant que Varnish pour les ressources statiques et comme il s’agit d’un vrai serveur web, il peut faire du HTTPS. Il peut également utiliser Redis comme backend de cache. Varnish monte, et est très fonctionnel.
Si majorité de contenus privés, il faut faire le cache au niveau applicatif. En utilisant par exemple MemCached en sharding. Le sharding est obligatoire, sinon on a des risques de désynchronisation, car deux serveurs peuvent avoir leur cache, mais un peu différent de l’autre, et du coup d’une requête à l’autre, même rapidement, on risque de ne pas voir la même page, même si elle est mise en cache. A part MemCached, il y a aussi Redis, mais ce dernier est un peu moins performant, même s’il permet de faire de l’asynchrone, du message queuing, du multi-taggage, etc.
Le Content Delivery Network consiste à répartir des contenus statiques un peu partout dans le monde pour servir l’utilisateur au plus vite. Ce n’est pas vraiment un cache, mais optimise les temps de chargement. Il permet de séparer les sites internationaux.
Utiliser un cache applicatif intégré au serveur, comme APC sur PHP, est beaucoup plus performant que même un Memcached, mais est en général beaucoup plus limité en taille de mémoire utilisable. On peut même détourner le cache de code de PHP pour envoyer de la donnée, en créant un script PHP dynamiquement qui renvoie un tableau de donnée, et qui sera mis dans le cache d’OPcode
Résumé :
- Maitrisez les caches
- Trouvez le bon TTL en fonction du contexte
- Réfléchissez à la stratégie d’invalidation
- Mettez en place plusieurs niveaux de cache
- Etudiez le comportement des utilisateurs
- Suivre les évolutions des solutions
Sur les Single Page Applications, il vaut mieux mettre un no-cache sur index.html. Et pour le développement, on met systématiquement une date de péremption pour ne pas se baser sur le cache. Et pour la production, on utilise du versioning pour forcer le refresh.
Varnish
Varnish est un cache orienté haute-performance, Linux et FreeBSD seulement, et qui peut tourner sur des VMs, mais pas pour de la production.
On configure les politiques de cache avec un DSL, proche du PERL et transformé en C puis compilé pour pouvoir accepter une forte montée en charge. Il expose un automate fini, avec des règles par défaut au cas où.
Par exemple, on peut faire un code qui dit que si la requête contient admin, alors on bypasse le cache. Ou alors, on peut dire que si on détecte que le protocole est en demande d’élévation pour passer en web socket (bidirectionnel), Varnish doit passer en mode pipe (il laisse passer les allers-retours sans s’interposer). On peut également faire de la redirection d’URL par la DSL.
Varnish gère :
- Le TTL
- Les variantes (JSON ou XML derrière la même URL, selon le Content-Type)
- Le gzip
Le VCL (le DSL de Varnish) par défaut ne cache pas :
- Les cookies
- Les authentifications
- Les méthodes autres que GET et POST
Purge de cache possible, par invalidation d’une URL dans le VCL. Le « ban » ne purge pas complètement le contenu, mais le rend inutilisable pendant un temps. On peut donc invalider certaines régions du cache, par URL mais par d’autres critères également bien sûr.
Il est possible de mettre en place un délai de grâce sur un TTL dépassé : on peut donc faire de la très haute dispo en servant du contenu périmé en cas de défaillance du back-end par exemple.
Le load balancing n’en est pas vraiment dans le sens où son but n’est pas de répartir la charge, mais plutôt d’utiliser le « Director » pour maximiser les chances de trouver un cache, par exemple en recherchant le contenu de cache dans plusieurs serveurs différents.
Il y a un shell d’admin qui permet d’agir sur le Varnish, et tout se fait à chaud pour pouvoir être en très haute disponibilité. On peut faire du diagnostic, du tuning, de gérer du VCL, etc.
Les logs traditionnels sont peu utiles, on le sait bien (place disque, illisible, trop ou pas assez, jamais lus, etc.) mais Varnish a une approche un peu plus sophistiqué en stockant les logs en mémoire, et en mettant en place des outils autour pour exploiter ce contenu très complet (il logue tout ce qui se passe).
Le logiciel accepte des plugins, nommés modules, pour l’étendre. Sa version 4, avec des nouveautés suffisantes pour justifier une non-compatibilité ascendante, vient de sortir (Avril 2014). Il utilise deux pools de threads, un pour le client et un pour le serveur, ce qui lui permet de servir en streaming même des clients qui sont en attente de la mise à jour du cache par un autre.
Recette de mise en place :
- Cacher le contenu statique
- Configurer la compression
- Cacher le contenu semi-statique
- Automatiser l’invalidation du cache
- Améliorer les backends (entêtes, etc.)
Autres caractéristiques : il y a un framework de test, cela supporte le multi-tenancy, etc.
Durabilité des données par versioning NoSQL
Idée de pipeline de montée en version d’un document au moment où on l’utilise, comme ça la migration est progressive.
Plutôt que de mettre plein de if / else dans le code en fonction d’un numéro de version, il est plus propre de mettre au moins tout ceci dans une seule classe où on regroupe tout ceci, qui n’est pas très élégant.
En gros, l’idée principale est de faire la même chose que pour la montée en version d’un mécanisme de type prévalence objet, en évitant d’avoir la sérialisation qui ne fonctionne plus.
Agile (we are family)
Voir comment les entreprises gérées en famille fonctionnent, par opposition avec des grands groupes.
Les entreprises familiales, déjà, sont quasiment les seules à dépasser la centaine d’année. Or, c’est un critère important de réussite que de durer au long terme.
Dans les grands groupes, il y a souvent une direction « lab » qui cherchent des nouveaux moyens de fonctionner, et qui sont plus libres, précisément parce que le grand groupe a oublié cette liberté. Les petites entreprises familiales ne se rendent pas compte qu’elles sont agiles : elles ne le font pas de manière consciente, et la confiance fait que les gens savent que leur oncle / sœur fait les choses de façon la plus appropriée pour ne pas mettre la famille en danger.
C’est souvent à la troisième génération que les problèmes arrivent, car cette génération n’a pas participé à la difficulté de mise en place, ni en acteur ni en spectateur. Et du coup, il ne la voit que comme une machine à cash.
La structure (hiérarchique ou pas) d’une entreprise doit découler naturellement de son organisation au jour le jour. Ce n’est pas une bonne pratique d’essayer d’en mettre une arbitraire en place.
Le plus important : People + Core values + Enjoy what you work on.
Approche des architectures micro-services (Aurélien Maury – Xebia)
Vert.x utilisé par le conférencier sur les micro-services
Définition en débat : juste des services, mais plus petits. Ou alors, des services automonitorés, faiblement couplés, facilement déployables et self-monitoré (Fred Georges). Ou encore James Lewis qui dit que c’est de la SOA à la façon Unix, c’est-à-dire petits grains.
En gros, ce qu’on fait avec des pipes en Unix, c’est ça qu’on refait mais avec des services qui s’enchaînent les uns les autres. Donc, comme pour des services de fusion de document qui appelle l’URL OData et qui pousse dans la GED, en une seule URL qui en compose trois.
Choisir la portabilité plutôt que l’efficacité.
C’est un peu aussi comme si on appliquait SOLID aux services fonctionnels, en déployant plein de services complètement autonomes, tout en réduisant le couplage fort. On met donc un bus de message le plus simple possible (rien que du publish subscribe pour éviter les travers des ESB) : il vaut mieux un tuyau bête et des extrémités intelligentes (comme pour l’internet neutre). Ce qui veut dire qu’on ne fait pas de route ni d’EIP. On fait une émission libre, avec une topologie flexible. Il faudra voir comment ça s’articule avec du BPMN, car les routes de médiation ne sont pas le problème, mais celles au milieu.
Chaque service a obligatoirement sa propre base de données
Couplage lâche : chaque service s’abonne au fil RSS des autres dont il a besoin.
Chaque service doit être suffisamment petit pour tenir dans la tête d’une personne (pouvoir le réécrire dans le langage qui lui va si problème de personne absente définitivement).
Besoin fort de monitoring si le service ne fonctionne pas. C’est le client qui doit pouvoir remonter que sa dépendance ne fonctionne plus. Ne pas se gêner pour émettre plein de messages, même s’ils ne servent pas dans un premier temps. Ca évite de redéployer plus tard.
Multipliez les versions de service car ce n’est pas un problème. Faire par exemple de l’élection de service. Si c’est le bus qui donne l’annuaire des services, ça ne pose pas de problème.
L’application est supplantée par le système : que propose le SI plutôt que quelle application a la bonne fonctionnalité, voire qu’elle soit partagée (encore pire) ?
Métaphore des flux d’eau, avec des services rapides (torrents), des rivières et des lacs (entrepôts de données). Tout passe par un bus de premier niveau, mais seuls les services de premier niveau prennent les messages dessus. Le reste est pris en compte par un bus secondaire, lui-même éventuellement avec un bus tertiaire pour les logs, audits, etc. qui sont plus longs. Quel que soit le niveau du service, il réémet dans le bus principal.
Avant d’appeler un service, on envoie un message demandant qui le propose. Deux peuvent répondre dans le temps, et il faudra choisir lequel on appelle. Cette élection de service peut se faire de manière régulière. Voir si on peut faire évoluer notre architecture simple, sans annuaire de services, vers ceci.
Le logging et le monitoring sont des services qui sont abonnés à tout.
Pour vendre le principe, parler du décommissionnement progressif, en mettant un proxy qui redirige progressivement.
Les pièges à éviter :
- Monitoring obligatoire dès le début
- Ne pas tomber dans le nano-service
- Faire des déploiements rapides (car il y a plein de services)
- Ne pas avoir des grosses équipes
Loi de Conway (le logiciel reflète l’organisation qui l’a créé) dit :
- Micro-services => micro-team
- Devops mais pas à moitié : l’équipe est responsable de tout, y compris le maintien en condition opérationnel
- Exigence de qualité et de rigueur (phase d’apprentissage plus longue que juste coder des stories)
Le plus important est que cela permet d’avoir un système à long terme. Un peu comme les cellules du corps humain, il y en a qui sont remplacées à chaque moment.
Important d’avoir un déploiement continu. Et par conséquence, que nous maitrisions le déploiement, donc mode SaaS pour pouvoir bien partir dessus.
Indicator driven : montrer que les dossiers passent bien, que le temps est vérifié, etc.
DropWizard est un outil avec un socle Jetty, Jersey, Jackson, Guava avec du Maven prédéfini, etc. Un peu comme Johan a prévu des artefacts. Connecteurs SPDY, et monitoring pré-défini pour aller plus vite.
Spring Boot permet de faire des applications Spring standalone, avec convention plus que configuration, et même chose pour le monitoring, là aussi avec Metrics.
Vert.x est peut-être le meilleur. Il est asynchrone by design, multi-langage, avec une boîte à outils TCP & HTTP, une structure modulaire, du mode script, et un bus de message communiquant à la base en JSON.
Conseil : utiliser ZeroMQ de préférence si on n’a pas déjà un bus, car il est simple à utiliser, bien documenté et possède tous les patterns nécessaires.
Pour le transactionnel, on oublie, ou alors on fait en deux phases, avec un acknowledge. Pour la granularité, il est intéressant de la baser sur le fait qu’on doit pouvoir remplacer facilement un service.
La différence avec une architecture orientée services est qu’il n’y a aucune intelligence dans le bus. Du coup, est-ce que c’est proche d’une architecture orientée WOA ? Ou même du EDA, d’ailleurs, vu le sens dans lequel c’est expliqué ?
Services de blocage pour dire par exemple de ne pas écouter une ancienne version d’un service, qui est considérée comme plus bonne.
Il faut versionner les messages pour que les services sachent quoi faire.
Il faut le vendre avant de pouvoir mettre en place cette architecture. La mise en place fait énormément de bazar, selon le conférencier. Il faut faire du devops, en remélangeant les équipes pour qu’elles s’alignent sur un même but, qu’elles ajoutent plein de logs, qu’elles changent le mode de monitoring, etc.
Comment faire en cas de gros changement d’évènement, qui impacte tout le monde ?
Pour discuter avec le conférencier, préférer Twitter.
Question : comment éviter le problème de la complexité de déploiement ?
Question : est-ce que c’est adapté à un éditeur de logiciels ? En particulier pour les clients qui ont le service installé chez eux, donc il faut vraiment qu’on passe en mode Cloud.
Question : à quoi servait le RSS du service ? A réaliser un mode complètement asynchrone sans avoir la complexité d’un bus. Chaque émet son besoin dans son RSS et les autres écoutent et traitent ce qu’ils savent faire.
Question : est-ce qu’il y a une cartographie ? Broadcast de messages OPTION pour que chaque service réponde avec la liste de ce qu’il fait faire.
Concevoir en équipe sans architecte
Peu de notes sur cette session, pour la raison que je suis personnellement en désaccord avec le contenu. Pour moi, l’orateur a confondu deux réalités distinctes : le rôle de l’architecte n’est pas de concevoir. La conception est faite par les développeurs, effectivement. Mais l’architecte est nécessaire lorsque plusieurs équipes ont besoin de communiquer et que des normes n’existent pas encore.
Bref, approche réductrice et volontairement polémique, qui ne fait pas avancer les choses. Bien sûr qu’on peut développer sans architecte. Mais pas tout. De la même manière que pour faire ma vidange, je n’ai pas besoin d’un mécano. Mais s’il faut déposer le moteur, je préfère le laisser faire.
Leap Motion en Java / Processing (Claude Falguière)
Processing + Hermes (game engine) + Leap Motion
setup / draw : les deux fonctions de base pour Processing
Processing gère le changement de référentiel, pratique car Leap part du bas alors que Processing est en bas. pushMatrix / translate / popMatrix pour réaliser ceci.
rdlester.github.io/hermes pour bien comprendre par le jeu. Hermes possède un moteur physique, gère la propagation des évènements pour ne pas avoir une méthode draw trop complexe dans Processing. Il y a aussi du MVC dans Hermes. Les objets visuels sont des vues, et le World est le controleur.
World gère le thread graphique et le rendu concurrent. Les Being sont les objets, les Groupes permettent d’assembler les Being (par exemple le groupe de briques dans le jeu de casse-brique qui est notre exemple). Les Interactor et les Collider sont les objets pour la gestion physique, avec les bounding box. Enfin, PostOffice est un gestionnaire de messages entre objets. La difficulté est de propager les évènements en fonction des stades de l’objet, et plutôt que d’appeler toutes les méthodes, on peut faire avec ce mode du publish / subscribe.
Hermes.setPApplet(this); // Hermes a besoin de connaître le contexte graphique de Processing
Update permet de faire les calculs avant que draw ne soit appelé, de façon à réduire le lag. On peut aussi utiliser PreUpdate, par exemple pour récupérer les données de la Leap.
Pour intégrer Leap Motion, on utilise des commandes de type OSC (envoie des tableaux, au lieu de Keys ou de positions de souris).
import de.voidplus.leapmotion.*; pour ramener tous les objets API de LeapMotion par une librairie spéciale et existante pour Processing.
leap = new LeapMotion(Hermes.getPApplet());
https://github.io/cfalguiere/Air-Breakout et http://cfalguiere.github.io/Presentations
Penser à updater le driver, car il est plus précis désormais (détection de phalanges, etc.)
Au final, super session, bien entre les deux entre les explications de haut niveau et le technique. Je me pose la question : serait-il possible d’utiliser Leap pour piloter Maya ?
Vagrant pour les développeurs (Alexis Seigneurin)
Sert à l’orchestration de machines virtuelles. Ne fait pas la virtualisation. C’est Virtual Box, par exemple, qui fait ceci. Vagrant s’occupe de configurer la Base Box (l’image nue de l’OS) et d’installer dessus les programmes et fichiers qu’on lui demande (c’est le Vagrant file).
Le but est de reproduire de la production sur les machines de développeurs, même si c’est aussi utilisé pour déployer des machines en production.
Vagrant crée la Virtual Box / VMWare / HyperV, configure le réseau, les répertoires partagés, et fait le provisionning (shell, Puppet, Chef, etc.)
vagrantcloud.com et cloud-images.ubuntu.com/vagrant pour récupérer des base boxes (mais attention aux images pas officielles)
Les base boxes sont mises en cache local, pour ne pas les télécharger à chaque fois. Pour cela, on crée un alias qui s’appelle box. Dans provision.sh, pas besoin de sudo, mais ne pas oublier d’enlever le mode interactif (enlever les demandes de confirmation).
vagrant up démarre la box, et quand SSH est prêt, a fait la configuration et le provisionning.
vagrant ssh permet de se loguer sur la machine virtuelle, avec la clé SSH que vagrant a positionnée.
vagrant status renvoie l’état de la machine.
vagrant provision relance le provisionning, pour installer plus de choses. Le script est alors relancé en root sur la machine virtuelle, et le retour de la console est renvoyé sur le shell depuis lequel on manipule Vagrant.
vagrant suspend permet de ne pas avoir à passer par l’interface de Virtual Box, et fonctionnerait pareil avec VMWare.
vagrant destroy pour supprimer la machine.
Infrastructure avec un Nginx en load balancer et deux Apache derrière, avec une configuration réseau posée statique.
On peut avoir du forward de port dans le fichier de configuration, la définition d’un fichier de provisionning partagé par toutes les machines.
Si on fait un vagrant up avec un nom derrière, ça démarre cette machine-là.
vagrant status, dans ce cas, donne les différents statuts pour toutes les machines.
Refaire l’exercice sous forme de session du midi en faisant voir que quand une machine tombe, après le timeout, on vient bien dessus grâce au round robbin de Nginx.
Le repackaging de box permet de créer ses propres base boxes avec des choses installées dessus. On fait pour cela un snapshot qu’on pourra redistribuer.
vagrant box list donne toutes les boxes de base qui existent sur la machine (pas les machines virtuelles, les boxes de base qui servent à monter des machines).
VBoxManage list vms donne la liste des machines qui tournent.
vagrant package –base [id de la machine] –ouput [fichier] permet de créer un package empreinte dont on pourra se servir comme base pour d’autres création automatique. Il fait un tar du vmdk et d’autres fichiers nécessaires.
vagrant box add [nom] [fichier] pour ajouter le fichier ainsi généré comme nouvelle base box (on pourrait l’envoyer sur internet dans un repo, si on ne souhaite pas rester en local).
Outil Packer plus complexe, mais qui permet d’avoir le contrôle sur une ISO originale et de donner un fichier de preceding qui donne toutes les réponses qui doivent être données pour l’install interactive.
http://github.com/aseigneurin/pres-vagrant-breizhcamp
http://aseigneurin.github.io/pres-vagrant-breizhcamp
Keynote jour 2
Startup vs SSII
How to scale your app (Quentin Adam)
Opposition scale up / scale out : grossir une instance, ce qui ne tient pas à long terme, ou découper.
Première chose : séparer clairement code et data. La clé est le « sans état » : une machine ne sait absolument rien de la data. Elle est remplaçable. D’ailleurs, on ne doit pas lui donner un nom, mais plutôt un numéro. Les sessions sont de la data. Un event est de la donnée : on doit passer par une queue, un disque dur, une base de donnée, etc.
Du coup, il faut absolument un middleware, qui donne du trust.
RabbitMQ testé par le Comité Interbancaire Américain. C’est fait pour qu’on puisse avoir une confiance absolue dans la livraison du message.
Tout le processus de data en INSERT pur est en fait une simple queue. On revient sur les principes de performance liés à la prévalence objet : un moteur super rapide en écriture, dans lequel on évite les problèmes de lock grâce à la rapidité, qui permet de traiter les requêtes les unes après les autres + plusieurs instances repliquées en asynchrone (mode CQRS) pour la lecture des données et le reporting avec des agrégations spécifiques.
Pour le datastore, il est une bonne idée d’avoir plusieurs types. Comme ça, on peut adapter en fonction de si on a besoin de l’ACID ou pas, si on a besoin d’accès concurrent en lecture / écriture, si on a plus d’écriture (logs, etc.) ou plus de lecture, si on a besoin de relations (et dans ce cas, pas de MongoDB), si on a besoin de grosses capacités (et dans ce cas, pas de RAM-based)
Amazon Web Services a 6 jours de down time par an, ce qui est loin d’être faible.
Utiliser des bases de données en ligne empêche de se bloquer pour des questions d’install, et force à coder correctement le client pour qu’il reste réactif. Si l’admin n’est pas capable de gérer cette nouvelle techno, il faut que ce soit pris comme un service en ligne.
Ne jamais utiliser le filesystem local des serveurs : POSIX est ACID et ne peut donc pas scaler. Il y a plein de solutions (S3, etc.) mais ne pas utiliser GridFS de MongoDB car c’est un hack sur le FS local, et qui perd des fichiers. Les logs ne doivent pas être stockés sur des fichiers : ils doivent être envoyés dans syslog / logstash.
Conseil : utiliser le streaming d’IO pour envoyer directement la data dans la DB.
Ne pas utiliser la mémoire comme une base de données : ne pas mettre la connexion DB dans la session, ne pas faire de variables globales, ne pas faire de cache dans le code, etc. La RAM doit être complètement stateless. La vie d’une variable doit être limitée à une seule requête, de la même manière qu’une salle d’opérations doit être complètement nettoyée avant la prochaine intervention chirurgicale. On rejoint le concept de programmation fonctionnelle : une requête, c’est une fonction mathématique : entrée donne sortie, et point.
Pompage.net : « Comment j’ai expliqué REST à ma femme » explique l’importance de respecter HTTP. On pourra beaucoup plus scaler si tout le monde comprend ce que fait l’application. Exemple : si l’admin sait que c’est un GET, il paramétrera un Varnish, et roule.
Le code peut planter, et il le fera toujours. C’est pour ça qu’il faut séparer la donnée et ne pas la mettre en mémoire pour ne pas qu’elle soit perdue à ce moment-là.
Ne pas utiliser de framework qu’on ne comprend pas. Exemple de Angular.JS qui parse le code avec des expressions régulières pour offrir des fonctions de réflexion. Si ça paraît magique, c’est certainement qu’il y a un truc pourri derrière. Exemple de MeteorJS qui a besoin de sticky sessions et pourrit donc les cookies.
Conseil final : bien utiliser l’outil qui convient à votre projet et ne pas laisser des geeks venir avec la dernière techno à la mode sans connaître le but du projet.
Dans la boîte de l’orateur, une pratique est d’empêcher le code de grossir, pour ne pas créer des monstres. Il faut savoir bouger d’un langage à l’autre.
Toutes les hard computations sont en Async. Les calculs complexes sont faits en dehors du traitement de la requête. La requête elle-même doit aller vite. Ce calcul peut même être fait avec un autre langage, et le séparer rend aussi plus simple de comprendre qu’un applicatif dédié va lentement, pendant que tout le reste va à une vitesse normale. Le superviseur Nagios ne verra pas ainsi un mélange de temps de requête qui est « normal » car certaines font des calculs.
Faire des modules spécialisés qui vont vite. C’est le retour de SOA, mais sans le dire. Ca permet de bien séparer les équipes. C’est ce qui permet d’avoir des équipes internationales. Chacun s’occupe de son micro-service. Cela permet d’utiliser la puissance du rewrite everything. Le boulot est de bien comprendre le problème, et de réécrire le legacy de manière progressive, en commençant par ce qui pose le plus de souci.
Il est essentiel pour avancer dans ce sens d’avoir industrialisé le process de déploiement. Git push devrait suffire à déclencher toute la ligne.
Toujours utiliser un reverse proxy en frontal. Comme ça, quand il y a un problème sur l’application, on peut toujours faire autre chose, rediriger, mettre un message en attendant, etc. Il faut donc toujours mettre un reverse proxy.
Ne pas s’embêter avec des annuaires de service, alors que DNS fait ça très bien (il y a beaucoup plus de choses que la simple correspondance nom / IP, comme l’envoi d’adresses multiples, etc.)
Enfin, il est essentiel d’avoir dès le début des métriques et des logs. On peut même faire ça sur des services en ligne qui sont capables de gérer ceci.
@waxzce est le Twitter du conférencier
Faire de la veille sur le langage RUST
Le monitoring à l’heure de Devops et Big Data (Claude Falguière)
On passe de la surveillance à l’anticipation et à l’orientation « data »
Le slogan « Measure everything » ne signifie pas de mesurer tout et n’importe quoi, mais de prendre des indicateurs de différents domaines pour ne pas observer un problème d’un seul point de vue.
Intéressant de poser les choses à mesurer dès la construction de la backlog pour recueillir les besoins de tous autour de la donnée enregistrée.
Une application « qui marche bien » : le critère est en termes de service rendu à l’utilisateur, plutôt que des mesures formelles de performance d’un seul service, par exemple. Pour les opérationnels, c’est encore autre chose : plutôt une capacité en ressources. Au final, le SLA est aussi une gestion de risque. Une perte de performance, même forte, peut parfois être tolérée, alors qu’un arrêt définitif serait catastrophique.
Les différents stades :
- Nombre + unité = mesure
- Mesure + contexte = métrique
- Métrique + range = indicateur
- Indicateur + description = information
- Information + lecteur = compréhension
- Compréhension + expérience = connaissance
Bien penser à mesurer les ressources physiques (CPU, RAM, HD, BP), mais aussi configurables (pools, queues, caches, etc.)
Chercher aussi à comprendre le parcours de l’utilisateur, pour améliorer la compréhension du processus global de l’application qu’on cherche à monitorer.
Pour l’urbanisation, intéressant de se poser la question si la signature standard des logs doit bien être un WADL fixe ou bien s’il faut standardiser autour des APIs de style Log4J ou Log4Net, sachant qu’elles ont la possibilité de pousser dans logstash. Au final, tant qu’on fournit une API avec un bon niveau d’indirection, on pourra changer facilement.
Quand on fait des prévisions, il faut déterminer une baseline, et certains outils sont capables de séparer la tendance du cycle.
On peut faire aussi du Complex Event Processing, qui converge avec les outils d’analyse de type Big Data. Par exemple, trois warnings proches sur des modules séparés révèlent un problème réel. Ou bien plusieurs instances qui tombent à quelques minutes d’écart.
Le nb de processeurs en attente est mieux corrélé au nombre de requêtes traités que le taux de CPU, car celui-ci est limité à 100%.
Bonne pratique de mettre dans un dashboard un lien sur la prochaine activité à réaliser. Par exemple, pour ouvrir un ticket d’assistance dans le cas où une mesure n’est pas bonne.
Ne pas oublier de valider le monitoring en termes de représentativité, de fiabilité et de cohérence, de compréhension par le destinataire (exemple des messages incompréhensibles par des personnes autres que le développeur qui les a créés) et d’adaptation de la réponse au problème levé (même si c’est une étape suivante).
Attention à ne pas créer de la contention par le compteur. On peut sharder un compteur.
Ne pas gérer l’alerte directement dans le code, sinon on ne pourra pas gérer les agrégations, l’escalade, le débrayage d’alerte (lorsque le traitement est en cours), l’abonnement sur un média donné, etc. Tout ceci est la responsabilité du système d’alerte, pas de l’application.
Voir Splunk, en parallèle de logstash + elasticsearch
Il faut gérer la collecte / historisation à part, typiquement avec Graphite.
Datomic : base clojure d’insertions seulement.
Jamon, AppDynamic pour le profiling au sens analyse.
Conclusion :
- Design for failure
- Identifiez les user stories de monitoring
- Confrontez vos mesures à la réalité
Java en 15 minutes et en caleçon (Nicolas De Loof)
Blindé de monde, pas pu voir la session. Logique, tout le monde voulait voir Nico en caleçon. Il va vraiment falloir que j’apprenne à être plus vendeur dans mes titres de session
Sensors en HTML 5
API HTML5 pour accéder à de nombreux capteurs. Certains ne sont pas encore standards, mais il y en a désormais pas mal dans la norme.
Travailler en indépendant (Guillaume Collic)
Airpair.com : des outils pour travailler en pair programming, par exemple modifier le même fichier en même temps, etc.
Nouveautés de MongoDB 2.6 (Tugdual Grall)
@tgrall pour le compte Twitter du conférencier
Améliorations du moteur de requête
Intersection d’index
On ne fait plus appel au GetLastError
Les index peuvent désormais être composés (plus obligé d’avoir un index pour chaque requête qui a besoin), même si c’est limité à deux pour l’instant.
L’agregation framework a suffisamment évolué pour ne plus avoir de raison de passer par le Map Reduce. Il vaut mieux la première solution car elle est beaucoup plus intégrée, sur les mêmes threads, etc. Le Map Reduce nécessite de monter un moteur V8, donc il ne faut le faire que si les opérations deviennent trop complexes pour être réalisées dans le moteur d’agrégation. Jusqu’à la 2.4, l’agrégation se faisait sur un document, et ne pouvait donc pas dépasser 16 Mo. Désormais, dans la 2.6, chaque document répond avec un curseur et on utilise le $out pour le garder dans une collection. Cela permet également d’avoir un recalcul uniquement sur ce qui change, et donc de travailler en incrémental.
On peut aussi faire des opérations sur les tableaux dans l’agrégation, ce qui n’était pas possible avant.
Une première version du Full Text Search existait dans la 2.4, mais dans une commande à part. En 2.6, c’est supporté comme un opérateur standard, dans le find ou l’agrégation framework. La fonctionnalité gère le langage : suppression des mots, liens entre les synonymes, etc. Il y a du field-weighted scoring (typiquement, le titre a un poids double par rapport à la recherche sur le contenu d’un blog).
.explain() ou .explain(true) pour avoir des détails sur l’exécution du find.
.agregate( $unwind : « $champ »), $groups, $sum, $out [pour écrire dans une collection]
Sécurité
Rôle dédié en lecteur seule pour la BI et le reporting
$redact pour filtrer au niveau document. On peut utiliser les rôles mais aussi le document lui-même pour affecter les permissions.
Bizarre car se base sur le contenu de tags, mais sans qu’on force l’application du filtre. A voir dans la doc, car pas clair…
Recherche full text
.ensureIndex ( content : « text » )
.find( { $text : { $search : « coucou » } }) ;
Voir aussi la doc, car pas clair sur l’utilisation multi-lingue : les exemples montrent « english » au lieu de « en » qui est la norme, donc dur à comprendre comment il s’en tire.
Performance et scalabilité
Possibilité de créer les index en background, sur un nœud secondaire, ce qui permet de ne pas trop gêner la production
Cryptage entre tous les nœuds de la base de données séparé du cryptage en direction du client (le support du SSL est valable pour la version Entreprise). Attention, seuls des produits partenaires permettent d’encrypter les données sur disque.
Il y a des sondes SNMP additionnelles.
Automatisation MMS
Outils pour les administrateurs
Disponible gratuitement en ligne pour monitorer / sauvegarder, et il faut être client support pour pouvoir l’installer localement
Souvent, la sauvegarde est faite par un snapshot des disques. On peut aussi faire un dump, mais c’est lourd. Et sinon, il y a MMS qui va faire une sauvegarde plus à chaud. Ce dernier est disponible en ligne.
Il y a des améliorations de la méthode d’upgrade, par de l’automatisation.
UX Design Thinking (Cédric Bourré)
Conception centré utilisateur : démarche
UX : tout ce qui concerne la compréhension de l’utilisateur, mais aussi du business, et qui est nécessaire avant d’arriver enfin à l’UI
Fonctionnel < robuste < utilisable < pratique < agréable < signifiant : un peu la pyramide de Maslow pour l’expérience. C’est autour du « pratique » que les entreprises s’arrêtent comme la frontière de leur approche.
Qualité d’utilisation = efficience (est-ce que j’ai réussi) + efficacité (est-ce que c’était facile) + satisfaction (est-ce que c’était agréable) + apprentissage (est-ce que la prochaine fois sera plus simple)
Risque d’une conception « technique » : rejet + inadaptation (donc besoin de formation) + déception + sous-performance (perte de temps, typiquement)
Peut-être pas une bonne idée d’avoir un designer attitré, car tout le monde doit être impliqué : les fonctionnels, les utilisateurs, etc.
Les 5 étapes de méthode de conception Design Thinking : comprendre le besoin, puis concepts / idéation, puis interaction, puis tester et adapter, et enfin atteindre le produit fini
Socialcompare.com
Argument de ROI : ergonomie mal pensée fait perdre une minute par jour pour 1000 employés => 500 jours/an perdus
Mutualiser du code natif multiplateforme (Guillaume Collic)
La part des applications natives par rapport à l’utilisation web des smartphone augmente, et est très forte (80% en 2013, 86% en 2014)
La note de l’application Facebook est passée de 1 à 5 en devenant native
Add shared project reference pour partager au niveau du code source (mais il faut alors avoir des directives de pré-compilation, y compris dans les tests) / Portable Class Libraries pour partager au niveau de la librairie (et compléter avec de l’injection de dépendance)
Danrigby.com
Genymotion : émulateur Android plus performant que celui de base, et gratuit pour usage non commercial
Installer l’application store Xamarin avec son compte pour avoir un tee-shirt
Attention, Xamarin ne cible pas Windows Phone
Soyez productifs avec MEAN (Tugdual Grall)
MEAN = MongoDB / Mongoose / Express / AngularJS / NodeJS
Express = framework de routage de requête HTTP
L’objet JSON est traité dans le même format dans toutes les couches, ce qui permet d’aller très vite pour le développement
Mongoose = framework d’accès à la base de données, même si on peut aussi prendre le plugin NodeJS d’accès direct à la base Mongo
Mongoose possède un schéma de la data structure, une connexion à la base de données (qui utilise le driver Node), le modèle et un moteur de validation
npm mongoose.validation pour plus de fonctionnalités de validation
sudo npm install -g meanio (installation de la stack MEAN)
mean init [nom de l’application]
Cela crée un squelette complet d’application, avec le serverjs, des routes, la configuration, des dépendances de base, etc.
Ligne de commande npm install pour charger toutes les dépendances
Ligne de commande grunt pour lancer l’application
PassportJS est le framework d’authentification
mean user permet de gérer les utilisateurs et de leur ajouter des rôles, par exemple
Mongoose permet de faire de la simili-jointure
Le mapping de Mongoose permet d’éviter que le client envoie n’importe quoi dans le schéma
mean install mean-tokens, puis redémarrage avec grunt : permet de passer l’interface en mode edit l’interface, et de tout modifier directement depuis l’interface elle-même, en multilangue (encore plus puissant qu’avec Liferay)
mean package permet de créer son propre package, comme on en a ajouté un à l’instant (plus pratique que l’ancienne version uniquement avec yeoman)
Le schéma n’empêche pas de rajouter ses propres attributs
Jsonstudio.com