Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

背景:我们手机总会收到商品推销的短信,短信中包含一个商品链接,既然是个网页链接,它一定是http或者https的,但是短信中的链接特点是很短,从链接中看不出任何的信息,而且没有超文本传输协议,不同于常用的URL格式。这就是短链系统。

image-20250619105401682

短链系统

这个链接就是一个短链URL,使用它

短链系统的优点

  1. 屏蔽URL中的信息,相对更加安全
  2. 让短息更简洁
  3. 利于营销

短链系统的核心原理

短链系统的组成:域名+随机码(其中域名在书面表达上可以不具备任何意义),那我收到的这条短信,3.cn/v就是个域名,ey8j是随机码。

在数据库表中存储短链和实际可以用于访问的URL的映射关系,将短链发送给用户,用户点击短链后,根据映射关系找到访问的URL,然后进行重定位跳转。

重定位跳转

我们在访问网页的时候,当资源的位置发生改变的时候,会出现跳转,资源重定位常用的转移码是301,302

301(资源永久重定位):首次请求是访问短链系统,获取短链对应的长链URL,后面再访问时不经过短链系统,而是直接使用首次访问时获取的长链URL进行访问

302(资源临时重定位):每一次访问短链时都要经过短链系统获取对应的长链URL,通过长链URL进行访问

短链系统一般使用的是302资源临时重定位

![屏幕截图 2025-06-19 104932](../image/高性能短链系统/屏幕截图 2025-06-19 104932.png)

数据库设计

1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE short_url_map (
id int unsigned NOT NULL AUTO_INCREMENT,
long_url varchar(160) NOT NULL COMMENT '原始长链接',
short_url varchar(10) NOT NULL COMMENT '短链接代码',
gmt_create datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
gmt_modified datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (id),
UNIQUE KEY uk_short_url (short_url),
KEY idx_gmt_create (gmt_create)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='长短链接映射表';
DESC short_url_map

image-20250619095459672

那怎么产生短链系统呢?

因为短链是由 域名+随机码组成的,所以如何生成一个随机码(这个随机码要是全局唯一的)是短链系统的关键

生成随机码通常有三种方法:Base62、Hash、全局唯一ID(雪花算法)

Base62

Base62 表示法是一种基数为62的数制系统,包含26个英文大写字母(A-Z),26个英文小写字母(a-z)和10个数字(0-9)。这样,共有62个字符可以用来表示数值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <string>
#include <random>
#include <algorithm>
#include <iostream>
using namespace std;
class RandomCodeGenerator {
private:
static const string CHAR_62;
static mt19937_64 random_engine; // C++ 中用于生成高质量伪随机数的静态随机数引擎
static uniform_int_distribution<int> dist;

public:
static string generateRandomCode(int length) {
string result;
result.reserve(length); //预分配空间

for (int i = 0; i < length; ++i) {
int rndCharAt = dist(random_engine) % CHAR_62.length();
char rndChar = CHAR_62[rndCharAt];
result.push_back(rndChar);
}

return result;
}
};

// 初始化静态成员
const string RandomCodeGenerator::CHAR_62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
mt19937_64 RandomCodeGenerator::random_engine(random_device{}());
uniform_int_distribution<int> RandomCodeGenerator::dist(0, CHAR_62.length() - 1);

int main() {
RandomCodeGenerator number;
string result = number.generateRandomCode(5);
cout << result << endl;
system("pause");
}

Hash

①将长链进行哈希,截取前面的几个字符串作为随机数

②将长链进行哈希,然后再进行压缩(使用MurmurHash哈希算法将长链哈希成一个32位的10进制正数,然后再转换成62或者64进制(压缩),就可以得到一个6位的随机数)

使用雪花算法生成唯一ID

评论