← Microservices: desenhar fronteiras e operar sistemas distribuídos
11 / 12 · 70 MIN

Capacidade ocupada e controlo de admissão

Observa trabalho ainda ativo após expirar a espera e limita a admissão antes de criar novos workers.

Preparar uma experiência controlada

O laboratório novo não usa HTTP nem SQLite. Executa workers próprios num único processo, com dois lugares de admissão e um Event que mantém os jobs batch em curso. A thread principal espera pelo sinal started de cada job antes de observar active=2. Essa sincronização elimina a suposição de que uma pausa arbitrária basta para os jobs arrancarem. O bloqueio de oito segundos é uma proteção do ensaio: se o guião falhar ao libertar o Event, o worker termina com erro. Não representa um SLA de negócio. Executa o ficheiro com um caminho de saída novo e conserva o relatório juntamente com o hash do guião.

A espera terminou, o trabalho não

Com os dois jobs retidos, o guião chama join com uma espera de 0,02 segundos sobre o primeiro worker. Depois verifica três factos em conjunto: a thread continua viva, finished continua por sinalizar e active permanece em dois. O resultado demonstra a fronteira de uma espera local, sem simular um servidor remoto ou um protocolo de cancelamento. No trabalho real, um dashboard pode mostrar pedidos abandonados enquanto a dependência continua ocupada. Antes de repetir ou libertar recursos, identifica quem possui a operação e quem confirma a sua conclusão. Um prazo curto no chamador pode reduzir a espera visível sem aumentar a capacidade efetivamente disponível.

Rejeitar antes de criar trabalho

A admissão tenta adquirir um lugar sem esperar. Quando os dois lugares estão ocupados, submit devolve rejected-before-worker e o objeto não recebe uma thread. O guião verifica esse detalhe para o pedido crítico e para seis novas tentativas manuais. admitted continua em dois; rejected sobe para sete. Não existe fila automática, backoff ou mecanismo de retry neste exemplo. A decisão de rejeitar tem consequências que o consumidor precisa de compreender: uma operação ainda não admitida exige um tratamento diferente de uma operação cujo resultado se perdeu. Em produção, o contrato de resposta, a política de repetição e os limites de entrada precisam de ser acordados e testados separadamente.

Contabilizar a vida do recurso

O worker liberta o lugar no bloco finally, depois da conclusão ou do erro. Um caso injeta ValueError e confirma que outro job consegue entrar a seguir. Outro caso usa apenas um semáforo para mostrar uma falha de contabilização: libertar cedo permite uma segunda aquisição antes de a primeira operação terminar. O contador limitado só deteta a libertação em excesso posterior; não conhece a vida do trabalho. Este caso não arranca um worker adicional nem mede sobrecarga. Serve para rever o local do release no código e perceber por que motivo um contador aparentemente válido não prova que o recurso associado já está livre.

Ler métricas sem esconder rejeições

O relatório separa active, peak, admitted e rejected. São contadores pedagógicos protegidos por lock, não métricas exportadas para um sistema de observabilidade. No primeiro estado há dois jobs ativos, dois admitidos e sete rejeições. Depois da libertação real, um novo job conclui e active regressa a zero. Uma taxa de sucesso calculada apenas sobre trabalho admitido esconderia os consumidores recusados. Num exercício de suporte, apresenta ambos os denominadores e distingue rejeição de admissão, erro durante execução e desistência do chamador. Regista também qual pool foi observado, porque um total agregado pode ocultar um caminho crítico sem capacidade.

Decidir a mitigação no incidente

Numa equipa fictícia de fundos, a produção de relatórios ocupa todos os lugares usados por consultas operacionais. O responsável de incidente deve confirmar a ocupação, reduzir entrada não prioritária segundo uma decisão autorizada e acompanhar a recuperação efetiva. Aumentar o pool pode apenas deslocar a saturação para a base de dados. Repetir cada rejeição seis vezes cria mais tentativas sem terminar os jobs presos, como mostra o guião. Prepara um critério de reversão, uma comunicação sobre funcionalidade degradada e uma verificação do backlog. O laboratório ajuda a explicar a decisão; a capacidade segura e o comportamento de uma plataforma concreta exigem um ensaio representativo.

python3 content/labs/micro-capacity/run.py --output /tmp/dr-capacity-new-run.json
# Use a new output path for each run; existing reports are not overwritten.
NA PRÁTICA

Dois jobs batch ocupam os dois lugares de um pool fictício. Um pedido crítico e seis repetições são rejeitados antes de criar threads.

Armadilhas comuns

Libertar capacidade quando o cliente desiste; confundir timeout com cancelamento; contar apenas pedidos concluídos; criar threads antes da admissão.

Tópicos relacionados: Timeout após commit · Monitorização e observabilidade

Leva esta ideia contigo

O lugar pertence ao trabalho admitido até esse trabalho terminar. A espera do cliente e a vida do worker são observações diferentes.

Criar conta

Referência: threading: bounded semaphores, Event and thread lifecycle · Microservice architecture patterns and scoped platform examples; primary guidance consulted 2026-09-30