blog-image

Défi - Fabriquer un LoadBalancer assisté de l'IA DeepSeek

  • dHENRY
  • 11/05/2025
  • (Durée de lecture : 6 mn)

Abonné à Hacker News et submergé par les articles sur l’intelligence artificielle, en particulier sur les IA génératives, j’explore la possibilité d’apprendre un nouveau langage de programmation, Rust, en développant une application concrète.

Le projet, un LoadBalancer :

  • Configuration Yaml: frontend ⇨ acl ⇨ backend ⇨ servers
  • Les frontends :
    • Listeners HTTP/HTTPS
    • upgrade websocket
  • Les backends :
    • HTTP et HTTPS
  • Distribution roundrobin, uniquement
  • Insertion de l’entête “X-Forwarded-For”
  • API Rest pour modifier la configuration
  • Application de la configuration sans redémarrage
  • Chargement automatique des certificats (format pem) pour la résolution TLS
  • Intégrer un système anti-bot (basique), le but n’est pas de développer un système complet, mais tenter une implémentation au cœur du LoadBalancer.

** Les éléments cochés sont fonctionnels dans le premier commit.

Cela paraît très ambitieux. Je précise que je ne suis pas un débutant en développement logiciel et que j’ai une bonne connaissance des infrastructures. Ceci va avoir un impact important sur la suite des opérations.

1ʳᵉ phase : Apprentissage de Rust

Chacun sa méthode, durant un week-end, je me suis inscrit en ligne au MIT et pris un cours sur les “Machine Learning”. Ce type de cours propose de nombreux algorithmes, avec des exemples en python, que je ne connais pas plus que Rust, mais le plus important sont les exemples avec des résultats. La première étape consiste à réimplémenter les algorithmes en Rust en adoptant une approche de développement guidé par les tests. (les tests avec Rust sont un pur bonheur).

2ᵉ étape : Choix d’une IA

Ce sera DeepSeek. Cette IA a fait couler beaucoup d’encre et remis les pendules à l’heure sur la valorisation boursière de l’écosystème IA :)

Sur le papier, aussi puissante que ChatGPT, gratuite et ne demande pas ton numéro de téléphone. Concernant la protection de la vie privée, la compagnie propriétaire de DeepSeek, voit l’adresse IP de sortie du VPN et mes “prompts” ne comportent rien de confidentiel. Pour éviter les “copier-coller” indésirables, utilisez les constantes dans le code, les valeurs ne seront ainsi jamais “captée” par l’IA.

Tous les “prompts” seront faits en anglais, c’est parti.

3ᵉ étape : Construction du LoadBalancer

Je commence par demander des explications sur le fonctionnement d’un LoadBalancer, je travaille habituellement avec Haproxy, il est donc certain de trouver dans mon raisonnement, des similitudes avec ce logiciel. Les réponses sont correctes avec beaucoup de schémas (mermaid). L’IA DeepSeek est très bavarde.

Naïvement, je commence avec le code présenté, puisque je ne connais pas Rust et plus particulièrement son écosystème de dépendances. Je commence avec un premier “forwarder” : listener HTTP vers backend HTTP. Sans trop d’efforts le résultat est bluffant.

Je continue avec un listener HTTP vers HTTPS, là encore assez facile.

Ça se complique, un listener HTTPS vers HTTP ou HTTPS, la brique Rust cliente (hyper) fonctionne pour les deux. Concernant le listener, il faut implémenter le concept de l’acceptation TLS, tout part en vrille, l’IA mélange du code avec des niveaux de version de composants non compatibles. Je m’en sors avec la documentation constructeur des composants (pas avec l’IA). Trouvant complexe la syntaxe de l’implémentation d’un service REST avec “hyper”, l’IA me propose d’intégrer le framework “rocket”, je suis toujours ses conseils et la cohabitation semble fonctionner.

Au bout d’environ 36 heures de travail, j’obtiens un système qui fonctionne, avec upgrade websocket, et une configuration modifiable sans redémarrage. Pour les tests websocket, j’ai demandé à l’IA un mini-serveur websocket nodejs, le code est dans le projet git.

C’est bluffant, novice en Rust, ne comprenant bien évidemment pas tous les aspects du langage, le LoadBalancer fonctionne. Passons aux performances : déplorables, il fallait s’en douter.

