短链接服务的设计与实现

欢迎关注微信公众号:coder家园
更多技术讨论尽在coder家园。

业务背景

现在很多应用都提供短链接的形式,短链接较长链接比较,有阅读起来友好、容易复制优势。

短链接服务核心部分包括:

(1) 长链接转短链接的算法

(2) 对应关系持久化,方便长链接和短链接互相查询

短链接重定性流程

http://blog.csdn.net/poem_qianmo/article/details/52344732转成短链接为:http://t.cn/RtFFvic
用户通过短链接访问长链接过程如下:

  • 用户访问短链接:http://t.cn/RtFFvic
  • 短链接服务器t.cn收到请求,根据URL路径RtFFvic获取到原始的长链接:http://blog.csdn.net/poem_qianmo/article/details/52344732
  • 服务器返回302状态码,将响应头中的Location设置为:http://blog.csdn.net/poem_qianmo/article/details/52344732
  • 浏览器重新向http://blog.csdn.net/poem_qianmo/article/details/52344732发送请求
  • 返回响应

长链接转短链接算法

三只松鼠

长链接转短链接的算法根据实际需要可以选择支持如下特性:

(1) 高可用,服务可以部署到多台服务器上不会出现单点故障问题。

(2) 长链接和短链接1:1映射。一方面可以解决存储资源,另外也可以方便点击统计等功能实现。

(3) 少碰撞。生成短链接性能不会随着已生成短链接数量增加而线性增加。

比较常用的算法有:

  1. 随机算法 & hash算法(MD5)
  2. 发号器 & 进制转化
  3. 预生成 & 访问分配

随机算法

随机算法原理是根据长链接随机生成字符串,然后将字符串映射到[0-9][a-z][A-Z]集合上。

为了减少随机造成的冲突,很多公司会使用微博的短链接生成算法的变种。

算法一

1)将长网址md5生成32位签名串,分为4段, 每段8个字节;
2)对这四段循环处理, 取8个字节, 将他看成16进制串与0x3fffffff(30位1)与操作, 即超过30位的忽略处理;
3)这30位分成6段, 每5位的数字作为字母表的索引取得特定字符, 依次进行获得6位字符串;
4)总的md5串可以获得4个6位串; 取里面的任意一个就可作为这个长url的短url地址;

这种算法,虽然会生成4个,但是仍然存在重复几率,下面的算法一和三,就是这种的实现.

算法二

62个可选元素在随机选两个组成长度为64的字符数组。

  1. 随机生成36位 0/1的随机数
  2. 36位分成6份,通过randomValue>>6以此获取低6位元素。
  3. (randomValue>>6) & 0x3F 获取对应的字符

算法二冲突的概率为1/646=1/236。

发号器 & 进制转化

算法三

  1. 首先请求发号器生成不重复十进制数字
  2. 十进制数字转化成62进制

该算法能够支持62^6=500多亿条长链接。

发号器可以选择数据库自增ID,snake算法,redis等诸多实现。

预生成 & 访问分配

算法四

a-zA-Z0-9 这62位取6位组合,可产生500多亿个组合数量.把数字和字符组合做一定的映射,就可以产生唯一的字符串,如第62个组合就是aaaaa9,第63个组合就是aaaaba,再利用洗牌算法,把原字符串打乱后保存,那么对应位置的组合字符串就会是无序的组合。
把长网址存入数据库,取返回的id,找出对应的字符串,例如返回ID为1,那么对应上面的字符串组合就是bbb,同理 ID为2时,字符串组合为bba,依次类推,直至到达64种组合后才会出现重复的可能,所以如果用上面的62个字符,任意取6个字符组合成字符串的话,你的数据存量达到500多亿后才会出现重复的可能。

301还是302?

301永久跳转
302临时跳转

两者区别主要体现在2个方面:
(1) SEO优化

(2) 浏览器缓存

搜索引擎遇到301跳转时认为是永久跳转, 搜索引擎只会将新链接加到索引里。
当遇到302跳转时, 搜索引擎会同时索引老链接和新链接。

浏览器遇到301跳转时,会使用浏览器缓存,下次访问老链接时会直接访问新链接。当遇到302跳转时, 浏览器会认为临时跳转,新老链接都会被访问到。

因此, 为了统计到短链接访问次数, 一般使用302状态码进行跳转。

随机算法

参考:

  1. 短网址安全浅谈 https://security.tencent.com/index.php/blog/msg/126
  2. 微博URL短网址生成算法原理及(java版、php版实现实例)http://www.voidcn.com/article/p-ydjqllgt-ed.html

更多互联网故事和后端技术请关注公众号:coder家园 和个人主页(samdyli.github.io)。

发布了53 篇原创文章 · 获赞 16 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/gexiaochuan122/article/details/103929946