Criei uma CLI de Benchmark HTTP em Go para estudar Concorrência (httgo)
Fala, pessoal!
Estou estudando Go mais a fundo, especificamente o modelo de concorrência com Goroutines e Channels, e decidi criar uma ferramenta de CLI para colocar a teoria em prática.
O resultado é o httgo, uma ferramenta leve para benchmark HTTP (similar, em menor escala, ao ab ou wrk), onde o foco foi implementar uma arquitetura limpa e concorrente.
💡 A Ideia e Arquitetura
O maior desafio foi orquestrar as requisições sem causar race conditions na hora de calcular as métricas. Para resolver isso, adotei o padrão Producer-Consumer:
- Producers (Senders): Várias goroutines (definidas pela flag
--concurrency) bombardeiam a URL alvo. Elas não calculam nada, apenas enviam a requisição e jogam o resultado cru (tempo, status, erro) em um canal (chan metrics.Metrics). - Consumer: Uma única goroutine lê desse canal. Como ela é única, não preciso de mutexes complexos para agregar os dados ou calcular a latência média.
- Actions: Implementei um sistema de interfaces para "Ações". O consumidor não sabe o que fazer com os dados, ele apenas delega para implementações de
Action. Isso permite adicionar funcionalidades (como log verboso ou exportação para JSON) sem mexer no core do loop.
Um trecho do código (Consumer)
func Consumer(ch chan metrics.Metrics, args *args.Args, actions *[]actions.Action) {
// Hooks "Before"
for _, act := range *actions {
act.Before(args)
}
// Processamento concorrente
for range args.Concurrency {
value := <-ch
for _, act := range *actions {
act.Run(&value, args)
}
}
// Hooks "After" (ex: calcular média)
for _, act := range *actions {
act.After(&results, args)
}
}
🚀 Como usar
O projeto é compilado em um binário único. Um exemplo simples rodando 50 workers simultâneos:
httgo --concurrency 50 https://api.exemplo.com/v1/health
Também adicionei uma flag --verbose que usa a interface de Actions que mencionei para logar o status de cada requisição individualmente.
📂 Estrutura
Tentei seguir o Standard Go Project Layout, organizando o código em cmd/ (entrypoint) e internal/ (lógica de negócio protegida).
Link do Repositório
O código está aberto no GitHub. Quem tiver sugestões de melhoria no código, principalmente sobre boas práticas em Go 1.25+, ficarei feliz em ouvir!
🔗 github.com/rickferrdev/httgo