Gestión de Procesos y Recursos
ps, htop, señales, nohup y límites de recursos en Linux: gestiona workers web de Python, procesos Celery y scripts de larga ejecución sin zombies huérfanos ni cierres por falta de memoria (OOM kills).
Receta
pgrep -af "uvicorn|celery|gunicorn"
kill -TERM <pid>
sleep 5
kill -KILL <pid> # solo si todavía está en ejecución
htop -p <pid>Cuándo usar esto:
- Despliegue de uvicorn duplicado en el mismo puerto
- Fuga de memoria del worker necesita reinicio
- Apagado elegante antes de una ventana de mantenimiento
- Diagnosticar un pico de CPU por un bucle descontrolado
Ejemplo Práctico
# Buscar el maestro y los workers de billing-api
pgrep -af gunicorn
# Recarga elegante (si está configurado USR2/HUP) o TERM
sudo kill -TERM "$(pgrep -f 'gunicorn.*billing-api' | head -1)"
sleep 10
sudo ss -tlnp | grep 8000
# Comprobar archivos abiertos por fuga de conexiones
PID=
Lo que esto demuestra:
pgrep -afmuestra la línea de comandos completa para procesos de Python- TERM permite un cierre elegante de FastAPI/Gunicorn
- KILL solo después del tiempo de espera
- Inspección de
/procpara fugas de descriptores de archivo (fd)
Profundización
Cómo Funciona
- Señales - SIGTERM para un apagado educado; SIGKILL inmediato; SIGUSR1/2 específicos de la aplicación.
- Padre/hijo - El maestro de Gunicorn genera workers; matar al maestro para reciclarlos a todos.
- Asesino OOM - Linux mata el proceso con mayor RSS bajo presión de memoria.
- cgroups - Límites de memoria/CPU de contenedores en Docker/K8s.
Hoja de Referencia de Señales
| Señal | Efecto en el servicio Python |
|---|---|
| SIGTERM | Uvicorn/Gunicorn deja de aceptar; vacía las solicitudes |
| SIGINT | Igual que Ctrl+C en desarrollo en primer plano |
| SIGHUP | Recarga la configuración en algunos daemons |
| SIGKILL | Muerte inmediata - sin bloques finally |
Notas de Python
# La aplicación registra un manejador SIGTERM para la limpieza
import signal
def handle_term(signum, frame):
close_db_pool()
signal.signal(signal.SIGTERM, handle_term)Errores Comunes
- SIGKILL primero - Descarta transacciones HTTP y de base de datos en curso. Solución: TERM, esperar, luego KILL.
- Matar PID incorrecto desde pgrep - El patrón es demasiado amplio y coincide con dos aplicaciones. Solución: verificar la línea de comandos en
ps -fp. - nohup en producción - Crea procesos huérfanos al desconectar SSH sin rotación de logs. Solución: unidad systemd.
- Procesos Zombie - El padre no está recolectando a los hijos. Solución: reiniciar el supervisor padre.
- Ignorar
dmesgde OOM - Reinicios misteriosos. Solución:dmesg -T | rg -i oom. ulimitdemasiado bajo - "Demasiados archivos abiertos" bajo carga. Solución:LimitNOFILEen systemd.
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| systemd restart | Servicios de producción | Experimento local rápido |
| Docker stop | Período de gracia del contenedor | VM bare metal |
| Kubernetes delete pod | Rollouts orquestados | Solución de problemas SSH |
| py-spy | Muestreo de Python atascado | Un reinicio simple es suficiente |
Preguntas Frecuentes
¿Cuánto esperar después de SIGTERM?
Coincidir con el tiempo de espera de vaciado del balanceador de carga upstream, a menudo 10-30s para APIs.
¿Múltiples workers de uvicorn?
Un proceso por CPU con --workers N bajo gunicorn; cada uno aparece en pgrep.
¿Apagado en caliente de Celery?
celery control shutdown o TERM worker; permitir que las tareas acks_late finalicen.
¿nice/ionice para trabajos por lotes?
nice -n 10 uv run python batch.py reduce la contención de CPU con la API en la misma VM.
¿Máximo de memoria cgroups v2?
systemd-run -p MemoryMax=2G ... limita un worker descontrolado en un host compartido.
¿Cuándo usar strace?
Último recurso para rendimiento/depuración - sobrecarga enorme; prueba py-spy primero.
¿lsof vs ss?
ss para puertos de escucha; lsof -p para archivos/sockets abiertos por PID.
¿Carga promedio vs CPU?
Alta carga con baja CPU puede ser espera de IO - comprueba iostat.
¿Hijo defunct zombie?
Identifica el padre con ps -o ppid= -p ZPID; reinicia el proceso padre.
¿Memoria libre en Linux?
La columna available en free -h es más importante que la lectura de caché free.
Relacionado
- Fundamentos de Sysadmin - systemd
- SSH y Trabajo Remoto - matar remotamente
- Despliegue de FastAPI - diseño de gunicorn
- Fundamentos de Rendimiento - profiling
Versiones de Stack: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.