系统设计:短链服务

Authors
  • avatar
    Name
    小明&小艺
    Twitter

背景

短链接的现实生活中比较常见,比如我们接受到的广告短信、微信分享、二维码链接等。 其优势是

  • 链接简洁,可节省字数,利于宣传推广,而且微信支付 API 会限制链接长度
  • 可隐藏短链后的内容,便于动态修改
  • 生成的二维码不密集
  • 可定制链接,增强链接的标识度

基本原理

将短链标识,传递给服务器,服务器匹配后返回长链接。

这里核心的内容主要有:

  • 短链标识设计
  • 链接转发
  • 性能要求高

标识设计

标识主要考虑的因素有容量和字符集以及长度。

我们希望能用尽可能短的字符表示尽可能大的容量。

以 UUID 为例子,如果用随机字符+时间戳+用户 ID+随机数的形式,那可能会是这样子的:1_ec3665fd60679de5f08c55a9e73533941631246492968

这显然是太长了,不适合在短链的情景。那有办法变短么?回归到计算机的原理,数据都是用二进制存储的,不难发现以下规律:

二进制:111111111111 四进制:333333 八进制:7777

随着进制的增加,字符长度在变短。而在位数相同的情况下,进制越高,能表示的访问就越大,相当于容量增加了。所以短链更适合用高进制来表示。

通常可用的字符集有 0-9,a-z,A-Z,三者混合而成,加起来一共 62 个字符,因此可以用 62 进制来形成标识。

位数个数区间
1 位620-61
2 位38440-3843
3 位23w0-238327
4 位1400w0-14776335
5 位9.1 亿0-916132831
6 位568 亿0-56800235583

基本上 6 位就够用了。

链接转发

需要实现的效果是访问短链,系统自动跳转到长链上。熟悉计算机网络的大家都知道 301 和 302 都有重定向的功能,那这里该怎么选择呢?

301 和 302 的区别:

301 永久重定向,即浏览器只需要第一次请求拿到长链接后,下次再去访问这个短链就不会向短网址服务器请求了,而是直接从浏览器的缓存里拿。这样可以提高浏览器的访问速度,但是也有一个问题,就是如果我们想统计活动链接的访问数据的话就无从下手了。或者是这个活动结束了我想删除访问入口,但由于浏览器缓存可能还会导致有用户访问到。所以我们一般不使用 301。

302 临时重定向,即每次访问短链都会去请求短网址服务器(除非响应中用 Cache-Control 或 Expired 暗示浏览器缓存),这样就便于 server 数据监控,所以虽然用 302 会给 server 增加一点压力,但明显是利大于弊的。

所以一般为了确保链接的可控性,都是选择 302 的跳转方式。

高性能

短链一般是服务于多个业务场景,具体性能要求有多高,可以根据各个公司的业务场景来决定。

方案 1:redis+nginx+数据库

采用服务化的方式,构建短链服务中心,负责长短链的转换,缓存的管理等功能。其它系统需要使用相关功能时,统一调用短链服务。

缓存设计: 1)因为缓存只用来查询,而且需要满足高流量要求,所以采用 redis 来存储数据

2)数据结构:key=短链码 value=原始链接

3)因为长短链对照数据不存在修改,所以正常数据有效期设置为永久存在。

4)缓存更新模式使用主动推送,在数据新增的时候直接推送到 redis 集群;同时提供数据全量更新的接口,以供手动推送缓存数据或者每天自动更新。

5)因为可能存在热点缓存的问题,使用短链服务的本地内存缓存热点数据,采用 LRU 去更新热点缓存,减少一次网络 io,提高性能

这种方式,高并发情况下只能通过横向服务器节点进行扩容。

方案 2:OpenResty + MySQL

OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

OpenResty® 通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将 Nginx 有效地变成一个强大的通用 Web 应用平台。这样,Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。

OpenResty 定制了 nginx,集成了 redis,支持编写 lua 脚本,其高性能主要取决于支持在 ng 层配合缓存和数据库做业务逻辑处理。减少了很多不必要的中间接,做到快速相应。

功能设计

主要分为 B 端和 C 端,其中 B 端是做短链配置管理,C 端是提供短链转换服务。

B 端功能:

  • 短链转换:访问后重定向到长网址。

C 端功能:

  • 短链管理:提供将长网址转换成短链的功能,支持设置短链的有效时长,启用、禁用短链,修改短链的映射。支持单个和批量以及接口方式创建。
  • 访问日志分析:分析 nginx 的访问日志,将访问记录保存至 MySQL。
  • 访问统计:统计访问记录,获取访问的 IP、客户端代理,从而提炼并统计访问的区域、设备等信息。
  • 多域名管理:支持配置不通的业务域名,避免因业务公用导致连带问题