Mapproxy - le serveur de tuiles ultra-configurable
Cet article illustre les retours d’un petit voyage au centre du monde du code de mapproxy.
Moritz Kirmse
Nous avons été contacté par un client français pour effectuer quelques petites améliorations fonctionnelles dans mapproxy. Sans grande expérience préliminaire avec cet outil, nous avons pu très rapidement fournir une solution satisfaisante à notre client.
Choix des outils
Nous connaissons bien cette situation: un nouveau projet demande la mise en place d’un serveur de tuiles et nous devons choisir une technologie parmi celles qui sont à notre disposition. Finalement nous choisissons souvent l'outil que nous connaissons le mieux et nous n’avons qu'une crainte - que le logiciel puisse un jour arriver en fin de vie.
Regardons quelques logiciels que nous avons fréquemment en main chez camptocamp:
- Mapcache: un bel outil aux côtés de mapserver, c’est quasiment la référence, le support est bon, c’est rempli de fonctionnalités et très fiable
- GeoWebCache (en tant que part de GeoServer ou application indépendante): un autre vétéran parmi les serveurs avec des configurations du cache limités
- ArcGIS: une suite de serveur très complète, mais c’est propriétaire et bien sûr, nous préférons des solutions open-source
- QGIS server avec le plugin de cache: plein de fonctionnalités et facile à configurer, mais installation assez volumineuse
Voici donc mapproxy, un serveur de tuiles écrit en python avec de nombreux back-ends.
Backends de sources | Backends de cache | |
Compatibilité | WMS sources (1.0.0–1.3.0), | Filesystem, |
Si vous avez déjà essayé de modifier le code source de mapserver vous avez surement eu besoin d’un grand thermos de café. Déchiffrer et comprendre ce code C hautement optimisé donne l’impression d’un voyage dans le passé et je n’ai jamais été bien confiant en effectuant des petites modifications sans bien en connaître les effets indirects.
Tout au contraire, le développement dans mapproxy est un plaisir. Le logiciel est entièrement écrit en python, et le code source me paraît très lisible et facile à entretenir. Les modules sont bien structurés et la couverture de tests est très complète.
Mise en place du cache de tuiles
Intérêt
Un cache de tuile se trouve entre une source de données géographiques et les utilisateurs.
- Il réduit la charge sur le serveur des données source
- Il évite un re-calculation redondante de données identiques
- Il peut exécuter des traitements avancés tels que l'ajout de filigranes, la reprojection ou la mise à disposition de données en projections multiples
Il exécute principalement 2 actions: précalcul (seeding) et téléchargement (serving).
- Le seeding permet de charger un jeu de données bien défini depuis les sources et de l’enregistrer en mode optimisé dans un système de stockage cache.
- Il faut générer un jeu de données initial mais aussi réactualiser un jeu de données existant
- Il est possible de lancer la tâche manuellement ou de l’exécuter régulièrement de manière automatique (ex: cron job)
- Le serveur de tuiles permet aux applications clientes d’ouvrir une connexion et de télécharger depuis le cache des tuiles ou images composites suivant le protocole demandé. Il peut aussi générer des tuiles à la volée depuis les données sources lorsqu’elles ne peuvent pas être trouvées dans le cache.
Configuration
Mapproxy charge sa configuration à partir de deux fichiers:
- mapproxy.yaml
- seed.yaml
Les différents comportements du cache sont définis dans ces fichiers:
- Sources des données
- Définitions de grilles spatiales
- Type et accès au cache
- Durée de validité du cache
- Valeurs par défaut (tuiles vides)
- etc.
Amélioration des performances
La performance de serveur peut être contrôlée par un choix judicieux du serveur web sous-jacent. Il convient de déployer mapproxy dans un serveur web robuste et puissant. (apache + mod_wsgi, NGINX, gunicorn, etc.)
Une pyramide de tuiles pré-générée peut aussi être accédée en local par une application front-end ou ouverte au téléchargement grâce à un serveur de fichiers.
Les détails de notre modification de code
Nous avons souhaité ajouter un peu plus de granularité dans la gestion du cache, avec des options supplémentaires pour des tuiles périmées et pour l’actualisation du cache.
Les enjeux principaux étaient:
- Une réduction de la sollicitation des serveurs de sources
- Une minimisation de l’espace de stockage de cache
- Une gestion intelligente de serveurs de sources défaillants
Organization du code
Le code est bien divisé en modules pour les différentes fonctionnalités. Suivant le paradigme de programmation orientée objet, le code utilise des classes virtuelles parent et implémente le détail des fonctions dans les classes enfant. (ex. parent = MapLayer; enfants = [WMSSource, TiledSource, ArcGISSource, etc.])
Les fonctions comprennent:
- La gestion du cache
- La gestion des sources
- Les services publics
- La pré-génération de tuiles
- Etc.
Cette conception modulaire simplifie la personnalisation des options et la propagation des réglages aux classes qui les utilisent.
Nouveaux réglages
- Rafraîchir les tuiles périmées à la volée au cours d’une requête client (et non seulement lors du seeding)
- Améliorations du seeding
- Actualiser uniquement les tuiles déjà présentes en cache (le remplissage du cache se fait alors à travers des requêtes clients)
- Conserver des tuiles périmées si la source est indisponible
Ces changements précis ont nécessité de plonger dans les profondeurs du code source à travers plusieurs niveaux de classes. Mais la conception de mapproxy s’est avérée très robuste et les modifications ont pu être très ciblées sans demander de refactoring complet.
Pour le 1er point, les modifications ont pu être localisées:
- Adaptation du système de configuration
- Modification du service interne cache -> tuile
- Nouvelle gestion de tuiles vides en cas d’erreurs des sources
https://github.com/mapproxy/mapproxy/pull/518
Le 2ème point a seulement demandé un ajustement des paramètres transmis entre les différentes classes sans changement fonctionnel, pour pouvoir changer les options depuis la ligne de commande.
https://github.com/mapproxy/mapproxy/pull/515
Sans aller plus en détail, nous avons vu que des interventions dans des parties variées du code étaient possibles sans impacter d’autres fonctionnalités.
Conclusion
Le contrôle sur le cache dans mapproxy est déjà très fin. Mais si les réglages existants ne sont pas suffisants, il est facile d’adapter le code source pour gérer de nouvelles options.
Mapproxy est un excellent choix si vous désirez configurer une stratégie de cache très complexe ou si vous aimez jouer avec le code source. La communauté mapproxy est aussi très ouverte pour de nouvelles fonctionnalités, qui pourront alors servir un grand nombre d’utilisateurs dans le futur.
Dans le futur, l’outil fera certainement partie de la boîte à outils de camptocamp, puisque l’expérience de travail a été si positive.
En deux mots: fortement recommandé !
Pour plus d'informations,
n'hésitez pas à prendre contact avec nous !
Carrière
Vous souhaitez travailler dans un environnement inspirant et rejoindre nos équipes motivées et multiculturelles ?