长地址URL转短地址URL

时间:2024-02-21 19:00:34

1.前言

  长地址:

    就是页面请求实际的地址。如知乎某文章https://www.zhihu.com/question/20103344

  短地址:

    特定长地址缩短后对应的长度很短的地址,基本上可以理解为一一对应关系

    如https://www.zhihu.com/question/20103344的短地址为 http://dwz.date/am7a

  备注:

    上述地址是由新浪地址转换平台提供的,对于同一个长地址,不同的转换平台生成的短地址不一样,

    同一个平台不同时间长成的短地址也可能不一样

2.使用场景

  微博上发送新微博内容时,限制字数为140字,如果需要分享链接,那么很长的链接会导致内容篇幅缩小,而且url本身也可能超过140个字,所以如果把地址转换为短地址,那么用户输入短地址,看到的是和输入长地址一样的页面信息,那么用户体验会变好。

  发送推广短信时超出70字算两条短信,费用增加,长链接也影响用户体验

  综上

    在特定场景下,需要能够把长连接转换为短链接

    用户输入短链接的效果和长连接一样(浏览器后台重定向)

    短链接需要长期有效(或者一定时间内,如1天内有效)

    对于同样的长链接,生成的短链接需要一样(或者在一定时间内一样)

3.实现必要条件(基于本博客所用方案而言的必要条件)

  1.有一个独立的域名系统,用于拼接完整的短链接,以后后续反查长链接地址

  2.一个id发号器(生成树数字保持唯一),如数据库的自增序列

4.实现方案

  a.将长链接字符串插入数据库,使用sequence递增序列作为主键,然后返回主键id

  或者是先从发号器取出一个新的id,插入id和长链接字符串(两个字段,且id为主键)

  b.将主键id进行62进制编码(10数字+26大写字母+26小写字母,一般url用这些表示)

  c.使用自身域名信息+62进制字符串拼接为完整的url,然后返回

  解析:

    客户请求短链接时,时间是寻址短链接域名发送到我们的系统上,

    然后根据链接后面的url后缀,转换为10进制,去数据库查询这个主键,找出长链接,

    然后返回给客户端,且返回码为301/302(浏览器会自动重定向到长链接地址,用户无感知).

5.优化方案

  上面有两个问题未解决:

    a.发号器可能会成为瓶颈

    b.对于同样的长链接,生成的短链接不一样

  解决办法:

    a.发号器问题

      可以多用几个发号器,各自发号不重复即可。

      如10个发号器,则发号尾号是1,2,3,4,5,6,7,8,9,0

      即发号进制等于发号器的数量,如果发号器只有一个,那么每次发号数增加1.

    b. 短链接不一样的问题

      方案一:内存存放LinkedHashMap,key为长链接,value为短链接,

      考虑到内存问题,那么只能存放一定数量的键值对,使用LRU进行驱逐。

      这样,在一定时间内,某个长链接生成的短链接一直不变。

 

      方案二:(考虑到要求长链接对应的短链接要永久一样)

      存入数据库时,除了唯一id和长链接地址外,使用长链接生成64位hashcode,然后一并存入数据库,并且添加索引

      下次插入数据库之前,先查询hashcode列是否有这个值,有的话则取出比较value是否相等,

      这里可能是hash冲突,实际上不是同一个长链接,但是使用64位hashcode的话,冲突概率会小很多,

      这里使用hashcode做索引,而不是直接使用长链接本身,是考虑到长链接比较长,作为索引的话,会导致索引层级加深,需要增加额外的磁盘寻址

6.产品举例

    新浪长地址转短地址,使用结果如下:

    https://www.zhihu.com/question/20103344 生成的短地址为:  am7a

    

 

    

 

 

      https://www.kanzhun.com/employee/gsl1194828/1587907702/ 生成的短地址为:am7c

 

   

  使用短链接去请求页面: