如何设计一个短链系统?

98

如何设计一个短链系统?

  • 最近可能要做个问卷系统,对于处理问卷访问这part,如果是使用url链接方式访问,我不尤想起了干脆来做个短链系统。

Why I need 短链?

  • 下面举个🌰:
  • 显然:
    • 短链更简洁、更方便传播,tm如果我的问卷链接又臭又长,不仅你们觉得我是lowB,我自己也觉得。
    • 方便对链接的点击情况做后续追踪:比如查看短链最近一周的访问量、访问数等、访问来源等。
    • 对于一些限制字数的场景友好。你短一个字,我多bb一个字🤪。

短链原理

  • 一句话:通过短链找到长链(原始链接),然后再重定向到长链地址即可。

  • 白嫖gudie哥示意图截屏2022-11-16 15.29.57

  • 🌰:你说说什么时候会用到302状态码?🤪

  • 当然还有301代表永久重定向,只要浏览器拿到长链之后就会对其进行缓存,下次请求短链就直接从缓存中拿对应的长链地址。

    但是这样的话,我们就无法对短链进行相关分析了。

  • 而302代表资源被临时重定向了,不会存在上述问题。

短链生成

  • 原链肯定是唯一的,所以我们也要保证生成的短链唯一。

  • 常见方式:通过哈希算法对长链进行哈希

  • 一般建议使用MurmurHash,相比MD5、SHA等加密型哈希算法,非加密型的哈希算法往往效率更高。

  • MurmurHash的最新版本是MurmurHash3,能够产出32-bit或128-bit哈希值。

    // Guava 自带的 MurmurHash 算法实现
    String url = "http://www.luelueking.com/api/public/survey/loadProject?id=111";
    long s = Hashing.murmur3_32().hashnencodedChars(url).padToLong();
    

    生成的hash是十进制的,为了缩短长度,可以转换为62进制。

  • 如何判断hash冲突?

    • 如果我们使用的是MySQL这种关系型数据库,可以给存放短链的字段添加唯一索引。
    • 或者为了提高性能和并发量,可以使用布隆过滤器
  • 如何解决hash冲突?

    • 如果发生了hash冲突,就随便在后面加个字符,直到不冲突为止呗。
  • 长链对短链是一对一还是一对多?

    • 视情况而定,看具体业务需求。

短链存储

  • 使用关系型数据库进行存储

    • 大致表结构

      CREATE TABLE `url_map` (
      	`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
        `long_url` varchar(160) DEFAULT NULL COMMENT '长链',
        `short_url` varchar(16) DEFAULT NULL COMMENT '短链',
        PRIMARY KEY (`id`)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
      
    • 存放长链时,要判断是否被转换过

    • 如果要对长链就行区分的话(比如不同用户使用同一个长链生产的短链不同),在判断的时候加上对于条件就行

  • 使用redis这种nosql数据库存,刚好K-V

    • 当然无论是否用nosql,都建议热点数据存缓存。