短链接
短链接子域把长 URL 压缩为短码,并支持按短码解析 / 跳转(带访问计数)、批量创建与删除。它的核心特征不在"缩短"本身,而在于数据归属与规模治理:短链数据存储在独立的 FreeSql 实例(ShortFlag,连接串 ShortUrlConnectionStrings),与主业务库物理隔离,并按表索引水平分片。
业务能力
- 生成短链:长 URL 经哈希算法(由
Salt/MinHashLength控制短码长度)生成ShortKey,返回完整短链地址ShortUrl。 - 解析 / 跳转:按
ShortKey取回原链接;GET /api/plat/short-urls/r/{shortKey}直接 302 跳转到原地址并累加ViewHits。 - 批量与删除:支持一次创建 / 删除多条。当前创建、批量创建、按短码解析和跳转允许匿名访问;列表、详情与删除受
Platform.ShortUrl权限保护。 - 过期:创建时可指定
ExpireTime,为空表示永不过期。
概念与关系
IShortUrlService:GetListAsync(ShortUrlQuery)/GetAsync(long id)/GetShortUrlAsync(shortKey, inCreateViewHits)/CreateAsync(...)/BatchCreateAsync(...)/DeleteAsync(long id)/BatchDeleteAsync(...)。- 短码由
Hashids基于Salt与MinHashLength对自增id编码得到;跳转计数ViewHits在解析/跳转时累加。
为什么用独立库 + 分表
短链接在 Platform 里是写多、读多、体量大、但与核心业务无强关联的典型代表。设计上把这块数据单独拎出来,理由有三:
- 物理隔离,互不影响:通过
AddDefaultFreeSql<ShortFlag>(c, "ShortUrlConnectionStrings")创建与主库不同的IFreeSql实例,配UnitOfWorkManager<ShortFlag>与IShortDbRepository<T,TKey>。短链库可单独备份、迁移、扩容,一次慢查询或大批量写入不会波及订单/用户等核心表。 - 水平分表抗体量:
ShortUrlOption.FileTableCount(默认 64)决定分片数。ShortUtil.GetTableIndex(id, FileTableCount)用id取模得到TableIndex,FreeSql 的AsTable把数据落到short_urls_{tableIndex}这类分表里。单表不会无限膨胀,查询走对应分片即可。 - 短码较紧凑:
Salt参与Hashids编码,MinHashLength控制最短长度,便于在长度与空间之间权衡。Hashids 不是加密或访问控制,不能依靠短码本身保护敏感链接。
注:短链跳转走
/api/plat/short-urls/r/{shortKey},不是独立统计接口;当前实现没有二维码生成接口。
配置
| 键 | 业务含义 |
|---|---|
ShortUrlOption:Salt | 哈希盐值,决定短码生成结果,影响不可预测性 |
ShortUrlOption:MinHashLength | 短码最小长度 |
ShortUrlOption:FileTableCount | 分表数量(短链数据按 id % FileTableCount 分片,ShortUrlQuery.TableIndex 取 0 ~ 63) |
ShortUrlConnectionStrings:DefaultDB | 短链库的 FreeSql DataType 数值;0 表示 MySQL |
ShortUrlConnectionStrings:MySql | 短链库 MySQL 连接串(经 AddDefaultFreeSql<ShortFlag> 绑定) |
Host:ShortUrlApi | CreateAsync 返回的短链接基础地址;应以 / 结尾 |
{
"ShortUrlOption": {
"Salt": "ShortUrlApi",
"MinHashLength": 6,
"FileTableCount": 64
},
"ShortUrlConnectionStrings": {
"DefaultDB": "0",
"UseJsonMap": true,
"MySql": "Data Source=localhost;Port=3306;User ID=<user>;Password=<password>;Initial Catalog=freekit_shorturl;Charset=utf8mb4;SslMode=none"
},
"Host": {
"ShortUrlApi": "https://example.com/kit_api/api/plat/short-urls/r/"
}
}
开发配置当前没有填写 Host:ShortUrlApi,此时创建结果中的 ShortUrl 只会包含短码。要在本地直接得到可访问的完整 URL,需要显式配置该项。
开发示例
private readonly IShortUrlService _shortUrlService;
// 生成短链
var created = await _shortUrlService.CreateAsync(new CreateShortUrlReq
{
LongUrl = "https://very-long-url.com/path",
ExpireTime = null
});
string url = created.ShortUrl; // 完整短链地址
// 按短码取原地址(inCreateViewHits=true 表示累加访问数)
var hit = await _shortUrlService.GetShortUrlAsync(created.ShortKey, true);
string origin = hit.LongUrl;