早年玩过微博的人,大概还记得一个细节:一条微博只给140个字,贴条商品链接进去,光链接就能吃掉小一半字数,真正想说的话反而没了地方。短信场景更现实——按条计费,链接一长,一条短信硬生生被拆成两三条发出去,钱花得冤枉,收信的人对着一串碎消息也头疼。短网址系统就是在这种环境里长大的:把动辄一两百个字符的长链接,压成十几个字符的短串,别人点开这个短串,浏览器再自动跳回原来的长地址。
听起来像个讨巧的小工具,它做的事也确实单纯:生成短码、记住对应关系、负责跳转。难就难在,这三件事一旦放到海量请求下,要做得又快又稳,就没那么单纯了。

先看整个流程。系统拿到一条长链接,用某种算法算出与它唯一对应的短码,再把"短码—长链接"这对映射写进数据库。等有人点开短网址,服务器拿着短码去库里查出原始链接,返回一个重定向响应,浏览器顺着跳到目标页面——整套动作通常在几十毫秒内完成,用户几乎无感。顺带一提,重定向用301还是302是有讲究的:302是临时跳转,每次访问都会经过短链服务器,点击统计才准;301是永久跳转,浏览器可能直接把目标地址缓存下来,之后的点击就绕开了服务器。所以大多数短链服务默认走302,为的就是保住数据。
短码怎么生成?主流做法就两派。
一派走哈希路线:用MD5、SHA这类算法把长链接算出一个哈希值,截取其中一段,再转成62进制字符串——所谓62进制,就是拿数字加大小写字母共62个字符来编码,这样短码才能又短又能装。这条路的好处是简单直接,同一条链接算出来的结果恒定,不用查库就能预判。麻烦出在冲突上:短码截得越短,撞车概率越高,两条毫不相干的链接算出同一个短码并不稀奇。通行的解法是,冲突了就给原链接加点"盐"重新算一遍,或者落库时比对一下已存的原始链接,发现不是同一条,就换个种子再来。

另一派更省事:发号。每来一条新链接就发一个自增ID,把ID转成62进制,就是天然不重复的短码,干净利落。单机时代这么干毫无压力,可一旦请求量上来、服务器不止一台,号怎么发就成了学问——各台机器各发各的,早晚撞号。常见的思路是搭一个统一的发号服务,每台机器每次领走一段号码慢慢用;或者采用雪花算法这类方案,让不同节点各自发号也互不冲突。和哈希相比,发号没有冲突重试的损耗,短码还能从短到长自然增长,系统早期生成的短码短得惊人——不少短链服务偏爱这条路,原因就在这里。
短网址带来的好处,省字符只是最表面的一层。一条挂着utm_source、utm_medium一连串参数的原始链接,贴出来又长又乱,看着就不太像正经东西,用户未必敢点;换成干净的短链,起码视觉上清爽,信任感也好一些。参数藏进短码背后,还顺带免去了被人随手篡改的麻烦。
真正被低估的价值在数据。同一个活动,在朋友圈、社群、短信渠道各投一条不同的短链,哪边点击多、用户用什么设备访问、大致来自什么地区,后台一目了然。投放效果好不好,不用再拍脑袋判断。对做运营的人来说,短链算得上是成本最低的渠道追踪工具之一。
应用场景也因此比想象中宽。社交媒体发帖、短信营销是刚需,自不必说,邮件里同样用得上。还有一个常被忽略的地方是二维码——二维码里存的就是链接本身,链接越长,码点排得越密,印小了容易扫不出来;链接短了,图案就稀疏,容错率跟着上去。所以线下海报、产品包装、名片上的二维码,底下垫着的往往也是一条短链。
这条路大厂早就走过。新浪的t.cn跟着微博生态普及开来,百度的dwz.cn也服务了很多年,谷歌早年同样推出过goo.gl。它们的共同点在于:功能听上去一句话就能说完,背后却要扛住天量的跳转请求,是不折不扣的基础设施。
当然,真正上线之后,磨人的问题才刚开始。除了前面提到的哈希冲突和发号难题,性能压力是躲不掉的:一条热门短链可能短时间内被点击成千上万次,每次跳转都查数据库,库迟早被打垮,所以热点映射基本都会塞进缓存,让绝大多数请求根本碰不到磁盘。数据越攒越多,分库分表、冷热分离也得排上日程。还有一层麻烦在安全上:短链天然遮蔽了真实地址,很容易成为钓鱼链接和垃圾信息喜欢套用的壳。正经做服务的平台,多少都得在内容检测和风控上花功夫,否则域名信誉很快就会被拖垮。

所以短网址这东西,入口小,门道不少。用户看到的是十几个字符的短串,背后撑着的却是算法、存储、缓存、风控一整套配合。互联网里这类"小而重"的服务其实还有不少,短链算是其中把"简单功能做扎实"演示得很完整的一个例子。

今すぐログイン