Para quién es
Escribes Go y tu servicio corre en una sola máquina Linux bajo systemd. Quizá es una API con un worker en segundo plano y SQLite, quizá un receptor de webhooks, quizá una herramienta interna de la que depende toda la empresa. Funciona. Lo que quieres saber es qué pasa en los bordes: un deploy con peticiones en vuelo, un cliente que nunca termina de enviar los headers, un container con muy poca memoria, una caída a las 3 de la madrugada.
Esto no es un tutorial de Go. Da por hecho que conoces el lenguaje y que ya has publicado algo. Si buscas una introducción a las goroutines, los libros de Go más conocidos son mejor punto de partida.
Qué contiene
Un libro de 16 capítulos, de unas 2,000 líneas, y un pequeño servicio de referencia del que sale cada listado de Go del libro. Un script comprueba que cada uno de los 60 bloques de código coincide con el código fuente probado, así que nada del texto es un fragmento que nadie haya ejecutado.
| # | Capítulo |
|---|---|
| 1 | Estructura de un proyecto para un servicio pequeño |
| 2 | Configuración desde el entorno: valida todo y falla pronto |
| 3 | Logging estructurado con log/slog, sin filtrar secretos |
| 4 | Timeouts del servidor HTTP |
| 5 | Graceful shutdown |
| 6 | Health frente a readiness |
| 7 | Context, cancelación y comprobaciones de fugas de goroutines |
| 8 | Acceso a bases de datos con SQLite: WAL, un solo escritor, migraciones |
| 9 | Errores y panics |
| 10 | Métricas y pprof, con seguridad |
| 11 | Testing |
| 12 | Compilación: binarios estáticos y reproducibles |
| 13 | systemd: unidad, hardening, reinicio, parada |
| 14 | Memoria: qué hace un proceso Go bajo presión |
| 15 | Deploy con carpetas de release |
| 16 | Bugs habituales en producción, cada uno con una comprobación que lo detecta |
También recibes el servicio de referencia (biblioteca estándar y un driver de SQLite), un generador de carga, un pequeño experimento de memoria, la unidad de systemd y un Dockerfile, tres checklists y un banco de pruebas en Docker que repite todas las comprobaciones desde un container limpio. Incluimos la salida de nuestra última ejecución completa para que puedas compararla con la tuya.
Qué muestran las pruebas
Los capítulos sobre apagado y systemd se apoyan en tests que arrancan el binario real y le envían señales reales.
| Qué hicimos | Qué pasó |
|---|---|
| SIGTERM con un trabajo de 1.5 s en curso | Las conexiones nuevas se rechazaron a los 11 ms, la petición en curso terminó a los 1.399 s y el proceso salió con código 0 a los 1.669 s |
| SIGTERM a un servicio inactivo | Salida en 2 ms |
| SIGTERM con un trabajo de 9 s y un límite de apagado de 500 ms | Salida a los 515 ms con código 1, el trabajo vuelve a la queue |
| Cliente que envía los headers despacio, con un timeout de headers de 300 ms | Conexión cortada a los 295 ms |
systemctl stop con una petición de 3 s en curso | La petición devolvió 200 y la parada tardó 3.19 s |
kill -9 bajo systemd | De nuevo sano 2.10 s después |
| Dos builds desde directorios distintos | Binarios idénticos byte a byte (y distintos cuando se omite -trimpath, como control) |
La unidad de systemd incluye opciones de hardening, y el resultado lo leemos del proceso en ejecución en lugar de fiarnos del archivo: sin capabilities, con un filtro seccomp, /usr y /etc en solo lectura y un límite de memoria. systemd-analyze security dio a la unidad una puntuación de exposición de 1.4.
Rendimiento y memoria
Configuración: Docker Desktop en un portátil con Apple Silicon, 8 CPU, el servicio, el generador de carga y la base de datos en un mismo container, 16 clientes, tres ejecuciones de 8 segundos por modo.
| Modo | Peticiones por segundo (3 ejecuciones) |
|---|---|
| Escrituras | De 9,190 a 11,189 (p99 de 8.4 a 11.7 ms) |
| Lecturas | De 13,541 a 18,421 |
| Endpoint de health | De 23,032 a 26,757 |
La memoria residente fue de 13 MiB en reposo y de 23 MiB después de la prueba de carga, con un pico de 25 MiB.
GOMEMLIMIT, medido
El capítulo 14 no se limita a decirte que definas GOMEMLIMIT y sigas adelante. Ejecuta un programa pequeño con un heap vivo de 40 MiB dentro de un container limitado a 80 MiB. Sin límite, el OOM killer lo mató en 3 de 3 ejecuciones. Con GOMEMLIMIT=56MiB sobrevivió 3 de 3, a cambio de unas cuatro veces más ciclos de garbage collection. El libro también explica por qué el límite es blando y qué implica eso a la hora de dimensionar.
Requisitos y formato
Go 1.24 o posterior. Docker, solo si quieres repetir el banco de pruebas. Todo es Markdown, código Go, shell y archivos de configuración: sin bloqueo de PDF, sin cuenta, léelo donde quieras.
Preguntas frecuentes
¿Es un libro para principiantes?
No. Da por hecho que ya escribes Go. Trata del lado de producción: qué hace el proceso cuando algo sale mal.
¿Cubre Postgres?
El servicio de referencia y sus tests usan SQLite. El capítulo de bases de datos también da pautas para Postgres.
¿En qué se diferencia del Go Webhook Receiver Starter?
El starter es un producto pequeño que pones a correr. El manual explica el razonamiento y las pruebas detrás de un servicio Go que se porta bien, y usa otro servicio de referencia.
¿Puedo usar el código en mis propios proyectos?
Sí, en tus proyectos y en los servidores tuyos o de tu empresa. Por favor, no revendas ni redistribuyas el libro ni el kit.
Historial de cambios
- 0.1.0: primera versión.
Leer más
- Graceful shutdown for a Go HTTP server under systemd (en inglés)
- GOMEMLIMIT in an 80 MB container, with the numbers (en inglés)
- Go SQLite reads returning 404 for rows that exist (en inglés)
- log/slog setup for a small Go service on journald (en inglés)
- Go HTTP server timeouts that survive slow and stuck clients (en inglés)
Obtener
Polar, como merchant of record, se ocupa del pago, los impuestos y las facturas. Al terminar la compra recibes un enlace de descarga.