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

Docker部署Django+PostgreSQL高负载下域名解析失败,如何调优连接器?

问题

我的Django项目与PostgreSQL数据库均部署在Docker容器中,日常运行正常,但在高负载场景下偶尔会出现django.db.utils.OperationalError: could not translate host name "db" to address: Temporary failure in name resolution错误。请问是否可以通过调整Django数据库连接器的重试次数或超时时间来解决该问题?

附上修改后的docker-compose.yml配置:

version: '3.5'

services:
  django:
    build:
      context: ./django
      dockerfile: Dockerfile
    command:
      python manage.py runserver 0.0.0.0:8000
    volumes:
      django_volume:/home/django/django/files/
    ports:
      8000:8000
    env_file:
      env.django
    depends_on:
      db

  db:
    build: 
      context: ./db
      dockerfile: Dockerfile
    volumes:
      db_volume:/var/lib/postgresql/data/
    env_file:
      env.db

volumes:
  django_volume:
  db_volume:

Django容器的entrypoint.sh包含如下循环,用于确保数据库完全启动后再启动Django:

while ! nc -x $DB_HOST $DB_PORT ; do
  sleep 0.1
done

exec "$@"

解决方案

1. 调整Django数据库连接的重试与超时配置

可以通过修改Django数据库配置来应对DNS解析临时失败的问题,具体配置如下:

在Django的settings.py中,针对PostgreSQL数据库添加连接优化参数:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.getenv('DB_NAME'),
        'USER': os.getenv('DB_USER'),
        'PASSWORD': os.getenv('DB_PASSWORD'),
        'HOST': os.getenv('DB_HOST'),
        'PORT': os.getenv('DB_PORT'),
        # 连接池保持连接的时间,减少重复建立连接的DNS解析开销
        'CONN_MAX_AGE': 60,
        'OPTIONS': {
            # 设置连接超时时间(秒)
            'connect_timeout': 10,
            # 启用psycopg2的自动重连特性(需psycopg2>=2.8)
            'reconnect': True,
        },
    }
}

如果你的psycopg2版本不支持reconnect参数,可以自定义重试逻辑:捕获OperationalError异常后,手动重试数据库连接(可通过装饰器或自定义数据库路由实现)。

2. 修复entrypoint.sh的nc命令错误

你的entrypoint.sh中nc命令使用了-x参数(该参数用于指定代理服务器),正确检测端口开放状态的参数应为-z(扫描模式,不发送数据)。修改后的脚本:

while ! nc -z $DB_HOST $DB_PORT ; do
  sleep 0.1
done

exec "$@"

这个错误可能导致容器启动时无法正确校验数据库状态,高负载下会进一步放大DNS解析问题的影响。

3. 优化Docker DNS配置

高负载下Docker内置DNS可能出现临时解析失败,可通过以下方式优化:

  • 在docker-compose.yml的django服务中添加外部DNS服务器配置:
services:
  django:
    # ... 其他原有配置
    dns:
      - 8.8.8.8
      - 1.1.1.1
  • 修改Docker daemon配置(/etc/docker/daemon.json),增加DNS重试次数和超时:
{
  "dns-opts": ["timeout:2", "attempts:3"],
  "dns": ["8.8.8.8", "1.1.1.1"]
}

修改后重启Docker服务:systemctl restart docker

4. 连接池优化

使用第三方连接池库进一步减少DNS解析压力,例如django-db-connection-pool:

# 安装库后替换数据库引擎
DATABASES = {
    'default': {
        'ENGINE': 'dj_db_conn_pool.backends.postgresql',
        'NAME': os.getenv('DB_NAME'),
        'USER': os.getenv('DB_USER'),
        'PASSWORD': os.getenv('DB_PASSWORD'),
        'HOST': os.getenv('DB_HOST'),
        'PORT': os.getenv('DB_PORT'),
        'CONN_MAX_AGE': 300,
        'OPTIONS': {
            'connect_timeout': 10,
        },
        'POOL_OPTIONS': {
            'POOL_SIZE': 10,
            'MAX_OVERFLOW': 20,
        }
    }
}

内容的提问来源于stack exchange,提问作者deadkitten

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 10:10:23