短链的好处
- 方便传播:太长的链接容易被限制长度
- 提升用户体验:短链接看着简洁,长链接看着容易懵
- 安全:不想暴露参数
- 统计分析:可以统一链接转换,当然也可以实现统计点击次数等操作
短链的原理
短链系统的核心原理是将长链接映射为一个短标识。当用户访问短链时,系统根据这个短标识找到对应的长链接,然后进行重定向。这就好比给一个复杂的地址起了一个简单的别名,通过别名就能找到真实地址。
需要注意的是,在使用短链系统时,重定向应该选择 302 状态码,而不是 301 状态码。若使用 301 状态码,浏览器存储了这个映射关系后,下一次访问就直接访问长链,而不是先重定向了,从而使得统计分析变少。
短链的生成
-
哈希算法:对长链接进行哈希计算,得到一个固定长度的哈希值。推荐 MurmurHash 算法,这种算法是一种非加密型哈希函数,适用于一般的哈希检索操作,目前 Redis,Memcached,Cassandra,HBase,Lucene 都在用这种算法。对于碰撞问题,最简单的一种思路是,如果发生碰撞,就给原始 URL 附加上特殊字符串,直到躲开碰撞为止。对于判断是否碰撞的方法,数据库的唯一索引 vs 布隆过滤器。
-
自增 ID:使用数据库自增 ID 作为短链标识。每生成一个短链,ID 自增 1。这种方式生成的短链具有唯一性,但 ID 可能会暴露系统的链接数量等信息。
-
随机字符串:生成一段固定长度的随机字符串作为短链。为了保证短链的唯一性,需要在生成后检查是否已存在。
短链存储
- 关系型数据库:如 MySQL、PostgreSQL 等,可以使用表来存储长链接和短链的对应关系,以及相关的统计信息。优点是数据一致性好,适合复杂查询;缺点是在高并发场景下性能可能受限。基本的数据信息如下,可能会根据需要增加一些补充信息,如创建短链的用户信息、IP 地址等等。
CREATE TABLE `url_map` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`long_url` varchar(169) DEFAULT NULL COMMENT '长链',
`short_url` varchar(10) DEFAULT NULL COMMENT '短链',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;- 非关系型数据库:像 Redis,以键值对的形式存储短链和长链的映射关系,读写速度快,适合高并发场景。但不适合复杂的统计分析操作。
长链合法性校验
如果是对外提供服务的短链系统,还需要对用户的原始长链接进行验证,以确保链接指向的是合法且可信任的目标资源。一般会考虑两个方面:
- 主域名合法性:我们会解析原始长链接,提取其中的域名信息。然后,我们会将这个域名与预先定义的合法域名列表进行比对,以确认链接是否指向了我们期望的域名。这样做可以有效地防止恶意链接或指向不安全网站的情况。
- 查询参数域名合法性:链接中的查询参数域名也可能影响到用户安全。我们也需要验证这些域名是否合法,以免引发潜在的安全风险。