shrl.io 是一个自托管的 URL 短链接服务,采用 Go 微服务架构,隐私优先——不存 IP,只存聚合统计。
shrl.io 用 Go 写了四个微服务:内部 API、公开认证服务、Redis 驱动的重定向器、分析 worker。PostgreSQL 做数据源,Redis 缓存链接并流式处理访问记录。前端是 SvelteKit。整个栈通过 Docker 部署,podman compose up -d 一条命令起来。

亮点特性
- 不存 IP。 访问者 IP 在生成地理位置后就丢弃,只保留聚合统计数据。访问者身份存为
(链接, 日期, IP+User-Agent 的哈希)——原始 IP 在日志里都找不到。相比大多数短链接服务把访问者数据当作商业模式,这个设计是刻意为之的。 - 重定向不碰数据库。 链接创建时 write-through 到 Redis 缓存,重定向请求只读 Redis,返回 302。数据库永远不在重定向的热路径上,延迟在亚毫秒级。
- 开放重定向防护。 拒绝回环地址、私有地址、链路本地地址。短链接服务天然容易被当作开放重定向攻击的跳板,这个小细节说明作者认真考虑过安全问题。
- 其他功能包括:自动生成的短码(6 位,剔除了 0/O/1/l 这些容易混淆的字符),浏览器内生成可下载 1024px 的 QR 码,团队协作(邀请码、共享链接所有权),按设备/浏览器/国家/地区/城市的访问分析,以及 6 个 UTM 参数分解。
系统架构
┌───────────────────┐
user (browser) ───────►│ frontend (Svelte) │ login + session cookie
└─────────┬─────────┘
│ proxies with the user's token
▼
┌──────────────┐
│ api │ Internal API, frontend-only
└──────┬───────┘
│ write-through (Link cache)
script / CI ── API key ──► ┌────────────┐
│ auth │ Auth API /v1, rate-limited
└──────┬─────┘
│ write-through (Link cache)
┌──────────┴──────────┐
▼ ▼
┌──────────────┐ ┌──────────────┐
│ PostgreSQL │ │ Redis │
│ source of │ │ Link cache │
│ truth │ │ Visit stream │
└──────────────┘ └──────┬───────┘
│ cache read
▼
visitor ─── GET /{code} ───► ┌──────────────┐
│ redirector │ ── 302 ──► Destination
└──────┬───────┘
│ Visit → stream
▼
┌──────────────┐ batch ┌──────────────┐
│ Redis │ ────────► │ worker │
│ Visit stream │ └──────┬───────┘
└──────────────┘ │ upsert rollups
▼
┌──────────────┐
│ PostgreSQL │
└──────────────┘