mardi 4 août 2015

Le voyage du Kimsufi en Docker (Etape 1)

J'ai un petit serveur kimsufi avec quelques applications sympa et puis ça me permet de bidouiller un peu, de m'ouvrir à de nouveaux aspects de l'informatique qui dépassent ce que je réalise professionnellement.

J'ai donc un petit Nginx en frontal de divers applications comme Seafile, Subsonic, un Monit pour voir si tout tourne bien et réaliser un monitoring des ressources.

Et là je me dis pourquoi pas dockeriser tout ce petit monde.
On se demande bien pourquoi ? Quel est l'intérêt de consacrer de l'énergie pour tout mettre dans des containers Docker ?
Le premier est tout personnel : apprendre à utiliser cet outil et voir si ça vaut le coup de le mettre en place sur des projets professionnels avec un peu d'architecture en microservices.
En suite le serveur est sous Debian et réaliser une montée de version n'est pas si évident ainsi je peux créer des container dans un version plus récente de Debian sans modifier mon système hôte.
Cela peut faciliter la monté de version de Debian, la migration vers une autre machine, chez un autre hébergeur ou dans une infrastructure cloud...

Après que vais-je perdre ? A priori Monit ne permettra pas de manager les différents services dans les containers, ou à payer mmonit. Il va falloir passer à supervisord installé dans chaque container et un container pour supervisorctl et peut-être un cAdvisor en prime... De plus supervisord semble la solution préconisée pour lancer plusieurs processus dans le même container.
Et pas mal de temps... visionner les vidéos pour survoler les concepts et l'utilisation de Docker. Du temps pour installer Docker (et une petite montée de kernel pour que ça marche). Du temps pour faire les Dockerfiles et les commandes docker run... Du temps pour tester, modifier les conf et un peu d'astuce pour ne pas avoir une indisponibilité trop longue des divers services de mon kimsufi.

La stratégie de migration en Docker, là on a deux options un marathon de 48h ou y aller progressivement, container par container valider puis tous les containers.
Je prends la seconde option car je n'ai pas de fenêtre de 48h dans mon emploie du temps, juste une heure par-ci par-là. Donc le principe créer une image pour chaque service, et réaliser un run de chaque container puis réaliser les liens au travers d'un fichier docker-compose.yml
J'ai réalisé la 1er étape :



Sans trop de difficultés l'astuce est de réaliser le run du container nginx avec les options suivantes
--privileged=true --net=host 
Ainsi il n'y a pratiquement pas de modification à faire le la configuration de nginx. Par contre le processus nginx ne peut plus être supervisé par Monit... il reste les stats du container : 

CONTAINER CPU % MEM USAGE/LIMIT MEM % NET I/O 
nginx               0.00%   10.22 MB/2.08 GB      0.49%     0 B/0 B

Tranquille tout ça.

J'oubliais ça peut-être intéressant les Dockerfile :

FROM nginx
MAINTAINER niclange
RUN apt-get update
RUN apt-get upgrade -y
RUN apt-get install -y php5-fpm php5
RUN sed -i 's/;extension=gd.so/extension=gd.so/g' /etc/php5/fpm/php.ini
RUN sed -i 's/;extension=iconv.so/extension=iconv.so/g' /etc/php5/fpm/php.ini
RUN sed -i 's/;extension=mcrypt.so/extension=mcrypt.so/g' /etc/php5/fpm/php.ini
RUN sed -i 's/;extension=mysql.so/extension=mysql.so/g' /etc/php5/fpm/php.ini
RUN sed -i 's/;extension=sqlite3.so/extension=sqlite3.so/g' /etc/php5/fpm/php.ini
RUN sed -i 's/;extension=pgsql.so/extension=pgsql.so/g' /etc/php5/fpm/php.ini
RUN sed -i 's/;extension=ldap.so/extension=ldap.so/g' /etc/php5/fpm/php.ini
RUN sed -i 's/;extension=openssl.so/extension=openssl.so/g' /etc/php5/fpm/php.ini
RUN sed -i 's/;extension=pdo_pgsql.so/extension=pdo_pgsql.so/g' /etc/php5/fpm/php.ini
RUN sed -i 's/;extension=pdo_mysql.so/extension=pdo_mysql.so/g' /etc/php5/fpm/php.ini
RUN sed -i 's/;extension=pdo_sqlite.so/extension=pdo_sqlite.so/g' /etc/php5/fpm/php.ini
RUN sed -i 's/listen.owner = www-data/listen.owner = nginx/g' /etc/php5/fpm/pool.d/www.conf
RUN sed -i 's/listen.group = www-data/listen.group = nginx/g' /etc/php5/fpm/pool.d/www.conf
RUN sed -i 's/;listen.mode = 0660/listen.mode = 0660/g' /etc/php5/fpm/pool.d/www.conf
COPY nginx.conf /etc/nginx/nginx.conf
COPY users /etc/nginx/conf/users
COPY toto.crt /etc/ssl/private/
COPY titi.key /etc/ssl/private/
EXPOSE 80 443 442
Et oui j'ai ajouté php5-fpm mais je ne suis pas certain que cela soit pertinent.

