短链接服务
短连接的原理
很多人一定想的是短连接是通过一定的算法将长链接变成短连接的,然后访问的时候再还原,恩,非常高大上,但是仔细想想,怎么可能,那得多牛逼的压缩算法,多长的url都可以压缩为几个字节,而且还能还原,还是无损压缩。
所以,实际上,短连接生成核心就两个字:数数,就是不停的自增一个数,然后有个表保存每个数和原始链接的对应关系,访问短连接的时候将原是连接取出来。
知道了原理就好弄了,最简单的办法,就是用一个数组来存储,数组的索引就是短链接,数组的值就是原始链接,恩,完美,由于数组下标是短链接,那么获取短链接的时间复杂度是O(1),同时生成短链接的时间复杂度也是O(1)
短链接服务的实现
实现一个短链接服务,用数组固然可能,但也显得太LOW了吧,所以为了实现这个服务,从以下几个部分来实现。
首先,给两个概念
- 解析短链接,就是请求是短连接,返回一个跳转的原始链接
- 生成短链接,就是有个长链接,返回生成的短链接
存储
持久化的部分使用Redis数据库来实现,很明显,key-value的结构很适合存在Redis中 这部分主要在 shortlib/RedisAdaptor.go中
计数器
数数的功能可以用Redis的自增功能实现,这样也保证了原子性,同样这部分也可以自己实现,因为go语言开线程很容易,专门开一个线程实现这个功能,通过channl来接受请求,保证是串行的就行了,不就是数数嘛,大家都会 这部分在shortlib/RedisAdaptor.go和shortService/CountThread.go中,具体实现的时候通过配置文件的参数,返回一个高阶函数,调用的时候自动分配到不同的函数实现。
缓存服务
Redis固然很快,但是我们还需要更快,要是热门数据存在内存中就更快了,而且还有个问题,就是热门的url要是有人不停的申请短连接会造成浪费,为了防止这个问题,自己实现了一个LRU模块,解析短链接的时候,命中了话直接返回结果,否则从Redis返回数据,如果是申请短链接的话,如果在LRU中,那不再重新生成短链接了。 这部分主要在 shortlib/LRU.go中。
对外服务
这一部分用的go的http框架,很容易实现高并发,没啥好说的,现在编程高并发不是问题了,连语言都自带这框架了。 这部分包括shortlib/Router.go , shortService/OriginalProcessor.go,shortService/ShortProcessor.go 这几个文件。