从零搭建一个短信平台:LESMS 架构全解析

行云流水
2026-03-02 / 0 评论 / 7 阅读 / 正在检测是否收录...
短信服务看似简单,但真要自己搭一个能支撑业务运转的平台,坑比想象中多得多。

去年有个朋友找我吐槽:公司每个月短信费用好几万,想自建平台省点钱。我反问了他三个问题——高并发怎么扛?通道故障怎么切?账单对不上怎么办? 他沉默了。

这就是短信平台的真相:发一条短信容易,发一亿条还能稳定、安全、可追踪,完全是另一回事。

今天聊聊我自己写的 LESMS这个项目,看看一个轻量级企业短信平台是怎么从 0 到 1 搭建起来的。

短信平台登录


一、为什么要自己搭短信平台?

先泼点冷水——大部分公司不需要自建短信平台。直接接阿里云、腾讯云,API 调一下就能用,省心省力。

但以下几种情况,自建就有意义了:

  • 成本敏感:月发送量过百万,第三方平台的单价和附加费会吃掉不少利润
  • 数据合规:金融、医疗行业,用户手机号不能外流到第三方
  • 功能定制:需要特殊的签名审核流程、定时发送策略、精细化的通道调度
  • 技术储备:团队有能力维护,且业务长期依赖短信触达

LESMS 的定位很明确:中小型企业的自建方案,不求大而全,但求核心链路稳、二次开发易。


二、三模块架构设计

整个系统拆成三大块,每块只干一件事:

架构图

1. Django 管理后台:业务的"大脑"

Django 在这里扮演两个角色:

一是客户中心 API。用户注册、登录、余额查询、发送记录查看,这些面向客户的接口都由 Django 提供。用 Django REST Framework(DRF)写起来很快,自带序列化、权限控制、限流。

二是运营管理后台。基于 Django Admin 改造的管理界面,运营人员可以在里面审核签名、配置通道、查看统计报表。SimpleUI 美化了一下,至少不像原生 Admin 那么丑。

关键模块包括:

  • 用户管理:实名认证、企业认证、余额与计费
  • 消息管理:模板审核、签名报备、上下行记录
  • 通道管理:多运营商通道配置、黑名单管理
  • 充值管理:套餐、订单、卡密核销
    管理平台

2. Vue 3 前端:用户的"门面"

前端用的是 Vue 3 + TypeScript + Element Plus,基于 Vben Admin 框架二次开发。

为什么不用 Django 自带的模板?因为现代前端工程化已经成熟了,Vue 的组件复用、状态管理、构建优化都比传统后端渲染强太多。

前端主要承载:

  • 客户自助服务:发送短信、查看记录、管理通讯录
  • 可视化数据:发送成功率、消费趋势、通道质量
  • 开发者工具:API 密钥管理、SDK 下载、调试控制台

3. Go API 服务:性能的"发动机"

这是整个系统的性能担当,用 Go + Gin 框架实现。

短信发送有几个特点:高并发、低延迟、重可靠。Django 是同步阻塞模型,处理这种场景比较吃力;Go 的 goroutine + channel 天然适合高并发网络 IO。

Go 服务负责的核心功能:

  • 短信发送接口:接收请求、校验签名、写入队列
  • Worker 调度:从 Redis 队列取任务,分发到不同运营商通道
  • 状态回执:接收运营商的送达报告,更新数据库
  • 上行处理:处理用户回复的短信(MO)

流程图


三、技术选型背后的思考

有人可能会问:为什么搞这么复杂,用一种技术栈不行吗?

当然行,但会有代价。

模块选型理由
管理后台Django快速开发、生态成熟、Admin 开箱即用
核心 APIGo高并发性能、部署简单、资源占用低
前端Vue 3组件化、TypeScript 支持好、团队熟悉
数据库PostgreSQLACID 保障、JSON 字段支持、运维友好
队列/缓存Redis原子操作丰富、持久化可选、生态完善

一句话总结:让合适的工具做合适的事。

Django 适合业务逻辑复杂、变更频繁的场景;Go 适合性能敏感、高并发的场景。两者通过 REST API + Redis 队列协作,既保留了各自的优势,又避免了过度耦合。


四、一条短信的完整旅程

光讲架构有点抽象,我们跟踪一条短信从用户点击"发送"到手机收到的全过程:

第一步:前端提交
用户在 Vue 界面填写手机号、选择模板、点击发送。前端组装请求体,带上时间戳、nonce、签名,调用 /api/v1/sms/send

第二步:Go 服务接入
Go 服务收到请求,依次执行:

  1. 中间件链:CORS → 日志 → 签名校验 → 限流检查
  2. 参数校验:手机号格式、模板是否存在、余额是否充足
  3. 写入队列:将任务序列化后推入 Redis 队列

第三步:Worker 调度
Worker 进程从队列取出任务:

  1. 解析手机号前 7 位,识别归属运营商(移动/联通/电信)
  2. 查询用户的通道配置策略
  3. 选择最优通道,HTTP 调用运营商网关

第四步:运营商处理
运营商网关返回提交结果(成功/失败),Worker 记录提交状态。真正的送达是异步的——运营商会在短信送达后推送状态报告。

第五步:状态回执
运营商回调 Go 服务的 /callback/status 接口,携带手机号、状态、时间戳。Go 服务更新数据库中的发送明细,同时触发计费扣减。

第六步:用户感知
用户在前端刷新页面,看到"已送达"状态。如果失败了,能看到失败原因(余额不足、黑名单拦截、通道故障等)。

整个过程通常在 3-5 秒内完成,其中大部分时间花在运营商网络上。


五、写在最后

LESMS 的架构没有炫技,就是一个务实的企业级方案

  • 用 Django 快速搞定业务和管理后台
  • 用 Go 保证核心链路的性能和稳定性
  • 用 Redis 解耦同步压力和异步处理
  • 用 Vue 提供现代化的用户体验

这套架构支撑过日发送量百万级的业务,也经历过双 11 的流量洪峰。它不是最完美的,但在开发效率、运维成本、性能表现之间找到了一个不错的平衡点。

下篇文章,我会带你 15 分钟把这套环境在本地跑起来,从安装依赖到发出第一条测试短信,手把手教你踩完所有的坑。


本文基于 LESMS 开源项目撰写,如需了解更多实现细节,可参考项目文档或源码。

评论 (0)

取消
只有登录/注册用户才可评论