如何让Unix服务器Docker容器内启动的进程保持持续运行不被自动终止
问题根因及解决方案
1. Pika连接断连问题(最高发原因)
你的单条任务执行耗时5-7分钟,远超过RabbitMQ默认60秒的心跳超时阈值,消费进程执行业务逻辑期间会阻塞pika的IO循环,无法和MQ服务端交互心跳包,服务端会判定连接失效主动断开连接,未配置重连逻辑的进程会直接无报错退出。
- 解决方法:
- 调整pika连接参数,调大心跳阈值或关闭心跳,同时增加断连自动重连逻辑:
import pika import logging logging.basicConfig(level=logging.INFO, filename="consumer.log") credentials = pika.PlainCredentials("你的MQ用户名", "你的MQ密码") parameters = pika.ConnectionParameters( host="MQ服务地址", port=5672, credentials=credentials, heartbeat=600, # 调大到600秒,也可设为0关闭心跳 blocked_connection_timeout=600 ) # 外层加死循环实现断连自动重连 while True: try: conn = pika.BlockingConnection(parameters) channel = conn.channel() # 此处写你原有队列声明、消费绑定逻辑 channel.basic_consume(queue="你的队列名", on_message_callback=你的消费回调函数, auto_ack=False) channel.start_consuming() except pika.exceptions.ConnectionClosedByBroker: logging.info("连接被Broker断开,尝试重连") continue except pika.exceptions.AMQPConnectionError: logging.info("连接异常,尝试重连") continue except Exception as e: logging.error(f"未捕获异常: {str(e)}", exc_info=True) break- 优化执行逻辑:消费到消息后先ack,再将任务丢到本地线程/进程池执行,避免阻塞pika的IO循环导致心跳无法发送。
2. 进程无托管自动退出问题
你直接用nohup启动进程没有监控托管机制,进程因为任意异常退出后不会自动拉起,同时Docker容器如果未配置重启策略,容器异常退出也不会自动恢复。
- 解决方法:
- 容器层面:启动容器时添加
--restart=always参数,容器退出后自动重启。 - 进程层面:用
supervisor托管所有消费进程,配置异常退出自动重启规则,单进程配置示例如下:
按进程序号新增多段配置即可,supervisor会持续监控进程状态,异常退出后自动拉起。[program:sales-consumer-1] command=python3 /你的脚本绝对路径/sales_of_years.py 1 directory=/你的脚本所在目录 user=root autostart=true autorestart=true startretries=5 stdout_logfile=/var/log/sales-consumer-1.log stderr_logfile=/var/log/sales-consumer-1.err.log - 容器层面:启动容器时添加
3. 资源限制或隐式异常问题
- 检查Docker容器的资源配额:如果进程内存占用持续上涨超过容器配置的内存上限,会被系统OOM killer直接杀掉无报错,可通过
docker stats 容器ID查看运行时资源占用,启动容器时添加--memory=8G之类的参数放大内存配额。 - 检查RabbitMQ服务端的
consumer_timeout配置:默认值为30分钟,如果你的单任务实际执行时长超过该阈值,服务端会主动取消消费者,按需调大该参数即可。
内容的提问来源于stack exchange,提问作者jhon B
相关产品推荐
相关产品推荐

