神奇又有趣的短链服务系统
文章目录
- 为什么要使用短链?
- 如何实现短链?
- 62进制
- 实现短链服务
- 总结
大家在刷微博或者在接收短信时应该都会注意过类似这样的链接url:
weibo.com/4yBWU
weibo.com/42Ipf
weibo.com/2BmFL
weibo.com/23rwx
这些链接通常非常简短,仅此被称为短链,但是当你点击这些短链后却会发现真实的url其实是一个很长的链接,类似这样:
weibo.com/prd/direction.html?pageId=51e3d088bbfa489e818462a9d84167ff&pwId=dedb75e7516e46b29f181754ecffadb6&channelId=10010001005
效果就是明明你在浏览器中输入的是一个短链接,但是回车后这个链接变成了一个很长的链接。你有没有好奇过为什么微博或者短信中的链接都非常短,这样有什么好处,这一切又是如何实现的呢?
为什么要使用短链?
我们知道发微博是有字数限制的,当博主试图转发一个链接时如果链接本身很长就像上面这个链接的话那么博主的内容会受到很大的限制,因此为了节省链接本身占用的空间微博中大量使用了短链。
而对于短信来说,我们通常收到的垃圾短信其实是有商家希望推广某种商品发出来的,发送短信当然要收商家的钱,这些都是按字数收费的,当然字数越少费用就越低,因此短链也被大量应用于推广短信当中。
那么这一切都是如何实现的呢?
如何实现短链?
短链服务的功能非常简单,无非就是把类似:
weibo.com/prd/direction.html?pageId=51e3d088bbfa489e818462a9d84167ff&pwId=dedb75e7516e46b29f181754ecffadb6&channelId=10010001005
转为类似:
weibo.com/4yBWU
其实也就是把一个“长字符串转为短字符串”,当用户点击短链的时候我们只需要查找该短链对应的真实链接并把用户重定向过去就可以了。
那么这里的问题是该如何把一个长字符串转为唯一的一个短字符串呢?
可能大家第一个想到的就是hash,没错,通过将长字符串进行hash可以实现上述目的,但是不要忘了hash会存在冲突的可能性,也就是有可能两个长链都映射到了某个短链上,有的同学也许会想这样的概率很低吧,但是不要忘了像微博体量的内容,其短链的数量可能会有上百亿,在这种情况下使用hash显然就不满足要求了。
在这里我们需要一个短链和长链是唯一对应的,那么最简单的方法就是给每个长链唯一编号,我们可以从1开始给每个长链依次编号,这样短链的形式就是这了:
weibo.com/1
weibo.com/2
weibo.com/3
weibo.com/4
但是这样的方案会存在很多问题,比如这样简单的方法就给了爬虫很大的便利,只需要简单写个脚本就可以拿到微博几乎所有的内容;而且该方案对于编号很大的长链接来说依然会占用较多的字符,像十亿(1000000000)这样的数字依然占用了10位数,因此简单的编号不可用。
我们看到了简单采用计数的方法有很多缺点,那么该如何改进呢?
本质上这其实就是需要对:
1,2,3,4,5,6,7,8,9,10......
这样的依次递增计数方法换一种不是那么直观而且又节省长度的计数方式。
62进制
说道节省数字本身的长度,有的同学第一反应可能就是使用更大的进制来计数:
对于二进制数来说,6个二进制数字可以表示2^6,也就是64个数;
对于十进制数来说,6个十进制数字可以表示10^6,也就是一百万个数;
对于十六进制来说,6个十六进制数字可以表示16^6,也就是超过一千六百万个数;
而对于人类熟悉的数字(09)、小写字母(az)、大写字母(A-Z),这些字符加起来有62个数字,因此我们可以使用62进制数,那么6个62进制数字可以表示62^6个数,也就是超过500亿,我们只需要6位62进制数就可以表示超过500亿个短链。
那么我们该如何把一个10进制的id转为一个由数字(09)、小写字母(az)、大写字母(A-Z)表示的62进制数呢?相信这应该难不倒聪明的你吧,这应该是学习C语言时入门级别的练习题难度,C++版如下所示:
string long_url_2_short_url(long int id){string base = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";string url;while(id) {url = (char)(base[id % 62]) + url;id /= 62;}return url;
}
代码非常简单,核心仅有6行代码,输入60000000该函数会返回43kjw,显然weibo.com/43kjw 比weibo.com/60000000好多了。
现在我们已经成功的将十进制id转为62进制的短链了,那么给定一个短链我们该如何获取其id呢?代码也非常简单,无非就是把62进制数转为10进制:
long int short_url_2_id(string url) {long int id = 0;for(int i=0; i<url.length(); i++){if ('0'<=url[i] && url[i]<='9')id = id*62 + url[i] - '0';else if ('A'<=url[i] && url[i]<='Z')id = id*62 + url[i] - 'A' + 10;elseid = id*62 + url[i] - 'a' + 36;}return id;
}
实现短链服务
现在我们已经成功的将长链转为了短链,也可以根据短链获取到长链的id,那么接下来的任务就是实现重定向。
当用户点通过浏览器点击短链时,浏览器会向我们的短链服务发送请求,短链服务接收到情况后根据短链计算出长链的id,查询数据库后得到长链比如叫做real_url,然后告诉用户浏览器“hey,你跳转到的real_url吧”,那么短链服务该如何告诉用户浏览器跳转到真实的链接地址呢?
很简单,我们只需要将返回给浏览器的长链接加一个302的http返回码就可以了,用户浏览器接收到请求后发现是一个302的返回数据,这时浏览器就去请求该真实长链接了。
而我们之所以将其称为短链服务,是因为有一堆服务器,这些服务只做一件事那就是提供短链服务,包括:
- 将长链转为短链并放入数据库
- 将用户请求的短链重定向到真实的长链
也就是说对于短链,浏览器至少要发送两次请求才能获得真实的内容,一次发送给短链服务获取真实的长链,再一次请求真实的长链。
总结
在本篇中我们看到了一种很有意思的互联网服务,也就是短链服务,这种服务的目的就在于将一个长链接转为一个很简短的短链,当用户请求短链时将用户浏览器重定向到长链,这里涉及的原理非常简单,就是我们熟悉的进制转换。
但是在这里不想给大家一种互联网服务很easy的感觉,对于真实的短链服务来说还有很多要考虑的因素:
- 这里的短链实现方式其实依然没有解决很容易被爬虫爬取的缺点,因为62进制的43kj6的下一个数很直观就是43kj7,有没有更好的办法?
- 由于我们将所有长链都转为了短链,那么当用户请求到来时首先第一步就是请求短链服务,短链服务就成了一个关键点,一旦短链服务不可用影响极大,因此高并发、高可用是短链服务必须具备的,你知道这个短链服务的性能瓶颈会出现在哪里吗,你该如何优化系统性能,又该如何保证高可用呢?
这些都留给大家来思考。
更多计算机内功文章,欢迎关注微信公共账号:码农的荒岛求生。
彻底理解操作系统系列文章
1,什么程序?
2,进程?程序?傻傻分不清
3,程序员应如何理解内存:上篇
4,程序员应如何理解内存:下篇
计算机内功决定程序员职业生涯高度
神奇又有趣的短链服务系统相关推荐
- 一个完整的微服务系统,应该包含哪些功能?--转
原文地址:http://chuansong.me/n/405417651660 近几年,微服务架构迅速在整个技术社区窜红,它被认为是IT软件架构的未来方向,大神Martin Fowler也给微服务极高 ...
- 在Java中构建响应式微服务系统——第三章 构建响应式微服务
第三章 构建响应式微服务 在本章中,我们将使用Vert.x构建我们的第一个微服务.由于大多数微服务系统使用HTTP进行交互,因此我们将以HTTP微服务作为开始.但是由于系统包含多个相互通讯的微服务,因 ...
- 如何设计一个短链服务?
相信很多小伙伴都使用过短链服务,但如果让你实现一个短链服务,你知道怎么实现吗?其实实现短链服务并不是很难,最主要还是需要知道一些设计思路,还需要有一些基础技术知识,例如:哈希算法.全局发号器等. 短链 ...
- 自己做一个短链服务,设计思路分享!
其实实现短链服务并不是很难,最主要还是需要知道一些设计思路,还需要有一些基础技术知识,例如:哈希算法.全局发号器等. 下面一起来学习如何设计一个短链服务吧! 短链的价值 网址大家都知道,很长的一串字符 ...
- FarBox--另类有趣的网站服务【转】
FarBox--另类有趣的网站服务 转自:http://mosir.org/html/y2012/the-interesting-web-service-serve-by-FarBox.html 作者 ...
- java纳税服务_纳税服务系统【总结】
纳税服务系统总结 纳税服务系统是我第一个做得比较大的项目(不同于javaWeb小项目),该项目系统来源于传智Java32期,十天的视频课程(想要视频的同学关注我的公众号就可以直接获取了) 我跟着练习一 ...
- 纳税服务系统十一【抽取BaseService、条件查询】
tags: 纳税服务系统项目 抽取BaseService 到目前为止,我们已经写了三个模块的开发了.我们已经抽取过了BaseAction.BaseDao,我们这次来看看我们的Service接口. Us ...
- 动软发布微信营销服务系统,微信商城系统!
动软微信营销服务系统,是基于移动互联网发展趋势,集成了企业移动官网,微信公众平台,微信商城,微博营销等功能,旨在为企业建立一套微信移动营销和用户服务平台,快速抢占手机移动端用户市场,帮助企业在移动互联 ...
- java医疗框架,java毕业设计_springboot框架的城市智慧医疗服务系统
今天介绍一个java毕设题目, 题目内容为springboot框架的城市智慧医疗服务系统, 是一个采用b/s结构的javaweb项目, 采用java语言编写开发工具eclipse, 项目框架jsp+s ...
最新文章
- c语言sprt的程序怎么用,sqrt函数在c语言中怎么用?
- SetWindowRgn注意点
- 可变与不可变数据类型详解
- 不用比较运算符及循环控制语句,判断int型的a、b两数的大小
- android setimageresource取list的,Java ImageView.setImageTintList方法代码示例
- oracle数据库,增加序列,自增序列,规定位数,不足用0补足
- CentOS7.5搭建k8s集群
- 【C语言】矩阵乘法(二维数组)
- spark学习-76-目标:如何成为大数据Spark高手
- Spring框架----通用切入点表达式
- CSS3属性选择器(CSS3)
- ios 判断手机角度_iPhone那么贵,为什么电池还那么小呢?安卓手机电池都那么大了!...
- 管理感悟:如何看待培训
- 2021FME博客大赛 —— FME在道路实景建模中的应用研究
- SVN版本管理的回滚(SmartSVN)
- Android播放声音SoundPool、MediaPlayer、AudioTrack
- 一份Yann LeCun等16个顶级数据科学家给新人的建议
- 动态规划 01背包问题
- 流程引擎规则引擎_规则引擎的优势
- iOS Swift RxSwift 的使用(二)
热门文章
- java string 空间_Java中,String str = “Runoob”;这个语句中str和“Runoob”都占空间吗?分别占多大?...
- java的goto语句_语法 - Java中是否有goto语句?
- Linux编程之ioctl
- 萌新熟悉一下csdn
- 每个孩子都是天使派来陪伴我们的
- 栈的数学性质(Catalan函数)
- win7 ipv6的默认网关怎么填
- 魔方矩阵 幻方 九宫图 河洛图
- 367、POE交换机中1236和4578到底哪个供电?以及供电距离的选择
- 2018年末施瓦辛格热血演讲《关于成功·成功的真谛》—YouTuBe播放量超1个亿!盘它!