2026-01-04 19:17:33 +08:00
2026-01-04 19:17:33 +08:00
2026-01-04 20:55:28 +08:00

家庭日报系统

专注于家庭生活的轻量级日报系统使用Django框架开发。

功能特性

  • 阅读记录管理(支持添加阅读笔记)
  • 感悟记录管理
  • 家庭事项管理(支持自定义事项类型)
  • 今日计划管理
  • 报告生成
  • 邮件发送
  • 后台管理界面(访问路径:/houtai

技术栈

  • Python 3.10+
  • Django 4.2+
  • Bootstrap 5
  • SQLite开发环境
  • PostgreSQL/MySQL生产环境
  • Gunicorn + Nginx生产部署

快速开始

安装依赖

pip install -r requirements.txt

运行开发服务器

python manage.py runserver

访问系统

打开浏览器访问:http://127.0.0.1:8000

数据库迁移指南

基本迁移流程

  1. 生成迁移文件:

    python manage.py makemigrations
    
  2. 查看迁移文件内容(重要!):

    cat core/migrations/000x_xxx.py
    
  3. 应用迁移:

    python manage.py migrate
    

当数据库有数据时增加字段

问题说明

当数据库中已有数据时通过Django的migrate命令增加新字段不会删除原有数据,但需要注意以下几点:

  1. 如果新字段设置为非空null=False, blank=False),则必须提供默认值,否则迁移会失败
  2. 如果新字段设置为可空null=True, blank=True则迁移会自动执行原有记录的新字段值为NULL

正确部署流程

  1. 在开发环境测试

    • 首先在开发环境生成迁移文件
    • 检查迁移文件内容,确保:
      • 新字段设置为可空(null=True, blank=True),或者
      • 新字段提供了合理的默认值
    • 在开发环境执行迁移,测试功能是否正常
  2. 备份生产数据库(重要!):

    # PostgreSQL示例
    pg_dump -U username -d dbname > backup_$(date +%Y%m%d_%H%M%S).sql
    
    # MySQL示例
    mysqldump -u username -p dbname > backup_$(date +%Y%m%d_%H%M%S).sql
    
  3. 在生产环境执行迁移

    # 进入项目目录
    cd /path/to/diary-family
    
    # 激活虚拟环境
    source venv/bin/activate
    
    # 生成迁移文件(如果在开发环境已生成,可跳过)
    python manage.py makemigrations
    
    # 应用迁移
    python manage.py migrate
    
  4. 验证迁移结果

    • 检查应用是否正常运行
    • 验证新功能是否可用
    • 检查数据是否完整

