Go on One VPS: Production Handbook

Como escrever um serviço em Go que você pode deixar rodando em um servidor só: shutdown, timeouts, memória e systemd, com um serviço de referência funcional por trás de cada listagem.

Comprar na Polar: $39 Compra única · v0.1.0 · download imediato pela Polar

Capa de Go on One VPS: Production Handbook
Saída de uma execução real dos testes, não uma montagem.

Para quem é

Você escreve Go e o seu serviço roda em uma única máquina Linux, sob o systemd. Pode ser uma API com um worker em background e SQLite, um receptor de webhooks ou uma ferramenta interna da qual a empresa inteira depende. Ele funciona. O que você quer saber é o que acontece nos extremos: um deploy com requisições em andamento, um cliente que nunca termina de mandar os headers, um container com pouca memória, um crash às 3 da manhã.

Este não é um tutorial de Go. Ele parte do princípio de que você já conhece a linguagem e já colocou algo em produção. Se você procura uma introdução a goroutines, os livros de Go mais conhecidos são um ponto de partida melhor.

O que tem dentro

Um livro de 16 capítulos, com cerca de 2,000 linhas, e um pequeno serviço de referência de onde sai cada listagem de Go do livro. Um script confere se cada um dos 60 blocos de código bate com o código-fonte testado, então nada no texto é um trecho que ninguém executou.

#Capítulo
1Estrutura de projeto para um serviço pequeno
2Configuração pelo ambiente: valide tudo e falhe cedo
3Logging estruturado com log/slog, sem vazar segredos
4Timeouts do servidor HTTP
5Graceful shutdown
6Health e readiness: qual é a diferença
7Context, cancelamento e checagem de goroutine leak
8Acesso a banco com SQLite: WAL, um único escritor, migrations
9Erros e panics
10Métricas e pprof, com segurança
11Testes
12Build: binários estáticos e reproduzíveis
13systemd: unit, hardening, restart, stop
14Memória: o que um processo Go faz sob pressão
15Deploy com pastas de release
16Bugs comuns em produção, cada um com uma checagem que o pega

Você também recebe o serviço de referência (biblioteca padrão mais um driver de SQLite), um gerador de carga, um pequeno experimento de memória, a unit do systemd e um Dockerfile, três checklists e um harness em Docker que refaz todas as checagens a partir de um container limpo. A saída da nossa última execução completa vai junto, para você comparar.

O que os testes mostram

Os capítulos de shutdown e de systemd têm por trás testes que sobem o binário de verdade e mandam sinais de verdade.

O que fizemosO que aconteceu
SIGTERM com um job de 1.5 s em andamentoNovas conexões foram recusadas após 11 ms, a requisição em andamento terminou em 1.399 s e o processo saiu com código 0 após 1.669 s
SIGTERM em um serviço ociosoSaída em 2 ms
SIGTERM com um job de 9 s e limite de shutdown de 500 msSaída após 515 ms com código 1, job devolvido para a fila
Cliente que manda os headers devagar, header timeout de 300 msConexão cortada após 295 ms
systemctl stop com uma requisição de 3 s em andamentoA requisição retornou 200 e o stop levou 3.19 s
kill -9 sob o systemdDe volta ao normal 2.10 s depois
Dois builds a partir de diretórios diferentesBinários idênticos byte a byte (e diferentes quando o -trimpath é omitido, como controle)

A unit do systemd vem com opções de hardening, e lemos o resultado no processo em execução em vez de confiar no arquivo: nenhuma capability, um filtro seccomp, /usr e /etc somente leitura, um limite de memória. O systemd-analyze security deu à unit uma nota de exposição de 1.4.

Throughput e memória

Ambiente: Docker Desktop em um notebook Apple Silicon, 8 CPUs, com o serviço, o gerador de carga e o banco em um único container, 16 clientes, três execuções de 8 segundos por modo.

ModoRequisições por segundo (3 execuções)
Escritas9,190 a 11,189 (p99 8.4 a 11.7 ms)
Leituras13,541 a 18,421
Endpoint de health23,032 a 26,757

A memória residente foi de 13 MiB em repouso e 23 MiB depois da carga, com pico de 25 MiB.

GOMEMLIMIT, medido

O capítulo 14 não manda você definir o GOMEMLIMIT e seguir em frente. Ele roda um programa pequeno, com 40 MiB de heap ativa, dentro de um container limitado a 80 MiB. Sem limite, o processo foi morto por OOM em 3 de 3 execuções. Com GOMEMLIMIT=56MiB, sobreviveu em 3 de 3, ao custo de umas quatro vezes mais coletas de lixo. O livro também explica por que o limite é soft e o que isso significa para o dimensionamento.

Requisitos e formato

Go 1.24 ou mais recente. Docker só se você quiser refazer o harness. Tudo é Markdown, código Go, shell e arquivos de configuração: sem trava de PDF, sem conta, e dá para ler em qualquer lugar.

Perguntas frequentes

É um livro para iniciantes?

Não. Ele pressupõe que você já escreve Go. O assunto é o lado de produção: o que o processo faz quando algo dá errado.

Cobre Postgres?

O serviço de referência e os testes usam SQLite. O capítulo de banco de dados também traz orientações para Postgres.

Qual a diferença para o Go Webhook Receiver Starter?

O starter é um produto pequeno que você coloca para rodar. O handbook traz o raciocínio e os testes por trás de um serviço Go bem-comportado, usando um serviço de referência diferente.

Posso usar o código nos meus projetos?

Pode, nos seus projetos e nos servidores seus ou da empresa onde você trabalha. Não revenda nem redistribua o livro ou o kit.

Changelog

  • 0.1.0: primeira release.

Ler mais

Quero este

Comprar na Polar: $39

Pagamento, impostos e notas fiscais ficam com a Polar, que atua como merchant of record. Você recebe o link de download assim que concluir a compra.