* add staging ios app build script * feat(api): add OpenTelemetry LGTM stack for local observability Wire OTel traces, metrics, and logs through a collector to Tempo, Prometheus, and Loki, with custom LLM instrumentation, dev compose overlay, Grafana provisioning, env templates, and development.sh auto-start. * feat: expand observability, harden dev tooling, and fix expo staging UX Add business and LLM Prometheus metrics with Grafana dashboards, alerting, and a metrics verification script. Wire telemetry through adapters and core LLM paths, and document the local LGTM workflow. Fix development.sh for macOS bash 3.2, open Grafana and eval-web in Chrome, and repair eval-web auto-open (unbound EVAL_WEB_BROWSER_SCHEDULED). Merge internal-eval into the main dev script with improved compose handling. Require EXPO_PUBLIC_* at build time, improve iOS HTTP ATS for staging IPs, show memoir empty state instead of load errors when no chapters exist, and add jest env setup plus chapter list response normalization. * chore: enable Grafana Assistant Cursor plugin * fix: memoir empty state and repair withdrawn 0020_chapters_book_id stamp Show empty memoir UI when the chapter list succeeds with no items; treat auth/404 as non-fatal. Extend alembic revision repair so local dev DBs stamped with the removed 0020_chapters_book_id migration can roll back and upgrade to 0019. --------- Co-authored-by: Kevin <kevin@brighteng.org> Co-authored-by: Cursor <cursoragent@cursor.com>
12 KiB
12 KiB
短信验证码功能部署指南
概述
本文档说明如何在生产环境中部署短信验证码功能,包括环境配置、数据库迁移、服务配置等。
前置条件
- PostgreSQL 数据库已安装并运行
- Redis 服务已安装并运行
- 已注册腾讯云账号并开通短信服务
- 已获取腾讯云短信服务凭证
部署步骤
1. 腾讯云短信服务配置
1.1 登录腾讯云控制台
访问:https://console.cloud.tencent.com/smsv2
1.2 创建短信应用
- 进入"应用管理"
- 点击"创建应用"
- 填写应用名称(如:Life Echo)
- 记录生成的 SDK AppID
1.3 配置短信签名
- 进入"国内短信" -> "签名管理"
- 点击"创建签名"
- 填写签名内容(如:【人生回响】)
- 选择签名类型(如:App)
- 上传相关证明材料
- 等待审核通过
1.4 配置短信模板
创建一个通用的验证码模板(所有场景共用):
验证码模板:
【人生回响】您的验证码是:{1},有效期{2}分钟,请勿泄露给他人。
模板参数说明:
{1}- 验证码(6位数字){2}- 有效期(分钟数,如:5)
注意: 所有场景(注册、登录、重置密码、修改手机号)共用同一个模板。
记录模板ID。
1.5 获取API密钥
- 访问:https://console.cloud.tencent.com/cam/capi
- 点击"新建密钥"
- 记录 SecretId 和 SecretKey
- 重要:妥善保管密钥,不要泄露
2. 环境变量配置
2.1 编辑生产环境配置文件
编辑 api/.env.production:
# 数据库配置
DATABASE_URL=postgresql://username:password@host:5432/life_echo
# Redis配置
REDIS_URL=redis://localhost:6379/0
# JWT配置
JWT_SECRET_KEY=your_jwt_secret_key_here
JWT_ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
REFRESH_TOKEN_EXPIRE_DAYS=7
# 腾讯云短信服务配置
TENCENT_SMS_SECRET_ID=your_secret_id_here
TENCENT_SMS_SECRET_KEY=your_secret_key_here
TENCENT_SMS_SDK_APP_ID=your_app_id_here
TENCENT_SMS_SIGN_NAME=人生回响
# 统一使用一个短信模板ID(所有场景共用)
TENCENT_SMS_TEMPLATE_ID=your_template_id_here
# 其他配置
CORS_ORIGINS=["https://your-domain.com"]
2.2 配置说明
| 配置项 | 说明 | 示例 |
|---|---|---|
TENCENT_SMS_SECRET_ID |
腾讯云API密钥ID | AKIDxxxxxxxxxxxxx |
TENCENT_SMS_SECRET_KEY |
腾讯云API密钥Key | xxxxxxxxxxxxxxxx |
TENCENT_SMS_SDK_APP_ID |
短信应用ID | 1400xxxxxx |
TENCENT_SMS_SIGN_NAME |
短信签名(不含【】) | 人生回响 |
TENCENT_SMS_TEMPLATE_ID |
短信模板ID(所有场景共用) | 123456 |
3. 数据库迁移
3.1 备份数据库
# 备份现有数据库
pg_dump -U postgres -d life_echo > backup_$(date +%Y%m%d_%H%M%S).sql
3.2 执行迁移脚本
# 方式1:使用psql命令
psql -U postgres -d life_echo -f api/migrations/add_sms_verification.sql
# 方式2:使用数据库管理工具
# 打开 pgAdmin 或其他工具,执行 add_sms_verification.sql 中的SQL语句
3.3 验证迁移结果
-- 检查表是否创建成功
SELECT * FROM information_schema.tables
WHERE table_name = 'sms_verification_codes';
-- 检查索引是否创建成功
SELECT indexname FROM pg_indexes
WHERE tablename = 'sms_verification_codes';
-- 检查 refresh_tokens 表是否添加了 device_info 字段
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'refresh_tokens' AND column_name = 'device_info';
4. 依赖安装
4.1 更新Python依赖
cd api
pip install -r requirements.txt
确保 requirements.txt 中包含:
tencentcloud-sdk-python>=3.0.1000
4.2 验证依赖安装
python -c "from tencentcloud.sms.v20210111 import sms_client; print('腾讯云SDK安装成功')"
5. 服务部署
5.1 使用Docker部署
编辑 api/docker-compose.yml,添加环境变量:
version: '3.8'
services:
api:
build: .
ports:
- "8000:8000"
environment:
- DATABASE_URL=${DATABASE_URL}
- REDIS_URL=${REDIS_URL}
- JWT_SECRET_KEY=${JWT_SECRET_KEY}
- TENCENT_SMS_SECRET_ID=${TENCENT_SMS_SECRET_ID}
- TENCENT_SMS_SECRET_KEY=${TENCENT_SMS_SECRET_KEY}
- TENCENT_SMS_SDK_APP_ID=${TENCENT_SMS_SDK_APP_ID}
- TENCENT_SMS_SIGN_NAME=${TENCENT_SMS_SIGN_NAME}
- TENCENT_SMS_TEMPLATE_ID=${TENCENT_SMS_TEMPLATE_ID}
depends_on:
- postgres
- redis
restart: unless-stopped
postgres:
image: postgres:15
environment:
- POSTGRES_DB=life_echo
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
restart: unless-stopped
redis:
image: redis:7
restart: unless-stopped
volumes:
postgres_data:
启动服务:
cd api
docker compose up -d
5.2 使用Systemd部署
创建服务文件 /etc/systemd/system/life-echo-api.service:
[Unit]
Description=Life Echo API Service
After=network.target postgresql.service redis.service
[Service]
Type=simple
User=www-data
WorkingDirectory=/path/to/life-echo/api
Environment="PATH=/path/to/venv/bin"
EnvironmentFile=/path/to/life-echo/api/.env.production
ExecStart=/path/to/venv/bin/python main.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
启动服务:
sudo systemctl daemon-reload
sudo systemctl enable life-echo-api
sudo systemctl start life-echo-api
sudo systemctl status life-echo-api
6. GitHub Actions配置
如果使用GitHub Actions自动部署,需要配置Secrets:
- 进入GitHub仓库 -> Settings -> Secrets and variables -> Actions
- 添加以下Secrets:
| Secret名称 | 说明 |
|---|---|
TENCENT_SMS_SECRET_ID |
腾讯云API密钥ID |
TENCENT_SMS_SECRET_KEY |
腾讯云API密钥Key |
TENCENT_SMS_SDK_APP_ID |
短信应用ID |
TENCENT_SMS_SIGN_NAME |
短信签名 |
TENCENT_SMS_TEMPLATE_ID |
短信模板ID(所有场景共用) |
参考文档:github-actions-secrets.md
7. 验证部署
7.1 健康检查
curl http://localhost:8000/health
预期响应:
{
"status": "healthy"
}
7.2 测试发送验证码
curl -X POST http://localhost:8000/api/auth/sms/send \
-H "Content-Type: application/json" \
-d '{
"phone": "13800138000",
"purpose": "register"
}'
预期响应:
{
"message": "验证码已发送",
"expires_in": 300
}
7.3 检查日志
# Docker部署
docker compose logs -f api
# Systemd部署
sudo journalctl -u life-echo-api -f
8. 监控与告警
本地开发与预发可观测性栈(OpenTelemetry + Grafana LGTM)见 可观测性指南。staging/production 全量接入为第二阶段(docker-compose profile)。
8.1 配置日志监控
建议使用以下工具:
- Grafana + Loki + Tempo + Prometheus(仓库内
deploy/observability/,推荐) - ELK Stack (Elasticsearch + Logstash + Kibana)
- 云服务商的日志服务
8.2 配置性能监控
监控指标:
- API响应时间
- 短信发送成功率
- 验证码验证成功率
- 数据库查询性能
- Redis连接状态
8.3 配置告警
告警规则:
- 短信发送失败率 > 5%
- API响应时间 > 2秒
- 数据库连接失败
- Redis连接失败
- 磁盘空间 < 20%
9. 安全加固
9.1 防火墙配置
# 仅允许必要的端口
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw enable
9.2 SSL证书配置
使用Let's Encrypt免费证书:
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d api.your-domain.com
9.3 限流配置
在Nginx中配置限流:
limit_req_zone $binary_remote_addr zone=sms_limit:10m rate=1r/m;
location /api/auth/sms/send {
limit_req zone=sms_limit burst=2 nodelay;
proxy_pass http://localhost:8000;
}
10. 备份与恢复
10.1 数据库备份
设置自动备份:
# 创建备份脚本
cat > /usr/local/bin/backup-db.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="/var/backups/postgresql"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
pg_dump -U postgres -d life_echo | gzip > $BACKUP_DIR/life_echo_$DATE.sql.gz
# 保留最近7天的备份
find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete
EOF
chmod +x /usr/local/bin/backup-db.sh
# 添加到crontab(每天凌晨2点执行)
echo "0 2 * * * /usr/local/bin/backup-db.sh" | crontab -
10.2 数据恢复
# 恢复数据库
gunzip < backup_file.sql.gz | psql -U postgres -d life_echo
11. 故障排查
11.1 短信发送失败
检查步骤:
- 验证环境变量配置
echo $TENCENT_SMS_SECRET_ID
echo $TENCENT_SMS_SDK_APP_ID
-
检查腾讯云账户余额
-
查看后端日志
grep "SMS" /var/log/life-echo-api.log
- 测试API连接
from tencentcloud.common import credential
from tencentcloud.sms.v20210111 import sms_client
cred = credential.Credential(SECRET_ID, SECRET_KEY)
client = sms_client.SmsClient(cred, "ap-guangzhou")
11.2 验证码验证失败
检查步骤:
- 查询数据库中的验证码记录
SELECT * FROM sms_verification_codes
WHERE phone = '13800138000'
ORDER BY created_at DESC
LIMIT 5;
- 检查验证码是否过期
- 检查验证码是否已使用
- 检查用途是否匹配
11.3 数据库连接失败
检查步骤:
- 验证数据库服务状态
sudo systemctl status postgresql
- 检查数据库连接配置
psql -U postgres -d life_echo -c "SELECT 1"
- 查看数据库日志
sudo tail -f /var/log/postgresql/postgresql-15-main.log
12. 性能优化
12.1 数据库优化
-- 分析表统计信息
ANALYZE sms_verification_codes;
-- 查看慢查询
SELECT * FROM pg_stat_statements
WHERE query LIKE '%sms_verification_codes%'
ORDER BY total_time DESC;
12.2 Redis优化
# 配置Redis持久化
redis-cli CONFIG SET save "900 1 300 10 60 10000"
# 设置最大内存
redis-cli CONFIG SET maxmemory 256mb
redis-cli CONFIG SET maxmemory-policy allkeys-lru
12.3 应用优化
- 使用连接池
- 启用缓存
- 异步发送短信
- 批量清理过期验证码
13. 定期维护
13.1 清理过期验证码
创建定时任务:
-- 创建清理函数
CREATE OR REPLACE FUNCTION cleanup_expired_sms_codes()
RETURNS void AS $$
BEGIN
DELETE FROM sms_verification_codes
WHERE expires_at < NOW() - INTERVAL '1 day';
END;
$$ LANGUAGE plpgsql;
-- 每天凌晨3点执行(使用pg_cron扩展)
SELECT cron.schedule('cleanup-sms', '0 3 * * *', 'SELECT cleanup_expired_sms_codes()');
13.2 监控数据库大小
SELECT
pg_size_pretty(pg_total_relation_size('sms_verification_codes')) as table_size,
(SELECT count(*) FROM sms_verification_codes) as record_count;
部署检查清单
- 腾讯云短信服务已配置
- 环境变量已正确设置
- 数据库迁移已执行
- 依赖包已安装
- 服务已启动并运行
- 健康检查通过
- 发送验证码测试通过
- 日志正常输出
- 监控已配置
- 告警已配置
- 备份已配置
- SSL证书已配置
- 防火墙已配置
- 限流已配置
回滚计划
如果部署出现问题,执行以下步骤回滚:
- 停止新版本服务
docker compose down
# 或
sudo systemctl stop life-echo-api
- 恢复数据库
psql -U postgres -d life_echo < backup_file.sql
- 切换到旧版本代码
git checkout previous-version
- 重启服务
docker compose up -d
# 或
sudo systemctl start life-echo-api
联系支持
如有问题,请联系:
- 技术支持邮箱:support@your-domain.com
- 开发团队:dev@your-domain.com
更新日志
- 2024-01-XX: 初始版本
- 添加短信验证码功能
- 添加账户管理功能