原创 短链接服务Octopus的实现与源码开放

发布时间:2021-06-24 00:13:55 浏览 1547 来源:猿笔记 作者:Throwable

    提出了一个把长链接压缩为短链接的功能需求,使用了一些比较知名的第三方短链压缩平台,应该是"短链接")因为实现的功能并不复杂,`octopus`的实现参考了互联网中几篇关于"短链服务实现"浏览量比较高的文章,短链服务的核心就是构建短链接和长链接的唯一映射关系,依赖到一个高性能、排列组合数量大而且破解难度大的映射标识生成算法,构建唯一映射关系其实就是基于一个固定的长链接,要求生成的短链接满足,-不容易被破解(使用数字例如数据库的自增主键作为唯一映射标识容易被人遍历出来进行恶意调用)。


    #主题列表:juejin,github,smartblue,cyanosis,channing-cyan,fancy,hydrogen,condensed-night-purple,greenwillow,v-green,vue-pro,healer-readable,mk-cute,jzman,geek-black,awesome-green

    #投稿主题:

    theme:smartblue

    highlight:

    ##前提

    大约半年前(` 2020-06 ')疫情见底,公司业务量持续增长。运营部为了方便短消息、模板消息等渠道的传递,提出了将长链接压缩成短链接的功能需求。当时为了快速推广,使用了一些知名的第三方短链压缩平台,出现了一些问题:

    -很贵

    -在某些情况下,短链域名会在微信等一些第三方平台上被屏蔽

    -返回源的数据没有办法定制处理方案,无法打开整个业务环节进行数据分析和跟踪

    基于这样的问题,我决定开发一个短链接服务(长链接压缩成)。当时微服务是同步拆分的,组内很多微服务都需要重命名。群里有个妹子说,用‘Github’的吉祥物来命名‘章鱼猫’(octopus cat)会更好,但考虑到版权问题,她最喜欢的猫被去掉了,章鱼就剩下以‘octopus’命名了

    (项目描述也拼错了,应该是“短链接”。)由于实现的功能并不复杂,第一版是在` 2020-06年底发布的。‘octopus’的实现是指网上几篇关于“短链服务实现”的文章。在这里,我们将讨论实现原理、服务实现和部署架构。

    # #基础

    短链服务的核心是在短链和长链之间建立唯一的映射关系,这依赖于一种高性能、大量排列组合、破解难度大的映射标识生成算法。

    # # #建立唯一的映射关系

    上图是作者收到的JD.COM白条分期还款结果的提醒信息,信息内容中还包含一个短链

    访问

    jrmkt.jd.com和3.cn查证都是doge东的域名

    事实上,建立唯一的映射关系是基于固定的长链接,并映射到一个或多个可以动态生成的短链接。这种独特的映射关系要求生成的短链接满足以下要求:

    -不容易被破解(使用数据库的自增主键等数字作为唯一映射标识符,很容易被恶意调用遍历掉)

    -不能重复(一个短链接只能对应一个长链接,当然一个长链接可以对应多个短链接)

    -长度尽量短,因为第三方推送的消息内容一般都有长度限制。如果短链太长,就不容易传递,推送的内容字数会受到限制。(试想运营商的短信内容最大长度是` 30 `个字符长,短链已经占用了` 20 `个字符长,只剩下` 10 `个字符供运营同事玩,显然不合理。)

    -如果链接过长,生成的二维码中的“码点”会非常密集,不利于客户端识别和传输。刚好作者的公司用二维码操作一个场景,所以链接长度一定要尽量缩短

    一般来说,这种唯一的映射关系中的映射标识符,作为“hash”算法生成的“hash”码,需要具有较高的唯一性和较低的冲突频率,并且具有传输时间短、容易传输的特点。有关如何生成映射唯一标识符的详细信息,请参见下一节“压缩代码生成算法”。

    # # #压缩代码生成算法

    这里,“compression_code”是作者杜撰的名词。本文中是指短链接“URL”的路径部分(为了节省长度,除了协议和域名部分,短链接“URL”只有第一条路径):

    其中,协议部分基本固定为

    -`N=4 `,组合数为` 62 ^ 4 = 14 _ 776 _ 336 `,` 147万'接近` 148万'

    -`N=5 `,组合数是` 62 5 = 916 _ 132 _ 832 `,` 916 `万左右

    -`N=6 `,组合数是` 62 ^ 6 = 56 _ 800 _ 235 _ 584 `,` 568亿`左右

    一般来说,组合数量越少,破解难度越小。组合数量越多,所需的压缩代码长度就越大。所以常用的长度有‘4’、‘5’、‘6’。在后期,故障长链可以恢复或禁用。这三种长度可以满足生产大对数短链的应用场景。octopus '在实现时选择了一个长度为' 6 '位的压缩码,因为有一个现成成熟的参考方案:` 62 '十进制数只是由字符' 0-9a-zA-Z '组成。当生成压缩代码时,它只需要生成一个唯一的‘10’十进制数,然后基于这个‘10’十进制数进行转换。说到这里,看来计划如下:

    虚线通常依赖于高效且低冲突的摘要算法,例如“MurmurHash”,而步骤(1)中的实线是生成全局唯一的“10”二进制序列。常见的方法如下:

    -数据库自增序列(如自增主键)

    -`Snowflake`算法

    -自行开发的类似UUID算法生成全球唯一的序列值

    考虑到作者以前已经研究过“雪花”算法的原理,这

作者信息

Throwable [等级:3] 公众号: Throwable
发布了 72 篇专栏 · 获得点赞 2100 · 获得阅读 133823

相关推荐 更多