用SHA256而非MD5或rand.String生成短码,因其确定性高、6位Base62理论组合达56亿,碰撞率低于0.01%,且支持URL标准化与加盐重试防冲突。

为什么用 sha256 而不是 md5 或 rand.String 生成短码
短码冲突是服务上线后最隐蔽的雪崩点——看似随机的 rand.String(6) 在千万级链接下碰撞概率超 15%,而 md5 前6位截取同样不安全,已知有公开碰撞案例。用 sha256 对原始 URL 做哈希再 Base62 编码,能保证确定性+低冲突:sha256("https://example.com/very-long-path") 每次输出唯一,且 6 位 Base62 码理论支撑约 56 亿组合(62⁶),实际可用率在 99.99% 以上。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 别直接用
sha256.Sum256().String()—— 它带 `sha256` 前缀和空格,要用sum256.Sum(nil)[:6]取字节再转 Base62 - 如果 URL 含查询参数顺序不固定(如
?a=1&b=2vs?b=2&a=1),先做参数键值排序并拼接标准化字符串,否则相同语义 URL 会生成不同短码 - Redis 中用
HSET url_map short_code original_url存映射,但首次写入前必须HEXISTS url_map short_code检查是否已被占用,冲突时对哈希加盐重算(比如追加时间戳毫秒)
Redis 的 HSET 和 SETNX 该选哪个存短码
HSET 适合把所有短码存在一个 Hash 结构里(url_map),省 key 数量、方便批量查;SETNX 是单 key 单值,天然支持原子写入防覆盖。但真实场景中两者都不够——HSET 无法原子判断“短码未存在且写入”,SETNX 则没法高效反查(比如统计总短链数)。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 用
SETNX存短码到独立 key(如short:abc123),值设为原始 URL,同时用INCR url_counter计数,这是最稳妥的写入路径 - 额外维护一个 Hash:
HSET url_reverse original_url abc123,用于防止同一长链重复生成多个短码(查这个 Hash,命中就直接返回已有短码) - 千万别用
GET + SET两步操作代替SETNX:Go 的 goroutine 并发下必然出现竞态,两个请求同时查到“不存在”,然后都写入,导致覆盖或重复
Go HTTP 路由里怎么安全解析 /aBc123 这类短码路径
URL 路径里短码可能含大小写字母+数字(Base62),但 Go 的 http.ServeMux 默认不区分大小写路由匹配,而且没做长度/字符集校验,直接透传给 handler 容易被构造恶意路径绕过(比如 /../../../../etc/passwd)。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 用
http.StripPrefix去掉根路径后,立刻用正则^[A-Za-z0-9]{4,8}$校验短码格式,长度卡死在 4–8 位,太短易撞,太长影响传播 - 不要用
strings.Split(r.URL.Path, "/")手动切分——r.URL.Path可能被客户端双重编码(如%252F),应优先用r.URL.EscapedPath()再解码 - 查 Redis 前加一层本地 LRU 缓存(如
groupcache或bigcache),避免高频短码反复打 Redis;但注意缓存击穿:用SETNX加锁 + 回源重建,而不是简单空值穿透
短链跳转时如何避免 301 导致浏览器缓存错误目标
第一次访问 https://s.co/xyz 返回 301 Moved Permanently 到目标站,浏览器会永久记住这个跳转。如果运营 later 修改了目标 URL,用户再点旧短链,浏览器直接跳转老地址,根本不会请求你的服务——这是最常被忽略的线上故障根源。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 一律用
302 Found,它不被浏览器强制缓存,每次都会重新请求你的服务端 - 如果追求 SEO 或想降低回源压力,可对「稳定不变」的短链(比如活动页)单独支持
301,但必须加配置开关,并在 Redis 里存字段标记:HSET url_meta abc123 "redirect_type:301" - 响应头务必加
Cache-Control: no-store, must-revalidate,哪怕用了302,也能防止中间 CDN 或代理缓存跳转响应
短码生成和跳转看似简单,真正卡住人的永远是并发写入时的冲突处理、URL 标准化边界、以及缓存与重定向语义的耦合——这些地方一漏,服务上线三天就出问题。










