Ouvrez elido.me/abc123 et quelque chose doit transformer cette courte chaîne en une adresse web complète avant que votre navigateur puisse charger quoi que ce soit. Le mécanisme est plus simple que la plupart des gens ne le supposent. Un raccourcisseur d'URL stocke un mapping d'un code court vers une longue URL de destination. Quand vous cliquez sur le lien court, le service traite le code comme une clé de recherche, trouve la destination, et retourne une redirection HTTP qui indique à votre navigateur où aller réellement. Une requête en entrée, une redirection en sortie.
C'est toute l'idée. Tout le reste est de l'ingénierie autour de trois contraintes : rendre la recherche rapide, garder les codes courts et uniques, et enregistrer le clic sans ralentir personne. Cet article parcourt le fonctionnement des raccourcisseurs d'URL de bout en bout, en utilisant l'architecture edge d'Elido comme exemple concret tout en gardant l'explication vraie pour les raccourcisseurs en général. Nous couvrirons le mapping slug-vers-URL, comment les codes courts sont générés, où les données vivent, le choix redirection 301-versus-302 qui piège plus de gens que n'importe quoi d'autre, à quoi ressemble réellement une redirection HTTP sur le réseau, pourquoi la mise en cache à l'edge est importante, et comment un clic est compté de manière asynchrone.
Comment fonctionnent les raccourcisseurs d'URL : le mapping au coeur#
Dépouiller l'infrastructure et un raccourcisseur d'URL est un magasin clé-valeur avec un gestionnaire de redirection greffé. La clé est le slug, le code court après le domaine. La valeur est la destination, la longue URL que vous avez collée à l'origine.
Quand vous créez un lien court, le raccourcisseur écrit une ligne : ce slug pointe vers cette destination. Quand quelqu'un visite le lien court, le raccourcisseur lit cette ligne et agit en conséquence. La création de liens est rare ; leur lecture est constante. Un seul lien marketing peut être écrit une fois et ensuite lu quelques centaines de milliers de fois au cours de sa vie. Ce ratio à lecture intensive est le fait le plus important sur la charge de travail, et il façonne chaque décision de conception qui suit, notamment la mise en cache.
Le mapping lui-même peut porter plus qu'une destination. Dans Elido, un slug peut contenir des règles de ciblage, de sorte qu'un lien court route vers différentes destinations par pays, appareil, langue ou heure. C'est ce que nous appelons un smart link, et c'est toujours la même recherche, juste avec une petite évaluation de règle après la lecture. La relation de base ne change jamais : slug en entrée, destination en sortie.
Générer le code court#
Si le slug est la clé, d'où vient-il ? Il existe deux approches éprouvées, et la plupart des raccourcisseurs utilisent l'une ou un mélange des deux.
La première est l'encodage en base62 d'un ID de base de données. Chaque nouveau lien reçoit un ID entier auto-incrémenté de la base de données. Vous encodez cet entier en base62, qui utilise les 62 caractères URL-sûrs a-z, A-Z et 0-9. L'ID 1 devient b, l'ID 125 devient un code à deux caractères, et ainsi de suite. La base62 est dense : trois caractères couvrent environ 238 000 liens, cinq caractères couvrent environ 916 millions, six couvrent environ 56 milliards. Les codes restent courts et, parce qu'ils se mappent un-à-un sur des IDs uniques, ils ne collisionnent jamais. La contrepartie est que les IDs séquentiels sont devinables, donc de nombreux systèmes mélangent ou décalent l'espace d'ID avant l'encodage.
La deuxième approche est la génération aléatoire. Choisir une chaîne aléatoire d'une longueur fixe depuis le même alphabet, puis vérifier dans la base de données qu'elle n'est pas déjà prise. En cas de collision, en générer une autre. Les collisions sont extrêmement rares à des longueurs raisonnables, donc la boucle de réessai ne se produit presque jamais. Les slugs aléatoires ne sont pas énumérables, ce qui est l'argument de sécurité en leur faveur.
Les slugs personnalisés, les brandés comme elido.me/soldes-printemps, s'appuient sur l'un ou l'autre schéma. L'utilisateur fournit la chaîne ; le raccourcisseur la valide pour les caractères autorisés et vérifie l'unicité par rapport au même index avant de la sauvegarder. Que le slug soit généré ou choisi à la main, il atterrit au même endroit : une colonne unique dans la base de données.
Où vivent les données#
Le mapping slug-vers-destination a besoin d'un endroit qui peut répondre à « vers quoi pointe ce slug » rapidement et de manière cohérente. Pour la source de vérité, cet endroit est presque toujours une base de données relationnelle. Elido utilise Postgres, avec le slug stocké comme une colonne unique indexée pour qu'une recherche soit une seule lecture par clé plutôt qu'un balayage de table. Postgres détient l'enregistrement canonique pour chaque lien, utilisateur et workspace.
Mais interroger Postgres à chaque clic individuel serait gaspilleur étant donné le ratio à lecture intensive. Une recherche de slug par clé dans Postgres prend généralement entre un et trois millisecondes, ce qui semble rapide jusqu'à ce que vous le multipliiez par le volume de clics d'un lien viral et que vous vous souveniez qu'une connexion à la base de données est une ressource finie. Donc les raccourcisseurs de production placent un cache devant la base de données. Le cache est là où la plupart des lectures sont réellement servies ; la base de données est le recours pour tout ce que le cache n'a pas encore.
Elido exécute un cache à deux niveaux devant Postgres. Le premier niveau est un cache LRU en cours de processus vivant dans le binaire de redirection lui-même, qui retourne une destination en quelques centaines de nanosecondes sans aucun saut réseau. Le deuxième niveau est un cluster Redis dans la même région, qui sert en moins d'une milliseconde. Seul un cold miss, un slug qu'aucun des deux niveaux n'a vu récemment, tombe jusqu'à un appel gRPC d'origine contre api-core, qui lit Postgres. Le taux de hit combiné sur les deux niveaux de cache se situe autour de 99,4%, donc la base de données est touchée sur environ une requête sur 167. L'analyse complète du comportement de ce cache, y compris sa politique d'éviction et les modes de défaillance que nous avons rencontrés, est dans notre article sur la stratégie de cache.
Ce qu'est réellement une redirection HTTP#
Une fois que le raccourcisseur a la destination, il doit la rendre au navigateur. Il le fait avec une redirection HTTP, qui est juste un type spécifique de réponse. Au lieu de retourner du contenu de page avec un 200 OK, le serveur retourne un code de statut 3xx et un en-tête Location nommant la vraie URL. Sur le réseau, la réponse est petite :
HTTP/1.1 302 Found
Location: https://shop.example.com/spring-collection
Content-Length: 0
Le navigateur lit le code de statut, voit un en-tête Location, et envoie immédiatement une nouvelle requête vers cette adresse. Pour la personne qui clique, cela ressemble à une seule navigation ; sous le capot, ce sont deux requêtes, avec le lien court agissant comme une recherche rapide dans un annuaire au milieu. La sémantique de chaque code 3xx est définie dans la RFC 7231, et le guide Mozilla sur les redirections HTTP est la référence pratique la plus claire sur ce que fait chaque code.
Le corps est vide car il n'y a rien à rendre. Tout le contenu est la ligne de statut et l'en-tête. C'est en partie pourquoi les redirections sont peu coûteuses à servir : il n'y a pas de modèle, pas de jointure de base de données pour le contenu, pas de balisage. Résoudre le slug, définir un en-tête, envoyer.
301 vs 302 : le choix qui détermine vos analyses#
C'est là où les raccourcisseurs prennent silencieusement une décision que la plupart des utilisateurs ne voient jamais mais qui détermine si leur lien est modifiable et traçable. Le code de statut de redirection n'est pas une formalité. Les deux options courantes se comportent très différemment.
Un 301 Déplacé Définitivement indique au navigateur, et à chaque proxy et CDN entre vous et le serveur, que ce lien court pointera toujours vers le même endroit. Donc ils le mettent en cache. Un 301 est stocké de manière agressive. La prochaine fois que le visiteur clique sur ce lien court, son navigateur peut le résoudre depuis le cache et ne jamais contacter le raccourcisseur du tout. C'est parfait pour économiser un aller-retour, et c'est une catastrophe pour un outil de liens, car deux choses se brisent. Premièrement, les analyses deviennent aveugles : les clics servis depuis le cache du navigateur n'atteignent jamais votre serveur, donc ils ne sont jamais comptés. Deuxièmement, la destination est effectivement figée. Si vous changez l'endroit où le lien pointe, quiconque a déjà mis en cache le 301 continue d'atterrir sur l'ancienne adresse jusqu'à l'expiration de son cache, que vous ne contrôlez pas.
Un 302 Found (et son cousin plus strict 307 Temporary Redirect) indique au navigateur que c'est temporaire : revenez demander à nouveau la prochaine fois. Le navigateur ne met pas en cache le mapping, donc chaque clic re-demande le lien court au serveur. Cet aller-retour supplémentaire est exactement ce que veut un outil de liens. Chaque clic atteint votre infrastructure, donc chaque clic est comptable, et parce que le serveur résout la destination fraîche à chaque fois, vous pouvez changer l'endroit où un lien pointe et faire prendre effet la nouvelle cible au prochain clic. Le coût est un aller-retour réseau par clic, qu'un edge bien construit maintient dans les millisecondes à un chiffre.
C'est pourquoi Elido utilise par défaut un 302. Les destinations modifiables et les données de clics précises sont tout l'intérêt d'un lien géré, et un 301 sacrifie les deux pour une optimisation de cache que vous ne voulez généralement pas. La RFC 7231 précise qu'un 301 est mis en cache par défaut alors qu'un 302 ne l'est pas, à moins que les en-têtes ne le disent autrement, ce qui est précisément le comportement que les deux cas d'usage réclament. Il existe des cas étroits où une redirection permanente est correcte, une vraie migration de domaine, par exemple, mais pour les liens courts traçables et modifiables, la redirection temporaire est le bon défaut.
Mise en cache à l'edge pour une faible latence#
Une redirection est synchrone et bloquante. Le navigateur du visiteur s'arrête sur le lien court jusqu'à ce que la redirection arrive, et seulement alors peut-il commencer à charger la page qui compte vraiment. Chaque milliseconde passée à résoudre le slug est une milliseconde ajoutée à l'attente du visiteur. C'est pourquoi les raccourcisseurs sérieux poussent la recherche aussi près du visiteur que possible.
Elido exécute le gestionnaire de redirection dans des points de présence edge à Francfort, Ashburn et Singapour, avec le trafic routé vers le plus proche. Le gestionnaire est écrit en Go sur fasthttp, choisi parce que son chemin de requête sans allocation garde les pauses de ramasse-miettes prévisibles sous une charge soutenue. Combiné avec le cache en mémoire, cela maintient les redirections à un p95 inférieur à 15ms sur un cache hit, mesuré au POP : environ 4,8ms de médiane à Francfort, montant jusqu'à environ 14ms p95 à Singapour où la géographie est plus large. La majeure partie de ce budget est le transit réseau physique, la distance inévitable entre le visiteur et le POP le plus proche, qui est la partie que vous ne pouvez pas optimiser en logiciel. Nous avons documenté le budget de latence complet et comment chaque région se mesure dans l'article sur le p95 sous 15ms.
Placer la recherche à l'edge plutôt qu'à un seul serveur central est la différence entre une redirection qui semble instantanée et une qui ajoute un délai visible. C'est aussi pourquoi le routage edge anycast bat une configuration DNS seulement pour cette charge de travail, une comparaison que nous approfondissons dans edge POPs versus routage DNS seulement. La version courte : le réseau fait la géographie, et le cache fait la vitesse.
Compter le clic sans ralentir la redirection#
Un raccourcisseur qui ne ferait que rediriger serait un service de redirection. Ce qui en fait un outil de gestion de liens, c'est qu'il compte chaque clic et vous dit qui a cliqué, d'où, sur quel appareil. La partie difficile est de faire cela sans faire attendre le visiteur.
La réponse est de découpler complètement les deux. Quand le gestionnaire de redirection résout un slug, il envoie la réponse 302 immédiatement. Enregistrer le clic se produit après, en mode fire-and-forget. Le gestionnaire ajoute un événement de clic - slug, horodatage, une IP tronquée, un hash de user-agent - dans une file de messages et continue. Il n'attend pas que l'écriture confirme. Si la file est brièvement indisponible, le clic est perdu plutôt que la redirection ne soit retardée ; nous avons délibérément décidé que perdre un clic lors d'une défaillance d'infrastructure est acceptable et qu'échouer une redirection ne l'est pas.
Elido utilise Redpanda comme cette file. Un consommateur séparé, l'ingéreur de clics, lit les événements de la file et les écrit dans ClickHouse, une base de données en colonnes construite pour le type de charge de travail à volume élevé d'ajout et d'agrégation qu'est l'analyse des clics. La redirection du visiteur s'est déjà terminée des millisecondes plus tôt ; la ligne d'analyse atterrit quelques secondes plus tard, complètement hors du chemin chaud. Nous expliquons la conception de la file dans l'ingestion de clics fire-and-forget et pourquoi un magasin en colonnes bat Postgres pour cela dans pourquoi nous utilisons ClickHouse pour les analyses de clics.
Ce découplage est la raison pour laquelle vos analyses peuvent être détaillées sans être lentes. Le chemin de redirection reste léger parce qu'aucun comptage, scoring ou agrégation ne se produit pendant que le visiteur attend.
Mettre tout ensemble#
Un raccourcisseur d'URL, de bout en bout, est une courte séquence. Vous créez un lien, et le raccourcisseur stocke un mapping slug-vers-destination dans Postgres, générant ou validant le slug comme clé unique. Un visiteur clique, la requête atterrit au POP edge le plus proche, et le gestionnaire résout le slug depuis un cache en mémoire, tombant vers Redis puis vers la base de données seulement sur un miss. Il retourne un 302 avec la destination dans l'en-tête Location, pour que le clic soit comptable et que la destination reste modifiable. Puis il envoie l'événement de clic dans une file pour qu'un consommateur séparé le stocke, sans faire attendre personne.
Chaque pièce est individuellement simple. L'ingénierie est dans les ratios et les budgets : une charge de travail à lecture intensive qui veut un cache, un plafond de latence qui veut l'edge, et une exigence d'analyse qui veut rester hors du chemin chaud. Si vous voulez construire directement là-dessus, la fonctionnalité Smart Links expose la couche de règles, l'API et les SDKs vous permettent de créer des liens depuis du code, et la page solutions développeurs et les docs d'architecture edge-redirect vont plus en profondeur sur les pièces mobiles. Si vous pesez un outil plutôt que d'en construire un, nos articles sur ce qu'est un raccourcisseur d'URL et si les raccourcisseurs d'URL sont sûrs couvrent le terrain du côté utilisateur, et la page de tarification indique où se termine le niveau gratuit.