短链接的实现方案
这个过程的核心逻辑是链接到短链接的一一对应,通过链接能够查询到这个唯一的短链接,通过短链接可以查询到唯一对应的链接。链接变短的方法可以通过hash
实现,解决hash
冲突可以通过一个全局自增id
实现,通过链接加自增id
之后的hash
是唯一的。通过这个唯一值映链接的关系,通过hash
值生成唯一短链接,将短链接和链接建议关系。其中自增id
需要注意线程安全,可以通过redis
实现,短链接到hash
值以及链接的映射关系可以通过数据库或者redis
存储实现。
主体之间的关系
- 分享的
URL
通过hash
函数,获得唯一的hash
值,通过唯一的hash值与短链接建立连接关系 - 短链接的地址需要单独维护,要实现唯一性,可以通过
redis
实现自增id
实现 hash
函数可能出现hash
冲突,可以通过多个hash
函数组合成一个长hash
值,也可通过增加hash
函数的位数避免
数据库存储信息
- 通过hash值可以获取到短链接
- 通过短链接可以获取到这个短链接的详情,例如URL信息,是否需要密码,过期时间
- 通过短链接可以获取URL信息
在实现上可以考虑实际请求的性能要求和技术栈,在短链接唯一性上推荐用redis
高性能NoSQL
,其他的几个服务也可以使用这种键值对存储服务。
具体实现
创建短链接的过程
- 创建长连接,通过hash函数获取hash值,如果hash值已经存在,则直接返回对应短链接信息。
- 如果hash值不存在,则获取短链接自增之后的新短链接
- 建立hash和短链接的关系
- 建立短链接和长连接的关系
- 建立短链接和短链接详情的关系
- 上述三个关系优先通过事务实现
数据存储方式,都可以通过k-v
存储,如果使用redis
,通过string
即可。
访问分享的过程
通过访问的短链接,查询是否有短链接到URL的关系,如果没有则返回404,如果存在,则返回HTTP code 307以及URL,临时跳转到URL。
代码实现
创建短链接
1 | func (r *RedisClient) Shorten(url string, exp int64) (string, error) { |
验证短链接
1 | func (r *RedisClient) ShortLinkInfo(url string) (detail ShortLinkInfo, err error) { |
删除短链接
1 | func (r *RedisClient) UnShort(url string) error { |
跳转
1 | func (s *Storags) Redirect(c *gin.Context) { |