• 短链系统设计


    短 URL 系统是怎么设计的?

    短网址(short URL)系统的原理及其实现

    全网最通俗易懂的【短链接】入门

    短链介绍

    把普通网址,转换成比较短的网址。比如:http://t.cn/RlB2PdD 这种,在微博这些限制字数的应用里。好处不言而喻。短、字符少、美观、便于发布、传播。

    百度短网址 http://dwz.cn/
    谷歌短网址服务 https://goo.gl/ 号称是最快的

    使用场景

    比如短信有字数限制啊,长链传播麻烦啊。

    短链跳转原理解析

    当我们在浏览器里输入 http://t.cn/RlB2PdD 时

    1. DNS首先解析获得 http://t.cn 的 IP 地址
    2. 当 DNS 获得 IP 地址以后(比如:74.125.225.72),会向这个地址发送 HTTP GET 请求,查询短码 RlB2PdD
    3. http://t.cn 服务器会通过短码 RlB2PdD 获取对应的长 URL
    4. 请求通过 HTTP 301 转到对应的长 URL https://m.helijia.com 。

    为啥是302

    301 是永久重定向,302 是临时重定向。短地址一经生成就不会变化,所以用 301 是符合 http 语义的。同时对服务器压力也会有一定减少。

    但是如果使用了 301,我们就无法统计到短地址被点击的次数了。而这个点击次数是一个非常有意思的大数据分析数据源。能够分析出的东西非常非常多。所以选择302虽然会增加服务器压力,但是我想是一个更好的选择。

    ps:

    1、对于GET请求, 301跳转会默认被浏览器cache。也就是说,用户第一次访问某个短链接后,如果服务器返回301状态码,则这个用户在后续多次访问同一短链接地址,浏览器会直接请求跳转地址,而不会再去短链接系统上取!

    这么做优点很明显,降低了服务器压力,但是无法统计到短链接地址的点击次数。

    2、对于GET请求, 302跳转默认不会被浏览器缓存,除非在HTTP响应中通过 Cache-Control 或 Expires 暗示浏览器缓存。因此,用户每次访问同一短链接地址,浏览器都会去短链接系统上取。

    这么做的优点是,能够统计到短地址被点击的次数了。但是服务器的压力变大了。

    短链实现原理

    发号器 + 62进制转换。

    给每一个过来的长地址,发一个号即可,小型系统直接用mysql的自增索引就搞定了。如果是大型应用,可以考虑各种分布式key-value系统做发号器。不停的自增就行了。第一个使用这个服务的人得到的短地址是 第二个是  第11个是  第依次往后,相当于实现了一个62进制的自增字段即可。

    为什么用62进制?而不是64进制

    1. 62进制转换是因为62进制转换后只含数字+小写+大写字母。而64进制转换会含有/,+这样的符号(不符合正常URL的字符)

    2. 10进制转62进制可以缩短字符,如果我们要6位字符的话,已经有560亿个组合了。(62^6 = 56800235584)

    发号器顺序生成自增ID不安全

    构造 62进制的字母不要按顺序排列。

    举例

    ID自增后,转成62进制,在DB保存映射关系,生成短链接。

    如:短链服务网址:http://shorurl.cn/,需要转短链的长url为 https://www.baidu.com/asdfg.com。发号器给的数字为1000,转62进制为2Bi。

    那么生成的短链地址为http://shorurl.cn/2Bi。然后用DB保存映射关系 2Bi -> https://www.baidu.com/asdfg.com

    用户自定义短链

    比如,我们用mysql去存储短链-长链的对应关系,再增加一个字段:短链生成方式(1:系统自动;2:用户自定义)

    如果有用户自定义过短码,把它的类型标记自定义。

    每次根据 id 计算短码的时候,如果发现对应的短码被占用了,就从类型为自定义的记录里随机选取一条记录,用它的 id 去计算短码。

    这样既可以区分哪些长连接是用户自己定义还是系统自动生成的,还可以不浪费被自定义短码占用的 id。

    如何保证同一个长地址,每次转出来都是一样的短地址

    建立一个长对短的KV存储即可。嗯,听起来有理,但是。。。这个KV存储本身就是浪费大量空间。所以我们是在用空间换空间,而且貌似是在用大空间换小空间。

    其实也没必要存,就算存,可以存“最近”生成的长对短的一个对应关系。注意是“最近”,也就是说,我并不保存全量的长对短的关系,而只保存最近的。比如采用一小时过期的机制来实现LRU淘汰。保存热门短链即可。

    如何保证发号器的大并发高可用

    2个发号器,1个发单号,一个发双号。依此类推。

    一些不好的方案

    (X) 实现算法将长链变为短链

    实现一个算法,将长地址转成短地址。实现长和短一一对应。然后再实现它的逆运算,将短地址还能换算回长地址。但不行!!!

    即使我们定义短地址是100位。那么它的变化是62的100次方。62=10数字+26大写字母+26小写字母。无论这个数多么大,他也不可能大过世界上可能存在的长地址。所以实现一一对应,本身就是不可能的。 再换一个说法来反驳,如果真有这么一个算法和逆运算,那么基本上现在的压缩软件都可以歇菜了,而世界上所有的信息,都可以压缩到100个字符。这~可能吗。

    不要逆运算

    和上面一样,也找一个算法,把长地址转成短地址,但是不存在逆运算。我们需要把短对长的关系存到DB中,在通过短查长时,需要查DB。也不行!!!

    也能会存在hash碰撞。

    就算碰撞,在后面加1,2,3

    用一个hash算法,我承认它会碰撞,碰撞后我再在后面加1,2,3不就行了。 ok,这样的话,当通过这个hash算法算出来之后,可能我们会需要做btree式的大于小于或者like查找到能知道现在应该在后面加1,2,或3,这个也可能由于输入的长地址集的不确定性。导致生成短地址时间的不确定性。

    随机生成一个短地址

    随机生成一个短地址,去查找是否用过,用过就再随机,如此往复,直到随机到一个没用过的短地址。

  • 相关阅读:
    WCF、Net remoting、Web service概念及区别
    新浪微博技术架构分析
    谈SOA和云的分层架构
    开发人员眼中最好的代码编辑器是什么?
    调试脚本,远离alert
    struts2与cookie实现自动登录和验证码验证
    把旧的项目改变名称重新部署到tomcat下发现项目名称还是原来的项目名称,解决方案
    myeclipse2014 安装maven3.3.9和mave配置本地仓库
    mysql在表的某一位置增加一列、删除一列、修改列名
    Java实现对cookie的增删改查
  • 原文地址:https://www.cnblogs.com/fanguangdexiaoyuer/p/11947658.html
Copyright © 2020-2023  润新知