当前位置: 首页 > news >正文

短链接生成器架构解密:62 进制编码 + 分布式 ID,如何让 6 位字符支撑 568 亿个网址?

短链接生成器架构解密:62 进制编码 + 分布式 ID,如何让 6 位字符支撑 568 亿个网址?

摘要:每天数十亿次的短链接请求背后,隐藏着怎样的技术架构?本文将从数学原理、编码算法、分布式 ID 生成、高并发设计等维度,深度解析短链接系统的核心设计,并附带完整的 Spring Boot 3 实现代码。


一、从一条推文说起:短链接的万亿级市场

2023 年,Twitter 每天处理的短链接数量超过 50 亿次。Bitly 平台累计生成的短链接已突破 800 亿个。这些数字背后,是一个看似简单却蕴含深厚技术功力的系统——短链接生成器。

原始 URL: https://www.example.com/products/category/electronics/smartphones/brand-x/model-y/specifications?color=black&storage=256gb&utm_source=wechat&utm_medium=social&utm_campaign=2024_spring 短链接: https://short.link/aB3xK9

6 位字符,从 200+ 字符压缩而来,压缩比高达 97%。但问题来了:

6 位字符真的能表示 568 亿个不同的 URL 吗?这个系统该如何设计才能支撑高并发场景?


二、数学基石:6 位字符的排列组合魔法

2.1 字符集的选择

短链接系统的核心在于字符集(Character Set)的选择。常见的选择有:

字符集包含内容字符数量6 位组合数
10 进制0-9101,000,000
16 进制0-9, a-f1616,777,216
36 进制0-9, a-z362,176,782,336
62 进制0-9, a-z, A-Z6256,800,235,584
64 进制0-9, a-z, A-Z, +, /6468,719,476,736
/** * 62 进制字符集定义 * 为什么选择 62 进制? * - 足够大的组合空间(568 亿) * - 兼容 URL 安全字符(无需 URL 编码) * - 大小写敏感,增加熵值 */ public class Base62 { private static final String BASE62_CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; private static final int BASE = 62; /** * 将十进制数字转换为 62 进制字符串 */ public static String encode(long num) { if (num == 0) return "0"; StringBuilder sb = new StringBuilder(); while (num > 0) { sb.append(BASE62_CHARS.charAt((int)(num % BASE))); num /= BASE; } return sb.reverse().toString(); } /** * 将 62 进制字符串转换回十进制数字 */ public static long decode(String str) { long num = 0; for (char c : str.toCharArray()) { num = num * BASE + BASE62_CHARS.indexOf(c); } return num; } }

2.2 组合数计算验证

