浅谈短链接设计
随着互联网的普及,尤其是移动互联网的发展,如今我们每个人都要和各种各样的网站、APP打交道,每天都会收到很多服务、营销等信息,有邮件、短信、微信推送等,其中短信应该是接触最频繁的,毕竟除了正经的短信外,还有很多不良信息甚至有害信息源源不断地发送到我们的手机上。
不知道大家有没有注意,我们经常可以在服务类短信的最后可以看到一个链接,通常是xx活动链接或xx账单链接,而且基本上都很简短,有些甚至只有几个字母,如下图中的中国电信链接,当我们点击链接时,往往会跳转到另一个网址,并且网址链接会比短信中的要长很多,这里其实就是使用的短链接。
- 短信中的短链接
实际跳转网址
为什么要使用短链接
短信文本过长会拆分成多条计费,而网址链接一般都比较长,使用短链接能有效降低企业成本
某些内容平台限制文本长度
降低网络传输成本,文本越长,消耗的网络资源也越多
将链接转为二维码,如果链接过长,生成的二维码会难以识别
某些平台对长链接识别不友好
短链接原理
- 根据上面图片可以看到,点击短链接后,会向服务器发起一个请求,服务器返回的状态码为
302
,并且在response
的Location
属性返回了实际网址,这里用到的就是302重定向 - 重定向分为301重定向和302重定向,301是永久重定向,即首次访问后,每次访问不再请求服务器,而是直接根据浏览器缓存跳转到对应的页面;302是临时重定向,即每次访问都会重新请求服务器
- 对长链接进行压缩,最常见的就是使用哈希,当然使用其他的算法也可以,比如MD5、SHA等,对于短链接我们关心的是效率,所以使用一般的哈希函数就可以了
- 生成短链接后,我们需要在数据库保存短链接和长链接的映射关系,这样在重定向时才知道应该向浏览器返回哪个长链接
知道了原理后,我们可以自己模仿实现上面的效果
开始动手
创建一个web工程,这里为了方便,直接创建一个SpringBoot项目,引入guava和redis依赖,我们使用guava的哈希算法生成哈希值,使用redis来保存链接数据
1
2
3
4
5
6
7
8
9
10<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>编写
BizController
负责生成短链接1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class BizController {
StringRedisTemplate stringRedisTemplate;
public String generateShorUrl() {
// 这里使用SpringBoot的官方文档页面作为要重定向的长链接网址
String longUrl = "https://docs.spring.io/spring-boot/docs/2.7.11/reference/html/getting-started.html#getting-started";
// 使用guava提供的哈希工具类对长链接进行压缩,这里使用的是murmur3_32_fixed算法,它会生成32位的哈希值,当然也可以使用其他哈希算法,
String shortUrl = Hashing.murmur3_32_fixed().hashBytes(longUrl.getBytes()).toString();
// 将短链接和长链接的映射关系保存到redis中,实际开发中可以保存到MySQL数据库,这里为了演示方便直接使用redis
stringRedisTemplate.opsForValue().set(shortUrl, longUrl);
return "shorUrl: http://127.0.0.1:8080/short/" + shortUrl;
}
}编写
ShortUrlController
负责重定向1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class ShortUrlController {
StringRedisTemplate stringRedisTemplate;
public void redirect( String url, HttpServletResponse response){
// 从数据库获取短链接对应的长链接,这里用redis演示
String longUrl = stringRedisTemplate.opsForValue().get(url);
if (Strings.isEmpty(longUrl)) {
response.setStatus(HttpStatus.NOT_FOUND.value());
}
// 设置状态码为302
response.setStatus(HttpStatus.FOUND.value());
// 设置Location为长链接
response.setHeader(HttpHeaders.LOCATION, longUrl);
}
}测试
测试生成短链接
查看redis
测试重定向
在浏览器输入http://localhost:8080/short/9591dfe4,发现成功重定向至SpringBoot文档页面
总结
- 使用短链接可以为我们带来很多好处
- 生成短链接的方式有很多,除了哈希算法外,还可以使用数据库自增id、redis自增、UUID、雪花算法等,每种方法各有有点,根据自身需求合理选择
- 生成的短链接需要保证其唯一性,使用MySQL数据库,可以为短链接字段设置唯一索引,使用其他方式需要自己实现方法保证短链接唯一