likes
comments
collection
share

短链服务

作者站长头像
站长
· 阅读数 22

短链服务

本文柯苏远写于2024年5月11日 12点0分

背景

上个月对接了短信厂商的发送短信接口,但是由于短信里会存在链接,链接太长影响影响用户看短信的内容。为了优化用户短信观看体验,所以有了这个需求,主要是做一个映射,将原先的长链接映射成一个短链接,用户通过访问短链接再重定向到原先的长链接。

产品参考了友商短链长度之后,决定将短链的长度固定在24个字符。

短链服务设计

我可以映射的长度

什么叫我可以映射的?

由于产品已经将短链的长度固定在24个字符,https:// 就已经包含8个了,还有16个长度要包含域名以及待跳转长链对应的字符串。由于目前公司所购买的所有域名中最短的一个是9个字符,形式是:xxx.yyyyy,所以还剩7位,但是域名和长链接对应的字符串之间需要/来分割,最后我能用的长度就只剩下6位了。

最后整个短链的格式就是:https://xxx.yyyyy/ABCDEF

最后的ABCDEF就是长链对应的字符串映射。

定义一下短链名词说法

短链 = 短链域名 + 6位短链字符串(短链字符

短链服务的时序图

短链服务

时序图中的关键步骤

在时序图中就包含了短链服务的所有交互,这里记录下短链服务中的关键步骤和思想。

1. 根据base62算法生成短链字符

base62算法:

62是指62个字符,分别是26个小写字母,26个大写字符以及10个数字字符,总共就是62个。

这里说的base62算法更像是一种62进制

举个例子: base62的字符串是:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789

如果当前数字是5,那么我用base62怎么表示? 步骤就是用5对62取余,然后去这个字符串对应下标获取对应字符,最后获取到的答案是F

同理,128用base62怎么表示?同样的步骤,得到答案是CE

相关代码:

private static final String BASE62_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

public static String encode(long num) {
    StringBuilder sb = new StringBuilder();
    do {
        int remainder = (int)(num % 62);
        sb.insert(0, BASE62_CHARACTERS.charAt(remainder));
        num /= 62;
    } while (num != 0);
    return sb.toString();
}

2. 6位短链字符串能表示多大的数字?

上面介绍过短链字符串只给我留了6位长度,这6位对应的是base62这个62进制。 那么这6位字符对应的最大十进制怎么算?

6位对应的最大base62是:999999,在base62中9表示的是61,所以6位base62能表示的最大值是:62^6-1这个是进制转换的知识,可以网上找找,类比二进制的。

62^6-1约等于 568_0023_5583,有568亿的数据量,够用了,单表数据就几千万。

3. 短链字符串对应的十进制数字怎么来?

在我们的实现中是直接取的短链表主键(long类型)。

由于我们的业务量并不大,所以单库单表够用了,如果单表数据量太多就要进行分表设计了。

后面如果我们业务的短链表要进行分表,那么要是根据时间范围进行归档,因为按理说一个短链发出去是有有效期的概念的,虽然我们的业务没有涉及,哈哈

4. 短链表的设计

CREATE TABLE `short_url`  (
  `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '短链表id',
  `long_url` varchar(4096) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '原始长链',
  `long_url_md5` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '原始长链的md5',
  `short_url_str` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '6位短链字符串',
  `status` int UNSIGNED NOT NULL DEFAULT 0 COMMENT '0: enable  1: disable',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `uk_md5`(`long_url_md5`) USING BTREE,
  UNIQUE INDEX `uk_short_url_str`(`short_url_str`) USING BTREE
) 

总结

感谢公司提供了这样一个场景,让我接触到了短链服务的设计,挺锻炼人的,让我获得了对应的成长。 期间也遇到了些许问题,也是在老大帮助下解决了。

短链服务归根结底其实就是维护一个长链和短链的映射关系,然后可以通过不同方式实现,不一定非得我文章中的方式。 还有就是base62这种62进制思想挺有意思的。

转载自:https://juejin.cn/post/7367292352275562535
评论
请登录