Almost 20 days after the training, I have completed the AWS Solution Architect Associate exam and I’m now certified 🙂
So I can use this badge :

Almost 20 days after the training, I have completed the AWS Solution Architect Associate exam and I’m now certified 🙂
So I can use this badge :
Cette formation de 3 jours chez TNP a permis de revoir les bases et d’affiner certains sujets (architecture serverless, lambda, dynamoDB…). Avec 1430 nouveaux services ouverts cette année chez AWS, il y avait tout de même de quoi faire en nouveautés intéressantes.
Merci à Oliver Bazatole, le formateur de cette session pour ses conseils avisés.
La certification va suivre…
Il aura fallu un peu plus de 3 ans pour que la solution de la « serrure connectée » soit autonome, et je la laisse entre de bonnes mains.
Il est temps pour moi de proposer mes services à de nouvelles structures. Avec 10 d’expériences de conception et de développement et 10 ans d’architecture applicative et système ; mes connaissances couvrent un spectre assez large : analyse et conception (IAF), développement backend (Java, PHP), développement mobile (Android et IOS), définition et mise en œuvre d’infrastructure cloud (AWS, python), sécurisation (TLS, X509…), expertise système linux (debian, ubuntu), cryptographie (AES, RSA), conception de protocole et contrat d’interface (M2M), customisation d’Android (AOSP), amélioration des performances des systèmes existants (Mysql, MariaDB, nginx, analyse de complexité…).
Je suis joignable par email : chrystophe.vergnaud [at] gmail.com pour discuter de votre futur projet ou d’une problématique en production.
un petit script simple pour purger tous les mails de la queue de message d’exim4 :
Stocker tous les id de messages dans une variable (attention à la mémoire si la liste est grande, passer par un pipe sera plus judicieux dans ce cas) :
# id_list=`exim -bp | awk '{print $3}'`
Lancer la purge sur la liste des ids identifiés :
# exim -Mrm $id_list
Exemple de charge avec 500 clients concurrents, qui vont lancer une charge de 50000 requêtes au total.
ab -c 500 -n 50000 "https://mon_serveur/page.html"
Siege à la différence d’ab lance un maximum de requêtes avec les clients concurrents dont il dispose sur une durée définie lorsque l’option -t est utilisiée. Si l’on utilise l’option -r, cela définit le nombre de requête par client
Dans cet exemple, lancement de 500 clients concurrents qui vont charger 5 fois, on aura 2500 requêtes lancées au total.
siege "https://mon_serveur/script.php" -c 500 -r 5
nb : attention l’option -t prévaut sur l’option -r.
Avec jmeter, on commence à entrer dans le domaine du test fonctionnel car on peut créer des scénarios et autres. Il est un peu gros pour simplement tester des temps de réponses sur une requête.
Comme jmeter, mais une équipe française derrière.
https://vincent.bernat.im/fr/blog/2014-tcp-time-wait-state-linux
http://veithen.github.io/2014/01/01/how-tcp-backlog-works-in-linux.html
https://lzone.de/cheat-sheet/ulimit
https://unix.stackexchange.com/questions/345595/how-to-set-ulimits-on-service-with-systemd
import platform
if 'linux' in platform.system().lower():
import resource # Linux only
limit_nofile = resource.getrlimit(resource.RLIMIT_NOFILE)
limit_nproc = resource.getrlimit(resource.RLIMIT_NPROC)
print 'Max number of opened files allowed:', limit_nofile
print 'Max number of processes allowed', limit_nproc
Le système de gestion des limites a évolué et utiliser /etc/security/limits.conf n’est plus valide sur ubuntu 16 car le système de gestion de service est maintenant basé sur systemd.
Le plus frustrant c’est qu’à première vue rien a changé : dans /etc/init.d/ on retrouve nos scripts de lancement classique mais effectivement on observe un if systemd qui peux mettre la puce à l’oreille. En effet, l’installateur de paquet a fait son travail et a mis en place les fichiers de service compatible avec systemd. Il faut donc aller voir du côté de /etc/systemd/system/multi-user.target.wants pour trouver nos services fpm et nginx.
# ll /etc/systemd/system/multi-user.target.wants total 8 drwxr-xr-x 2 root root 4096 Jan 29 17:27 ./ drwxr-xr-x 13 root root 4096 Jun 13 2017 ../ [...] lrwxrwxrwx 1 root root 33 Jun 15 2016 nginx.service -> /lib/systemd/system/nginx.service lrwxrwxrwx 1 root root 38 Nov 29 2016 php7.0-fpm.service -> /lib/systemd/system/php7.0-fpm.service [...]
Ensuite c’est assez simple, il suffit d’ajouter la limitation de fichiers dans le service nginx ou fpm:
LimitNOFILE=30000
Voici le service complet pour php7.0-fpm:
[Unit] Description=The PHP 7.0 FastCGI Process Manager After=network.target [Service] Type=notify PIDFile=/run/php/php7.0-fpm.pid ExecStartPre=/usr/lib/php/php7.0-fpm-checkconf ExecStart=/usr/sbin/php-fpm7.0 --nodaemonize --fpm-config /etc/php/7.0/fpm/php-fpm.conf ExecReload=/usr/lib/php/php7.0-fpm-checkconf ExecReload=/bin/kill -USR2 $MAINPID LimitNOFILE=30000 [Install] WantedBy=multi-user.target
idem pour la limitation dans une session ssh. Le /etc/security/limits.conf n’a pas d’effet, j’ai donc forcé la limitation en ajoutant directement un ulimit dans le /etc/bash.bashrc :
ulimit -n 30000
Attention ceci s’appliquera à tous les utilisateurs, assurez-vous que c’est acceptable dans votre cas d’utilisation.
Il faut se poser la question de la donnée reçue en réponse de la requête : est-ce que la donnée doit être rafraîchie à chaque requête ou non. Cette question s’applique aussi bien a des données dynamiques que statiques, car une donnée statique peut être mise à jour par un gestionnaire de configuration à la volée, il faut alors savoir quelle est la fréquence d’update ou de changement de version du fichier. Dans l’autre sens, une donnée dynamique peut très bien s’avérer statique sur un an, imaginons une page de contact en php, dont l’html généré ne change qu’une fois l’an. Bref du bon sens et une bonne connaissance des contenus est nécessaire pour paramétrer au mieux son cache et un copié/collé d’une config trouvée sur le web n’aidera pas forcément.
A un niveau extrême, sur des cas d’usage à très forte volumétrie, la création d’un micro-cache sur un stream dynamique (php ou autre) est a étudier pour bénéficier de certaine optimisation nginx sur le remplissage de la socket TCP.
https://www.nginx.com/resources/admin-guide/reverse-proxy/
Gardez à l’esprit qu’on est sur du TCP, donc le MTU et la gestion du buffer réseau va impacter le tout. De ce fait nginx a mis en place des directives pour optimiser tout ça :
sendfile on; tcp_nopush on; tcp_nodelay on;
Voici une explication claire de ce qui se passe derrière ces directives :
https://www.nginx.com/blog/nginx-caching-guide/
https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
De ce fait utilisez plutôt une variable (directive set) dans une directive location afin d’éviter la directive if et utilisez la directive proxy_cache_bypass pour ouvrir des trous dans le proxy et ainsi ne pas inclure dans le cache des contenus temps réels.
L’option de faire un micro-cache dédié au contenu temps-réel peut aussi être une option afin de réduire la latence liée au remplissage du buffer réseau.
https://angristan.fr/cache-module-pagespeed-ram-tmpfs/
tmpfs est meilleur que ramfs car plus récent mais on peut retomber sur des accès disques car tmpfs peut repartir dans le swap.
https://www.jamescoyle.net/knowledge/951-the-difference-between-a-tmpfs-and-ramfs-ram-disk
https://serversforhackers.com/c/nginx-caching
Cette configuration est une bonne base pour comprendre les principes et voir la différence entre un cache de fichiers statiques et un cache fastcgi. Il reste à ajouter un micro-cache en mémoire, customiser les tailles de buffers et supprimer les if.
Le tuto nginx est plutôt « léger » sur l’explication concrète de cette configuration de limitation, voici donc quelques compléments d’explication :
geo $limit {
default 1;
10.0.0.0/8 0;
192.168.0.0/24 0;
}
map $limit $limit_key {
0 "";
1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=req_zone:10m rate=5r/s;
server {
location / {
limit_req zone=req_zone burst=10 nodelay;
# ...
}
}
L’instruction geo
créé un variable $limit qui aura pour valeur 0 ou 1 en fonction de l’adresse IP du client. Ici les 2 réseaux privés 10.0… et 192.168.. vont valoriser la variable $limit avec un 0, sinon $limit sera valorisée à 1.
L’instruction map
va définir une variable $limit_key, sa valeur va dépendre de la valeur de la variable $limit. Si geo
a identifié une IP publique, $limit contiendra 1, donc $limit_key sera valorisé à « $binary_remote_addr se qui va entraîner l’instruction limit_req_zone
à s’appliquer sur l’IP du client. Si le client a une IP privée dans ce cas $limit_key sera valorisé à zéro et l’instruction limit_req_zone
ne va pas s’exécuter.
La balise limit_req_zone
applique une limitation à 5 requêtes par seconde si $limit_key
est valorisé à 1.
Dans l’instruction limit_req
, un burst
(un bonus) de 10 est ajouté. Le nodelay
va amener des réponses 503 à partir de la requête 16 si elles arrivent dans la même seconde. En supprimant le nodelay, le navigateur affichera une page qui se charge lentement.
Les liens vers le détail technique des commandes :