2
respostas

PostgreSQL consumindo 100% de CPU

Estou trabalhando num projeto junto com um amigo usando Docker e Ansible para deploy. Todas as vezes que subimos os container's depois de um tempo o PostgreSQL começa a consumir 100% de CPU conforme print a seguir Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Nossos arquivos do docker estão assim configurados:

docker-compose

version: "3.7"

networks:
  xpto_web_network:
    name: xpto_web_network

services:
  xpto_web_database:
    container_name: xpto_web_database
    image: postgres:16.1
    restart: always
    volumes:
      - xpto_web-db:/var/lib/postgresql/data
    environment:
      - LC_ALL=C.UTF-8
      - POSTGRES_DB=xpto_web_db
      - POSTGRES_USER=xpto_web_dbmanager_2LiyBoLHeHo5yG
      - POSTGRES_PASSWORD=...
      - POSTGRES_HOST_AUTH_METHOD=md5
    networks:
      - xpto_web_network
    ports:
      - "5439:5432"

  xpto_web_django:
    container_name: xpto_web_django
    image: xpto_web:1.0
    environment:
      - DB_NAME=xpto_web_db
      - DB_PASSWORD=...
      - DB_USER=xpto_web_dbmanager_2LiyBoLHeHo5yG
      - DB_HOST=xpto_web_database
      - DB_PORT=5432
      - DEBUG=False
      - ...
    build:
      context: .
      dockerfile: ./Dockerfile
    entrypoint: /home/app/xpto_web_django/xpto-web.sh
    networks:
      - xpto_web_network
    volumes:
      - xpto_web-media:/home/app/xpto_web_django/media
      - xpto_web-static:/home/app/xpto_web_django/static
    depends_on:
      - xpto_web_database

  gateway:
    image: nginx:1.19-alpine
    container_name: xpto_web_gateway
    restart: unless-stopped
    networks:
      - xpto_web_network
    expose:
      - 443
      - 82
    ports:
      - "8007:82"
    depends_on:
      - xpto_web_django
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      - xpto_web-media:/home/app/xpto_web_django/media
      - xpto_web-static:/home/app/xpto_web_django/static

volumes:
  xpto_web-db:
  xpto_web-media:
  xpto_web-static:

Dockerfile

FROM python:3.12.1-slim as builder

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV CRYPTOGRAPHY_DONT_BUILD_RUST=1

WORKDIR /app

RUN apt-get clean && apt-get update
RUN apt-get -y install sudo --no-install-recommends build-essential libpq-dev
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
COPY . /app
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels -r requirements.txt

EXPOSE 8000

FROM python:3.12.1-slim

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV CRYPTOGRAPHY_DONT_BUILD_RUST=1

ENV HOME=/home/app
ENV APP_HOME=/home/app/xpto_web_django

RUN mkdir -p $HOME
RUN mkdir $APP_HOME

WORKDIR $APP_HOME

COPY --from=builder /usr/src/app/wheels /wheels
COPY --from=builder /app .

RUN mkdir -p $APP_HOME/static
RUN mkdir -p $APP_HOME/media

RUN pip install -U setuptools pip
RUN pip install --no-cache /wheels/*

COPY ./xpto-web.sh ./xpto-web.sh
RUN chmod +x ./xpto-web.sh

RUN adduser -u 5678 --disabled-password --gecos "" appuser && chown -R appuser $APP_HOME 
USER appuser

nginx.conf

#nginx config file
upstream xptoweb {
  server xpto_web_django:xxxx;
}

server {
    listen xx;
    charset utf-8;
    server_name _;

    # Frontend
    location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect off;
        proxy_pass http://xptoweb/;
    }

    location /static/ {
        alias /home/app/xpto_web_django/static/;
    }

    location /media/ {
        alias /home/app/xpto_web_django/media/;
    }

    location = /favicon.ico
    {
        access_log off; log_not_found off;
    }
}

xpto-web.sh

#!/bin/bash

python manage.py migrate
python manage.py collectstatic --noinput
python mock_superuser.py

gunicorn base.wsgi:application --workers=1 --bind=0.0.0.0:8007
2 respostas

Olá Afrânio!

Parece que o PostgreSQL está consumindo uma quantidade anormal de CPU, o que pode ser causado por várias razões. Podemos testar algumas abordagens para resolver o problema:

  1. Análise de Queries: Verifique se não existem queries mal otimizadas ou que estão consumindo muitos recursos. Você pode utilizar ferramentas como pg_stat_statements para identificar queries que estão consumindo mais tempo ou recursos.

  2. Configurações do PostgreSQL: Revisar as configurações do PostgreSQL pode ajudar a reduzir o uso de CPU. Algumas diretivas importantes para ajustar incluem work_mem, maintenance_work_mem, shared_buffers e max_connections. Você pode começar com valores conservadores e ir ajustando conforme a necessidade.

  3. Limitar recursos no Docker: No seu docker-compose, você pode limitar os recursos que o container do PostgreSQL pode usar. Isso pode ser feito usando as opções cpus e mem_limit no serviço xpto_web_database. Por exemplo:

    xpto_web_database:
      container_name: xpto_web_database
      image: postgres:16.1
      restart: always
      volumes:
        - xpto_web-db:/var/lib/postgresql/data
      environment:
        - LC_ALL=C.UTF-8
        - POSTGRES_DB=xpto_web_db
        - POSTGRES_USER=xpto_web_dbmanager_2LiyBoLHeHo5yG
        - POSTGRES_PASSWORD=...
        - POSTGRES_HOST_AUTH_METHOD=md5
      networks:
        - xpto_web_network
      ports:
        - "5439:5432"
      deploy:
        resources:
          limits:
            cpus: '1.0'
            memory: 500M
    

    Essa configuração limita o PostgreSQL a usar no máximo 1 CPU e 500MB de memória.

  4. Monitoramento e Logs: Monitore os logs do PostgreSQL e do sistema operacional para identificar possíveis problemas ou comportamentos anormais. Verifique também o uso de I/O e se há alguma correlação com os picos de CPU.

  5. Atualizações e Manutenção: Certifique-se de que seu PostgreSQL e suas dependências estão atualizados. Às vezes, bugs conhecidos que causam alto uso de CPU são corrigidos em versões mais recentes.

Implemente essas mudanças uma de cada vez e observe como cada uma afeta o desempenho do PostgreSQL. Isso ajudará a identificar a causa raiz do problema e a encontrar a solução mais eficaz.

Bons estudos!

Olá,

O que eu descobri aqui é que na verdade existe um PostgreSQL que está fora do container, e é ele quem tem comsunido tais recursos. Estou tentando configurar o Ansible para todas as vezes que eu fizer um deploy ele matar o processo. Não consegui identificar em que momento o start do postgreSQL ocorre, já tentei inclusive desinstalar, mas tem algo nos meus códigos que instala.