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

K8s中Django多副本连PostgreSQL/PGBouncer遇连接数耗尽问题求助

Django + PGBouncer + PostgreSQL 多副本连接问题排查与扩容疑问

问题现象

在Kubernetes环境中运行Django+PGBouncer+PostgreSQL架构的应用,单Django副本运行无异常,但启动2个副本后,部分请求触发以下错误:

Django侧报错

django.db.utils.OperationalError: ERROR:  no more connections allowed (max_client_conn) 

PGBouncer侧报错

1 WARNING C-0x55d76aeb6330: (nodb)/(nouser)@xx.xx.xx.xx:37002 pooler error: no more connections allowed (max_client_conn)

当前配置

PostgreSQL配置

容器启动参数设置max_connections=400,实际验证值一致:

containers:
  - name: acapela-cloud-database
    image: postgres:12.0
    imagePullPolicy: Always
    ports:
      - containerPort: 5432 

    args:
      - postgres
      - -c
      - max_connections=400

执行SQL验证结果:

SHOW max_connections;
 max_connections
-----------------
 400
(1 row)

PGBouncer配置(Kubernetes Deployment + Service)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pgbouncer
  labels:
    app: pgbouncer
spec:
  selector:
    matchLabels:
      app: pgbouncer
  template:
    metadata:
      labels:
        app: pgbouncer
    spec:
      containers:
        - name: pgbouncer
          image: edoburu/pgbouncer:1.9.0
          imagePullPolicy: Always
          ports:
            - containerPort: 5432

          env:
            - name: DB_HOST
              value: "database"
            - name: DB_PORT
              value: "5432"
            - name: DB_USER
              value: ""
            - name: DB_PASSWORD
              value: ""
            - name: DB_DATABASE
              value: ""
            - name: PGBOUNCER_LISTEN_PORT
              value: "6432"
            - name: PGBOUNCER_MAX_CLIENT_CONN
              value: "800"
            - name: PGBOUNCER_DEFAULT_POOL_SIZE
              value: "400"            
            - name: POOL_MODE
              value: transaction
            - name: SERVER_RESET_QUERY
              value: DISCARD ALL
          livenessProbe:
            tcpSocket:
              port: 5432
            periodSeconds: 60
          lifecycle:
            preStop:
              exec:
                # Allow existing queries clients to complete within 120 seconds
                command: ["/bin/sh", "-c", "killall -INT pgbouncer && sleep 120"]
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: ['all']

---

apiVersion: v1
kind: Service
metadata:
  name: pgbouncer
  labels:
    app: pgbouncer
spec:
  type: ClusterIP
  ports:
    - port: 5432
      targetPort: 5432
      protocol: TCP
      name: pgbouncer
  selector:
    app: pgbouncer

问题解决配置调整

当前报错的核心原因是端口不匹配导致流量转发异常:
PGBouncer通过PGBOUNCER_LISTEN_PORT设置监听6432端口,但Deployment的containerPort和Service的targetPort都配置为5432,导致Kubernetes无法正确将Django的连接请求转发到PGBouncer的实际监听端口,无效连接堆积最终触发max_client_conn上限。

需要调整两处配置:

  1. 修改PGBouncer Deployment的容器端口:将containerPort改为6432,与PGBOUNCER_LISTEN_PORT保持一致
  2. 修改PGBouncer Service的targetPort:同样改为6432,确保流量转发到正确端口

调整后的关键配置片段:

Deployment容器端口部分

ports:
  - containerPort: 6432

Service端口部分

ports:
  - port: 5432
    targetPort: 6432
    protocol: TCP
    name: pgbouncer

同时确认Django的数据库连接配置指向PGBouncer Service的5432端口(Service的port保持5432不变)。

扩容可行性分析

问题修复后,该架构完全支持启动5/10/15甚至更多Django副本,核心依据如下:

  • 连接池机制适配:采用transaction池模式,事务结束后立即回收数据库连接并复用,避免每个Django进程长期占用独立PostgreSQL连接
  • 配置匹配合理:PGBOUNCER_DEFAULT_POOL_SIZE=400与PostgreSQL的max_connections=400完全匹配,确保PGBouncer不会向PostgreSQL发起超出上限的连接请求
  • 客户端连接能力充足:PGBOUNCER_MAX_CLIENT_CONN=800支持最多800个客户端连接,每个Django副本通常仅维护少量持久连接(默认CONN_MAX_AGE配置下每个进程最多1个),800的上限足以支撑数十个副本的连接需求

若后续副本数持续增长,可根据实际连接压力逐步上调PGBOUNCER_MAX_CLIENT_CONN(建议不超过PostgreSQLmax_connections的2-3倍,避免PGBouncer自身资源过载);同时需注意PostgreSQL的max_connections不要盲目调大,每个连接会占用内存,过高会导致数据库性能下降。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 17:22:38