
引言
在互联网技术日新月异的今天,URL短链服务已经成为日常网络生活中不可或缺的一部分。每当想要分享一个冗长的网页链接,或者需要在对字符数量敏感的平台(如社交媒体、短信等)发布链接时,URL短链服务都能将长长的URL地址精简成短小、易于传播的链接。例如,将冗长的 https://www.systeminterview.com/q=chatsystem&c=loggedin&v=3&i=long 缩短为 https://tinyurl.com/y7keocwj,这不仅提升了用户体验,也方便了链接的分享和管理。
需求分析
对于URL短链服务而言,其核心需求看似简单,即将长URL转换为短URL,并将短URL重定向回原始的长URL。然而,在实际设计过程中,需要考虑更多细节和约束条件。
1. 功能性需求
首先,需要明确URL短链服务的基本功能。
https://www.example.com/very/long/path/to/resource?param1=value1¶m2=value2,系统应返回 https://tinyurl.com/shortCode 这样的短链接。https://tinyurl.com/shortCode,浏览器应自动跳转到 https://www.example.com/very/long/path/to/resource?param1=value1¶m2=value2。2. 非功能性需求
除了基本功能,非功能性需求同样重要,它们直接关系到系统的性能、可靠性和可扩展性。
3. 封底估算
在系统设计初期进行封底估算(Back-of-the-Envelope Estimation)非常关键。它帮助我们快速评估系统规模,识别潜在瓶颈,并指导后续的设计方向。上述的流量和存储容量估算就是典型的封底估算。
高层设计:架构蓝图
在明确了需求和范围之后,进入高层设计阶段,勾勒出系统的整体架构蓝图。
1. API 端点设计
API (Application Programming Interface) 是客户端与服务器交互的桥梁。对于URL短链服务,需要设计简洁、易用的API端点。采用 RESTful API 设计风格是一个不错的选择。RESTful API 以资源为中心,使用标准的HTTP方法(GET, POST, PUT, DELETE 等)进行操作。
/api/v1/data/shortenlongURLString (长URL字符串),通常放在请求体 (Request Body) 中。/api/v1/{shortURL},其中 {shortURL} 是短URL的路径部分,例如 y7keocwj。2. URL 重定向机制
当用户在浏览器中输入短URL(例如 https://tinyurl.com/y7keocwj)并访问时,浏览器会向URL短链服务发起一个GET请求。服务器接收到请求后,需要将短URL解析,找到其对应的长URL,并进行重定向。
这里,需要选择合适的HTTP重定向状态码:
对于 tinyurl.com 这样的URL短链服务,301 重定向通常是更合适的选择。因为其主要目标是提供高效的URL缩短和重定向服务,减少服务器负载,提升用户访问速度。如果需要进行详细的点击分析,可以考虑其他方案,例如在重定向前,先通过消息队列异步记录点击事件。

(展示了用户访问短URL tinyurl.com 时的重定向流程:浏览器发送请求到服务器,服务器查找短URL对应的长URL,并使用301重定向返回给浏览器。)
3. 短URL生成 (URL Shortening) 流程
如何将长URL映射为短URL?一个初步的想法是使用哈希表(Hash Table)。可以将短URL作为键(Key),长URL作为值(Value)存储在哈希表中。当需要重定向时,根据短URL在哈希表中查找对应的长URL。
然而,仅仅使用哈希表作为数据存储方案是不够的,主要有以下几个原因:
因此,需要更合适的持久化存储方案,例如关系型数据库(如MySQL, PostgreSQL)或NoSQL数据库(如Redis, Cassandra, HBase 等)。在详细设计中,将深入探讨数据模型和短URL生成算法。
核心组件
在高层设计的基础上,进一步深入到核心组件的设计细节,包括数据模型、哈希函数、URL缩短算法和URL重定向的具体实现。
1. 数据模型:关系型数据库设计
考虑到数据持久性、事务支持和成熟的技术生态,关系型数据库是存储URL映射关系的良好选择。可以设计一个简单的数据库表,例如命名为 URL_MAPPING。

(图4 展示了一个简化的数据库表 URL_MAPPING 设计,包含三列:id (主键,自增ID), shortURL (短URL字符串), longURL (原始长URL字符串)。)
id (BIGINT, Primary Key, Auto Increment): 作为主键,使用自增的BIGINT类型,保证唯一性和高效索引。它不仅是表的主键,也将作为生成短URL的基础。shortURL (VARCHAR(255), Unique Index): 存储短URL字符串,例如 "y7keocwj"。设置为唯一索引,确保短URL的唯一性,并加速根据短URL查找长URL的查询。longURL (TEXT): 存储原始的长URL,使用TEXT类型可以存储较长的URL字符串。2. 哈希函数与短URL生成算法
核心问题是如何将长URL高效、唯一地映射为短URL。内容中探讨了两种主要的哈希函数方法:

(表展示了短URL长度 n 与其能支持的最大URL数量的对应关系。当 n=7 时,62^7 ≈ 3.5万亿,足以支持3650亿条URL。) 因此,短URL长度至少需要7位。

(图描述了哈希碰撞解决的流程:首先尝试使用哈希函数生成短URL,如果短URL已存在(碰撞),则在原始长URL上添加一个前缀字符串,再次进行哈希,重复此过程直到生成一个未被使用的短URL。) 这种方法虽然可以解决碰撞,但效率较低,每次生成短URL可能需要多次数据库查询以检查碰撞。布隆过滤器 (Bloom Filter) 可以用于优化碰撞检查过程,减少数据库查询次数。布隆过滤器是一种概率型数据结构,可以快速判断一个元素是否可能在一个集合中。虽然布隆过滤器可能存在误判(将不存在的元素判断为存在),但可以大大减少不必要的数据库查询。

(图展示了将十进制数 111571 转换为基数 62 的过程。通过不断地除以 62 并取余数,得到基数 62 的表示 [2, 7, 55, 59],对应基数 62 编码 "2TXK" (假设 55 对应 'X', 59 对应 'K')。)
最终得到的基数 62 编码字符串就是短URL的 Hash Value 部分。例如,ID 2009216747938 转换为基数 62 为 "zn9edcu"。
3. URL 缩短流程详解 (使用基数 62 转换)
![[iamge]](https://developer.qcloudimg.com/http-save/2441477/5d3abb2d30ccaef85a1dff46cb4029cb.png)
(图详细描述了使用基数 62 转换的 URL 缩短流程。)
/api/v1/data/shorten,携带 longURLString。URL_MAPPING 表中查询 longURL 列,检查该长URL是否已经被缩短过。shortURL 并返回给客户端。避免重复生成短URL,提高效率。hashValue (短URL的后半部分)。https://tinyurl.com/) 与 hashValue 拼接,生成完整的短URL。URL_MAPPING 表中插入一条新记录,包含 id (唯一ID), shortURL, longURL。shortURL 返回给客户端。4. URL 重定向流程详解

(图详细描述了 URL 重定向流程,包括缓存的使用。)
https://tinyurl.com/zn9edcu)。URL_MAPPING 表,根据 shortURL 查找 longURL。longURL 从数据库中取出,更新缓存 (Cache Update),将 <shortURL, longURL> 键值对放入缓存,并进行 301 重定向到 longURL。5. 分布式唯一ID生成器
在分布式系统中,生成全局唯一ID是一个常见的挑战。对于URL短链服务,需要一个能够生成高并发、低延迟、全局唯一ID的组件。常见的分布式ID生成方案包括:
id 列的备选方案。总结与扩展
讨论了API设计、数据模型、哈希函数选择、URL缩短和重定向流程,以及分布式唯一ID生成器等核心组件。
扩展 :
参考资料 ByteByteGo
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。