Mais c’est vrai que ça aide bien d’avoir sous les yeux les pratiques des autres.
Je ne vais pas expliquer pourquoi Python, je l’ai déjà fait.
Commençons plutôt par la partie purement Web, pour laquelle on utilise Django, le framework Web Python.
Max et moi avons tout deux fait du PHP avant, j’ai tâté des frameworks internes, du Symfony et plus tard du Zope. J’ai regardé du côté de Pyramid et de ses prédécesseurs, et Django est celui qui me plaît le plus. J’ai juste un peu forcé la main à Max :-)
Car oui, le framework a été avant tout un choix de goût.
Ce n’est pas un choix de performances : le framework n’a aucun impact dessus. Aucun. Les architectures ont un impact. Le framework, non. Votre bottleneck sera sur les IO, pas sur le CPU. Le choix de technos asynchrones peut avoir un impact, mais ce n’est pas une question de framework. Tornado, Twisted ou NodeJS, on s’en fout.
Donc Django, essentiellement parce qu’il me plait. Et il me plaît pour ces raisons :
En terme de base de données, on a fait du MySQL pendant longtemps. Ça a plutôt bien marché. Maintenant je commence mes nouveaux projets avec PostGres, qui est plus solide. Parfois je fais juste du Sqlite, parce que ça suffit.
Pas de NoSQL. Après plusieurs expériences avec MongoDB et CouchDB, je n’ai pas été convaincu que les bénéfices dépassaient le coût. Il faudrait un article complet là-dessus (qu’on m’a d’ailleurs demandé).
Question OS. c’est du CentOS avec Max (il a plus l’habitude) ou du Ubuntu Server pour mes autres projets. Je reste sur les LTS. Ce n’est pas un choix très réfléchi, c’est surtout par habitude.
Pas de machine virtuelle. On a essayé, sans y trouver un grand intérêt :
Et donc pour le déploiement, j’utilise fabric, avec fabtools.
Ce n’est pas la solution la plus efficace, d’autant que ça limite à Python 2.7, mais c’est la plus simple. C’est juste du code Python. N’importe qui peut comprendre le déploiement en 15 minutes. Ça se modifie vite, s’adapte facilement.
Il faut comprendre qu’on a jamais plus d’une dizaine de serveurs pour un projet, ces choix sont donc faits en fonction de cela. Il va sans dire que si vous gérez un parc de centaines de machines, ça ne sera pas du tout le même choix technique. Peut être que Chef ou des VM seront alors carrément plus intéressants. Peut être que le NoSQL et sa capacité au scaling sera bien plus rentable.
Il ne s’agit pas de décrier les technos que nous n’utilisons pas. Il s’agit juste de dire, voilà les choix que nous avons faits, dans tel contexte, pour telles (bonnes ou mauvaises) raisons.
Durant les dernières années, on a ajouté Redis à notre stack. C’est un outil fantastique qui sert à tout : de la base de données pour les trucs simples (il y a des fois ou un schéma est overkill) à la solution de caching. C’est ce qu’on a de plus proche du NoSQL.
L’outil est tellement simple à installer (vraiment le degré zero de la maintenance, c’est beau) et à utiliser que ça ne vaut juste pas le coup de s’en priver.
Du coup, plus de memcache. Toutes les grosses requêtes sont sauvegardées dans Redis, dès qu’on fait un script qui a besoin de persistance temporaire, Redis, pour communiquer entre plusieurs process, Redis, pour toutes les opérations qui ont besoin de grosses perfs comme les stats, Redis. Vive Redis.
D’ailleurs on utilise Redis aussi comme broker pour notre gestionnaire de queues et de taches : celery. Si vous pythonez, je vous recommande chaudement celery pour toutes les tâches en background, les crawlers, les chaînes de process, etc.
On a aussi du moteur de recherche. Là on tape dans du Solr (avec haystack). C’est très puissant, en tout cas syntaxiquement car ça ne fait pas de sémantique. Ne vous attendez donc pas à rattraper Google. Mais c’est aussi méga chiant à configurer et très lourd. Je pense qu’un jour on va migrer sur ElasticSearch, mais c’est pas la priorité. Don’t fix what ain’t broken.
Devant tout ça on a Nginx. Comme beaucoup on a fait Apache => Cherokee => lighttp => nginx. Et franchement, je ne reviendrai jamais en arrière : plus léger, plus rapide, plus facile à installer et à configurer, plus versatile. Nginx fait tout, et mieux.
En proxy on a du gunicorn. Parce qu’on avait la flemme de configurer uwsgi et qu’on a pris l’habitude.
Après on utilise plein de libs, de petits outils, etc. Mais ça c’est le gros de notre archi.
]]>PYTHONSTARTUP
:
export PYTHONSTARTUP=/chemin/vers/fichier/python/a/executer/au/demarrage.py
Mais comment lancer du code au démarrage pour Python quand on est PAS dans un shell ?
Comme pour l’exécution du code à la fermeture de la VM, il existe bien entendu un mécanisme pour cela.
Ouvez un shell, et tapez:
>>> import site
>>> site.getusersitepackages()
'/home/sam/.local/lib/python2.7/site-packages'
Vous obtenez ainsi le dossier des sites packages locaux, c’est à dire un dossier qui est dans le PYTHON PATH, mais uniquement pour l’utilisateur courant. Donc vous pouvez mettre dedans toute bibliothèque Python que vous voulez importable de partout, mais uniquement pour vous.
Dans ce dossier, créez un fichier nommé usercustomize.py, et voilà ! Tout ce qui est dans ce fichier est automatiquement exécuté au démarrage de Python.
Attention cependant, il est exécuté très tôt, et donc certaines choses ne sont pas encore chargées, telle que sys.argv
ou __builtin__
.
Il faut donc ruser un peut. Si vous êtes une loque qui n’aime pas taper import ipdb; ipdb.set_trace()
, vous pouvez par exemple mettre dedans :
import __builtin__
from pdb import set_trace
__builtin__.set_trace = set_trace
Et maintenant, dans votre code, vous pourrez appeler set_trace()
de pdb directement, sans import, sans préfixe.
Attention tout de même à ce que vous allez mettre là. Si vous commencez à trop trafiquer votre installation, vos programmes pourraient marcher dessus et pas ailleurs. Testez toujours vos logiciels sur des installations de Python standards.
Bonus point: le code de startup d’un codeur Python scientifique.
]]>