生成url shortener
2025-5-30
| 2025-5-30
0  |  Read Time 0 min
type
status
date
slug
summary
tags
category
icon
password
短URL
 
 
notion image

问题定义

 
 
核心功能
  • 输入长网址:https://www.example.com/very/long/path/to/some/resource?param1=value1&param2=value2
  • 输出短网址:https://t.ly/abc123
  • 短网址跳转到原始长网址
典型场景
  • 微博/Twitter的链接缩短
  • 二维码生成(短网址更容易编码)
  • 短信/邮件中的链接
  • 营销活动追踪
 
 

301 vs 302 redirect区别

 

301永久重定向

想象你搬家了,从老地址A搬到新地址B,而且再也不会回到A了。你会:
  • 去邮局办理永久地址变更
  • 告诉所有朋友以后直接去B找你,不要再去A了
  • A地址的房子可能被拆了或者给别人了
这就是301:这个资源永远不在原来的地方了,以后直接去新地方找

302临时重定向

想象你只是临时出差到B地,但A还是你的家,你会:
  • 告诉朋友"我现在暂时在B,但还是要先联系A"
  • 朋友每次找你都先打A的电话,然后被告知去B
  • 过段时间你回来了,还是在A
这就是302:我现在临时在别的地方,但请继续联系我的原地址

🌐 互联网中的实际应用

浏览器的"记忆"差别

301的浏览器行为: 浏览器记住了"A已经永久搬到B了",下次用户输入A的网址,浏览器直接跳转到B,甚至不问服务器。就像你记住了朋友的新地址,直接去新地址找他。
302的浏览器行为: 浏览器每次都要先问A:"你现在在哪里?"A回答:"我临时在B",然后浏览器再去B。每次都要问一遍

搜索引擎的理解差别

301的SEO影响
  • Google认为:原网页已经不存在了,把所有权重给新网页
  • 就像店铺搬迁,所有顾客和声誉都转移到新店
  • 原网页在搜索结果中消失,新网页继承排名
302的SEO影响
  • Google认为:原网页只是临时不在,保持原网页的权重
  • 就像店铺临时装修,顾客知道还会回来,不改变对老店的印象
  • 原网页保持搜索排名,新网页不获得权重

🔄 URL短网址服务中的选择

为什么短网址通常用302?

统计数据的需要: 假设你开了一家咖啡店,门口放了指路牌指向你的店。你想知道:
  • 每天有多少人看了指路牌
  • 什么时间人最多
  • 客人从哪里来
如果用301(永久重定向):
  • 看过一次指路牌的人,下次直接去咖啡店,不再看指路牌
  • 你就统计不到后续的访问数据了
如果用302(临时重定向):
  • 每个人每次都要看指路牌才能找到咖啡店
  • 你能统计到每一次访问
灵活性的需要: 短网址服务就像一个"智能指路牌":
  • 今天指向A网站
  • 明天可能需要指向B网站(比如活动结束了)
  • 用302,改变目标立即生效
  • 用301,浏览器记住了旧目标,可能还会去旧地方

什么情况下用301?

网站搬迁
  • 公司网站从 oldcompany.com 搬到 newcompany.com
  • 这是永久性的,旧域名不再使用
  • 希望搜索引擎把旧网站的权重转移给新网站
URL标准化
  • 同一内容有多个网址:example.com 和 www.example.com
  • 选择一个作为标准,其他的301重定向过去
  • 避免搜索引擎认为是重复内容

⚡ 性能差异

301的性能优势

用户第一次访问:
  1. 浏览器请求短网址
  1. 服务器返回301和目标网址
  1. 浏览器记住这个重定向关系
用户第二次访问:
  1. 用户输入短网址
  1. 浏览器直接跳转到目标网址(不请求服务器)
  1. 速度更快,服务器压力更小

302的统计优势

用户每次访问:
  1. 浏览器请求短网址
  1. 服务器记录访问数据
  1. 服务器返回302和目标网址
  1. 统计数据完整准确

🎯 选择决策

短网址服务选择302的原因
  1. 数据价值:每次点击都能被统计,这是短网址服务的核心价值
  1. 灵活控制:可以随时改变目标,做A/B测试,地域分流
  1. 商业需求:广告跟踪、转化分析、用户行为分析
