彻底关闭订单超时自动结算:总开关+移除 orders.tasks 注册
This commit is contained in:
@@ -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'},
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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。
|
||||
|
||||
@@ -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)---
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user