Le code produit par l’AI est basé sur la version 0.14 du composant hyper, avec très certainement une mauvaise implémentation du concept “hyper”.

Mais à partir de ce moment, j’ai une découpe parfaite des modules nécessaires pour construire un LoadBalancer respectant mes spécifications de départ.

4ᵉ étape : Optimisation

L’optimisation a consisté, dans ce cas, à supprimer toutes les dépendances et choisir le framework le plus rapide pour “parser” le protocole HTTP. On oublie l’IA un instant, je parcours le web pour essayer de trouver des benchmarks, et on en trouve. Mon choix reste “hyper”.

Je repars donc avec la dernière version 1.6.0. Le “Gap” est très important depuis la 0.14. L’IA DeepSeek s’est apparemment arrêtée à la version “1.0.0”, même si elle prétend connaître “1.6.0” en me présentant des méthodes qui existaient en “1.0.0” mais abandonnées en “1.6.0”. Bref la migration a pris 4 jours/homme (je suis toujours un débutant en Rust).

Coté performances

Les résultats obtenus sont à relativiser comparé à Haproxy, un monstre du monde des “reverse proxy” en place depuis plus de 20 ans, qui dispose de “parsers maison” et de paramètres d’optimisation qui ont nécessité beaucoup de recherches.

Je n’ai pas pris le temps d’établir des conditions de tests similaires à ce que l’on peut trouver dans ce domaine, mais avec des outils comme “ab” et “wrk”, c’est environ 20% en moins qu’avec Haproxy, très convenable pour mon utilisation personnelle et mes débuts sur le langage Rust.

Environnement :

  • Haproxy installé sur une unité de type “Raspberry Pi 4”, avec deux cartes réseau (entrant ⇨ backend)
  • Mon proxy installé sur une unité de type “Rock64”, avec deux cartes réseau (entrant ⇨ backend)
  • Le backend : Service de messagerie Matrix (sans websocket) installé dans un cluster Kubernetes exposé NodePort.
  • Résolution TLS effectuée par le LoadBalancer (HTTPS ⇨ HTTP)

Conclusion

Le but de cet exercice était d’évaluer une auto-formation à un langage de programmation assisté par IA.

L’IA “DeepSeek” est très bavarde, elle donne très souvent de bons conseils, mais il ne faut jamais s’arrêter à son premier niveau de réponse. En d’autres termes, lire la réponse complète.

Quand vous êtes très médiocre comme moi en design UI, l’IA est vraiment performante pour les questions du genre : “I would like to get a simple HTML template for the error proxy response, such as Service not available, Gateway error, etc.”, j’ai recopié tel quel le code HTML généré. C’est propre, responsive…

Les travers, dans ce cas précis : L’IA mélange sans cesse le code des différentes versions des composants à manipuler, mais donne une piste beaucoup plus rapidement qu’un moteur de recherche traditionnel.

Ma technique après quelques jours d’utilisation de l’IA :

  • Chercher la documentation constructeur de tous les composants impliqués, ouverte pour chacune, dans un onglet différent.
  • Posez des questions à l’IA aussi précises que possible.
  • Établir une analogie entre sa réponse et les exemples contenus dans le code source du composant Rust utilisé.

Au final, c’est une expérience incroyable, apprendre un nouveau langage, de nouveaux concepts, en quelques jours seulement et je ne prétends surtout pas être devenu une “bête” en programmation Rust. Le code présente encore beaucoup d’erreurs de conception.

L’utilisation d’une IA permet de renforcer ces principes fondamentaux :

  • Je dessine l’architecture souhaitée.
  • Je lis (beaucoup).
  • Et je code en utilisant l’IA (avec tous ses travers), mon éditeur n’est pas connecté à une IA (copier-coller à partir de DeepSeek).

Confirmation : l’IA, ne disposant pas de raisonnement, n’est pas prête à remplacer les programmeurs.

Temps passé : Étalé sur 2 semaines comprenant 2 Week-ends (intense ~10-12h/jour) + 1 et 8 mai (~10-12h/jour) + 2~3h après le taf sur 7 jours.

Début 29 avril 2025 ⇨ 11 mai 2025, je vous laisse faire les comptes…

Le code est ici, je n’ai pas assez d’expérience pour me lancer dans l’optimisation du code Rust, mais je vais persévérer et terminer l’implémentation des spécifications de départ.

+++