# 短信服务部署指南 > **文档版本**:v1.0 > **最后更新**:2026-01-27 --- ## 目录 1. [前置条件](#前置条件) 2. [配置步骤](#配置步骤) 3. [数据库迁移](#数据库迁移) 4. [功能测试](#功能测试) 5. [生产环境配置](#生产环境配置) 6. [故障排查](#故障排查) --- ## 前置条件 ### 1. 基础环境 - ✅ PostgreSQL 17(已安装 UUID v7 扩展) - ✅ Redis(用于限流) - ✅ Python 3.12+ - ✅ Celery(用于定时任务) ### 2. 阿里云短信服务(生产环境) 如果需要真实发送短信,需要: 1. 注册阿里云账号 2. 开通短信服务 3. 配置短信签名(如:道研组) 4. 配置短信模板(包含 `${code}` 变量) 5. 获取 AccessKey ID 和 Secret --- ## 配置步骤 ### 1. 更新环境变量 编辑 `server/.env` 文件: ```env # ==================== 短信服务配置 ==================== # 测试模式(开发环境推荐) SMS_TEST_MODE=True # 生产模式配置(生产环境必填) SMS_TEST_MODE=False SMS_ACCESS_KEY_ID=your_access_key_id SMS_ACCESS_KEY_SECRET=your_access_key_secret SMS_SIGN_NAME=道研组 SMS_TEMPLATE_CODE=SMS_123456789 # ==================== Redis 配置 ==================== REDIS_URL=redis://localhost:6379/0 ``` ### 2. 安装依赖 确保已安装必要的 Python 包: ```bash cd server pip install redis httpx ``` 或使用 requirements.txt: ```bash pip install -r requirements.txt ``` --- ## 数据库迁移 ### 1. 执行迁移脚本 ```bash cd server python app/migrations/011_sms_service_tables.py ``` ### 2. 验证表结构 连接数据库,检查表是否创建成功: ```sql -- 查看表结构 \d sms_verification_codes -- 查看索引 \di sms_verification_codes* -- 查看表注释 SELECT col_description('sms_verification_codes'::regclass, 0) as table_comment, column_name, col_description('sms_verification_codes'::regclass, ordinal_position) as column_comment FROM information_schema.columns WHERE table_name = 'sms_verification_codes'; ``` --- ## 功能测试 ### 1. 运行测试脚本 ```bash cd server python test_sms_service.py ``` 预期输出: ``` ============================================================ 短信服务测试 ============================================================ [测试 1] 发送验证码 ------------------------------------------------------------ ✅ 发送成功: {'message': '验证码已发送', 'expires_in': 600} 📱 验证码: 123456 ⏰ 过期时间: 2026-01-27 10:15:00 [测试 2] 验证验证码(正确) ------------------------------------------------------------ ✅ 验证成功: True [测试 3] 验证验证码(错误) ------------------------------------------------------------ ❌ 验证失败(预期): 验证码不存在或已过期 [测试 4] 防刷机制(1分钟内重复发送) ------------------------------------------------------------ ❌ 发送失败(预期): 验证码已发送,请稍后再试 [测试 5] 清理过期验证码 ------------------------------------------------------------ 🗑️ 清理记录数: 0 ============================================================ ✅ 所有测试完成 ============================================================ ``` ### 2. API 测试 #### 2.1 发送验证码 ```bash curl -X POST http://localhost:6170/api/v1/auth/sms/send \ -H "Content-Type: application/json" \ -d '{ "phone": "13800138000", "countryCode": "+86", "purpose": "login" }' ``` 预期响应: ```json { "code": 200, "message": "Success", "data": { "message": "验证码已发送", "expiresIn": 600 } } ``` #### 2.2 查看日志获取验证码(测试模式) ```bash # 查看 API 日志 docker-compose logs -f api | grep "验证码" ``` 输出示例: ``` [测试模式] 跳过短信发送: phone=13800138000, code=123456 ``` #### 2.3 验证验证码 ```bash curl -X POST http://localhost:6170/api/v1/auth/sms/verify \ -H "Content-Type: application/json" \ -d '{ "phone": "13800138000", "countryCode": "+86", "code": "123456", "purpose": "login" }' ``` 预期响应: ```json { "code": 200, "message": "Success", "data": { "success": true } } ``` --- ## 生产环境配置 ### 1. 阿里云短信服务配置 #### 1.1 创建短信签名 1. 登录阿里云控制台 2. 进入短信服务 → 国内消息 → 签名管理 3. 添加签名:`道研组` 4. 等待审核通过 #### 1.2 创建短信模板 1. 进入短信服务 → 国内消息 → 模板管理 2. 添加模板: - 模板名称:`验证码通知` - 模板内容:`您的验证码是${code},有效期10分钟,请勿泄露。` - 模板类型:`验证码` 3. 等待审核通过 4. 记录模板 CODE(如:`SMS_123456789`) #### 1.3 获取 AccessKey 1. 进入阿里云控制台 → AccessKey 管理 2. 创建 AccessKey 3. 记录 AccessKey ID 和 Secret(仅显示一次) ### 2. 更新生产环境变量 ```env # 生产环境配置 SMS_TEST_MODE=False SMS_ACCESS_KEY_ID=LTAI5tXXXXXXXXXXXXXX SMS_ACCESS_KEY_SECRET=xxxxxxxxxxxxxxxxxxxxxxxx SMS_SIGN_NAME=道研组 SMS_TEMPLATE_CODE=SMS_123456789 ``` ### 3. 配置 Celery 定时任务 编辑 `server/app/tasks/celery_app.py`,添加定时任务配置: ```python from celery.schedules import crontab app.conf.beat_schedule = { # 清理过期短信验证码(每小时执行) 'clean-expired-sms-codes': { 'task': 'sms.clean_expired_codes', 'schedule': crontab(minute=0), # 每小时的第 0 分钟 }, } ``` ### 4. 重启服务 ```bash # 重启 API 服务 docker-compose restart api # 重启 Celery Worker docker-compose restart celery-worker # 重启 Celery Beat docker-compose restart celery-beat ``` --- ## 故障排查 ### 问题 1:短信发送失败 **症状**:API 返回 500 错误,日志显示"短信发送失败" **可能原因**: 1. AccessKey 配置错误 2. 短信签名或模板未审核通过 3. 阿里云账户余额不足 4. 网络连接问题 **解决方案**: ```bash # 1. 检查配置 cat .env | grep SMS # 2. 检查阿里云控制台 # - 签名状态:已审核 # - 模板状态:已审核 # - 账户余额:充足 # 3. 测试网络连接 curl https://dysmsapi.aliyuncs.com/ # 4. 查看详细日志 docker-compose logs -f api | grep "短信" ``` ### 问题 2:验证码验证失败 **症状**:输入正确的验证码仍然提示"验证码错误" **可能原因**: 1. 验证码已过期(10分钟) 2. 验证码已被使用 3. 手机号或国家区号不匹配 **解决方案**: ```sql -- 查询验证码记录 SELECT id, phone, country_code, code, purpose, expires_at, verified, created_at FROM sms_verification_codes WHERE phone = '13800138000' ORDER BY created_at DESC LIMIT 5; ``` ### 问题 3:触发限流 **症状**:API 返回 429 错误,提示"发送过于频繁" **可能原因**: 1. 1分钟内发送超过 1 次(同手机号) 2. 1小时内发送超过 5 次(同手机号) 3. 1分钟内发送超过 3 次(同 IP) **解决方案**: ```bash # 查看 Redis 限流记录 redis-cli # 查看手机号限流 KEYS sms:phone:* # 查看 IP 限流 KEYS sms:ip:* # 清除特定限流(仅测试环境) DEL sms:phone:+86:13800138000:1min DEL sms:phone:+86:13800138000:1hour ``` ### 问题 4:定时任务未执行 **症状**:过期验证码未被清理 **可能原因**: 1. Celery Beat 未启动 2. 定时任务配置错误 **解决方案**: ```bash # 检查 Celery Beat 状态 docker-compose ps celery-beat # 查看 Celery Beat 日志 docker-compose logs -f celery-beat # 手动触发清理任务 docker-compose exec celery-worker celery -A app.tasks.celery_app call sms.clean_expired_codes ``` --- ## 监控建议 ### 1. 关键指标 在生产环境中,建议监控以下指标: | 指标 | 说明 | 告警阈值 | |------|------|----------| | 发送成功率 | 短信发送成功/总发送次数 | < 95% | | 验证成功率 | 验证码验证成功/总验证次数 | < 80% | | 限流触发次数 | 防刷机制触发次数 | > 100/小时 | | 平均响应时间 | API 响应时间 | > 2秒 | ### 2. 日志监控 关键日志关键字: ```bash # 发送成功 grep "验证码已发送" api.log # 验证成功 grep "验证码验证成功" api.log # 发送失败 grep "短信发送失败" api.log # 触发限流 grep "发送过于频繁" api.log ``` --- ## 相关文档 - [短信服务设计文档](../../requirements/backend/04-services/user/sms-service.md) - [短信服务实现变更日志](../changelogs/2026-01-27-sms-service-implementation.md) - [用户服务测试指南](./user-service-testing.md) --- **文档版本**:v1.0 **最后更新**:2026-01-27