短URL链接系统
定义:
短网址(Short URL),顾名思义就是在形式上比较短的网址。但不知道有多少人像我一样,由于面试问道才知道有这种系统而对短连接原理好奇,从而进行进一步的研究。在Web 2.0的今天,不得不说,这是一个潮流。目前已经有许多类似服务(短网址服务,现在大部分微博、手机邮件提醒等地方已经有很多应用模式了,并占据了一定的市场),借助短网址您可以用简短的网址替代原来冗长的网址,让使用者可以更容易的分享链接。例如:http://t.cn/SzjPjA。
自从twitter推出短网址(shorturl),继之国内各大微博跟风,google公开goo.gl使用API,短网址之风愈演愈烈。不得不说这是一个新兴又一大热门web2.0服务。
为什么要这样做的,原因我想有这样几点:
1、微博限制字数为140字一条,那么如果我们需要发一些连接上去,但是这个连接非常的长,以至于将近要占用我们内容的一半篇幅,这肯定是不能被允许的,所以短网址应运而生了。
2、短网址可以在我们项目里可以很好的对开放级URL进行管理。有一部分网址可以会涵盖暴力,广告等信息,这样我们可以通过用户的举报,完全管理这个连接将不出现在我们的应用中,应为同样的URL通过加密算法之后,得到的地址是一样的。
3、我们可以对一系列的网址进行流量,点击等统计,挖掘出大多数用户的关注点,这样有利于我们对项目的后续工作更好的作出决策。
短连接构成:
协议+域名+参数
例如:http://t.cn/SzjPjA 主要是参数:SzjPjA。这个是唯一标识。
短链接的好处:
1、内容需要;
2、用户友好;
3、便于管理。
短连接用途:
最简单的用途就是他的名字直译“短”的“链接”,可以把长长的一串链接(例如:亚马逊的购买链接)缩短成为几个简单的字符。
短连接原理:
短连接原理非常简单,就是用户访问短连接地址,到达我们的短连接网站,然后网站通过短连接里的code,查询数据库得到原始url,然后让网页跳转到原始url即可。
1、针对小型应用:
1)通过发号策略,给每一个过来的长地址,发一个号即可,小型系统直接用mysql的自增索引就搞定了。
2)创建一张数据库表,仅需要有2列即可:code列和url列。code列也就是标识列,建议直接设置为自增主键。用于存储短连接参数代码,也就是短连接里的code。
url列用于存储要跳转的原始url。
2、针对大型应用:
可以考虑各种分布式key-value系统做发号器。不停的自增就行了。第一个使用这个服务的人得到的短地址是http://xx.xx/0 第二个是 http://xx.xx/1 第11个是 http://xx.xx/a
依次往后,相当于实现了一个自增字段即可。
所说的链接推广分析功能,就是在这个过程中,记录访客的某些信息,例如:访问时间、访问的短链接、访客的IP、访客的UserAgent信息等。基于这些信息,配合推广方式,就可以辅助判断出什么时间,什么范围,什么人群的推广更有曝光效果。
短链接实现方法:
面试时,我的回答:
1、小型的就用数据库就好,利用自增ID作为参数;
2、大型的也就是高并发的情况,使用redis这种k-v存储系统进行存储。我的思路如下:利用列表存储,每个列表存储1万个数据;redis中每个列表的key从1开始(也就是对1万做整除);如果想得到某个短链接对应的原地址,那就通过divmod函数进行计算,他的商就代表是第几个列表,余数代表他的位置。这样去获取。
3、如果使用redis去实现的化,怎么保证你的系统内存不被撑爆?就是说我上一种存储机制是完全把数据存放在内存中的!我当时的回答是每隔一段时间做一次持久化。
4、内存的问题解决了,但是如果过一段时间我再来获取我存放的原url地址(假如我做持久化的时间是每隔12个小时,原数据已经存放到数据库中),这种情况怎么解决?我当时的回答是从数据表(表结构的设计是:原url,还有个num列)中批量获取一段数据,放入redis(但是这样的话就没有考虑高访问的情况,相当于是又把内存撑爆了)。
5、并发的问题。
网上查找得到的解决方案:(由简入难)
第一种:
26个大写字母 26小写字母,10个数字,随机生成6个然后插入数据库对应一个id,短连接跳转的时候,根据字符串查询到对应id,即可实现相应的跳转!不过2的62次方,不知道有没有重复的,小概率可以,但是对应不是很大的网站应该足够了。
第二种:
通过发号策略进行存储
几个子问题:
1、如何用数据库或者KV存储来做?
用10进制去记录。比如第10000个长地址,我们给它的短地址对应的编号是9999,我们通过存储自增拿到9999后,作为参数加到短链接之后;另一种方式就是拿到这个数之后,再做一个进制转换,例如10进制转成16进制(晋级版的可以考虑加密)。
2、如何实现同一个长地址多次转换,出来还是同一个短地址?
上面的发号原理中,是不判断长地址是否已经转过的。也就是说用拿着百度首页地址来转,我给一个http://xx.xx/abc 过一段时间你再来转,我还会给你一个 http://xx.xx/xyz。这看起来挺不好的,但是不好在哪里呢?不好在不是一一对应,而一长对多短。这与我们完美主义的基因不符合,那么除此以外还有什么不对的地方?
有人说它浪费空间,这是对的。同一个长地址,产生多条短地址记录,这明显是浪费空间的。那么我们如何避免空间浪费,有人非常迅速的回答我,建立一个长对短的KV存储即可。嗯,听起来有理,但是。。。这个KV存储本身就是浪费大量空间。所以我们是在用空间换空间,而且貌似是在用大空间换小空间。真的划算吗?这个问题要考虑一下。当然,也不是没有办法解决,我们做不到真正的一一对应,那么打个折扣是不是可以搞定?
这个方案最简单的是建立一个长对短的hashtable,这样相当于用空间来换空间,同时换取一个设计上的优雅(真正的一对一)。而实际情况是有很多性价比高的打折方案可以用。我的方案是:用key-value存储,保存“最近”生成的长对短的一个对应关系。注意是“最近”,也就是说,我并不保存全量的长对短的关系,而只保存最近的。比如采用一小时过期的机制来实现LRU淘汰。
这样的话,长转短的流程变成这样:
1.0 在这个“最近”表中查看一下,看长地址有没有对应的短地址
1.1 有就直接返回,并且将这个key-value对的过期时间再延长成一小时
1.2 如果没有,就通过发号器生成一个短地址,并且将这个“最近”表中,过期时间为1小时
所以当一个地址被频繁使用,那么它会一直在这个key-value表中,总能返回当初生成那个短地址,不会出现重复的问题。如果它使用并不频繁,那么长对短的key会过期,LRU机制自动就会淘汰掉它。
当然,这不能保证100%的同一个长地址一定能转出同一个短地址,比如你拿一个生僻的url,每间隔1小时来转一次,你会得到不同的短地址。这样做对整个短系统是没有影响的。
3、如何保证发号器的大并发高可用?
上面设计看起来有一个单点,那就是发号器。如果做成分布式的,那么多节点要保持同步加1,多点同时写入,这个嘛,以CAP理论看,是不可能真正做到的。其实这个问题的解决非常简单,我们可以退一步考虑,我们是否可以实现两个发号器,一个发单号,一个发双号,这样就变单点为多点了?依次类推,我们可以实现1000个逻辑发号器,分别发尾号为0到999的号。每发一个号,每个发号器加1000,而不是加1。这些发号器独立工作,互不干扰即可。而且在实现上,也可以先是逻辑的,真的压力变大了,再拆分成独立的物理机器单元。1000个节点,估计对人类来说应该够用了。如果你真的还想更多,理论上也是可以的。
4、具体存储如何选择?
这个问题就不展开说了,各有各道,主要考察的是对存储的理解。对缓存原理的理解,和对市面上DB、Cache系统可用性,并发能力,一致性等方面的理解。
5、跳转用301还是302?
这也是一个有意思的话题。首先当然考察一个候选人对301和302的理解。浏览器缓存机制的理解。然后是考察他的业务经验。301是永久重定向,302是临时重定向。短地址一经生成就不会变化,所以用301是符合http语义的。同时对服务器压力也会有一定减少。
但是如果使用了301,我们就无法统计到短地址被点击的次数了。而这个点击次数是一个非常有意思的大数据分析数据源。能够分析出的东西非常非常多。所以选择302虽然会增加服务器压力,但是我想是一个更好的选择。
短URL链接系统的更多相关文章
- ios系统中各种设置项的url链接
ios系统中各种设置项的url链接 在代码中调用如下代码:NSURL*url=[NSURL URLWithString:@"prefs:root=WIFI"];[[UIApplic ...
- 短URL系统、301/302重定向
短 URL 系统是怎么设计的?https://yq.aliyun.com/articles/87600 短网址(short URL)系统的原理及其实现 https://hufangyun.com/20 ...
- 生成Area URL链接
关于Area的URL链接生成,可以分为这么三种情况:第一种是在当前Area生成指向当前Area的链接:第二种是生成指向其他Area的链接:第三种是在某个Area中生成指向根目录的链接.下面是这三种情况 ...
- Python 网络爬虫 009 (编程) 通过正则表达式来获取一个网页中的所有的URL链接,并下载这些URL链接的源代码
通过 正则表达式 来获取一个网页中的所有的 URL链接,并下载这些 URL链接 的源代码 使用的系统:Windows 10 64位 Python 语言版本:Python 2.7.10 V 使用的编程 ...
- 二维码及二维码接合短URL的应用
二维码 1.什么是二维码? 二维条形码,最早发明于日本,它是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的,在代码编制上巧妙地利用构成计算机内部逻辑基础的“0 ...
- 短URL生成
算法原理 算法一 1)将长网址md5生成32位签名串,分为4段, 每段8个字节; 2)对这四段循环处理, 取8个字节, 将他看成16进制串与0x3fffffff(30位1)与操作, 即超过30位的忽略 ...
- Go 实现短 url 项目
首先说一下这种业务的应用场景: 把一个长 url 转换为一个短 url 网址 主要用于微博,二维码,等有字数限制的场景 主要实现的功能分析: 把长 url 地址转换为短 url 地址 通过短 url ...
- django简单实现短url
一.短url的原理 什么是短url: 简单讲就是把普通正常访问的网址,转换成比较短的网址,例如:https://www.cnblogs.com/angelyan/articles/10667354.h ...
- 【干货】零基础30分钟让你拥有一个完整属于自己的短视频APP系统
目录 一.附言: 1 二.购买域名和购买服务器: 2 三.搭建服务器环境: 5 四.配置APP前端部分: 8 1.工具以及文件准备: 9 2.配置后端接口地址 11 3.配置APP启动图和启动图标 ...
随机推荐
- django2中文界面
设置了中文语言 zh-hans后,django2默认页面是中文的. 看起来也不错哦. 创建django2超级管理员: createsuperuser 创建管理员后,就可以登录后台了. 注册用户user ...
- wxWidgets的配置
参考 :http://www.codeproject.com/Articles/11515/Introduction-to-wxWidgets 我是将D:\wxWidgets-3.0.1,中 编译过 ...
- visual studio 一些小技巧 整理
本博客将会陆续的整理一些作者在实际开发中的一些小技巧,一些挺有意思的东西,将会持续更新, 如果有问题,可以加群讨论,QQ群:592132877 #warning的使用 #warning 的意思是在程序 ...
- tensorflow 初学习
tenseroflow 拟合 y = ax*x+b构建神经网络主要分为 4 个步骤:构造数据.构建网络.训练模型.评估及预测模型.此外,还介绍了一些超参数设定的经验和技巧 #coding=utf-8 ...
- Android编程 高德地图 AMapLocationClientOption 类中 setWifiActiveScan过时
高德地图中 定位包中有以下方法: AMapLocationClientOption 类中 setWifiActiveScan 过时 isWifiActiveScan public boole ...
- 很让人受教的提高php代码质量的方法
1.不要使用相对路径 常常会看到: require_once('../../lib/some_class.php'); 该方法有很多缺点: 它首先查找指定的php包含路径, 然后查找当前目录. 因此会 ...
- POJ3422 Kaka's Matrix Travels 【费用流】*
POJ3422 Kaka's Matrix Travels Description On an N × N chessboard with a non-negative number in each ...
- Hexo+GitHub+Netlify一站式搭建属于自己的博客网站
喜欢的话请关注我的个人博客我在马路边https://hhongwen.cn/,此文为博主原创,转载请标明出处. 更好的阅读体验请点击查看:Hexo+GitHub+Netlify一站式搭建属于自己的博客 ...
- vmware linux nat模式设置静态ip
网上资料很多,但是都不怎么实用,这里给大家总结一下.nat模式上网.因为nat本身就能上网为什么还要设置ip.这有点自找麻烦.但是在集群这是必须的.要么你搭建伪分布,要么至少具有三台物理机器.为了节省 ...
- java创建多线程&创建进程
概述 并发和并行是即相似又有区别: 并行:指两个或多个事件在同一时刻发生: 并发:指两个或多个事件在同一时间段内发生. 进程是指一个内存中运行中的应用程序.每个进程都有自己独立的一块内存空间,一个应用 ...