ARTICLE · 1145791
【短网址系统源码】都以为短链拼的是算法,没想到拼的是归属
SOURCE REVIEW · 源码拆解
“
短链拼的是算法,还是归属
本文看点
01
归属在哪
02
两段路径
03
三条路
VERDICT · OWNERSHIP
判断:设计重心在归属,不在算法
后台点开生成页,粘一条带着 utm_source、utm_campaign、spm 的一长串推广地址,点回车。屏幕上跳出来的东西长得这样:https://你的域名/0810a7/tlWl6y。

大多数人看到的是「短了,能用了」。真正该多看一眼的是它有两段——第一段 0810a7 区分用户,第二段 tlWl6y 才是短码。
这个细节决定了这套系统的全部取舍。短链的算法部分早被做烂了,真正拉开差距的地方是短码归谁所有。
我给的判断是:这套源码的设计重心压根不在「怎么把长链变短」,而在把命名空间从全局下沉到每个用户。作者自己也说了,这是按个人需求自建的,偏向自己用起来顺手。
取舍说清:短码好不好看,这套系统主动让掉了,换来的是各扫各的巷子,互不打架。划不划算,取决于你有没有第二位用户。
DESIGN · NAMESPACE
第一层:把用户写进路径第一段
公共短链服务的老问题是短码全局唯一。数据库里一根唯一索引压在整个短码字段上,来了新请求先查一遍有没有人占过,占了就换码。

业内常规解法有两种:把用户 ID 掺进哈希一起算,或者换成雪花那种分布式唯一 ID 编成 62 进制。都能跑,但有个共同毛病——用户这个维度被塞进了码里,看不出来。

这套系统换了个做法:干脆让路径自己带。域名后面第一段就是用户标识,第二段才是短码。查的时候两级定位,命中就跳。
「同一串 tlWl6y,在 0810a7 名下是甲的那条链接,在 66b2c9 名下是乙的另一条。互不干涉。」
这才是这个格式真正的效果——数据库里的唯一约束跟着降级了,从「短码唯一」变成「用户内短码唯一」。索引是复合的,冲突面直接小掉一个量级。
就一段路径。
代价也摆在这儿:用户标识明晃晃写在 URL 里,谁都能看见、都能改。适合自建自用,不适合直接对外做成公共短链服务。
DESIGN · SHORTCODE
第二层:短码只有三条路可走
把短码怎么生成这件事摊开,其实只有三条路。先说哈希截断:对长链做哈希取前几位,撞了就追加随机串重算。优点是不依赖编号器,同一个长链天然稳定;缺点是碰撞处理在数据量上来之后会越来越烦,通常还要配布隆过滤器先挡一道。

第二条是自增编号转 62 进制。62 个字符是数字加大小写字母,7 位就是约 3.5 万亿种组合,容量上完全够用,而且天然无碰撞。代价有两个:编号连续,短码可猜;以及依赖一个全局编号器。
第三条是预生成码池:离线批量造几百万个随机码存进 Redis 集合,谁要就弹一个,用掉再补。请求路径上完全不用做唯一性检查,工程上最干净,代价是要养一个补池的进程。
撇开算法不管短链系统里另一个一次设定、终身不同的选择:301 还是 302。
301 永久重定向
浏览器第一次跳完就缓存住,之后根本不回你的服务器。快,但点击统计直接没了,目标地址改不了。
302 临时重定向
每次点击都回服务器问一遍。慢一点,但统计能记、目标能改、过期能收。
要数据就 302,不要数据就 301。这件事没有折中方案,因为它是给搜索引擎的一个明确声明:301 会把权重交给目标页并让它成为规范地址,302 则把短链自己留在索引里。多数带统计的短链服务默认给 302,就是为了把统计这条命脉攥在自己手里。
DESIGN · IDEMPOTENT
第三层:同码不重复入账
作者列的第一条特点,说的不是玩法,是幂等:同一个用户,把同一条长链接提交两次,返回的是同一个短码,不会多出一条记录。
这件事看起来像省事,实际省下的是三样东西。数据库不会因为反复粘贴而膨胀;统计面板不会被自己人刷出重复数据;短码空间不会在自己手里被无意义消耗。
实现路径不神秘,先查后插,或者给「用户+长链」建唯一索引、插冲突了回查那一条。很多自建的小工具就是漏掉这一步。
短码放行之后,跳转才是每次访问都要付钱的地方。短链服务读多写少的比例很极端——发十条链接,可能换来十万次点击。每次跳转都查一次数据库,这道开销能吃掉大半响应时间。
把映射关系缓存在 Redis 里是标准解法:先查缓存,命中直接返回;没命中再落到数据库,顺手把这条写回缓存。跳转是个轻请求,别让它在业务库门口排队。
BOUNDARY · RISK
第四层:什么情况下这套不划算
把上面的判断反过来问一次:如果这套系统只有你一个人用,这套设计就是纯负担。多一段路径、多一层复合索引,换来的是你根本用不上的隔离能力。判断值不值得,看你有没有第二位用户,仅此一条。
短码空间还有一层风险。短码本质是密钥空间,如果生成规则偏弱——纯数字、六位、连续递增——几千到几百万次请求就能把整个空间跑完,里面存着的原始长链接会被翻出来。统计这类需要看来源的短链,还要额外考虑访问者的隐私边界。
再往上一层是用途风险。短链把真实目标藏起来了,点之前看不到后面是什么。有资安机构统计过某年前九个月的钓鱼威胁指标,榜单前十里过半是常见短网址服务;更麻烦的是同一条链接可以按访问者的浏览器、地区分不同的目标,安全设备扫出来是正常页,人点进去是另一回事。
所以接手的顺序是:先定 301 还是 302,先确认短码生成规则够不够散,再决定要不要开放注册。这三件事定错了,后面加功能都救不回来。
到手第一步还是那件老事:审后门。这套系统要盯三处——生成接口有没有登录态校验、短码查询能不能被遍历、跳转目标有没有做协议白名单(只放行 http 和 https,file、javascript 这类一律挡掉)。
最后留一个问题给你想:如果让你在自己的短链上再加一层,你会先做过期时间,还是先做访问来源统计?这两个的先后顺序,其实决定了用户为什么愿意点第二次。
第二条特点更直接:不同用户可以生成相同的短码。
这解掉的是公共短链服务里最烦人的一类冲突。设想两个运营都想用 promo 这个码——在全局唯一的系统里,后一个只能干瞪眼,或者被迫加后缀。用户段一分开,这事就不存在了:各定各的。
作者给的说法是「便于用户操作设置指定短码,免除了不同用户间抢占指定短码的矛盾」。这句写得很实在,抢占冲突是这类系统里最常见的客诉来源,靠架构消掉,比靠客服解释划算得多。
但反过来也得认:短码一旦允许跨用户重复,它就不再是全局唯一的资产。你没法再靠「这个码是我的」来保护品牌词。这也解释了为什么这套设计更适合自用而不是开放注册。
冲突没了。
资源来源:源码库 bbbb.bid/37440.html关注星标公众号不定期分享各种源码「回复消息」查看原始资源