You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Celery+Django+Selenium应用出现大量僵尸进程,如何清理任务资源并解决该问题?

Celery+Django+Selenium应用出现大量僵尸进程,如何清理任务资源并解决该问题?

我正在构建一个Celery + Django + Selenium的应用,用Celery来运行基于Selenium的浏览器进程。使用的版本如下:

celery==5.2.6
redis==3.4.1
selenium-wire==5.1.0
Django==4.0.4
djangorestframework==3.13.1

运行几个小时后,我发现应用会生成数千个僵尸进程,而且确定问题与Celery Docker容器相关——因为执行sudo /usr/local/bin/docker-compose -f /data/new_app/docker-compose.yml restart celery命令重启Celery容器后,所有僵尸进程就都消失了。

我的代码

Web服务端点代码

from rest_framework.decorators import api_view

@api_view(['POST'])
def periodic_check_all_urls(request): # web-service endpoint
    ...
    check_urls.delay(parsing_results_ids) # call celery task

Celery任务代码

from celery import shared_task


@shared_task()
def check_urls(parsing_result_ids: List[int]):
    """
    Run Selenium-based parser
    the parser exctracts data and saves in database
    """
    try:
        logger.info(f"{datetime.now()} Start check_urls")
        parser = Parser() # open selenium browser
        parsing_results = ParsingResult.objects.filter(pk__in=parsing_result_ids).exclude(status__in=["DONE", "FAILED"])
        parser.check_parsing_result(parsing_results)
    except Exception as e:
        full_trace = traceback.format_exc()
    finally:
        if 'parser' in locals():
            parser.stop()

Selenium浏览器的停止函数与析构方法

class Parser():
    def __init__(self):
        """
        Prepare parser
        """
        if not USE_GUI:
            self.display = Display(visible=0, size=(800, 600))
            self.display.start()
        

        """ Replaced with FireFox
        self.driver = get_chromedriver(proxy_data)
        """
        proxy_data = {
            ...
        }
        self.driver = get_firefox_driver(proxy_data=proxy_data)

    
    def __del__(self):
        self.stop()

    def stop(self):
        try:
            self.driver.quit()
            logger.info("Selenium driver closed")
        except:
            pass
        
        try:
            self.display.stop()
            logger.info("Display stopped")
        except:
            pass

尝试过的优化(未解决僵尸进程问题)

我试过调整Celery的任务资源限制和超时设置,但没有效果:

Django settings.py中的Celery配置

# celery setting (documents generation)
CELERY_BROKER_URL = os.environ.get("CELERY_BROKER", "redis://redis:6379/0")
CELERY_RESULT_BACKEND = os.environ.get("CELERY_BROKER", "redis://redis:6379/0")
CELERY_IMPORTS = ("core_app.celery",)
CELERY_TASK_TIME_LIMIT = 10 * 60

Docker中的Celery配置

celery:
    build: ./project
    command: celery -A core_app worker  --loglevel=info --concurrency=15 --max-memory-per-child=1000000
    volumes:
      - ./project:/usr/src/app
      - ./project/media:/project/media
      - ./project/logs:/project/logs
    env_file:
      - .env
    environment:
    # environment variables declared in the environment section override env_file
      - DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]
      - CELERY_BROKER=redis://redis:6379/0
      - CELERY_BACKEND=redis://redis:6379/0
    depends_on:
      - django
      - redis

参考过的解决方案(未奏效)

  • 我曾查找过关于如何终止Celery任务的相关问题,但没有帮助
  • 也看过Celery撤销任务后遗留僵尸进程的相关案例,不过我的任务已经包含了try/finally逻辑来清理资源

僵尸进程示例

执行ps aux | grep 'Z'后得到的结果:

ps aux | grep 'Z'

root     32448  0.0  0.0      0     0 ?        Z    13:45   0:00 [Utility Process] <defunct>
root     32449  0.0  0.0      0     0 ?        Z    13:09   0:00 [Utility Process] <defunct>
root     32450  0.0  0.0      0     0 ?        Z    11:13   0:00 [sh] <defunct>
root     32451  0.0  0.0      0     0 ?        Z    13:44   0:00 [Utility Process] <defunct>
root     32452  0.0  0.0      0     0 ?        Z    10:12   0:00 [Utility Process] <defunct>
root     32453  0.0  0.0      0     0 ?        Z    09:52   0:00 [sh] <defunct>
root     32454  0.0  0.0      0     0 ?        Z    10:40   0:00 [Utility Process] <defunct>
root     32455  0.0  0.0      0     0 ?        Z    09:52   0:00 [Utility Process] <defunct>
root     32456  0.0  0.0      0     0 ?        Z    10:13   0:00 [sh] <defunct>
root     32457  0.0  0.0      0     0 ?        Z    10:51   0:00 [Utility Process] <defunct>
root     32459  0.0  0.0      0     0 ?        Z    14:01   0:00 [Utility Process] <defunct>
root     32460  0.0  0.0      0     0 ?        Z    13:16   0:00 [Utility Process] <defunct>
root     32461  0.0  0.0      0     0 ?        Z    10:40   0:00 [Utility Process] <defunct>
root     32462  0.0  0.0      0     0 ?        Z    10:12   0:00 [Utility Process] <defunct>

备注:内容来源于stack exchange,提问作者mascai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 17:49:37