示例增加阅读笔记note字段

  1. 在模型中添加字段(core/models.py

    # 正确的做法:设置为可空字段
    note = models.TextField(blank=True, null=True, verbose_name="阅读笔记")
    
    # 或者:提供默认值
    note = models.TextField(default="", blank=True, verbose_name="阅读笔记")
    
  2. 生成迁移文件:

    python manage.py makemigrations
    
  3. 检查迁移文件,确保新字段设置正确:

    # 迁移文件示例0003_readingrecord_note.py
    class Migration(migrations.Migration):
        dependencies = [
            ('core', '0002_xxx'),
        ]
    
        operations = [
            migrations.AddField(
                model_name='readingrecord',
                name='note',
                field=models.TextField(blank=True, null=True, verbose_name='阅读笔记'),
            ),
        ]
    
  4. 应用迁移:

    python manage.py migrate
    

CSV数据导入指南

生成CSV文件

项目包含一个generate_import_csv.py脚本用于生成符合数据库表结构的CSV文件并导入数据。

  1. 生成CSV文件

    python generate_import_csv.py
    
  2. 生成的CSV文件

    • reading_type.csv - 阅读记录类型
    • insight_record.csv - 感悟记录
    • reading_record.csv - 阅读记录

CSV文件格式说明

reading_type.csv阅读记录类型

字段名 类型 说明
name 字符串 阅读类型名称(如:书籍、文章、论文等)

insight_record.csv感悟记录

字段名 类型 说明
date 日期 记录日期格式YYYY-MM-DD
content 文本 感悟内容

reading_record.csv阅读记录

字段名 类型 说明
date 日期 记录日期格式YYYY-MM-DD
type_id 整数 阅读类型ID关联reading_type表的id字段
title 字符串 阅读标题
source 字符串 阅读来源
progress 字符串 阅读进度(如:已完成、进行中、未开始)
note 文本 阅读笔记

自定义CSV数据

你可以手动编辑生成的CSV文件添加或修改数据然后再次运行导入脚本将数据导入到数据库。

数据导入

脚本会自动将CSV数据导入到数据库中导入流程

  1. 清空ReadingType表的现有数据避免类型ID冲突
  2. 导入ReadingType数据
  3. 导入InsightRecord数据
  4. 导入ReadingRecord数据

验证导入结果

可以使用Django shell查询数据库验证数据是否正确导入

python -c "import os; os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'diary_family.settings'); import django; django.setup(); from core.models import ReadingType, InsightRecord, ReadingRecord; print('ReadingType数量:', ReadingType.objects.count()); print('InsightRecord数量:', InsightRecord.objects.count()); print('ReadingRecord数量:', ReadingRecord.objects.count()); print('ReadingType数据:', [rt.name for rt in ReadingType.objects.all()])"

生产部署

使用Gunicorn + Nginx

  1. 安装Gunicorn

    pip install gunicorn
    
  2. 启动Gunicorn

    gunicorn diary_family.wsgi:application --bind 0.0.0.0:8000
    
  3. 配置Nginx/etc/nginx/sites-available/diary-family

    server {
        listen 80;
        server_name example.com;
    
        location / {
            proxy_pass http://127.0.0.1:8000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    
        location /static/ {
            alias /path/to/diary-family/static/;
        }
    
        location /media/ {
            alias /path/to/diary-family/media/;
        }
    }
    
  4. 启用Nginx配置

    ln -s /etc/nginx/sites-available/diary-family /etc/nginx/sites-enabled/
    systemctl restart nginx
    

Redis服务器部署必需

家庭日报系统使用Celery进行异步任务处理如PDF生成、邮件发送而Celery依赖Redis作为消息代理和结果后端。在生产环境中必须部署Redis服务器

1. 安装Redis服务器

在Ubuntu服务器上安装Redis

# 更新包管理器
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配置文件以增强安全性

# 备份原始配置文件
sudo cp /etc/redis/redis.conf /etc/redis/redis.conf.backup

# 编辑Redis配置文件
sudo nano /etc/redis/redis.conf

在配置文件中进行以下修改:

# 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服务

# 重启Redis使配置生效
sudo systemctl restart redis-server

# 验证Redis是否正常运行
redis-cli ping

3. 测试Redis连接

验证Redis是否可以正常连接

基本连接测试:

# 测试无密码连接(如果设置了密码,应该失败)
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

高级测试:

# 测试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集成

# 运行完整的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配置正确。

快速验证命令:

# 一键验证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

# 生产环境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

# 激活虚拟环境
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性能

# 查看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

定期维护:

# 备份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故障排除

问题1Redis服务无法启动

# 查看Redis日志
sudo journalctl -u redis-server -f

# 检查配置文件语法
sudo redis-server /etc/redis/redis.conf --test

# 检查端口占用
sudo netstat -tlnp | grep 6379

问题2连接被拒绝

# 检查防火墙设置
sudo ufw status
sudo ufw allow 6379/tcp

# 检查Redis绑定地址
sudo grep "^bind" /etc/redis/redis.conf

# 检查Redis是否在监听
sudo ss -tlnp | grep 6379

问题3内存不足

# 查看内存使用情况
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 中设置:

requirepass your_strong_password_here

然后在Django的 settings.py 中更新:

CELERY_BROKER_URL = 'redis://:your_strong_password_here@localhost:6379/0'

Q5: Redis数据会丢失吗

A: Redis默认将数据存储在内存中重启服务会丢失数据。但可以通过配置持久化来避免

# 在redis.conf中启用持久化
save 900 1      # 900秒内至少有1个键被修改
save 300 10     # 300秒内至少有10个键被修改  
save 60 10000   # 60秒内至少有10000个键被修改

Q6: 如何监控Redis性能

A: 使用以下命令监控:

# 实时监控
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: 备份方法:

# 手动备份
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中
    maxclients 10000
    
  2. 优化Celery连接池
  3. 检查是否有连接泄漏

Q10: 如何验证Redis部署是否成功

A: 使用项目提供的测试脚本:

# 运行完整测试
python test_redis_celery.py

# 预期输出:所有测试通过,显示绿色成功信息

Q11: 生产环境Redis安全注意事项

A: 安全配置清单:

  • 设置强密码
  • 绑定到127.0.0.1或内网IP
  • 禁用危险命令FLUSHALL, FLUSHDB, CONFIG
  • 启用防火墙,只允许必要端口
  • 定期更新Redis版本
  • 配置日志监控

Q12: Redis性能调优参数有哪些

A: 关键调优参数:

# 内存管理
maxmemory 1gb
maxmemory-policy allkeys-lru

# 持久化优化
save 900 1
save 300 10
save 60 10000

# 网络优化
tcp-keepalive 60
timeout 300

常规代码更新流程

当需要更新代码时,可以使用以下命令:

# 退出虚拟环境
deactivate

# 切换到项目目录
cd /var/www/diary-family

# 1. 拉取远程最新代码(只获取,不合并)
git fetch origin

# 2. 硬重置本地分支到远程分支的最新版本(会覆盖所有本地未提交修改)
# 注意:将 main 替换为你的分支名(如 master、dev 等)
git reset --hard origin/main

# 3. 激活虚拟环境
source venv/bin/activate

# 4. 安装新依赖(如果有)
pip install -r requirements.txt

# 5. 收集静态文件(如果有静态文件更新)
python manage.py collectstatic --noinput

# 6. 重启服务
sudo supervisorctl restart all
sudo systemctl restart nginx

系统配置

在系统配置页面可以设置:

  • SMTP服务器信息
  • 邮件发送时间
  • 收件人邮箱

Celery 定时发送邮件任务配置

1. 邮件配置设置

在系统配置页面设置完邮件信息后,还需要在 Django 项目的 settings.py 中添加基础邮件配置:

# 邮件基础配置
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_PORT = 587  # 或根据你的 SMTP 服务器设置
EMAIL_USE_TLS = True  # 或根据你的 SMTP 服务器设置

2. 启动 Celery Worker 和 Beat

开发环境

# 启动 Celery Worker
celery -A diary_family worker -l info

# 启动 Celery Beat用于定时任务调度
celery -A diary_family beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler

生产环境

建议使用 supervisor 管理 Celery 进程。创建两个 supervisor 配置文件:

  1. celery_worker.conf

    [program:celery_worker]
    command=/path/to/venv/bin/celery -A diary_family worker -l info
    directory=/path/to/diary-family
    user=www-data
    group=www-data
    autostart=true
    autorestart=true
    stdout_logfile=/var/log/celery/worker.log
    stderr_logfile=/var/log/celery/worker_error.log
    
  2. celery_beat.conf

    [program:celery_beat]
    command=/path/to/venv/bin/celery -A diary_family beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler
    directory=/path/to/diary-family
    user=www-data
    group=www-data
    autostart=true
    autorestart=true
    stdout_logfile=/var/log/celery/beat.log
    stderr_logfile=/var/log/celery/beat_error.log
    

启动 supervisor 服务:

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start celery_worker
sudo supervisorctl start celery_beat

3. 配置定时任务

系统使用 django_celery_beat 进行定时任务管理,支持两种方式配置:

方式一:通过 Django 管理后台(推荐)

  1. 登录 Django 管理后台(/houtai
  2. 找到 Periodic tasks(周期性任务)
  3. 点击 Add 按钮添加新任务
  4. 配置任务:
    • Name: 任务名称(如:每日报告发送)
    • Task (registered): 选择 core.tasks.send_daily_report
    • Interval: 设置执行间隔(如:每天)
    • Enabled: 勾选启用
  5. 点击 Save 保存

方式二:通过代码配置

core/tasks.py 中添加定时任务配置:

from celery import shared_task
from django_celery_beat.models import PeriodicTask, IntervalSchedule

# 创建或更新定时任务
def setup_daily_report_task():
    # 创建每天执行的间隔
    schedule, created = IntervalSchedule.objects.get_or_create(
        every=1,
        period=IntervalSchedule.DAYS,
    )
    
    # 创建或更新定时任务
    task, created = PeriodicTask.objects.update_or_create(
        name='Daily Report Task',
        defaults={
            'interval': schedule,
            'task': 'core.tasks.send_daily_report',
        },
    )
    return task

然后在 Django 启动时调用此函数(如在 core/apps.py 中)。

4. 验证任务执行

  • 查看 Celery 日志:tail -f /var/log/celery/worker.log
  • 检查邮件是否正常发送
  • 在 Django 管理后台查看任务执行记录

5. 日志文件不存在问题解决方法

如果在生产服务器上执行 tail -f /var/log/celery/worker.log 时提示 No such file or directory,请按照以下步骤解决:

步骤1检查日志目录是否存在

# 检查日志目录是否存在
ls -la /var/log/celery/

# 如果目录不存在,创建目录
sudo mkdir -p /var/log/celery/

# 设置正确的权限(确保 Celery 进程用户有读写权限)
sudo chown -R www-data:www-data /var/log/celery/
sudo chmod -R 755 /var/log/celery/

步骤2检查 Supervisor 配置

确保 Supervisor 配置文件中指定的日志路径正确,并且 Celery 进程用户对该路径有读写权限。

步骤3重启 Supervisor 和 Celery

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl restart celery_worker celery_beat

5.1 日志文件查看指南

在生产环境中,有多种日志来源,了解每种日志的位置和查看方法非常重要:

5.1.1 Celery Worker 和 Beat 日志

这些日志由 Celery 进程产生,需要先创建日志目录:

# 创建日志目录
sudo mkdir -p /var/log/celery/

# 设置权限
sudo chown -R www-data:www-data /var/log/celery/
sudo chmod -R 755 /var/log/celery/

查看日志:

# 实时查看 Worker 日志
tail -f /var/log/celery/worker.log

# 实时查看 Beat 日志
tail -f /var/log/celery/beat.log

# 查看最近50行
tail -n 50 /var/log/celery/worker.log

# 搜索错误信息
grep -i error /var/log/celery/worker.log

# 搜索特定任务
grep -i "generate_daily_pdf_report" /var/log/celery/worker.log

5.1.2 测试脚本日志

运行测试脚本时,日志会同时输出到控制台和文件:

# 运行测试脚本(输出到控制台)
python test_redis_celery.py

# 查看测试日志文件
tail -f /var/log/celery/test_redis_celery.log

# 运行测试并保存到文件
python test_redis_celery.py 2>&1 | tee /var/log/celery/test_output.log

测试脚本日志内容示例:

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集成测试通过

5.1.3 Redis 日志

Redis 的日志通常在系统日志中:

# 查看 Redis 系统日志
sudo journalctl -u redis-server -f

# 查看 Redis 错误日志
sudo tail -f /var/log/redis/redis-server.log

# 查看所有 Redis 相关日志
sudo grep -i redis /var/log/syslog

5.1.4 Django 应用日志

# 查看 Django 应用日志
tail -f /path/to/diary-family/logs/app.log

# 查看 Gunicorn 日志
sudo tail -f /var/log/gunicorn/access.log
sudo tail -f /var/log/gunicorn/error.log

5.1.5 Nginx 日志

# 查看访问日志
sudo tail -f /var/log/nginx/access.log

# 查看错误日志
sudo tail -f /var/log/nginx/error.log

5.1.6 综合日志查看脚本

创建一个综合日志查看脚本:

#!/bin/bash
# save as: /usr/local/bin/view-all-logs

echo "=== Celery Worker Log ==="
tail -n 20 /var/log/celery/worker.log

echo -e "\n=== Celery Beat Log ==="
tail -n 20 /var/log/celery/beat.log

echo -e "\n=== Redis Server Log ==="
sudo tail -n 20 /var/log/redis/redis-server.log

echo -e "\n=== Nginx Error Log ==="
sudo tail -n 20 /var/log/nginx/error.log

使用方法:

# 给脚本添加执行权限
sudo chmod +x /usr/local/bin/view-all-logs

# 运行脚本
view-all-logs

5.1.7 日志轮转配置

为防止日志文件过大,配置日志轮转:

创建 /etc/logrotate.d/celery-app

/var/log/celery/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 www-data www-data
    sharedscripts
    postrotate
        supervisorctl restart celery_worker celery_beat > /dev/null 2>&1 || true
    endscript
}

启用配置:

sudo logrotate -f /etc/logrotate.d/celery-app

5.1.8 日志查看常见问题

问题1日志文件权限被拒绝

# 检查权限
ls -la /var/log/celery/

# 如果权限不对,重新设置
sudo chown -R www-data:www-data /var/log/celery/
sudo chmod -R 755 /var/log/celery/

问题2日志文件不存在

# 检查目录是否存在
ls -la /var/log/ | grep celery

# 如果不存在,创建目录
sudo mkdir -p /var/log/celery/
sudo chown www-data:www-data /var/log/celery/

问题3日志不更新

# 检查进程是否运行
ps aux | grep celery

# 检查文件是否被锁定
sudo lsof /var/log/celery/worker.log

# 检查磁盘空间
df -h /var/log/

问题4如何清理旧日志

# 删除7天前的日志
find /var/log/celery/ -name "*.log.*.gz" -mtime +7 -delete

# 清空当前日志文件(谨慎使用)
sudo truncate -s 0 /var/log/celery/worker.log

6. 试运行周期任务

当设置一个周期任务后,您可以通过以下方式试运行任务,而不需要等待到指定的时间:

方式1通过 Django 管理后台

  1. 登录 Django 管理后台(/houtai
  2. 找到 Periodic tasks(周期性任务)
  3. 选择您创建的任务
  4. 点击页面底部的 Run Task 按钮立即执行任务

方式2通过命令行

# 直接调用任务函数(同步执行)
python manage.py shell -c "from core.tasks import generate_daily_pdf_report; generate_daily_pdf_report()"

# 或者使用 Celery 命令行工具
celery -A diary_family call core.tasks.generate_daily_pdf_report

方式3使用测试脚本

项目提供了多个测试脚本,用于验证不同功能:

  1. Celery任务测试

    # 测试Celery任务执行
    python test_celery.py
    
  2. Redis和Celery集成测试(生产环境推荐):

    # 测试Redis连接、Celery集成和性能
    python test_redis_celery.py
    
  3. Redis连接测试(快速验证):

    # 仅测试Redis连接
    python -c "import redis; r = redis.Redis(host='localhost', port=6379); print('Redis连接成功' if r.ping() else '连接失败')"
    

7. 常见错误和解决方法

错误1日志文件不存在

错误信息tail: cannot open '/var/log/celery/worker.log' for reading: No such file or directory

解决方法

  • 按照步骤5中的说明创建日志目录并设置正确权限
  • 检查 Supervisor 配置中的日志路径是否正确
  • 重启 Supervisor 和 Celery 服务

错误2Celery 无法连接到 Redis

错误信息redis.exceptions.ConnectionError: Error 111 connecting to localhost:6379. Connection refused.

解决方法

  1. 检查Redis服务状态

    sudo systemctl status redis-server
    
  2. 如果Redis未运行启动服务

    sudo systemctl start redis-server
    sudo systemctl enable redis-server
    
  3. 检查Redis配置

    • 确保Redis配置文件 /etc/redis/redis.confbind 设置为 127.0.0.1
    • 检查是否有防火墙阻止连接:sudo ufw status
    • 检查端口是否被占用:sudo netstat -tlnp | grep 6379
  4. 测试Redis连接

    # 测试基本连接
    redis-cli ping
    
    # 如果设置了密码,使用密码连接
    redis-cli -a your_password ping
    
  5. 检查Celery配置

    • 确保 settings.py 中的 CELERY_BROKER_URLCELERY_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。

错误3任务执行失败

错误信息Task core.tasks.generate_daily_pdf_report[xxx] raised unexpected: Exception(...)

解决方法

  • 查看详细日志:tail -f /var/log/celery/worker.log
  • 检查任务代码中的错误
  • 确保所有依赖库都已正确安装
  • 检查相关服务如数据库、Redis是否正常运行

错误4PDF 生成失败

错误信息WeasyPrint库不可用无法生成PDF报告

解决方法

  • 安装 WeasyPrint 库:pip install weasyprint
  • 对于 Ubuntu 系统,可能需要安装系统依赖:
    sudo apt-get install -y libpango-1.0-0 libpangoft2-1.0-0
    

8. 常见问题排查

  1. 任务不执行

    • 检查 Celery worker 和 beat 是否正常运行
    • 检查 Redis 服务是否正常
    • 检查任务是否已启用
    • 检查系统时间是否正确
  2. 邮件发送失败

    • 检查 SMTP 服务器配置是否正确
    • 检查邮箱账号密码是否正确
    • 检查收件人邮箱格式是否正确
    • 查看 Celery 日志中的错误信息
  3. 任务执行延迟

    • 检查系统负载是否过高
    • 考虑增加 Celery worker 数量
    • 检查 Redis 性能

6. 生产环境优化建议

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文件配置

除了定时发送邮件外系统还支持单独定时生成PDF文件便于在服务器上保存历史报告。

1. 配置定时生成PDF任务

方式一:通过 Django 管理后台(推荐)

  1. 登录 Django 管理后台(/houtai
  2. 找到 Periodic tasks(周期性任务)
  3. 点击 Add 按钮添加新任务
  4. 配置任务:
    • Name: 任务名称每日PDF报告生成
    • Task (registered): 选择 core.tasks.generate_daily_pdf_report
    • Interval: 设置执行间隔(如:每天)
    • Enabled: 勾选启用
  5. 点击 Save 保存

方式二:通过代码配置

core/tasks.py 中添加定时任务配置:

from celery import shared_task
from django_celery_beat.models import PeriodicTask, IntervalSchedule

# 创建或更新PDF生成定时任务
def setup_daily_pdf_task():
    # 创建每天执行的间隔
    schedule, created = IntervalSchedule.objects.get_or_create(
        every=1,
        period=IntervalSchedule.DAYS,
    )
    
    # 创建或更新定时任务
    task, created = PeriodicTask.objects.update_or_create(
        name='Daily PDF Generation Task',
        defaults={
            'interval': schedule,
            'task': 'core.tasks.generate_daily_pdf_report',
        },
    )
    return task

然后在 Django 启动时调用此函数(如在 core/apps.py 中)。

2. PDF文件存储位置

生成的PDF文件默认存储在项目的 reports 目录下,命名格式为 report_YYYY-MM-DD.pdf

可以在 settings.py 中修改存储位置:

# Reports files configuration
REPORTS_URL = '/reports/'
REPORTS_ROOT = BASE_DIR / 'reports'  # 可以修改为其他路径

3. 验证PDF生成任务

  • 查看 Celery 日志:tail -f /var/log/celery/worker.log
  • 检查PDF文件是否生成ls -la /path/to/diary-family/reports/
  • 在 Django 管理后台查看任务执行记录

4. 常见问题排查

  1. PDF生成失败

    • 检查 WeasyPrint 库是否正确安装:pip list | grep weasyprint
    • 检查系统字体是否完整PDF生成需要系统字体支持
    • 查看 Celery 日志中的错误信息
  2. 任务执行但没有生成文件

    • 检查 REPORTS_ROOT 目录权限:确保 Celery 进程有写入权限
    • 检查磁盘空间是否充足
    • 查看 Celery 日志中的详细信息
  3. PDF内容不完整

    • 检查模板文件 core/templates/core/report_pdf.html 是否完整
    • 确保所有依赖的 CSS 和图像资源都能正常访问

邮件功能测试

项目提供了两个专门的测试脚本,用于验证邮件发送功能是否正常工作:

1. 基础邮件测试test_email.py

用于测试直接邮件发送功能验证SMTP配置是否正确。

测试内容

  • 邮件配置验证
  • SMTP连接测试
  • 发送简单文本邮件
  • 发送HTML邮件带附件
  • 邮件发送性能测试

运行方式

# 运行基础邮件测试
python test_email.py

测试结果说明

  • 所有测试通过:邮件系统配置正确,可以正常工作
  • 3项以上通过邮件系统基本可用部分功能可能需要优化
  • 少于3项通过邮件系统存在严重问题需要检查配置

2. Celery异步邮件测试test_celery_email.py

用于测试通过Celery异步发送邮件的功能验证整个异步任务链是否正常。

测试内容

  • Celery邮件配置验证
  • Celery Worker状态检查
  • Celery异步邮件任务执行
  • 同步发送测试邮件(用于对比)

运行方式

# 运行Celery异步邮件测试
python test_celery_email.py

测试结果说明

  • 所有测试通过Celery邮件功能正常
  • 2项以上通过Celery邮件功能基本可用
  • 少于2项通过存在严重问题需要检查配置

3. 常见问题排查

测试失败时的检查步骤

  1. 检查SMTP配置

    # 查看Django邮件配置
    python -c "import os; os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'diary_family.settings'); import django; django.setup(); from django.conf import settings; print('EMAIL_HOST:', getattr(settings, 'EMAIL_HOST', None)); print('EMAIL_PORT:', getattr(settings, 'EMAIL_PORT', None)); print('EMAIL_HOST_USER:', getattr(settings, 'EMAIL_HOST_USER', None))"
    
  2. 检查Redis服务

    sudo systemctl status redis-server
    redis-cli ping
    
  3. 检查Celery Worker状态

    # 查看Celery Worker状态
    celery -A diary_family status
    
    # 如果Worker未运行启动它
    celery -A diary_family worker -l info
    
  4. 查看日志文件

    # 查看邮件测试日志
    tail -f /var/log/celery/test_email.log
    tail -f /var/log/celery/test_celery_email.log
    
    # 查看Celery日志
    tail -f /var/log/celery/worker.log
    tail -f /var/log/celery/beat.log
    
  5. 验证网络连通性

    # 测试SMTP服务器连通性
    telnet smtp.example.com 587
    
    # 测试DNS解析
    nslookup smtp.example.com
    

常见错误及解决方案

错误信息 可能原因 解决方案
连接被拒绝 SMTP服务器地址/端口错误 检查SMTP配置确认服务器地址和端口
认证失败 用户名或密码错误 检查邮箱账号和密码确认是否开启了SMTP服务
Celery连接失败 Redis未运行或配置错误 检查Redis服务状态验证CELERY_BROKER_URL配置
任务超时 Worker未运行或任务执行时间过长 启动Celery Worker检查任务代码

Celery 监控(可选)

使用 Flower 监控 Celery 任务:

# 安装 Flower
pip install flower

# 启动 Flower
celery -A diary_family flower --port=5555

访问 http://your-server:5555 查看任务监控界面。

注意事项

  1. 定期备份数据库
  2. 生产环境建议使用PostgreSQL或MySQL数据库
  3. 定期清理过期数据
  4. 保持依赖包更新
  5. 定期运行邮件测试脚本,确保邮件功能正常

许可证

MIT License

Description
家庭的日常报告,包括阅读,体悟,运动,计划等等内容。
Readme 463 KiB
Languages
Python 56.4%
HTML 43.6%