相信大家在生活中,特别是最近的双十一活动期间,会收到很多短信,而那些短信都有两个特征,第一个是几乎都是垃圾短信,这个特点此处可以忽略不计,第二个特点是链接很短,比如下面这个:
我们知道,短信有些是有字数限制的,直接放一个带满各种参数的链接,不合适,另外一点是,不想暴露参数。好处无非以下:
太长的链接容易被限制长度
短链接看着简洁,长链接看着容易懵
安全,不想暴露参数
可以统一链接转换,当然也可以实现统计点击次数等操作
那背后的原理是什么呢?怎么实现的?让你实现这样的系统,你会怎么设计呢?【来自于某鹅场面试官】
短链接的原理短链接展示的逻辑这里最重要的知识点是重定向,先复习一下http的状态码:
分类含义1**服务器收到请求,需要请求者继续执行操作2**成功,操作被成功接收并处理3**重定向,需要进一步的操作以完成请求4**客户端错误,请求包含语法错误或无法完成请求5**服务器错误,服务器在处理请求的过程中发生了错误那么以 3 开头的状态码都是关于重定向的:
300:多种选择,可以在多个位置存在
301:永久重定向,浏览器会缓存,自动重定向到新的地址
302:临时重定向,客户端还是会继续使用旧的URL
303:查看其他的地址,类似于301
304:未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。
305:需要使用代理才能访问到资源
306:废弃的状态码
307:临时重定向,使用Get请求重定向
整个跳转的流程:
1.用户访问短链接,请求到达服务器
2.服务器将短链接装换成为长链接,然后给浏览器返回重定向的状态码301/302
301永久重定向会导致浏览器缓存重定向地址,短链接系统统计访问次数会不正确
302临时重定向可以解决次数不准的问题,但是每次都会到短链接系统转换,服务器压力会变大。
3.浏览器拿到重定向的状态码,以及真正需要访问的地址,重定向到真正的长链接上。
从下图可以看出,确实链接被302重定向到新的地址上去,返回的头里面有一个字段Location就是所要重定向的地址:
短链接怎么设计的?全局发号器
肯定我们第一点想到的是压缩,像文件压缩那样,压缩之后再解压还原到原来的链接,重定向到原来的链接,但是很不幸的是,这个是行不通的,你有见过什么压缩方式能把这么长的数字直接压缩到这么短么?事实上不可能。就像是Huffman树,也只能对那种重复字符较多的字符串压缩时效率较高,像链接这种,可能带很多参数,而且各种不规则的情况都有,直接压缩算法不现实。
那https://dx.10086.cn/tzHLFw与https://gd.10086.cn/gmccapp/webpage/payPhonemoney/index.html?channel=之间的装换是怎么样的呢?前面路径不变,变化的是后面,也就是tzHLFw与gmccapp/webpage/payPhonemoney/index.html?channel=之间的转换。
实际也很简单,就是数据库里面的一条数据,一个id对应长链接(相当于全局的发号器,全局唯一的ID):
idurl1https://gd.10086.cn/gmccapp/webpage/payPhonemoney/index.html?channel=这里用到的,也就是我们之前说过的分布式全局唯一ID,如果我们直接用id作为参数,貌似也可以:https://dx.10086.cn/1,访问这个链接时,去数据库查询获得真正的url,再重定向。
单机的唯一ID很简单,用原子类AtomicLong就可以,但是分布式的就不行了,简单点可以用 redis,或者数据库自增,或者可以考虑Zookeeper之类的。
id 转换策略但是直接用递增的数字,有两个坏处:
数字很大的时候,还是很长
递增的数字,不安全,规律性太强了
明显我们平时看到的链接也不是数字的,一般都是大小写字母加上数字。为了缩短链接的长度,我们必须把id转换掉,比如我们的短链接由a-z,A-Z,0-9组成,相当于62进制的数字,将id转换成为62进制的数字:
publicclassShortUrl{privatestaticfinalStringBASE="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";publicstaticStringtoBase62(longnum){StringBuilderresult=newStringBuilder();do{inti=(int)(num%62);result.append(BASE.charAt(i));num/=62;}while(num>0);returnresult.reverse().toString();}publicstaticlongtoBase10(Stringstr){longresult=0;for(inti=0;i<str.length();i++){result=result*62+BASE.indexOf(str.charAt(i));}returnresult;}publicstaticvoidmain(String[]args){//tzHLFwSystem.out.println(toBase10("tzHLFw"));System.out.println(toBase62(27095455234L));}}id转 62位的key 或者key装换成为id都已经实现了,不过计算还是比较耗时的,不如加个字段存起来,于是数据库变成了:
idkeyurl27095455234tzHLFwhttps://gd.10086.cn/gmccapp/webpage/payPhonemoney/index.html?channel=但是这样还是很容易被猜出这个id和key的对应关系,要是被遍历访问,那还是很不安全的,如果担心,可以随机将短链接的字符顺序打乱,或者在适当的位置加上一些随机生成的字符,比如第1,4,5位是随机字符,其他位置不变,只要我们计算的时候,将它对应的关系存到数据库,我们就可以通过连接的key找到对应的url。(值得注意的是,key必须是全局唯一的,如果冲突,必须重新生成)
一般短链接都有过期时间,那么我们也必须在数据库里面加上对应的字段,访问的时候,先判断是否过期,过期则不给予重定向。
性能考虑如果有很多短链接暴露出去了,数据库里面数据很多,这个时候可以考虑使用缓存优化,生成的时候顺便把缓存写入,然后读取的时候,走缓存即可,因为一般短链接和长链接的关系不会修改,即使修改,也是很低频的事情。
如果系统的id用完了怎么办?这种概率很小,如果真的发生,可以重用旧的已经失效的id号。
如果被人疯狂请求一些不存在的短链接怎么办?其实这就是缓存穿透,缓存穿透是指,缓存和数据库都没有的数据,被大量请求,比如订单号不可能为-1,但是用户请求了大量订单号为-1的数据,由于数据不存在,缓存就也不会存在该数据,所有的请求都会直接穿透到数据库。如果被恶意用户利用,疯狂请求不存在的数据,就会导致数据库压力过大,甚至垮掉。
针对这种情况,一般可以用布隆过滤器过滤掉不存在的数据请求,但是我们这里id本来就是递增且有序的,其实我们范围大致都是已知的,更加容易判断,超出的肯定不存在,或者请求到的时候,缓存里面放一个空对象也是没有问题的。
【作者简介】: 秦怀,公众号【秦怀杂货店】作者,技术之路不在一时,山高水长,纵使缓慢,驰而不息。个人写作方向:Java源码解析,JDBC,Mybatis,Spring,redis,分布式,剑指Offer,LeetCode等,认真写好每一篇文章,不喜欢标题党,不喜欢花里胡哨,大多写系列文章,不能保证我写的都完全正确,但是我保证所写的均经过实践或者查找资料。遗漏或者错误之处,还望指正。
logo设计
创造品牌价值
¥500元起
APP开发
量身定制,源码交付
¥2000元起
商标注册
一个好品牌从商标开始
¥1480元起
公司注册
注册公司全程代办
¥0元起
查
看
更
多
面试官说:你来设计一个短链接生成系统吧
1.用户访问短链接,请求到达服务器 2.服务器将短链接装换成为长链接,然后给浏览器返回重定向的状态码301\/302 301永久重定向会导致浏览器缓存重定向地址,短链接系统统计访问次数会不正确 302临时重定向可以解决次数不准的问题,但是每次都会到短链接系统转换,服务器压力会变大。3.浏览器拿到重定向的...
写了一个属于自己的操作系统(qyOS)
由于bootloader无法设置堆栈指针,因此如果你想用C++编写操作系统,就需要一段汇编程序来帮助你设置堆栈指针,以调用用C++编写的main函数。因此,操作系统的kernel应该包含两个程序:1. 一个是用汇编编写的loader.s,用于设置堆栈指针并将操作系统加载到内存;2. 用C++编写的操作系统kernel.cpp。基本框架有了...
面试内容运营常见问题
这个问题我相信大家都不陌生,而且也是对我们最重要的一个问题,当面试官问到这个问题,就说明对你很感兴趣,可以进一步了解。 1.心里首先有一个预期,同时对行业市场的工资水平应该有个了解吧。 2.面试之前如果能了解到该公司该职位的薪资范围最好,如果完全没有渠道能了解,那先尝试问对方“能不能介绍一下目前公司此...
SEO 面试技巧告诉我一下
1、自我的形象态度 个人形象一定要好,说话有底气。时刻保持面带微笑,能缓解紧张,也能将面试的压抑场景轻松化。2、专业知识方面 2.1 最重要的一点就是,千万不要说这个我不会,那个我不了解。可以变成 这个我还还在学习中,能够和您请教学习下呢?2.2 自我介绍有思路,面试官第一个开场就是你先...
怎么建立网站
一个杰出的网站,和实体公司一样,需要整体的形象包装和设计。准确的,有创意的CI设计,对网站的宣传推广有事半功倍的效果。具体的做法是: 1、设计网站的标志(logo) 就如同商标一样,标志是你站点特色和内涵的集中体现,看见标志就让大家联想起你的站点。标志的设计创意来自你网站的名称和内容: (1)网站有代表性的...
有人发给我短信说我手机中病毒了给了一个链接网站
这是一个恶意扣费的软件,如果你不慎安装上了立刻清除吧,打开这个软件里面罗列的病毒和木马都是子虚乌有,也就是你手机里面没有病毒但是软件会提示你有病毒,多流氓!结束进程立刻删除!!!
面试题目“网页设计人员最重要的能力是什么”怎么回答
在设计中要考虑主要读者群的背景和构成。 4.声音的正确运用能起到点睛的作用 随着网络技术的不断发展,声音也逐渐成为了网页制作过程中考虑的一个重要因素。如果能在五彩缤纷的网页中再加上美妙的声音,则有锦上添花的效果。由于声音是在空间上进行传播的,又具有延续性,因此音乐和声音可以为你的网站增添不少的精彩...
如何制作网页?
1、注册域名、域名注册要简短、有代表性、而且容易被客户记住的 2、租用服务器、服务器租用要稳定、安全、速度快、而且有及时的售后服务 3、使用成熟的CMS系统:pageadmin CMS、discuz cms 模板多、操作简单、使用方便、直接下载就能使用、官网有完善的功能插件、提供给客户下载使用的、方便客户日后扩展网站...
数据结构面试常见问题
数据结构面试常见问题 篇1 数据结构与算法,这个部分的内容其实是十分的庞大,要想都覆盖到不太容易。在校学习阶段我们可能需要对每种结构,每种算法都学习,但是找工作笔试或者面试的时候,要在很短的时间内考察一个人这方面的能力,把每种结构和算法都问一遍不太现实。所以,实际的情况是,企业一般考察一些看起来很基本...
苹果用光盘做系统教程视频
Time Machine 备份前会抹掉磁盘,如果你不想把整盘数据抹掉的话,要不就找一个空白的硬盘备份,要不就给要备份的移动硬盘单独分出一个苹果格式的文件分区来保存这个备份。 进入MAC 左上角的苹果图标菜单,选取“系统偏好设置”,找到Time Machine 开始备份,最好不要选自动备份,可以需要的时候自己手动备份,虽说是增量备...