其他场景选择301
  1. 网站迁移:SEO权重转移比统计更重要
  1. 性能优先:不需要每次都经过中间服务器
  1. 用户体验:减少跳转延迟

💡 关键洞察

301和302的本质区别
  • 301:告诉所有人"我永远搬走了,以后直接去新地方找我"
  • 302:告诉所有人"我临时在别处,但还是通过老地方联系我"
业务决策的核心
  • 需要控制和统计 → 302
  • 需要性能和SEO → 301
这个选择反映了不同的业务优先级:是要完整的数据控制,还是要更好的性能和搜索引擎优化。
 
 
 
 

Hash

 
核心就是要存一个 <shortURL, fullURL>关系
最好拿一个表来存
 

🎯 两种方案的核心思路

Hash + Collision Resolution(哈希+冲突解决)

核心思想:把长网址"压缩"成短码
  • 输入同样的长网址 → 得到同样的短码
  • 就像给每个长网址计算一个"指纹"
  • 不同的长网址可能产生相同的"指纹"(冲突)
 
 

Base62 Conversion(Base62编码)

核心思想:给每个长网址分配一个唯一的数字ID,然后转换成短码
  • 每个新的长网址 → 分配下一个数字(1,2,3,4...)
  • 把数字转换成62进制表示(用a-z,A-Z,0-9)
  • 就像银行给每个账户分配唯一账号
notion image
 
 
 
 

🔍 详细对比分析

数据存储差异

Hash方案的存储
Base62方案的存储

重复URL的处理方式

Hash方案
  • 用户输入相同长网址 → 返回相同短码
  • 好处:节省存储空间
  • 问题:无法区分不同用户、不同时间的相同URL
Base62方案
  • 用户输入相同长网址 → 每次都生成新的短码
  • 好处:每个短码都是独立的,便于统计和管理
  • 问题:相同内容会产生多个短码,占用更多存储

🎲 冲突问题的本质差异

Hash冲突

什么是冲突:不同的长网址产生了相同的哈希值
解决方案复杂性
  1. 检测冲突:每次生成短码都要查数据库确认是否已存在
  1. 解决冲突:加盐重新哈希,或者在原哈希基础上变化
  1. 性能影响:冲突越多,生成短码越慢
 
 
 

Base62无冲突

为什么无冲突:因为每个ID都是唯一的
优势
  • 生成过程简单直接
  • 性能稳定可预测
  • 无需复杂的冲突处理逻辑

⚡ 性能对比

Hash方案的性能特点

生成短码时
  1. 计算长网址的哈希值 (O(1))
  1. 查询数据库检查是否冲突 (数据库查询)
  1. 如果冲突,重新计算 (可能多次)
  1. 插入数据库 (数据库写入)
访问短码时
  1. 直接根据短码查询数据库 (O(1))

Base62方案的性能特点

生成短码时
  1. 获取下一个ID (可能是数据库自增,或分布式ID生成)
  1. Base62编码 (O(log n))
  1. 插入数据库 (数据库写入)
访问短码时
  1. Base62解码得到ID (O(log n))
  1. 根据ID查询数据库 (O(1))

🎯 实际业务场景的考虑

用户体验差异

Hash方案
  • 用户重复提交相同URL → 得到相同短码
  • 用户感知:"系统记住了我之前的请求"
  • 适合:个人工具、内部系统
Base62方案
  • 用户重复提交相同URL → 每次得到不同短码
  • 用户感知:"每次都是新的短码"
  • 适合:商业服务、需要独立统计的场景

统计分析的差异

Hash方案统计困难
Base62方案统计精确

🔧 扩展性考虑

Hash方案的扩展问题

冲突率随数据增长
  • 数据量小时:冲突很少
  • 数据量大时:冲突急剧增加
  • 性能下降:需要多次重试才能找到可用短码
生日悖论效应: 即使哈希空间很大,当数据量达到√(哈希空间)时,冲突概率就很高了。

Base62方案的线性扩展

可预测的增长
  • 6位Base62:可表示62^6 ≈ 568亿个短码
  • 7位Base62:可表示62^7 ≈ 3.5万亿个短码
  • 性能稳定:无论数据量多大,生成速度都一样

💼 业务模式的影响

Hash方案适合的场景

个人/内部工具
  • 用户希望相同URL得到相同短码
  • 不需要详细的访问统计
  • 存储成本敏感
