短链服务设计
资料参考地址1:
系统设计之路:如何设计一个URL短链服务
资料参考地址2:
分布式系统设计-短连接服务设计
一 什么是 URL 短链
URL 短链,就是把原来较长的网址,转换成比较短的网址。
好处是
- 网址短、美观、便于发布、传播,可以写更多有意义的文字;
- 我们平常看到的二维码,本质上也是一串 URL ,如果是长链,对应的二维码会密密麻麻,扫码的时候机器很难识别,而短链则不存在这个问题;
- 出于安全考虑,不想让有意图的人看到原始网址
二 短链跳转主要原理
重定向
客户端(或浏览器)请求短链: https://j.mp/38Zx5XC
短链服务器收到请求后,返回 status code: 301 或 302 ,说明需要跳转,同时也通过 location 字段告知客户端:你要访问的其实是下面这个长网址 :
https://activity.icoolread.com/act7/212/duanxin/index
客户端收到短链服务器的应答后,再去访问长网址:
https://activity.icoolread.com/
[
短链接跳转的示例代码
好的,以下是一个使用 Spring Boot 实现短链接跳转的示例代码,通过返回 301 或 302 状态码并设置 Location 头来实现跳转。
在 ShortUrlController 类:
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ShortUrlController {
// 这里简单模拟一个短链接到长链接的映射关系,实际应用中可以使用数据库存储
private static final String SHORT_URL_TO_LONG_URL_MAP = "https://example.com/long-url";
@GetMapping("/short/{shortUrlId}")
public ResponseEntity<Void> redirectToLongUrl(@PathVariable String shortUrlId) {
// 这里假设 shortUrlId 是唯一标识,根据实际情况获取对应的长链接
String longUrl = SHORT_URL_TO_LONG_URL_MAP;
// 返回 302 临时重定向,也可以根据需求改为 301 永久重定向
return ResponseEntity.status(HttpStatus.FOUND).header("Location", longUrl).build();
}
}
三 设计短链服务要考虑的点
- 高可用-搭集群-负载均衡
- 读流量大时考虑缓存
- 数据量大时考虑分库分表以及过期清除
四 生成短链的示例代码
将长链接经过MurmurHash算法生成整数,然后将整数转换为Base62字符
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.1-jre</version>
</dependency>
import com.google.common.hash.Hashing;
import java.nio.charset.StandardCharsets;
import org.apache.commons.codec.binary.Base64;
public class UrlShortenerDemo {
public static void main(String[] args) {
String longUrl = "https://www.example.com"; // 要缩短的长链接
// 使用MurmurHash算法生成整数
int murmurHash = Hashing.murmur3_32().hashString(longUrl, StandardCharsets.UTF_8).asInt();
// 将生成的整数转化为Base62的字符
String base62 = encodeBase62(murmurHash);
System.out.println("Long URL: " + longUrl);
System.out.println("MurmurHash: " + murmurHash);
System.out.println("Short URL (Base62): " + base62);
}
// 使用Base62编码将整数转化为字符串
private static String encodeBase62(int num) {
String characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
StringBuilder result = new StringBuilder();
while (num > 0) {
int remainder = num % 62;
result.insert(0, characters.charAt(remainder));
num /= 62;
}
return result.toString();
}
}
五 短链为什么要设置过期
1.安全性:如果短链永久有效,那么一旦短链泄露或者被滥用,长链接将永远处于风险之中。过期机制可以降低这种风险,因为即使短链被泄露,只要短链已过期,长链接将不再可用。
2.资源管理:短链服务需要存储大量的短链接映射,如果不实行过期机制,数据库会不断增长,导致资源浪费。过期机制可以自动删除不再需要的短链接映射,释放资源。
3.促使用户行动:短链的过期时间可以用来促使用户尽快点击链接,例如,在市场推广中,您可以创建一个短链,仅在活动期间有效,这样可以增加用户点击的紧迫感。
要实现短链的过期功能,可以考虑以下步骤:
-
数据库表设计:在短链接的数据库表中添加一个过期时间字段(expiration_date),用于存储短链的过期日期和时间。
CREATE TABLE url_mapping ( id INT AUTO_INCREMENT PRIMARY KEY, long_url VARCHAR(255) NOT NULL, short_url VARCHAR(50) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, expiration_date TIMESTAMP );
-
生成短链时设置过期时间:在生成短链接时,为其设置一个过期时间,可以是从当前时间开始的一段时间后,或者是一个具体的未来日期和时间。这可以在业务逻辑中实现。
public String shortenUrl(String longUrl, LocalDateTime expirationDate) { String shortUrl = generateShortUrl(); UrlMapping urlMapping = new UrlMapping(); urlMapping.setLongUrl(longUrl); urlMapping.setShortUrl(shortUrl); urlMapping.setExpirationDate(expirationDate); urlMappingRepository.save(urlMapping); return BASE_URL + shortUrl; }
-
验证短链是否过期:在访问短链接时,首先验证当前时间是否在过期时间之前。如果短链已过期,可以采取适当的措施,例如返回一个过期提示或重定向到其他页面。
public String expandUrl(String shortUrl) { UrlMapping urlMapping = urlMappingRepository.findByShortUrl(shortUrl); if (urlMapping != null) { LocalDateTime expirationDate = urlMapping.getExpirationDate(); if (expirationDate == null || expirationDate.isAfter(LocalDateTime.now())) { return urlMapping.getLongUrl(); } else { // 短链已过期,采取适当的处理 return "Short URL has expired"; } } return "Short URL not found"; }
通过这种方式,您可以实现短链接的过期功能,确保链接在指定的时间后不再可用。请注意,过期功能的具体实现方式可以根据需求进行调整,例如,您可以使用定时任务来定期清理过期链接,或者将过期链接移动到归档表中,以减小数据库大小。
六 布隆式过滤器防重复
可用redisson的实现布隆过滤器
防重复流程
先通过布隆过滤器进行快速初步判断,如果布隆过滤器显示不存在,直接插入数据库可以减少不必要的数据库查询,提高效率。若布隆过滤器显示存在,再到数据库精准查询,能确保准确性,避免误判导致的重复插入。
为什么这么做
这种方式能避免对数据库的过多访问,因为布隆过滤器可以在内存中快速进行判断,拦截大部分明显不存在的短链,只有在可能存在重复的情况下才去查询数据库。同时,通过布隆过滤器和数据库的双重验证,能有效保证短链的唯一性。
七 实际使用场景
做裂变引流时,我们服务采用短链加二维码的方式
原因有这几点:
一是美观,长链接杂乱、复杂二维码看起来不精致,换成短链与简洁二维码,视觉上更清爽,能提升用户参与意愿。
二是时效管控,短链可设置有效期,给用户紧迫感,督促他们赶紧分享,加速裂变传播。
三是数据安全,短链能隐藏真实接口,防止数据被篡改,保障业务数据可靠。
四是数据追踪,通过短链能精准记录用户操作,了解行为、来源等信息,方便后续优化营销策略。
另外,关于能否在微信分享,答案是可以,只要把短链域名加入微信白名单就行,这样就能利用微信平台做好裂变引流。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具