简介相信大家在生活中都会收到很多短信,尤其是在最近的双十一活动期间,那些短信有两个特点。首先是它们几乎都是垃圾短信。这里可以忽略此功能。第二个特点就是链接很短,比如下面这样:我们知道有些短信是有字数限制的,所以直接放一个链接,各种参数,不合适,还有一点就是,不想暴露参数。好处不外乎以下几点:太长的链接容易被限制长度。短链接看起来简单,长链接看起来容易安全。如果不想暴露参数,可以统一链接转换。当然你也可以统计点击等操作。它背后的原理是什么??它是怎么发生的?你将如何设计这样一个系统?【来自一位鹅场面试官】短链接的原理短链接展示的逻辑这里最重要的知识点就是重定向。先查看http的状态码:分类含义1**服务器收到请求,需要请求者继续执行操作2**成功,成功接收并处理操作3**重定向,需要进一步操作完成请求4**客户端错误,请求包含语法错误或无法完成请求5**服务器错误,服务器正在处理如果请求过程中出现错误,3开头的状态码都是关于重定向的:300:多个options,可以存在多个位置301:永久重定向,浏览器会缓存并自动重定向到新的地址302:临时重定向,客户端会继续使用旧的URL303:查看其他地址,类似301304:未修改.请求的资源没有被修改。服务器返回此状态码时,不会返回任何资源。305:访问资源需要代理306:过时状态码307:临时重定向,使用Get请求重定向整个跳转过程:1.用户访问短链接,请求到达服务器2.服务器将短链接替换成长链接,然后将重定向的状态码301/302301返回给浏览器。永久重定向会导致浏览器缓存重定向地址。短链接系统不会正确统计访问次数。302临时重定向可以解决时间不准确的问题。但是每次切换到短链接系统,服务器的压力都会增加。3、浏览器得到重定向的状态码和真正需要访问的地址,重定向到真正的长链接。从下图可以看出,链接确实被302重定向到了一个新的地址,并且在返回的header中有一个字段Location,就是要重定向的地址:如何设计短链接?全局数生成器肯定我们第一个想到的就是压缩,像文件压缩一样,压缩后,解压还原到原来的链接,重定向到原来的链接,可惜,这个不行,你有没有见过有什么压缩方法可以直接把这么长的数字压缩成这么短的数字吗?其实不可能。就像哈夫曼树一样,它只能更高效地压缩重复字符较多的字符串。像链接,可能参数很多,还有各种不规则的情况,所以直接压缩算法是不现实的。.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/w...这里用到了,也就是我们之前说的分布式全局唯一ID,如果我们直接把id作为参数,好像就可以了:https://dx.10086.cn/1,访问的时候这个链接,去数据库查询得到真实的url,然后重定向。单机的唯一ID很简单。原子类AtomicLong可以用,分布式的不行。简单点的可以用redis,或者数据库自增,也可以考虑Zookeeper之类的。而直接使用递增数的id转换策略有两个缺点:当数很大时,还是很长的递增数,不安全,正则性太强。显然,我们平时看到的链接并不是数字。它是大写和小写字母加上数字。为了缩短链接的长度,我们必须转换id。比如我们的短链接是由a-z、A-Z、0-9组成的,相当于一个62位的数字。将id转换为62位数字:publicstaticStringtoBase62(longnum){StringBuilderresult=newStringBuilder();做{inti=(int)(num%62);));数/=62;}while(num>0);返回结果.reverse().toString();}publicstaticlongtoBase10(Stringstr){longresult=0;对于(inti=0;i