vendredi 5 juin 2015

Combiner BitTorrentSync et Seafile

J'ai en place un serveur avec seafile, ça fonctionne bien, même très bien avec des fonctionnalités pertinentes. Bref c'est très pratique, mais BitTorrentSync est arrivé et le concept est aussi intéressant et peut répondre à une problématique : la synchronisation de 2 postes sur le même réseau local sans passer par le serveur sur internet.

Mais peut-on combiner les 2 produits pour synchroniser le même répertoire et bénéficier ainsi de tous les avantages :
  • BitTorrentSync :
    • utilisation du réseau local
    • pas de dépendance à un serveur central
  • Seafile :
    • un serveur central qui est presque toujours disponible (chez un hébergeur)
    • versioning et snapshot 
    • création de liens sécurisés pour partager accessibles tout le temps
    • interface web accessible
    • chiffrage côté serveur & coté client (option)

La réponse est oui, il peut y a voir quelques collisions de fichier mais Seafile semble bien s'en sortir en réalisant une duplication des fichiers qui lui posent problème. Mais le plus simple semble de mettre en pause la synchro Seafile lorsque que le répertoire se synchronise avec BitTorrent Sync.

Configuration des répertoires :


Ici le but est de synchroniser le répertoire "Ma Bibliothèque", le répertoire "save" est une sauvegarde de sécurité car les manipulations divers peuvent entraîner quelques pertes. "Seafile" est le répertoire de base de Seafile il n'est pas direchttp://seafile.com/en/help/ignore/tement synchronisé.

Voici les étapes :

  1. Mettre en place seafile et synchroniser 2 PC clients
  2. Ajouter un fichier seafile ignore : http://seafile.com/en/help/ignore/ avec le contenu suivant : .sync/
  3. Désactiver la syncho automatique
  4. Sur un premier PC installer BitTorrent Sync et partager le répertoier Ma Bibliothèque
  5. Installer BitTorrent Sync sur le second PC
  6. Vider le répertoire "Ma Bibliothèque" sur le second PC
  7. Là j'ai dû installer l'application Sync sur mon téléphone portable pour lier les 2 PC c'est le plus simple finalement
  8. Synchroniser avec BitTorrent Sync le second PC avec le répertoire "Ma Bibliothèque", là il devrait rapidement se synchroniser
  9. Activer la synchronisation de Seafile et vérifier que le répertoire .sync n'est pas synchronisé sur le serveur
Si tout marche cela devrait se stabiliser et aucune notification n’apparaît, si des notifications de synchronisation apparaissent c'est qu'un répertoire .sync/ est synchronisé, il peut aussi y avoir quelques collisions mais les fichiers sont faciles à identifier.

mercredi 28 janvier 2015

Logger les performances avec l'AOP dans une application n-tiers (Java)

La perf, un sujet incontournable, il sera mis tôt ou tard sur la table. Il faudra comprendre, améliorer, supprimer les points de contentions. Pour cela il est indispensable de réaliser des mesures. Un panel de solutions permettent de réaliser des mesures avec plus ou moins de finesse, dans diverses conditions.
Du temps d'exécution d'un test unitaire à un test de charge avec SoapUi ou JMeter, à une analyse de la jvm avec VisualVM ou Java Mission Control . Enfin en combinant tout ça on est certain d'arriver à une mesure fine et à identifier les axes d'optimisation. Mais à quel prix, ces outils on un coup non négligeable de mise en œuvre, et la traque prend du temps.

Une solution simple permettant de réaliser des rapports est la mise en place d'un logger par AOP s'appuyant sur l'architecture en couche (oui votre application est architecturée en couche). L'architecture en couche permettra l'utilisation de l'AOP de façon assez simple en interceptant les interfaces de chaque couche, et cela permettra de structurer le rapport. Cette approche est assez rapide et simple à mettre en oeuvre.

Pour cela j'ai développé un mini projet Log4Tiers (https://github.com/niclange/Log4Tiers) pour réaliser ces logs de performance, oui il est très simple et probablement beaucoup l'ont déjà implémenté. Il s'appuie sur Spring pour la mise en œuvre de l'AOP. On se place dans un contexte web, on va donc réaliser un log en tentant de suivre chaque appel au travers d'un identifiant (en rapport avec le thread), puis on identifiera chaque couche appelée et chaque méthode et les temps consommées.
Le plus complexe pour la mise en oeuvre est la configuration Spring de l'AOP.

Attention le fait de logger à un coût, et aura une impacte non négligeable, surtout si on log les éléments ayant une fine granularité, il faut donc en tenir compte, configurer la configuration AOP Spring en conséquence.

Vous trouverez un exemple complet dans la partie test unitaire du projet.
Je vais finir en ajoutant comment traiter le résultat du logger avec Excel.
On ouvre le fichier csv avec excel et on ajoute les entêtes des colonnes
En suite on peut réaliser un tableau croisé dynamique pour faire ressortir par exemple chaque appel :
Ou les couches de l'application :

A partir de là on peut réaliser toutes sortes de graphiques.


Sinon j'ai mis à jour le projet pour activer/désactiver les loggers par JMX.