短链服务设计
资料参考地址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/
[
三 设计短链服务要考虑的点
- 高可用-搭集群-负载均衡
- 读流量大时考虑缓存
- 数据量大时考虑分库分表以及过期清除
四 生成短链的示例代码
将长链接经过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"; }
通过这种方式,您可以实现短链接的过期功能,确保链接在指定的时间后不再可用。请注意,过期功能的具体实现方式可以根据需求进行调整,例如,您可以使用定时任务来定期清理过期链接,或者将过期链接移动到归档表中,以减小数据库大小。