特点
  • 去重效果好
  • 存储效率高
  • 实现相对复杂

Base62方案适合的场景

商业服务
  • 需要为每个用户、每次请求独立统计
  • 支持A/B测试、营销追踪
  • 需要稳定可预测的性能
特点
  • 统计能力强
  • 性能稳定
  • 实现简单

🎯 选择建议

选择Hash方案的情况

  1. 存储成本敏感:相同URL只存一份
  1. 用户期望一致性:相同输入得到相同输出
  1. 访问量 >> 创建量:读多写少的场景
  1. 数据量可控:不会达到高冲突率的规模

选择Base62方案的情况

  1. 需要精确统计:每个短码独立跟踪
  1. 高并发写入:大量短码生成请求
  1. 商业化运营:需要用户隔离、营销追踪
  1. 长期扩展:预期数据量很大

💡 核心洞察

Hash方案的本质:把短码当作长网址的"别名"
  • 优势:节省空间,去重效果好
  • 劣势:冲突处理复杂,统计能力弱
Base62方案的本质:把短码当作"数据库主键的编码"
  • 优势:性能稳定,统计能力强,实现简单
  • 劣势:存储开销大,相同URL会重复存储
关键决策点
  • 如果你的业务更像"书签工具" → Hash方案
  • 如果你的业务更像"营销平台" → Base62方案
现实中,大多数商业短网址服务(bit.ly、t.co等)都选择Base62方案,因为商业价值更多来自于数据分析和用户服务,而不是存储效率。
 
 
 

Bloom Filter应用

核心特性

Bloom Filter是一个概率性数据结构
  • 可能存在:如果BF说"存在",实际可能存在,也可能不存在(假阳性)
  • 绝对不存在:如果BF说"不存在",那绝对不存在(无假阴性)
通俗理解: 就像一个"不太准确的门卫":
  • 说"你不在名单里" → 100%准确,你确实不在
  • 说"你在名单里" → 可能准确,也可能认错人了

🔍 在短网址系统中的应用场景

1. 短码存在性检查(最重要)

传统方式的问题
使用Bloom Filter优化

2. 缓存穿透防护

缓存穿透问题
Bloom Filter防护

3. 分布式去重检查

分布式环境的挑战
Bloom Filter辅助方案

🛠️ 具体实现方案

方案一:单层Bloom Filter

应用场景:基础的短码存在性检查
适用场景
  • 中小型短网址服务
  • 对误判容忍度较高
  • 内存资源充足

方案二:分层Bloom Filter

设计思路:用多个BF分别处理不同"热度"的数据
优势
  • 热点数据误判率极低
  • 内存使用更高效
  • 适合访问模式有明显热点的场景

方案三:Counting Bloom Filter

解决的问题:传统BF无法删除元素

📊 性能对比分析

数据库查询减少效果

无Bloom Filter
有Bloom Filter(1%误判率)

缓存穿透防护效果

攻击场景测试

⚖️ 权衡考虑

内存 vs 性能权衡

Bloom Filter大小对比

一致性考虑

Bloom Filter更新滞后问题

误判处理策略

业务层面的误判处理

🎯 最佳实践建议

选择合适的BF方案

小型服务(<1000万短码)
  • 单层Bloom Filter
  • 误判率1%
  • 内存占用<100MB
  • 实现简单
中型服务(1000万-1亿短码)
  • 分层Bloom Filter
  • 热点数据0.1%误判率
  • 历史数据1%误判率
  • 平衡性能和内存
大型服务(>1亿短码)
  • 分布式Bloom Filter
  • 使用Redis Cluster存储
  • 支持动态扩容
  • 复杂但可扩展

监控和调优

关键监控指标

💡 核心价值

Bloom Filter在短网址系统中的价值
  1. 性能提升:减少90%+的无效数据库查询
  1. 成本降低:数据库压力减少,可以用更少的数据库资源
  1. 防攻击:有效防护缓存穿透攻击
  1. 用户体验:响应速度更快,特别是在高并发场景
适用的业务特点
  • 读多写少(短网址访问 >> 短网址创建)
  • 大部分查询都是"不存在"的结果
  • 对轻微误判有容忍度
  • 追求高性能和低成本
 
分布式id generatorNotification System设计
Loading...
Catalog