public class CombinationCalculator { public static void main(String[] args) { long base = 62; int length = 6; // 计算 62^6 long combinations = (long) Math.pow(base, length); System.out.println("=== 62 进制 6 位字符组合数 ==="); System.out.println("字符集大小:" + base); System.out.println("字符长度:" + length); System.out.println("总组合数:" + combinations); System.out.println("约等于:" + combinations / 1_0000_0000.0 + " 亿"); // 输出:568 亿 } }

结论:62 进制的 6 位字符可以表示 568 亿 个不同的短链接,足以支撑绝大多数业务场景。


三、核心架构设计:三种主流方案对比

3.1 方案一:自增 ID + Base62 编码(推荐⭐)

┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ 原始 URL │───▶│ 分布式 ID │───▶│ Base62 编码 │───▶│ 短链接 key │ │ 哈希校验 │ │ 生成器 │ │ (62 进制) │ │ (aB3xK9) │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘

优点: - 简单高效,O(1) 时间复杂度 - ID 连续,便于分页和统计 - 无碰撞风险

缺点: - 需要分布式 ID 生成器 - ID 可预测(可通过混淆解决)

3.2 方案二:哈希算法(MD5/SHA1)

/** * 基于 MD5 的短链接生成方案 * 注意:存在哈希碰撞风险,需要额外处理 */ public class HashBasedShortener { public String generate(String url) { // 计算 MD5 String md5 = DigestUtils.md5Hex(url); // 取前 6 位(或更多位减少碰撞) String shortKey = md5.substring(0, 6); // ⚠️ 需要检查碰撞 if (urlRepository.existsByShortKey(shortKey)) { // 碰撞处理:取后 6 位或使用其他策略 shortKey = md5.substring(md5.length() - 6); } return shortKey; } }

优点: - 无需存储 ID 映射 - 相同 URL 生成相同短链

缺点: - 存在碰撞风险(生日悖论) - 需要额外的碰撞处理逻辑

3.3 方案三:雪花算法(Snowflake)+ Base62

/** * 基于 Twitter Snowflake 的分布式 ID 生成 * 适合超大规模分布式系统 */ public class SnowflakeIdGenerator { private final long workerId; private final long datacenterId; private long sequence = 0L; private long lastTimestamp = -1L; // 位掩码配置 private static final long TIMESTAMP_BITS = 41; // 41 位时间戳 private static final long WORKER_BITS = 5; // 5 位工作节点 ID private static final long SEQUENCE_BITS = 12; // 12 位序列号 private static final long MAX_SEQUENCE = ~(-1L << SEQUENCE_BITS); private static final long WORKER_SHIFT = SEQUENCE_BITS; private static final long TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_BITS; public synchronized long nextId() { long timestamp = System.currentTimeMillis(); // 时钟回拨处理 if (timestamp < lastTimestamp) { throw new RuntimeException("时钟回拨,拒绝生成 ID"); } if (timestamp == lastTimestamp) {
http://www.jsqmd.com/news/492666/

相关文章:

  • JetBrains IDE试用期管理工具:从痛点到解决方案的完整指南
  • Ollama部署Llama-3.2-3B避坑指南:常见问题与解决方案
  • 都在用 OpenClaw 跑 Skill,但你写的“技能”为什么总让 AI 频繁罢工?
  • uni.createInnerAudioContext音频播放全攻略:从基础使用到duration获取异常处理
  • 简单研究一下 shipfast 的收益排行榜上的 SaaS 网站都是干什么的(转)
  • 实时口罩检测-通用应用指南:智能考勤与公共卫生管理解决方案
  • 开箱即用:Hunyuan-MT 7B翻译镜像,原文输入→一键翻译→实时展示
  • 关于 Amazon Linux 2023 (AL2023) 默认情况下确实没有 /var/log/secure 文件的解决方法
  • Vivado 2024.2编译提速秘籍:实测32线程设置与16线程性能天花板
  • Spring AI + RAG 构建电商智能客服:从 PDF 文档解析到精准问答的全链路实战
  • gte-base-zh效果对比图谱:t-SNE+UMAP双视角展示中文语义空间结构
  • 酷狗音频转换器进阶指南:无损格式互转与批量处理技巧
  • 快速生成树协议 RSTP IEEE 802.1w
  • ANSYS APDL工具栏进阶玩法:用嵌套Toolbar实现多级菜单(2023版)
  • Grok3角色扮演功能实测:从家庭作业助手到18+模式,哪个最实用?
  • Stable Yogi Leather-Dress-Collection季节主题作品展:春夏秋冬皮革风尚
  • 【SLAM坐标系精讲】从像素到世界:四大坐标系与核心变换的实战解析
  • 第七章 回溯算法part03
  • 半导体器件物理基础:金半接触的能带理论与整流机制
  • Zotero数据同步全攻略:从基础配置到坚果云WebDAV优化
  • 生成树协议 STP IEEE 802.1D-1998
  • 基于天空星GD32F407的SYN6288E语音合成模块移植与驱动开发实战
  • 开箱即用!Ollama快速部署GLM-4.7-Flash,开启本地AI对话新体验
  • 学习C语言第24天
  • 2026年金融GEO监测系统选型攻略:4大主流工具深度测评,谁是实力天花板? - 小白条111
  • 第九周第二天
  • Window下Nginx
  • 黑丝空姐-造相Z-Turbo风格迁移效果:从古典油画到现代时尚的演绎
  • Phi-3-vision-128k-instruct效果展示:128K长上下文图文理解惊艳案例集
  • 2026年跨境GEO工具服务商选型指南:从技术实力到效果落地的6家头部品牌深度测评 - 小白条111