diff --git a/README.md b/README.md index b42fcfd..62d1c36 100644 --- a/README.md +++ b/README.md @@ -247,6 +247,375 @@ python -c "import os; os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'diary_fam systemctl restart nginx ``` +## Redis服务器部署(必需) + +家庭日报系统使用Celery进行异步任务处理(如PDF生成、邮件发送),而Celery依赖Redis作为消息代理和结果后端。**在生产环境中必须部署Redis服务器**。 + +### 1. 安装Redis服务器 + +在Ubuntu服务器上安装Redis: + +```bash +# 更新包管理器 +sudo apt update + +# 安装Redis服务器 +sudo apt install redis-server -y + +# 启动Redis服务 +sudo systemctl start redis-server + +# 设置Redis开机自启 +sudo systemctl enable redis-server + +# 检查Redis服务状态 +sudo systemctl status redis-server +``` + +### 2. 配置Redis安全设置(生产环境重要) + +编辑Redis配置文件以增强安全性: + +```bash +# 备份原始配置文件 +sudo cp /etc/redis/redis.conf /etc/redis/redis.conf.backup + +# 编辑Redis配置文件 +sudo nano /etc/redis/redis.conf +``` + +在配置文件中进行以下修改: + +```ini +# 1. 绑定到本地地址(或特定IP),禁止外部访问 +bind 127.0.0.1 + +# 2. 设置强密码(强烈建议) +requirepass your_secure_password_here + +# 3. 禁用危险命令(防止误操作) +rename-command FLUSHDB "" +rename-command FLUSHALL "" +rename-command CONFIG "" + +# 4. 限制内存使用(根据服务器内存调整) +maxmemory 256mb +maxmemory-policy allkeys-lru + +# 5. 启用持久化 +save 900 1 +save 300 10 +save 60 10000 +``` + +保存并重启Redis服务: + +```bash +# 重启Redis使配置生效 +sudo systemctl restart redis-server + +# 验证Redis是否正常运行 +redis-cli ping +``` + +### 3. 测试Redis连接 + +验证Redis是否可以正常连接: + +#### 基本连接测试: + +```bash +# 测试无密码连接(如果设置了密码,应该失败) +redis-cli ping + +# 使用密码连接(应该成功) +redis-cli -a your_secure_password_here ping + +# 测试基本操作 +redis-cli -a your_secure_password_here set test_key "hello" +redis-cli -a your_secure_password_here get test_key +redis-cli -a your_secure_password_here del test_key +``` + +#### 高级测试: + +```bash +# 测试Redis信息 +redis-cli -a your_secure_password_here info + +# 测试内存使用 +redis-cli -a your_secure_password_here info memory + +# 测试持久化状态 +redis-cli -a your_secure_password_here info persistence + +# 测试连接数 +redis-cli -a your_secure_password_here info clients + +# 性能测试(设置100个键) +for i in {1..100}; do redis-cli -a your_secure_password_here set "perf:$i" "value$i" > /dev/null; done + +# 性能测试(获取100个键) +for i in {1..100}; do redis-cli -a your_secure_password_here get "perf:$i" > /dev/null; done + +# 清理测试数据 +for i in {1..100}; do redis-cli -a your_secure_password_here del "perf:$i" > /dev/null; done +``` + +#### 使用Python测试脚本: + +项目提供了专门的测试脚本,可以全面测试Redis和Celery集成: + +```bash +# 运行完整的Redis和Celery测试 +python test_redis_celery.py + +# 测试输出示例: +# 2024-01-15 10:30:00 | INFO | 开始测试Redis连接... +# 2024-01-15 10:30:01 | SUCCESS | Redis连接测试通过! +# 2024-01-15 10:30:02 | INFO | 开始测试Celery与Redis集成... +# 2024-01-15 10:30:03 | SUCCESS | Celery与Redis集成测试通过! +# 2024-01-15 10:30:04 | INFO | 开始测试Redis性能... +# 2024-01-15 10:30:05 | SUCCESS | Redis性能优秀! +# 2024-01-15 10:30:06 | SUCCESS | 所有测试通过!生产环境Redis和Celery配置正确。 +``` + +#### 快速验证命令: + +```bash +# 一键验证Redis服务状态 +sudo systemctl status redis-server --no-pager + +# 验证Redis端口监听 +sudo netstat -tlnp | grep 6379 + +# 验证Redis进程 +ps aux | grep redis-server + +# 验证Redis日志 +sudo tail -n 10 /var/log/redis/redis-server.log +``` + +### 4. 配置Django项目使用Redis + +在Django项目的`settings.py`中,更新Celery配置以使用Redis: + +```python +# 生产环境Redis配置(带密码) +CELERY_BROKER_URL = 'redis://:your_secure_password_here@localhost:6379/0' +CELERY_RESULT_BACKEND = 'redis://:your_secure_password_here@localhost:6379/0' +``` + +### 5. 验证Celery与Redis连接 + +测试Celery是否可以正常连接到Redis: + +```bash +# 激活虚拟环境 +source /path/to/venv/bin/activate + +# 测试Celery连接 +celery -A diary_family inspect ping + +# 查看Celery worker状态 +celery -A diary_family status + +# 查看任务队列 +celery -A diary_family inspect active +celery -A diary_family inspect scheduled +``` + +### 6. Redis监控和维护 + +#### 监控Redis性能: + +```bash +# 查看Redis基本信息 +redis-cli -a your_secure_password_here info + +# 查看内存使用情况 +redis-cli -a your_secure_password_here info memory + +# 查看连接数 +redis-cli -a your_secure_password_here info clients + +# 查看持久化状态 +redis-cli -a your_secure_password_here info persistence +``` + +#### 定期维护: + +```bash +# 备份Redis数据 +sudo cp /var/lib/redis/dump.rdb /backup/redis/dump.rdb.$(date +%Y%m%d) + +# 清理过期键 +redis-cli -a your_secure_password_here --scan --pattern "*" | xargs redis-cli -a your_secure_password_here del + +# 查看慢查询日志 +redis-cli -a your_secure_password_here slowlog get 10 +``` + +### 7. Redis故障排除 + +#### 问题1:Redis服务无法启动 + +```bash +# 查看Redis日志 +sudo journalctl -u redis-server -f + +# 检查配置文件语法 +sudo redis-server /etc/redis/redis.conf --test + +# 检查端口占用 +sudo netstat -tlnp | grep 6379 +``` + +#### 问题2:连接被拒绝 + +```bash +# 检查防火墙设置 +sudo ufw status +sudo ufw allow 6379/tcp + +# 检查Redis绑定地址 +sudo grep "^bind" /etc/redis/redis.conf + +# 检查Redis是否在监听 +sudo ss -tlnp | grep 6379 +``` + +#### 问题3:内存不足 + +```bash +# 查看内存使用情况 +redis-cli -a your_secure_password_here info memory + +# 清理过期数据 +redis-cli -a your_secure_password_here memory purge + +# 调整内存策略 +# 编辑 /etc/redis/redis.conf 调整 maxmemory 和 maxmemory-policy +``` + +### 8. 生产环境优化建议 + +1. **使用独立Redis实例**:为Celery专门配置一个Redis实例 +2. **配置监控告警**:使用Prometheus + Grafana监控Redis性能 +3. **定期备份**:设置定时任务备份Redis数据 +4. **性能调优**:根据实际使用情况调整内存和连接数配置 +5. **高可用方案**:考虑使用Redis Sentinel或Redis Cluster + +### 9. Redis部署常见问题解答(FAQ) + +#### Q1: Redis是必须的吗?可以用其他消息队列替代吗? +**A**: 是的,Redis是必须的。家庭日报系统使用Celery进行异步任务处理,而Celery默认使用Redis作为消息代理。虽然可以使用RabbitMQ、Amazon SQS等其他消息队列,但需要修改Celery配置和代码。Redis是最简单、性能最好的选择。 + +#### Q2: Redis应该安装在哪台服务器上? +**A**: 建议的部署方案: +1. **小型部署**:Redis和Django应用安装在同一台服务器上(推荐初学者) +2. **中型部署**:Redis安装在与Django应用不同的服务器上,但在同一内网 +3. **生产部署**:使用Redis集群或云Redis服务(如AWS ElastiCache、Azure Cache for Redis) + +#### Q3: Redis需要多少内存? +**A**: 内存需求取决于使用情况: +- **最小配置**: 256MB(适合小型家庭使用) +- **推荐配置**: 1GB(适合常规使用,有增长空间) +- **生产配置**: 2GB+(适合多用户或高频任务) + +#### Q4: 如何设置Redis密码? +**A**: 在 `/etc/redis/redis.conf` 中设置: +```ini +requirepass your_strong_password_here +``` +然后在Django的 `settings.py` 中更新: +```python +CELERY_BROKER_URL = 'redis://:your_strong_password_here@localhost:6379/0' +``` + +#### Q5: Redis数据会丢失吗? +**A**: Redis默认将数据存储在内存中,重启服务会丢失数据。但可以通过配置持久化来避免: +```ini +# 在redis.conf中启用持久化 +save 900 1 # 900秒内至少有1个键被修改 +save 300 10 # 300秒内至少有10个键被修改 +save 60 10000 # 60秒内至少有10000个键被修改 +``` + +#### Q6: 如何监控Redis性能? +**A**: 使用以下命令监控: +```bash +# 实时监控 +redis-cli -a your_password monitor + +# 查看统计信息 +redis-cli -a your_password info + +# 查看慢查询 +redis-cli -a your_password slowlog get 10 +``` + +#### Q7: Celery任务堆积怎么办? +**A**: 处理步骤: +1. 增加worker数量:`celery -A diary_family worker --concurrency=4 -l info` +2. 优化任务代码,减少执行时间 +3. 使用优先级队列 +4. 监控Redis内存使用,防止内存不足 + +#### Q8: 如何备份Redis数据? +**A**: 备份方法: +```bash +# 手动备份 +sudo cp /var/lib/redis/dump.rdb /backup/redis/dump.rdb.$(date +%Y%m%d) + +# 自动备份(添加到crontab) +0 2 * * * sudo cp /var/lib/redis/dump.rdb /backup/redis/dump.rdb.$(date +\%Y\%m\%d) +``` + +#### Q9: Redis连接数过多怎么办? +**A**: 解决方法: +1. 增加最大连接数(在redis.conf中): + ```ini + maxclients 10000 + ``` +2. 优化Celery连接池 +3. 检查是否有连接泄漏 + +#### Q10: 如何验证Redis部署是否成功? +**A**: 使用项目提供的测试脚本: +```bash +# 运行完整测试 +python test_redis_celery.py + +# 预期输出:所有测试通过,显示绿色成功信息 +``` + +#### Q11: 生产环境Redis安全注意事项? +**A**: 安全配置清单: +- [x] 设置强密码 +- [x] 绑定到127.0.0.1或内网IP +- [x] 禁用危险命令(FLUSHALL, FLUSHDB, CONFIG) +- [x] 启用防火墙,只允许必要端口 +- [x] 定期更新Redis版本 +- [x] 配置日志监控 + +#### Q12: Redis性能调优参数有哪些? +**A**: 关键调优参数: +```ini +# 内存管理 +maxmemory 1gb +maxmemory-policy allkeys-lru + +# 持久化优化 +save 900 1 +save 300 10 +save 60 10000 + +# 网络优化 +tcp-keepalive 60 +timeout 300 +``` + ## 常规代码更新流程 当需要更新代码时,可以使用以下命令: @@ -453,12 +822,25 @@ celery -A diary_family call core.tasks.generate_daily_pdf_report #### 方式3:使用测试脚本 -项目提供了一个测试脚本,用于验证 Celery 任务是否可以正常运行: +项目提供了多个测试脚本,用于验证不同功能: -```bash -# 运行测试脚本 -python test_celery.py -``` +1. **Celery任务测试**: + ```bash + # 测试Celery任务执行 + python test_celery.py + ``` + +2. **Redis和Celery集成测试**(生产环境推荐): + ```bash + # 测试Redis连接、Celery集成和性能 + python test_redis_celery.py + ``` + +3. **Redis连接测试**(快速验证): + ```bash + # 仅测试Redis连接 + python -c "import redis; r = redis.Redis(host='localhost', port=6379); print('Redis连接成功' if r.ping() else '连接失败')" + ``` ### 7. 常见错误和解决方法 @@ -476,9 +858,41 @@ python test_celery.py **错误信息**:`redis.exceptions.ConnectionError: Error 111 connecting to localhost:6379. Connection refused.` **解决方法**: -- 检查 Redis 服务是否正常运行:`sudo systemctl status redis-server` -- 启动 Redis 服务:`sudo systemctl start redis-server` -- 检查 Redis 配置是否允许本地连接 +1. **检查Redis服务状态**: + ```bash + sudo systemctl status redis-server + ``` + +2. **如果Redis未运行,启动服务**: + ```bash + sudo systemctl start redis-server + sudo systemctl enable redis-server + ``` + +3. **检查Redis配置**: + - 确保Redis配置文件 `/etc/redis/redis.conf` 中 `bind` 设置为 `127.0.0.1` + - 检查是否有防火墙阻止连接:`sudo ufw status` + - 检查端口是否被占用:`sudo netstat -tlnp | grep 6379` + +4. **测试Redis连接**: + ```bash + # 测试基本连接 + redis-cli ping + + # 如果设置了密码,使用密码连接 + redis-cli -a your_password ping + ``` + +5. **检查Celery配置**: + - 确保 `settings.py` 中的 `CELERY_BROKER_URL` 和 `CELERY_RESULT_BACKEND` 配置正确 + - 如果Redis有密码,URL格式应为:`redis://:password@localhost:6379/0` + +6. **详细排查**: + - 查看Redis日志:`sudo journalctl -u redis-server -f` + - 查看Celery日志:`tail -f /var/log/celery/worker.log` + - 参考 [Redis服务器部署](#redis服务器部署必需) 章节进行完整配置 + +**注意**:如果这是新部署的环境,请确保已按照 [Redis服务器部署](#redis服务器部署必需) 章节完整安装和配置Redis。 #### 错误3:任务执行失败 @@ -522,11 +936,36 @@ python test_celery.py ### 6. 生产环境优化建议 -- 使用独立的 Redis 服务器 -- 配置合适的 worker 数量(建议:CPU 核心数 × 2) -- 定期清理 Celery 任务结果 -- 配置监控系统(如 Prometheus + Grafana) -- 启用 Celery 监控工具(如 Flower) +#### Redis相关优化: +1. **使用独立Redis实例**:为Celery专门配置一个Redis实例,避免与其他应用共享 +2. **Redis性能调优**: + - 根据服务器内存调整 `maxmemory` 配置 + - 使用合适的内存淘汰策略(如 `allkeys-lru`) + - 启用持久化确保数据安全 +3. **Redis监控**: + - 配置Prometheus + Grafana监控Redis性能 + - 设置内存使用告警 + - 监控连接数和慢查询 + +#### Celery相关优化: +1. **Worker配置**: + - 配置合适的worker数量(建议:CPU核心数 × 2) + - 使用prefork或gevent模式根据任务类型选择 + - 设置合理的任务超时时间 +2. **任务管理**: + - 定期清理Celery任务结果 + - 配置任务重试机制 + - 使用任务优先级队列 +3. **监控工具**: + - 启用Celery监控工具(如Flower) + - 配置任务执行统计 + - 设置任务失败告警 + +#### 系统级优化: +1. **资源隔离**:为Celery worker和Redis分配独立的系统资源 +2. **日志管理**:配置集中式日志收集(如ELK Stack) +3. **备份策略**:定期备份Redis数据和任务结果 +4. **高可用方案**:考虑使用Redis Sentinel或Redis Cluster实现高可用 ## 定时生成PDF文件配置