长连接转短连接问题

在互联网的实际场景中,将长连接转换成短连接的需求是非常常见的,在大厂的面试中出现的频率也是比较高的,进行就针对这个话题聊一聊。

首先对于一个短连接转换的系统来说,一定要包括这两个接口:

  • 将长连接转换成短连接
  • 通过短连接跳转到原来的长连接

所以对于系统来说是要将短连接和对应的长连接存储到磁盘上的,这里不局限于哪种存储,根据实际场景选择适合的就好。

转换算法

不知道大家在看到这个题目的时候会怎么想,到底怎么讲一个长链接转换成短的呢?是用什么算法吗?

这里告诉大家,根本没有这样的算法,大家想一想,如果真的有这种算法,那还要什么压缩啊,任何东西直接转一下不就好了嘛。

实现方式

一、发号器

其实最简单的方法就是采用发号器的方式来实现,每次递增,比如我们的短连接的域名是:http://t.cn

那么将递增的结果转换成62进制即可(26个大写字母 + 26个小写字母 + 0~9的数字),这样就能生成 http://t.cn/shs7 这样对应的短连接了

然后直接将长短链接的对应关系存储起来即可。

不过这里也会存在两个问题:

  1. 发号器单点故障:如果在一个分布式的场景中,我们为了保证发号器的结果是全局递增的,那么必然需要一个统一的发号器,那么如果这个发号器出现了故障,那么这个系统就不能正常的运行了。
  2. 因为发号器的结果是递增的,那么我多次使用同一个长连接进行转换,那么对应的转换后的短连接是不一样的了

的确,发号器的实现方式是会出现上述的问题的,所以下面我们分开来说:

1. 针对发号器单点问题,既然是在分布式的环境下,那我们可以部署多台实例作为发号器,这里比如我们用10台,那么每一台只发尾号为0~9的数字,然后每次加10

    这样比如第一台机器只会发放:0,10,20,30,40  

   第二台机器只会发:1,11,21,31,41

以此类推,这样在系统中我们自己做健壮性处理,如果一个发号器失败了,我们自动调整去其他的发号器去获取就好了。

 

2.同一个长连接对应转换完之后是不同的短连接的问题,这个问题要看我们的系统的需求,如果我们真的是对这样对应关系有强依赖性,就是一定要保证幂等性

   那么就每次在转换之前都先去我们的存储中查找一下,看是否有对应的转换结果,这样做的代价就是对存储和系统的消耗比较大,比如我们把对应关系存储在redis中了,那么每次就需要用长连接去

   redis中查找一下,你可知道那么长的一个Key去查询,对系统的影响是比较大的,所以说这种设计要取决于系统的要求。

   不过我们我们系统对幂等性的要求没那么高,我们也可以在内存中将单位时间内的转换数据存储起来,然后通过LRU或者是过期时间等等方式去清理,这样就能保证短期内的长连接转换的结果是通一个。

   

二、MD5

这里只是提供一个解决问题的思路,之前我们通过发号器的方式在处理长短链接转换幂等性的问题上,是不太好处理的。

 那么我们可以换一种方式,先获取到长连接对应的Md5(这里为什么要用md5呢,因为对于任何链接的Md5的位数长度都是一样的,虽然Md5也存在碰撞的情况,但是还是比较低的)

获取到的Md5是一个32位的字符,这里我们可以分多次进行截取,然后通过位运算去转换成数字,再通过数字转换成62进制的结果

这样做就是程序处理起来比较麻烦,但是灵活度是比较大的,比如我们分多次截取不同的位数,然后进行不同的转换,可以保证在不查询磁盘的情况下,每次长连接对应的短连接都是一样的。

后记

其实还有一个问题被我们忽略了,就是通过短连接进行跳转的时候,我们是选择301还是302呢?

这个其实就是考察对Http码的理解,我们这里也是说一下这两者的区别,至于选择哪一个,还是要看系统的要求。

301是永久性转移,302是暂时性的转移。

也就是说如果浏览器接收到的返回码是301,那么浏览器自己会记录缓存,至于记录多久这个是每个浏览器都是不一样的。

不过这里建议,如果没有特殊需求,还是以302为主,因为301的浏览器缓存有的时候是很难清理掉了。

 

posted @ 2019-11-08 19:36  SyrupzZ  阅读(548)  评论(0)    收藏  举报