转转短链平台设计与实现

1 背景介绍

转转是中国领先的二手交易平台,链接作为用户在平台上进行交互和信息传递的重要媒介,扮演着不可或缺的角色。

传统长链接通常包含大量字符和特殊符号,不易记忆和传播。由于字数的原因,长链接在发送短信,生成二维码和社交平台发布等场合下会也有一定的局限性。

2 工作原理

2.1 短链接生成与存储

短链平台接收到业务方提供的长链接后,先通过哈希算法(MD5)检查是否已存在短链接映射关系,存在即返回,不存在则生成唯一 ID 标识(号段模式),再选择适当的短链接生成算法(Base62),将该唯一 ID 转换为短链接。生成的短链接与原始长链接之间的映射关系需要被持久化,以便在用户访问时能够快速地查找并定位到原始长链接。

2.2 短链接返回与传播

一旦短链接生成成功,短链平台将返回这个短链接给业务方。业务方可以通过多种方式将短链接传播给用户,如将其嵌入到网页中、发送短信、分享到社交媒体等。用户获得这个短链接后,就可以点击访问相应的资源。

2.3 用户点击与跳转

当用户点击短链接时,浏览器向短链平台发送请求。短链平台需要根据短链接查找映射关系,然后将用户正确引导到原始长链接的业务系统。这一步骤需要高效的数据检索和跳转机制。

HTTP 状态码 301 和 302 都能代表重定向,301 永久重定向会使用浏览器缓存导致统计短链访问次数不正确,302 临时重定向会每次都访问到短链平台从而增加服务压力。

3 核心算法

长链接到短链接的转换是短链平台的核心功能,这需要一个高效且唯一的算法来确保每个长链接都可以映射到一个对应的短链接。

3.1 哈希算法

3.1.1 MD5

MD5 是一种广泛应用的哈希算法,将输入数据转换为 128 位的哈希值,在短链平台中可以用于生成短链接的基础哈希值。

3.1.2 SHA-256

SHA-256 是一种更安全的哈希算法,它生成256位的哈希值。虽然相对于MD5,SHA-256更安全,但同时也会更长,影响了短链接的长度。

3.2 分布式 ID

直接使用哈希结果作为短链接时,哈希碰撞和链接长度都是需要考虑的问题。在短链平台中,需要采取措施来防止哈希碰撞,例如使用唯一性标识符。

3.2.1 全局递增

自增 ID 是另一种常见的分布式唯一 ID 生成方式,通过一个自增的计数器来生成唯一 ID。例如 MySQL 的自增主键,或者 Redis 的 incr 指令。这种方法简单且高效,适用于许多场景。

3.2.2 号段模式

号段模式会为不同的节点分配不同的号段范围,每个节点内部自增生成唯一的 ID,用完后再重新分配,从而确保全局唯一性。

3.2.3 SnowFlake

SnowFlake(雪花算法)是一种常用的分布式唯一 ID 生成算法,它将一个大整数 ID 拆分成多个部分,包括时间戳、机器 ID、数据中心 ID 和序列号等,从而保证了生成的 ID 是唯一且递增的。

然而,尽管雪花算法在分布式环境中生成唯一 ID 方面表现出色,但它并不免疫于时钟回拨问题。如果发生时钟回拨,可能会导致生成的 ID 在时间上产生逆序。

3.3 Base62 编码

Base62 编码是将数据转换为只包含数字和字母的一种方法。它使用了 62 个字符,分别是 0-9、a-z、A-Z,可以作为 URL 短链接、文件名等场景的字符串表示,相对于16进制或64进制等其他编码,Base62 具有更高的可读性和稳定性。

java 复制代码
import java.util.ArrayList;
import java.util.List;

public class Base62Encoder {

    private static final String BASE62_CHARACTERS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

    public static String encode(long num) {
        StringBuilder sb = new StringBuilder();
        do {
            int remainder = (int) (num % 62);
            sb.insert(0, BASE62_CHARACTERS.charAt(remainder));
            num /= 62;
        } while (num != 0);
        return sb.toString();
    }
}

仅 6 位的 Base62 编码,能表示约 568 亿(62 的 6 次方)的数。

4 安全与防护

在转转短链平台的设计与实现过程中,确保用户数据的安全性和平台的稳定性是首要任务。为此,我们采用了一系列安全与防护策略,以应对潜在的风险和威胁,保障用户隐私和系统的正常运行。

4.1 长链接合法性校验

在生成短链接之前,首先需要对用户提供的原始长链接进行验证,以确保链接指向的是合法且可信任的目标资源。

