短链系统

月伴飞鱼 2024-10-22 17:38:12
系统设计
支付宝打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者!

请求流程

举例:当当的短链接http://dwz.win/nXR,它是由两个部分组成

  • http://dwz.win:短链接系统的域名地址

  • nXR:请求参数

请求http://dwz.win/nXR地址后,返回状态如下所示

img img

功能分析

三个功能

  • 发号,存储,映射

可以分为两个模块:发号与存储模块、映射模块

发号与存储模块

  • 发号:使用发号器发号,为每个长地址分配一个号码ID
    • 并且需要防止地址二义,也就是防止同一个长址多次请求得到的短址不一样
  • 存储:将号码与长地址存放在DB中,将号码转化成62进制
    • 用于表示最终的短地址,并返回给用户

映射模块

用户使用62进制的短地址请求服务

  • 转换:
    • 将62进制的数转化成10进制
  • 映射:在DB中寻找对应的长地址
  • 通过302重定向,将用户请求重定向到对应的地址上

短地址算法原理

采用六十二进制表示法!

比如:http://xxx.cn/EYyCO9T

其中核心的部分 EYyCO9T 只有7位长度。

  • 这里的7位长度是使用62进制来表示的
    • 就是常用的0-9、a-z、A-Z,也就是10个数字+26个小写+26个大写=62位。

7位长度62进制可以表示多大范围呢?

62^7 = 3,521,614,606,208 (合计3.5万亿)

10进制 最大只能生成 10 ^ 6 - 1 =999999个
16进制 最大只能生成 16 ^ 6 - 1 =16777215个
16进制里面已经包含了 A B C D E F 这几个字母
62进制 最大能生成 62 ^ 6 - 1 =56800235583个

短网址的长度,可以根据自己需要来调整,如果需要更多,可以增加位数

  • 6位长度62^6能达到568亿的范围
private static final String BASE = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

public static String toBase62(long num) {
    StringBuilder sb = new StringBuilder();
    do {
        int i = (int) (num % 62);
        sb.append(BASE.charAt(i));
        num /= 62;
    } while (num > 0);

    return sb.reverse().toString();
}

全局发号器

分布式ID生成算法!

表结构

列名 说明
id BIGINT,自增主键
key 短串,需要加唯一索引
url 长地址,需要跳转的原地址

相同的原始网址可能会对应不同的短链

每次新来一个原始网址,就生成一个新的短链:

  • 这种做法就会导致两个相同的原始网址生成了不同的短链。

第一种处理思路是:

  • 不做处理,实际上,相同的原始网址对应不同的短链,这个用户是完全可以接受的。

第二种处理思路是:

  • 拿原始网址在数据库中查找,看数据库中是否已经存在相同的原始网址了。
    • 如果数据库中存在,那就取出对应的短链,直接返回给用户。
  • 这种处理思路需要给数据库中的短链和原始网址这两个字段,都添加索引。
  • 这是有代价的:
    • 一方面两个索引会占用更多的存储空间。
    • 另一方面索引还会导致插入、删除等操作性能的下降。
支付宝打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者!