$ 如何设计一个短链接服务
$ 实现一
正确的原理就是通过发号策略,给每一个过来的长地址,发一个号即可,小型系统直接用mysql的自增索引就搞定了。如果是大型应用,可以考虑各种分布式key-value系统做发号器。不停的自增就行了。第一个使用这个服务的人得到的短地址是http://xx.xx/0 第二个是 http://xx.xx/1 第11个是 http://xx.xx/a 第依次往后,相当于实现了一个62进制的自增字段即可。
62进制如何用数据库或者KV存储来做?
如何保证同一个长地址,每次转出来都是一样的短地址?
用key-value存储,保存“最近”生成的长对短的一个对应关系。注意是“最近”,也就是说,我并不保存全量的长对短的关系,而只保存最近的。比如采用一小时过期的机制来实现LRU淘汰。
如何保证发号器的大并发高可用 ?
我们可以退一步考虑,我们是否可以实现两个发号器,一个发单号,一个发双号,这样就变单点为多点了
跳转用301还是302?
这也是一个有意思的话题 301是永久重定向,302是临时重定向。短地址一经生成就不会变化,所以用301是符合http语义的。同时对服务器压力也会有一定减少。 但是如果使用了301,我们就无法统计到短地址被点击的次数了。而这个点击次数是一个非常有意思的大数据分析数据源。能够分析出的东西非常非常多。所以选择302虽然会增加服务器压力,但是我想是一个更好的选择。
$ 实现二
1,随机生成短链接 2,使用 Bloom Filter 检测这个短链接是否存在 3,假如存在返回步骤 1
$ 实现三
YOURLS
$ 安全性
按照算法从0-61都是1位字符,然后2位、3位...这样的话很容易被人发现规律并进行攻击,当然防御手段很多,请求签名之类的安全验证手段不在本文讨论范围内。 首先计数器可以从一个比较大的随机中间值开始,比如从10000开始计数,他的62进制是 2Bi 3位的字符串; 然后采用一些校验位算法(比如Luhn改进一下),计算出1位校验位拼接起来,4位短码,这样可以排除一定的安全风险; 再加点安全料的话,可以在62进制的转换过程中把排序好的62个字母数字随机打乱,比如ABCD1234打乱成1BC43A2D, 转换的62进制也就更难hack了; 最后如果仍不放心,还可以在某些位置(比如1,3,5)插入随机数,让人无法看出规律来也可以达到良好的效果。