17611538698
webmaster@21cto.com

URL短网址系统的设计与实践

资讯 0 2737 2020-02-23 12:04:09

导读:在本文中,我们讨论怎样使用Zookeeper、Redis和DynamoDB实现URL短网站服务。



01.png

 
关于短网址服务
 
在通常情况下,URL是由系统生成的,通常包括URI路径,多个查询参数,可以对参数进行加密和解密。当人们要分享某个URL,比如短信,邮件,社交媒体(如微博,微信,抖音等),这就需要短URL。
 
最开始时,URL短网址服务听起来是一个很简单的服务,当运行一段时间就会带来一些挑战,这便是系统的容积问题。
 
不妨思考一下,该如何设计为世界上所有的长网址生成无限数量的短URL呢?简单说,为长网址生成唯一的随机标识,这些标识应该是一些URL中可接受的字符。
 
关于短网址
 
典型的短网址可能是这样的:
 
[list=none]
[*] [/*]
[/list]
[code]https://url.cn/qp7h3iz
[/code]
 
其中 url.cn 是域名,是服务商公司的短名称。URL的最后一部分是唯一且随机的标识符,这部分称为Token——令牌。这由字母数字和字符串组成,用作长网址的替代标识符。请注意,它的长度在6-9个字符之间。
 
需要特别留意的是,要密切注意Token的长度和其包含的字符。为了确保安全,请使用小写字母a-z以及0-9之间的数字,即有36个字符集。
 
以下为使用不同的长度生成唯一Token的数量一览表:
 Token长度Token唯一组合数范围62,176,782,336> 20亿778,364,164,096> 780亿82,821,109,907,456> 2万亿9101,559,956,668,416> 100万亿
 
从上表中看到,可以使用Token为7个字符长,可以容纳780亿个独立Token。如果想更大范围,可以将它设置为8个个字符长度,大约为2万亿个。
 
这样可以容纳世界上所有的长URL提供短网址服务。
 
短网址系统设计
 
短网址服务将由以下两部分组成:
 
1)短网址系统如何将传入的长网址处理成短URL的请求
2)短网址系统处理用户点击网址后,将用户重定向到实际的地址,即长URL
 
短网址生成
 
生成的规则如下,URL短网址服务接受一个长URL输入,接下来生成一个短URL,返回用户。
 
如果长网址已经存在于系统中,则立即返回之前生成的短URL。
 
如果短URL已经过期,则需要新建一个新URL重新发送。
 
 

02.png

 
 
短URL生成的工作流程
 
短网址重定向
 
当用户点击访问短网址时,短网址服务将该短网址重定向到实际的长URL地址。短网址的短域名必须映射到如下服务:
 

03.png

 
 
Token生成规则
 
生成唯一的随机Token逻辑相对比较复杂。
 
短网址服务务必确保不将一个Token分配给两个长URL,以免将短网址指向错误。
 
可以使用第三方库或传统方法如Base 36编码等多种策略生成令牌,不需要依赖第三方。
 
第三方库
 
Hashids(https://hashids.org/),就是一个可靠的库,它可以生成唯一的随机Token Id,支持30多种语言。
 
 

04.png

 
 
Hashids可以根据数字(0和正整数)创建唯一Id,允许使用自定义字符和Salt,因此对开发者而言是唯一的。
 
Hashids生成的Id复杂,不容易被猜中,它占用空间很小,没有外部依赖库关联。
 
以下使用salt="this my salt"和字符集“abcdefghijklmnopqrstuvwxyz1234567890”生示Token的实例。
 
 哈希输入生成Token短网址13joed16https:// test.com / 3joed1628lop31whttps:// test.com / 8lop31w3l6o3k1nhttps:// test.com / l6o3k1n4leo2418https:// test.com / leo2418
 
Base 36 编码
 
此为最简单的方法,大多数编程语言均支持。假设你并不需要Hashids提供的额外功能,使用Base 36也是不错的选择。而且它速度更快,可以使用中心化的Zookeeper服务同步数字输入范围。
 
以下描述使用Hashids生成Token的进阶设计。
 
Hashids库生成唯一令牌的数字,因为URL短网址服务在N个节点的集群上运行,Hashids的数字输入必须是非重复的。此处引入同步服务Zookeeper,可以管理和处理给URL短网址服务节点的数字ID范围。
 
每个短网址应用程序节点启动后都会向Zookeeper服务请求新的数字范围,Zookeeper负责记录。对于每个短URL请求,短网址服务应用节点会在分配范围内增加一个数字,将它传递给Hashids库,后者生成相应的数字生成唯一Token,并保存到与长URL对应的数据库。
 
当分配的数字范围被应用节点用尽,短网址服务向Zookeeper请求新的数字资源,此种设计能让我们灵活地根据传入流量添加任意多的应用程序节点。
 
 

05.png

 
 
使用Hashids的流程
 
另外,Zookeeper可以由DynamoDB服务代替,由其维护计数。Zookeeper服务的作用是维护已分配给应用节点的数字,并在其发出新请求时分配新的数字段。这里可以用DynamoDB的计数器变量表,该计数器变量是原子性的,任何保存增量数值的应用程序节点都不会发生冲突。当然DynamoDB也可以用MySQL或其它任何生成原子数的系统代替。
 
短网址系统完整设计
 

06.png

 
 
在上图中看到的系统中,添加了Redis缓存,用来提高应用程序性能。在缓存中新生成短网址,而不再查询数据库。开发者可以设置缓存项的有效时间和回收策略,比如LRU。
 
1、URL短网址应用节点在集群中工作,每当应用启动或有新节点加入时,就与Zookeeper服务进行通信;
2、Zookeeper服务根据请求,为每个应用程序节点分配一个唯一的ID区段;
3、短网址URL请求先到达负载均衡设备,后者以轮循方式将调用分配给适合的URL短网址应用节点之一;
4、应用程序首先从高速缓存或数据库中查询该长URL是否已经存在,若存在,则短网址未过期且有效,返回 HTTP 200 OK的响应;
5、若数据库和缓存中不存在该长网址,则短网址应用在分配的数字内用Hashids生成新Token令牌,生成短网址,设置有效期,接着保存到数据库和缓存中,接下来返回 HTTP 201 CREATED的状态返回客户端;
6、当用户点短网址时,请求会先到达负载均衡设备,传递到URL应用的某个节点之一;
7、应用程序在Redis高速缓存中检查是否有短网址的对应长URL,然后转到步骤9;
8、如果高速缓存中没有,则向数据库中查询,然后转向步骤9;
9、当重定向到长URL时,应用程序会在HTTP的Header中设置长网址的HTTP 302响应,客户端会立即重定向到实际的网址,即长URL;
10、如果在数据库或缓存中找到相关Token,则应用程序节点将返回 HTTP 404 Not Found的状态响应。
 
 

作者:老九
来源:21CTO


评论