第八章 设计URL缩短程序
了解问题并建立设计范围
- 根据原始URL生成长度较短的别名,点击别名会重定向到原始URL
- 流量为每天生成1亿个
- 缩短后的URL可以是数字(0-9)和字符(a-z,A-Z)
- 简化为 缩短后的url不能被删除或更新
提出高级设计并获得认可
API端点
使用API端点进行客户端与服务器通信,为RESTful API,强调 无状态通信、资源导向 和 标准化的基于 HTTP 协议的网络应用程序设计风格。
- 无状态: 每个请求必须包含所有必要信息,服务器不存储客户端状态 ,例如用户通过Token认证
- 资源导向: 所有数据或功能抽象为 资源,通过 URI(如
/users/123)唯一标识 - 统一接口:使用标准HTTP方法操作资源GET/POST等
本章节提出的缩短器主要需要两个API端点:
-
URL缩短,创建新的短URL
POST api/v1/data/shorten• request parameter: {longUrl: longURLString} •return shortURL -
URL重定向:在浏览器输入短URL的时候,服务器收到对应请求会301重定向将短网址更改为长网址。
GET api/v1/shortUrl• Return longURL for HTTP redirection
URL缩短
找到一个散列函数将长URL映射成哈希值,缩短为www.tinyurl.com/{hashValue}的样式,哈希函数需要满足以下要求:
- 每个长URL必须被哈希到一个哈希值
- 每个哈希值可以映射回长URL
组件设计
数据模型
高级设计中使用哈希表存储<shortURL, longURL>的映射关系,实际上内存资源是有限的,将其存储在关系数据库中是更好的选择。表设计可简化为三列:id、shortURL、longURL。
哈希函数和冲突解决
哈希函数的输出值由[0-9,a-z,A-Z]中的字符组成,共62个字符。提前了解当前数据量的大小,从而计算出哈希值对应的最小长度n=7。目标是实现一个哈希函数,将长URL缩短成n个字符的字符串。
已知的哈希函数可以实现哈希这个过程,但是无法控制长度,即便最短的CRC32生成的哈希值也远远超过7。还需要进行缩短操作。
截取前n位+递归消除冲突
- 收集哈希值的前7位
- 使用布隆过滤器测试当前短URL是否存在于数据库中,不存在则保存,否则进行第3步
- 给其附加一个预定义的字符串,并且返回第2步
基数转换
基数转换是将不同数字系统中转换相同数字的方法,由于hash值共62个不同的数字,使用62作为转换。
URL缩短
最后考虑到URL缩短程序需要满足逻辑简单和功能强大的要求,在设计中采用了基于62进制的转换。总体流程为:
- 输入长URL
- 检查长URL是否在数据库中
- 如果存在于数据库中,说明被转换过,从数据库中直接返回
- 否则该URL为全新的。由唯一ID生成器生成唯一ID(主键)
- 根据基数62将ID转换成短URL
- 创建新列存储ID,短URL和长URL
分布式唯一ID生成器在之前章节讨论过
URL重定向
- 用户点击短链接
- 负载均衡器将请求转发给Web服务器
- 短网址已经存在于缓存中,则返回长网址
- 不存在于缓存中,则从数据库中检索,如果仍然不存在,则可能是用户输入了无效的长网址
- 返回长网址给用户
额外补充要点
- 恶意发送庞大URL缩短请求的安全问题-使用速率限制器设置过滤规则来过滤请求
- Web服务器扩展:由于Web是无状态,可直接添加和删除服务器来轻松扩展
- 数据库扩展:数据库复制和分片
- 分析模块:记录具体的访问数据用于分析,辅助商业决策。例如多少人在什么时候点击链接
- 可用性、一致性和可靠性
2025年7月17日阅读随笔
浙公网安备 33010602011771号