高性能短链接生成与跳转服务,适用于各种短链接推广场景,如活动、短信、二维码等。
- 雪花算法 + Base62 生成唯一短码,无冲突
- Redis 缓存热点短链接,跳转毫秒级响应
- 异步批量写入点击日志,不阻塞跳转请求
- 支持自定义过期时间
- 详细点击统计(IP、UA、Referer)
- 全链路 Trace ID 追踪
- 日志按天滚动、100M 限制、保留 7 天
- 管理后台集成(background 项目)
shortlink/
├── main.go # 服务入口
├── config.yaml # 配置文件
├── Makefile # 构建命令
├── Dockerfile # 容器化部署
├── config/ # 配置结构体
├── global/ # 全局变量(DB/Redis/Logger/Config)
├── initialize/ # 初始化(配置/日志/MySQL/Redis/表迁移)
├── middleware/ # Trace ID + 请求响应日志
├── model/ # 数据模型(dim_short_link / ods_click_log)
├── service/ # 业务逻辑(CRUD/跳转/雪花算法/点击统计)
├── api/ # HTTP Handler
├── router/ # 路由注册
└── response/ # 统一响应封装
- Go 1.24+
- MySQL 5.7+
- Redis 6+
cp config.yaml config.local.yaml
# 编辑 config.local.yaml,填入实际的 MySQL 和 Redis 连接信息# 直接运行
go run main.go -c config.local.yaml
# 或通过 Makefile
make build
./bin/shortlink -c config.local.yaml服务启动后自动创建数据表,无需手动建表。
make docker
docker run -d -p 8090:8090 -v ./config.local.yaml:/app/config.yaml shortlink:devserver:
host: ":8090" # 监听地址
shortlink:
domain: "https://s.example.com" # 短链接访问域名
code-length: 6 # 短码长度(6-8位)
default-expire-days: 0 # 默认过期天数,0=永久
snowflake:
machine-id: 1 # 机器ID,分布式部署时每个实例不同(0-1023)
mysql:
path: "127.0.0.1"
port: "3306"
db-name: "shortlink"
username: "root"
password: "your-password"
config: "charset=utf8mb4&parseTime=True&loc=Local"
max-idle-conns: 10
max-open-conns: 100
redis:
addr: "127.0.0.1:6379"
password: ""
db: 0
prefix: "sl" # Redis key 前缀
log:
filename: "./logs/shortlink.log"
max-size: 100 # 单文件最大 MB
max-backups: 7 # 最多保留文件数
max-age: 7 # 保留天数
compress: true
common:
ctx_request_id_key: "request_id"通过 -c 参数指定配置文件路径:
./shortlink -c /etc/shortlink/config.yamlGET /:code
访问短码自动 302 跳转到原始链接,同时异步记录点击。
POST /api/shortlink/create
Content-Type: application/json
{
"original_url": "https://example.com/very/long/url?params=xxx",
"title": "618活动推广链接",
"expire_days": 30
}
响应:
{
"code": 1,
"msg": "success",
"data": {
"short_code": "aB3xKm",
"short_url": "https://s.example.com/aB3xKm"
},
"request_id": "uuid-xxx"
}POST /api/shortlink/list
Content-Type: application/json
{
"page": 1,
"page_size": 20,
"title": "618",
"status": 1
}
POST /api/shortlink/update
Content-Type: application/json
{
"id": 123456,
"title": "新标题",
"status": 0
}
POST /api/shortlink/delete
Content-Type: application/json
{
"id": 123456
}
POST /api/shortlink/detail
Content-Type: application/json
{
"id": 123456
}
短链接模块已集成到 background 管理后台,提供可视化界面:
- 短链接列表:搜索、分页、状态切换
- 创建短链接:输入原始链接、标题、过期时间,一键生成
- 点击统计:查看每条短链接的访问明细(IP/UA/来源/时间)
- 编辑/删除
background 项目中已添加以下模块(服务重启自动生效):
| 层级 | 路径 |
|---|---|
| Model | server/model/short_link/ |
| Service | server/service/short_link/ |
| API | server/api/v1/short_link/ |
| Router | server/router/short_link/ |
| 前端API | web/src/api/shortLink.js |
| 前端页面 | web/src/view/shortLink/list.vue |
首次启动自动完成:
- 数据表迁移(dim_short_link / ods_click_log)
- 菜单注册(短链接管理 → 短链接列表)
- API 权限注册
- Casbin 策略分配(管理员角色 888)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | bigint PK | 自增主键 |
| short_code | varchar(16) | 短码,唯一索引 |
| original_url | text | 原始长链接 |
| domain | varchar(255) | 短链接域名 |
| title | varchar(255) | 备注标题 |
| status | tinyint | 1=启用 0=禁用 |
| expire_at | datetime | 过期时间,NULL=永久 |
| total_clicks | bigint | 总点击数 |
| creator | varchar(64) | 创建人 |
| created_at | datetime | 创建时间 |
| updated_at | datetime | 更新时间 |
| 字段 | 类型 | 说明 |
|---|---|---|
| id | bigint PK | 自增主键 |
| short_code | varchar(16) | 短码,索引 |
| ip | varchar(64) | 访问 IP |
| user_agent | varchar(512) | 浏览器 UA |
| referer | varchar(1024) | 来源页 |
| created_at | datetime | 访问时间 |
客户端 GET /aB3xKm
→ Trace 中间件(生成 request_id)
→ 查 Redis 缓存 (sl:aB3xKm)
→ 命中:直接 302
→ 未命中:查 MySQL → 回写 Redis → 302
→ 异步:写入点击日志 channel → 批量 INSERT
→ 异步:Redis INCR 点击计数 → 定时同步到 MySQL
- Redis 缓存跳转链接,QPS 万级
- 点击日志通过 buffered channel(容量 10000)异步写入
- 每 5 秒或满 100 条批量 INSERT,减少 DB 压力
- 点击计数通过 Redis INCR + 每分钟同步,避免热点行锁
所有日志携带 request_id 字段,支持全链路追踪:
{
"time": "2026-06-08T10:30:00.000+0800",
"level": "info",
"caller": "middleware/request_log.go:48",
"msg": "HTTP请求",
"request_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"method": "GET",
"path": "/aB3xKm",
"status": 302,
"duration": "1.2ms"
}make build # 编译到 bin/shortlink
make run # 编译并运行
make clean # 清理编译产物
make docker # 构建 Docker 镜像
make lint # 代码检查
make test # 运行测试
