点击上面的蓝色按钮并选择“设置为星星”
短网址长度
短网址的长度应该是多少?目前互联网上的网页总数约为45亿个(仅供参考),超过
,那么 64 位整数就足够了。
如何将64位整数转换为字符串? ,假设我们只是用大小写字母加数字,那么就可以看成是一个62位的数字,
,即最长的字符串11就够了。
实际生产中,还可以更短。例如,新浪微博使用的长度是7,因为
,这个数量级远远超过了互联网上的URL总数,绝对是够用的。
大多数现代Web服务器(例如Nginx)在URL中都区分大小写,因此使用大小写字母来区分不同的URL是没有问题的。
因此,正确答案是:长度不超过7的字符串,总共由62个字母组成,包括大小写字母加数字。
一对一还是一对多映射?
一个长URL对应一个短URL,还是可以对应多个短URL?这也是一个重大的选择问题
一般来说,对于长URL来说,在不同的地点、不同的用户等情况下,生成的短URL应该是不同的,这样可以在后端数据库中进行更好的数据分析。如果长URL和短URL一一对应,那么数据库中就只有一行数据,无法区分不同来源,从而无法进行数据分析。
使用这个7位短URL作为唯一ID,可以将各种信息链接到这个ID,例如生成该URL的用户名、所在网站、HTTP标头中的User Agent等。收集了这些信息以后是不是可以做大数据分析,挖掘数据的价值。 URL 缩短服务提供商的主要利润来源就是这些数据。
正确答案:一对多
如何计算短网址
现在我们已经将短网址设置为长度为7的字符串,那么如何计算这个短网址呢?
最容易想到的方法是散列。首先哈希得到一个64位整数,将其转换为62位整数,并截取低7位。但哈希算法会产生冲突,如何处理冲突又是一个麻烦。这种方法只是转移矛盾,并不能解决矛盾,只能放弃。
MySQL数据库有一个自动递增的ID。我们可以从中学习吗?每次传入一个长 URL 时,都会向其发送一个数字,并且这个数字不断自行增加。与散列相比,这种方法的优点是不存在冲突,不需要考虑冲突处理的问题。如何实现单一发号服务器?你可以使用MySQL服务器(一定要使用INTO,不要存储所有ID),也可以使用Redis服务器(使用INCR),无需编写一行代码;也可以自己写一个API,代码也很简单,就不用赘述了。
单号发射机有哪些缺点?是单点故障(SPOF,Point Of),也会成为性能瓶颈(其实如果你的QPS能够大到可以压垮这个MySQL,说明你的短网址服务非常成功,你可以考虑列出来:D),所以适合中小企业。对于非常大的企业(以及面试中追求高端的企业),我们还是要继续思考更好的解决方案,请继续阅读。
我们先来看看如何创建一个由多台机器组成的分布式调度器。
或者使用UUID算法生成。其实可以看成是UUID的一种。通过这种算法,每台机器都可以独立工作,并且是天然的分布式。然而,这种算法生成的ID通常很长。那么短网址服务的意义何在呢?所以这个方法行不通。
多个 MySQL 服务器。前面提到,采用单台MySQL作为发行服务器,自然可以进行扩展。例如,如果使用8个MySQL服务器一起工作,第一个MySQL的初始值为1,每次增加8,第二个MySQL的初始值为2,每次增加8,依此类推在。前面被循环负载阻塞。每当一个长URL请求到来时,轮询随机将请求发送到10台MySQL服务器中的任意一台,然后返回一个ID。这是使用的解决方案,仅使用两台 MySQL 服务器。这种方法唯一的缺点是ID是连续的,容易被爬虫抓取。爬虫基本上不需要写代码。他们只是沿着ID一一发送请求。真是太方便了(手动眯眼)。
分布式 ID 生成器 (Id)。以分布式方式生成唯一ID。例如,有一个成熟的开源项目专门从事这方面的工作。核心算法如下:
最高位不使用,最高位不使用,始终为0。其余三组位位置可以浮动,根据具体业务需求而定。默认情况下,41位时间戳可以支持使用该算法直到2082年,10位工作机器ID可以支持1023台机器,序列号支持1毫秒生成4095个自增序列ID。
采用类似的方案,41位表示时间戳,13位表示分片ID(一个分片ID对应一台机器),最低10位表示自增ID。怎么样?它与设计非常相似。该解决方案使用集群而不是集群。优点是使用现成的解决方案,易于理解,易于维护。
因此,正确答案: (ID)、Flick、解决方案都是不错的选择。
如何储存
如何存储短网址和长网址的对应关系?以短URL为key,长URL为value,可以存储在传统的关系型数据库中,比如MySQL,也可以存储在任何分布式KV数据库中,比如Redis。
如果你想手动设计这个存储,那就是另一个话题了。你需要完整构建一个KV存储引擎轮子。目前流行的KV存储引擎有哪些?阅读他们的源代码。
301 或 302 重定向
这也是一个有趣的问题。这道题主要考验你对301和302的理解,以及对浏览器缓存机制的理解。
301 是永久重定向,302 是临时重定向。短地址一旦生成就不会改变,因此使用301与http语义一致。但如果使用301、百度等搜索引擎,搜索时会直接显示真实地址,那么我们就无法统计短地址被点击的次数,也无法收集用户的、用户的信息。代理等信息。这些信息可以用来做很多有趣的大数据分析,也是URL缩短服务提供商的主要利润来源。
所以,正确答案是 302 重定向。
您可以抓包看看新浪微博的短网址是如何制作的。使用浏览器访问此 URL。是我提前发微博时自动生成的一个短网址。我们来抓包看看返回的结果是什么。
可以看到,新浪微博使用了302临时重定向。
防止攻击
如果一些别有用心的黑客在短时间内向服务器发送大量请求,很快ID就耗尽了,我们该怎么办?
首先,限制每天的IP请求总数。如果数量超过阈值,则直接拒绝服务。
单纯限制IP请求数量是不够的,因为黑客一般都有上百万的肉鸡和IP地址,所以仅仅限制IP的作用不大。
您可以使用 Redis 作为缓存服务器。不是存储 ID->长 URL,而是存储长 URL->ID。只存储一天内的数据,采用LRU机制淘汰。这样,如果黑客大量发送相同的长URL并直接从缓存服务器返回短URL,他将无法用完我们的ID。