短链设计方案总结

为什么用短链

所谓“短链”,就是短的链接。短链设计,就是设计一种方案,将原本很长的一串链接转换成一个非常短的链接。当用户访问这个短连接时,会自动跳转到真实链接对应的网页。

那么使用短链有什么好处呢?

  1. 链接变短,有时候我们要限制内容长度,使用长链接的话会占用过多字数,导致可编辑文字变少。

    • 比如,微博平台,限定只能发140个字,如果使用长链接,可能直接占用了50个字,那相当于只能编写90个字
    • 再比如,短信发文有长度限制,如果使用长链接,一条短信可能要拆分成好几条,不仅体验极差,还要花更多的钱
  2. 二维码,我们经常需要将连接转成二维码的形式分享给他人,如果使用长链的话,生成的二维码十分密集难以识别,短链就不存在这个问题。

  3. 无法识别,链接太长,有些平台无法自动识别为超链接,只能识别其中一部分。

短链实现方案

对于一个短链方案,我们需要考虑的有两点:

  1. 如何生成一个短链,短链要和长链一一对应?
  2. 用户访问短链时,如何跳转到其对应的长链?

短链生成

  1. 哈希算法

    一种简单直白的方法就是使用哈希算法,将长链映射成一小段字符串,然后用数据库或者Redis存储长链和短链之间的对应关系避免hash冲突。

    一个经典的hash算法是谷歌出品的MurmurHash算法,它是一种非加密型哈希函数,适用于一般的哈希检索操作。MurmurHash提供了两种长度的哈希值,32bit和128bit,我们可以根据数据量选择合适大小。

    另外,为了进一步缩短链接长度,我们可以将10进制的数字转成62进制(大写字母+小写字母+数字)。

    这样,使用hash算法实现的短链方案思路大致如下:

    1. 将长链,使用MurmurHash算法计算hash值;
    2. 用生成的hash值去mysql或者redis中查看,是否产生hash冲突。
      • 如果表中不存在,说明没有冲突,将(真实url,短链)存放到表中
      • 如果表中存在,说明产生hash冲突, 此时在长串上拼接一个自定义好的字段,比如「DUPLICATE」,然后再对接接的字段串「lurl + DUPLICATE」做第一步操作,如果最后还是重复呢,再拼一个字段串啊,只要到时根据短链取出长链的时候把这些自定义好的字符串移除即是原来的长链。
      • 另外,当数据量非常大时,可能频繁发生冲突,此时可以使用布隆过滤器存储已经生成的短链。每次查数据库前,先用布隆过滤器判断是否产生冲突,减少查表次数。
  2. 自增id

    其实和哈希差不多,我们可以维护一个ID自增生成器,比如1,2,3这样的整数递增ID,当收到一个长链转短链的请求时,ID生成器为其分配一个ID,在将其转化成62进制,拼接到固定域名后面,就可以作为最终短链了。

    在高并发情况下, ID 自增生成器的的 ID 生成可能会系统瓶颈,所以它的设计就显得尤为重要。 我们可以考虑分布式发号器、Redis、Snowflake等方案。

短链跳转

当我们访问短链时,是如何跳转到其对应的长链的?大致流程如下图所示:

客户端使用短链访问短网址服务器时,服务器返回重定向状态码301或者302以及长链地址。

那么问题来了,301 和 302 都是重定向,到底该用哪个,这里需要注意一下 301 和 302 的区别

  • 301,代表 永久重定向,也就是说第一次请求拿到长链接后,下次浏览器再去请求短链的话,不会向短网址服务器请求了,而是直接从浏览器的缓存里拿,这样在 server 层面就无法获取到短网址的点击数了,如果这个链接刚好是某个活动的链接,也就无法分析此活动的效果。所以我们一般不采用 301。
  • 302,代表 临时重定向,也就是说每次去请求短链都会去请求短网址服务器(除非响应中用 Cache-Control 或 Expired 暗示浏览器缓存),这样就便于 server 统计点击数,所以虽然用 302 会给 server 增加一点压力,但在数据异常重要的今天,这点代码是值得的,所以推荐使用 302!

参考资料

  1. https://juejin.cn/post/6844904090602848270#heading-2
打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2021-2022 Yin Peng
  • 引擎: Hexo   |  主题:修改自 Ayer
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信