合法性校验通常涵盖以下几个方面:

  1. 主域名合法性: 首先,平台会解析原始长链接,提取其中的域名信息。然后,这个域名会与预先定义的合法域名列表进行比对,以确认链接是否指向了预期的域名。这样做可以有效地防止恶意链接或指向不安全网站的情况。
  2. 查询参数域名合法性: 链接中的查询参数域名也可能影响到用户安全。平台也需要验证这些域名是否合法,以免引发潜在的安全风险。

4.2 重复生成短链接防护策略

重复生成短链接的防护策略在短链平台的设计中具有重要意义。它旨在防止因重复生成相同的短链接而造成的资源浪费和系统混乱。

短链平台可以基于长链接的 MD5 值采用幂等性设计,确保多次相同请求的处理结果是一致的,不会产生额外的短链接。

4.3 短链接有效性验证

在用户点击或输入短链接后,短链平台需要快速准确地判断该链接是否有效,从而决定是否将用户重定向到原始长链接或提供相应的错误信息。

短链平台会通过查询数据库来验证短链接的有效性。如果短链接与有效的映射关系存在,平台将确认链接有效,否则将判定链接无效。

5 系统性能优化

系统性能的优化是确保转转短链平台高效、稳定运行的关键。通过采用一系列策略和技术,我们不断提升平台的响应速度、并发处理能力和资源利用效率,以满足用户的需求并提供卓越的用户体验。

5.1 数据库索引

数据库是短链平台的核心数据存储组件,因此优化数据库的设计和访问非常重要。将长链接的唯一标识 ID 作为主键索引,长链接的 MD5 值作为普通索引,以支持快速的链接有效性验证和重定向操作。

5.2 缓存应用

利用缓存技术可以显著减少数据库访问次数,从而提高系统的响应速度。我们采用了分布式缓存 Redis,将短链接映射关系异步存储在缓存中,减轻数据库的压力。这样可以在高并发情况下,快速地获取链接映射信息,提升用户访问的效率。

5.3 号段模式优化

传统号段模式在节点消耗完所有号段时才会向发号器请求分配新的号段,这可能会引起短时间内的性能瓶颈。我们引入独立的监控线程定期检查号段的使用情况,一旦使用 ID 数量超过阈值时就请求分配新的号段。新的号段模式能够在高并发情况下平稳地切换号段,通过预先分配号段以避免阻塞业务流程,从而提高系统的性能和稳定性。

5.4 分表策略

随着用户数量和链接数据的增长,单一数据库表可能会面临性能瓶颈。为了应对这个问题,我们采用了分表策略。将链接数据按照唯一性 ID 对 64 取余的规则均匀拆分到 64 张表中,可以有效减轻单一表的压力,提高数据库的扩展性和性能。

5.5 业务监控

业务监控是系统关键环节之一,旨在实时追踪系统的性能和运行状况,以确保高可用性和高性能。借助转转监控系统 Prometheus,我们可以收集和展示关键的性能指标,如生成短链链接和获取长链接的请求频率,链接的安全性校验情况等等,使能够一目了然地查看系统运行情况,从而更好地进行决策和优化。

6 总结

通过深入的研究和实践,转转的短链平台为用户提供了高效、安全的链接服务。在不断发展的互联网环境下,短链平台将持续创新,满足用户不断变化的需求。

关于作者:

曹建涛,转转C2C&寄卖业务研发工程师

> 转转研发中心及业界小伙伴们的技术学习交流平台,定期分享一线的实战经验及业界前沿的技术话题。 关注公众号「转转技术」(综合性)、「大转转FE」(专注于FE)、「转转QA」(专注于QA),更多干货实践,欢迎交流分享~
相关推荐
啊松同学19 分钟前
【Java】设计模式——工厂模式
java·后端·设计模式
枫叶_v1 小时前
【SpringBoot】20 同步调用、异步调用、异步回调
java·spring boot·后端
源码12152 小时前
ASP.NET MVC宠物商城系统
后端·asp.net·宠物
Ai 编码助手3 小时前
Go语言 实现将中文转化为拼音
开发语言·后端·golang
hummhumm3 小时前
第 12 章 - Go语言 方法
java·开发语言·javascript·后端·python·sql·golang
杜杜的man3 小时前
【go从零单排】Directories、Temporary Files and Directories目录和临时目录、临时文件
开发语言·后端·golang
wywcool3 小时前
JVM学习之路(5)垃圾回收
java·jvm·后端·学习
喜欢打篮球的普通人4 小时前
rust高级特征
开发语言·后端·rust
代码小鑫5 小时前
A032-基于Spring Boot的健康医院门诊在线挂号系统
java·开发语言·spring boot·后端·spring·毕业设计
豌豆花下猫5 小时前
REST API 已经 25 岁了:它是如何形成的,将来可能会怎样?
后端·python·ai