From 635421b2183d8f5e1e4d1efa9d1200e251d00c07 Mon Sep 17 00:00:00 2001 From: XingQue Date: Tue, 16 Jun 2026 11:39:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BD=BB=E5=BA=95=E5=85=B3=E9=97=AD=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=E8=B6=85=E6=97=B6=E8=87=AA=E5=8A=A8=E7=BB=93=E7=AE=97?= =?UTF-8?q?=EF=BC=9A=E6=80=BB=E5=BC=80=E5=85=B3+=E7=A7=BB=E9=99=A4=20order?= =?UTF-8?q?s.tasks=20=E6=B3=A8=E5=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- a_long_dianjing/celery.py | 7 ++-- a_long_dianjing/settings.py | 4 ++- deploy/supervisor/README.md | 7 ++++ orders/signals.py | 65 ++++++++++++------------------------- orders/tasks.py | 14 ++++---- 5 files changed, 42 insertions(+), 55 deletions(-) diff --git a/a_long_dianjing/celery.py b/a_long_dianjing/celery.py index 93d3f8f..af17945 100644 --- a/a_long_dianjing/celery.py +++ b/a_long_dianjing/celery.py @@ -16,7 +16,8 @@ app = Celery('a_long_dianjing') app.config_from_object('django.conf:settings', namespace='CELERY') # 自动发现所有已注册app中的tasks.py文件 #app.autodiscover_tasks() -app.autodiscover_tasks(['users.tasks', 'users.ranking_tasks', 'orders.tasks', 'config.tasks']) +# 自动发现任务(不含 orders.tasks:订单超时自动结算已永久关闭) +app.autodiscover_tasks(['users.tasks', 'users.ranking_tasks', 'config.tasks']) # 配置周期性任务(Celery Beat Schedule) app.conf.beat_schedule = { @@ -91,9 +92,9 @@ app.conf.beat_schedule = { app.conf.timezone = 'Asia/Shanghai' app.conf.enable_utc = True -# 队列路由配置 +# 队列路由配置(orders.tasks 已移除:禁止 order_tasks 队列再调度超时结算) app.conf.task_routes = { - 'orders.tasks.*': {'queue': 'order_tasks'}, + # 'orders.tasks.*': {'queue': 'order_tasks'}, 'users.tasks.*': {'queue': 'periodic_tasks'}, 'config.tasks.*': {'queue': 'periodic_tasks'}, } diff --git a/a_long_dianjing/settings.py b/a_long_dianjing/settings.py index e8bfba1..da67050 100644 --- a/a_long_dianjing/settings.py +++ b/a_long_dianjing/settings.py @@ -294,7 +294,9 @@ CELERY_TASK_QUEUES = { } # ==================== 定时任务时间配置 ==================== -ORDER_EXPIRE_SECONDS = 48 * 60 * 60 # 48小时 = 172800秒 +# 订单超时自动结算(Celery process_expired_order / check_order_expire_task)总开关:False=彻底关闭 +ORDER_AUTO_SETTLEMENT_ENABLED = False +ORDER_EXPIRE_SECONDS = 48 * 60 * 60 # 48小时 = 172800秒(开关关闭时不生效) DAILY_TASK_HOUR = 0 DAILY_TASK_MINUTE = 30 MONTHLY_TASK_DAY = 1 diff --git a/deploy/supervisor/README.md b/deploy/supervisor/README.md index b4a35c7..fa5e17c 100644 --- a/deploy/supervisor/README.md +++ b/deploy/supervisor/README.md @@ -33,4 +33,11 @@ supervisorctl restart celery-broadcast - 不要用 `nohup` 再起第二个 celery worker,避免抢任务。 - 仅 `-Q default`,不会跑订单自动结算(order_tasks)。 +- **禁止** 启动 `celery beat` 或 `-Q order_tasks` 的 worker。 +- 部署后执行一次(清理旧进程): + ```bash + pkill -f "celery -A a_long_dianjing beat" || true + pkill -f "celery -A a_long_dianjing worker.*order_tasks" || true + supervisorctl restart celery-broadcast + ``` - 密钥文件 `app_secrets.py` 只放服务器,不要提交 Git。 diff --git a/orders/signals.py b/orders/signals.py index 4dbdae9..2534423 100644 --- a/orders/signals.py +++ b/orders/signals.py @@ -42,54 +42,29 @@ ensure_redis_loaded() @receiver(pre_save, sender='orders.Dingdan') def handle_order_status_8(sender, instance, **kwargs): """ - 订单状态变为8时,提交定时任务 + 订单状态变为8时的信号处理。 + ORDER_AUTO_SETTLEMENT_ENABLED=False 时不提交任何 Celery 超时结算任务。 """ - # 跳过新增的订单 - if instance.pk is None: + if not getattr(settings, 'ORDER_AUTO_SETTLEMENT_ENABLED', False): + if instance.pk is None: + return + try: + from orders.models import Dingdan + old = Dingdan.query.filter(pk=instance.pk).values_list('zhuangtai', flat=True).first() + if old != 8 and instance.zhuangtai == 8: + instance.status_8_time = timezone.now() + instance.pending_dispatch = False + instance.auto_task_id = '' + instance.auto_expire_at = None + elif old == 8 and instance.zhuangtai != 8: + instance.status_8_time = None + instance.pending_dispatch = False + instance.auto_task_id = '' + except Exception as e: + logger.error(f'信号处理失败: {e}') return - - try: - # 动态导入,避免循环依赖 - from orders.models import Dingdan - - # 获取旧状态 - old = Dingdan.query.filter(pk=instance.pk).values_list('zhuangtai', flat=True).first() - - # 状态从 非8 变为 8 - if old != 8 and instance.zhuangtai == 8: - # 订单自动结算已关闭:仅记录时间标记,不再提交 Celery 延时结算任务 - instance.status_8_time = timezone.now() - instance.pending_dispatch = False - instance.auto_task_id = '' - instance.auto_expire_at = None - logger.info(f"订单 {instance.dingdan_id} 状态变为8(自动结算已禁用,不提交结算任务)") - # --- 原自动结算逻辑(已禁用,保留代码备查)--- - # expire_seconds = getattr(settings, 'ORDER_EXPIRE_SECONDS', 48 * 60 * 60) - # try: - # from orders.tasks import process_expired_order - # task_result = process_expired_order.apply_async( - # args=[instance.dingdan_id], - # countdown=expire_seconds, - # queue='order_tasks', - # priority=9 - # ) - # instance.auto_task_id = task_result.id - # instance.auto_expire_at = timezone.now() + timezone.timedelta(seconds=expire_seconds) - # except Exception as e: - # logger.error(f"❌ 任务提交失败: {e}") - # instance.pending_dispatch = True - # instance.auto_task_id = f"failed_{timezone.now().timestamp()}" - - # 状态从 8 变为 非8 - elif old == 8 and instance.zhuangtai != 8: - instance.status_8_time = None - instance.pending_dispatch = False - instance.auto_task_id = '' - logger.info(f"📅 订单 {instance.dingdan_id} 状态离开8") - - except Exception as e: - logger.error(f"信号处理失败: {e}") + # --- 以下原自动结算逻辑保留备查(开关打开时才启用,当前生产应为 False)--- diff --git a/orders/tasks.py b/orders/tasks.py index 04796c9..69c62f1 100644 --- a/orders/tasks.py +++ b/orders/tasks.py @@ -27,10 +27,11 @@ logger = logging.getLogger(__name__) def process_expired_order(self, dingdan_id): """ 处理单个超时订单(订单状态=8,超过48小时未处理) - 【已禁用】保留任务定义避免 Celery 注册/引用报错,实际不执行结算逻辑 + 【已禁用】ORDER_AUTO_SETTLEMENT_ENABLED=False 且已从 Celery autodiscover 移除 """ - logger.info(f"订单{dingdan_id}自动结算任务已禁用,跳过执行") - return f"订单{dingdan_id}自动结算已禁用,跳过" + if not getattr(settings, 'ORDER_AUTO_SETTLEMENT_ENABLED', False): + logger.warning('订单%s自动结算已关闭(ORDER_AUTO_SETTLEMENT_ENABLED=False),拒绝执行', dingdan_id) + return f"订单{dingdan_id}自动结算已禁用,跳过" # --- 以下原结算逻辑保留备查 --- try: @@ -140,10 +141,11 @@ def process_expired_order(self, dingdan_id): def check_order_expire_task(): """ 批量检查超时订单(补偿机制) - 【已禁用】保留任务定义避免 Beat/Worker 引用报错,实际不执行 + 【已禁用】ORDER_AUTO_SETTLEMENT_ENABLED=False """ - logger.info("订单自动结算补偿检查已禁用,跳过") - return {"success": True, "message": "自动结算已禁用", "count": 0} + if not getattr(settings, 'ORDER_AUTO_SETTLEMENT_ENABLED', False): + logger.warning('订单自动结算补偿检查已关闭(ORDER_AUTO_SETTLEMENT_ENABLED=False),拒绝执行') + return {"success": True, "message": "自动结算已禁用", "count": 0} # --- 以下原补偿逻辑保留备查 --- try: