什么是短链接?
想要了解什么是短链接,就需要先知道为什么有短链接这个名字。我们正常浏览互联网内容的时候,若是使用浏览器,浏览器在每个网页的地址栏都会显示一个或者很短(例如百度https://www.baidu.com/
、哔哩哔哩https://www.bilibili.com/
)或者很长(https://list.iqiyi.com/www/1/-------------8-1-1-iqiyi--.html
)或者更长的地址。这种地址一般被称为链接,或者也可叫做长链接。在HTTP协议规范中,并未对链接进行长度限制,但是大部分浏览器和web服务器都会对请求的链接长度进行规定。
浏览器 | 长度 |
---|---|
IE 11 | 2047 |
Firefox | 大于64K |
Chrome | 32779 |
Safari | 大于64K |
注:若是目前上述浏览器对链接长度的限制和表格中不一致,可能是由于版本差异。
互联网上的内容是无穷无尽的,而且每天都在产生大量的新内容,链接用来唯一标识互联网上的内容,内容越来越多就导致链接越来越长。长链接首先带来的最明显的问题是难于记忆,不过由于各种方便的记录链接的工具,很多链接也都不需要直接记忆了。
和长链接相对应的就是短链接,可能会有人疑问,链接尽量用很少的字符组成不就是短链接了?但是互联网内容的庞大会导致这种方法很难实现。更为实际的方法是使用一种转换方法,能够把一个长链接对应到一个短链接。互联网中所有的内容都有长链接,但是并不是所有的内容都需要短链接来表示,仅在需要的时候才把长链接转换为短链接,而且这种情况仅仅是互联网内容的冰山一角。
常见的短链接形式类似suo.im/65VL1n
,貌似是一串毫无意义的字符,从中并不能看到链接的域名等相关信息。
为什么使用短链接?
内容长度限制
在某些场景下,长链接的使用会捉襟见肘甚至不能使用。首先是短信领域,使用手机短信进行营销活动时,需要把活动的链接通过短信发送给目标用户,长链接过长就会占用短信过多内容导致短信总体内容太长,由于国际标准的限制,每条短信会有最大长度限制,若是长度过长则会导致发送失败(营销活动无法触达用户)或者分多条发送(营销成本上涨)。其次随着twitter、微博类似的社交媒体的发展壮大,更多的人喜欢在这样的社交媒体上发声,但是微博在早期对用户发送的单条博文内容进行长度限制(最长140字),导致用户在使用微博分享其他链接时出现内容过长的问题(虽然后续新浪微博开启长微博的功能,但是过长的链接和博文内容混合会导致观看体验很差)。
即使没有上述条件的约束,在某些可用长链接的场景下,也可以使用短链接带来额外的好处。
- 匿名访问:隐藏访问来源,在最终页面通过
HTTP
的请求体Refer
字段获取不到跳转前的来源。 - 密码访问:对某些链接想设置密码访问,但是不能实现直接对原来的链接进行密码控制,就可以通过对原始链接转换后的短链接进行访问控制来实现目的(此时原始链接是没有访问控制的,但是链接的生成没有规律可言,便可以认为没有人能访问到原始链接),同密码访问类似,也可以对某个短链接限定访问次数、访问时段、访问黑白名单来控制访问。
- 访问统计:通过统计对短链接的访问数便可以得到原始链接的访问量,在移动互联网下,可针对不同的客户端(Android、IOS、PC、MAC)生成不同的短链接来统计不同客户端的访问量。
- 简化二维码:二维码图案的复杂度和原始信息的大小成正相关,过长的链接会导致生成的二维码图片过于复杂,降低二维码识别的成功率。
- 降低权重传递:在搜索引擎领域,存在链接权重传递的现实。即如果
链接A
有很多人访问,通过搜索引擎搜索链接A
相关内容时,会把链接A
放在搜索结果的前面,若是在一个没有很多访问量的链接B
中引入链接A
,就让搜索引擎在扫描链接关系时赋予链接B
稍高的权重,导致搜索链接B
相关内容时会把链接B
放在搜索结果的前面。使用短链接就可以打破原有的依赖链(从链接A>链接B
变成链接A>短链接>链接B
)。
如何生成短链接?
短链接服务
目前有很多提供短链接生成的服务,需要使用短链接的时候,直接调用相关服务进行转化即可。
短链接和原始链接的对应
这里我们把原始链接(https://item.jd.com/11757834.html
)转换为短链接(http://suo.im/6tbhV9
)。可见短链接地址的域名段是suo.im
,所以要是想生成短链接,必须首先申请一个正常的域名,而且这个域名越短越好。短链接的后半部分6tbhV9
应该就是在此短链接服务中标识原始链接的字符串。
如何引导浏览器通过短链接访问到原始链接呢?
在浏览器的地址栏键入http://suo.im/6tbhV9
,然后查看请求过程。
首先服务端返回浏览器302
,在HTTP协议中,30X
的错误码都表示重定向请求,此时服务端会返回新的地址,放在响应头的Location
字段中,浏览器重定向到该地址。
服务端返回了原始链接,浏览器再请求原始链接即成功引导浏览器通过短链接访问到原始链接。
注:关于使用短链接时,浏览器请求短链接,服务端返回301
和302
的争议。301 Moved Permanently永久重定向
表示请求的链接已经不可用,后续的请求都直接向服务端返回的Location字段的新地址请求,并且浏览器会缓存新地址。也就是说后续再请求短链接时,浏览器根据缓存的新地址直接请求,此时服务端是收不到对短链接的请求的,这样的话如果需要通过短链接来完成一些高级功能(统计、控制访问等)就不能实现了,但是能够降低服务端的请求压力。302 Moved Temporarily 临时重定向
表示链接只是暂时不可用,浏览器不会缓存新地址,每次都会向服务端请求短链接,然后服务端返回302
并且携带新地址。这样的话不会影响依赖短链接才能完成的高级功能,但是增加了服务端的压力。
所以关于请求短链接返回301
还是302
,要根据实际情况来定,综合考虑业务对网络延迟的敏感度、对短链接提供的高级功能的依赖性。
设计短链接生成服务
首先,也是最重要的,申请一个尽量短的域名。
后续的过程本质就是一个发号的过程,每当对一个长链接生成短链接时,就生成一个唯一标识,附加于短域名后,然后记录下对应关系并返回生成的短链接。后续有对原始链接的请求时,查询对应表,若是查询到就返回301
或302
并返回查询到的原始链接即可。
可见整个系统中关键的两点是,唯一标识生成和对应表存储。关于存储对应表的服务,由于只是存储简单的K-V
关系,所以可以采用类似Redis的K-V
数据库。
唯一标识生成的方案多种多样。
- 数据库自增ID:实现简单,但是需要依赖数据库,需要保证数据库服务的高可用,并且当主键自增到一个很大值(9223372036854775808),同样会让链接稍微有点长。
- UUID方案:UUID若是使用全部字段,则链接过长,若是使用部分较少,就会容易碰撞,同时由于UUID不是统一中心生成,也会造成唯一标识重复。
观察http://suo.im/6tbhV9
这个连接,可以发现唯一标识部分是6位由数字和字母组成的字符,如果我们采用类似的生成方案,生成的ID是从10数字、26个大写字母和26个小写字符中选取6个字符组成,则所有的组成共有62^6 = 56800235584
种,若是使用耗尽便可以通过增加字符数来生成更多ID(由于在实际的使用中,某些短链接有时效性,便可以节约一定ID)。
如何在采用上述方案时保证高可用呢?可以采用按段生成的方案,首先划分一定的服务(例如5个服务),服务1生成的ID第一位为数字,服务2生成的ID第一位为大写的字母从A-N...。这样提高服务的可用性可以通过增加服务数量的方法简便实现,然后增加服务自恢复和负载方案,可以保证整体服务有更高的可用性。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。