Como medir o desempenho de seus sistemas (benchmark)
Tags: desempenho, benchmark, go, portugues
Published: 2021-08-04 18:58:00

## Definição
Benchmark: Medir o desempenho relativo de um objeto, geralmente através de testes diretos e realizado comparações dos resultados periódicamente.

## Porquê
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhv08t63zyz7dhvmmd1r.png)
 
- Escalabilidade: Sua aplicação possui a habilidade de receber e suportar uma grande carga de requisições sem sacrificar a latência das respostas?

- Alta disponibilidade: Temos que manter as coisas funcionando, qual o limite do seu sistema? Quando ele para?

## Ferramentas

| Tool   | Language   | Gateways          | Advantages       |
| ------ | ---------- | ----------------- | ---------------- | 
| vegeta | Go         |  Http             |                  |
| wrk    | C          |  Http             |                  | 
| strest | TypeScript |  gRPC             |                  |
| ghz    | Go         |  gRPC             | stats + in use   | <
| pprof  | --         |  --               | profilling       | <
| k6     | Go         |  Http, gRPC       | scriptable       |
| hey    | Go         |  Http             | stats + ghz like | <

## ghz

- Go
- Não possui suporte a scripts mas pode ser usado como uma lib Go.
- Pode ser rodado: localmente & ambientes de integração continua(CI) e como testes de performance
- Pode enviar mensagens dinamicamente, ou seja, alterando o conteudo dos objetos em cada novo request
- As mensagens podem ser enviadas com JSON ou binário

## Métricas & Definições

Vamos selecionar algumas métricas, que importam para nosso sistema, e criar algumas definições para enendermos e também podermos acompanhar o desempenho com o tempo:

Fase I

- Req/s - O número de requisições que o serviço foi capaz de servir com sucesso
- Latência média - tempo o qual foi gasto entre o envio da requisição e o recebimento da resposta

Fase II

- Req/s
- Latência média e 90/95/99 percentis
- Consumo médio de CPU, memoria - recurso utilizado durante o benchmark provido pelo docker stats
- Profile - profile da aplicação (cpu, mem, threads)

## Como medir o desempenho

As requisições serão disparadas para nosso servidor e teremos inicialmente dois tipos de requisição: 

1 Definir cenários
	1.1 Input
	1.2 Output
2 Configurar app para profile
3 Executar localmente o benchmark


## Cenários

Exemplos:
- Inserção de transações
- Relatório
- Enxurrada de eventos do cliente
	- por algum motivo o cliente estava com eventos represados e foram liberado de uma vez
- Uso por horário de pico

## Profile

Depois do benchmark podemos analisar o profile do app para verificar pontos de otimização.

Tipos:
	- CPU: Determina onde um programa gasta tempo enquanto ativamente consumindo ciclos do processador (não sleeping ou esperando por I/O).
	- Heap: Reporta alocação de memória, usado para monitorar uso de memória atual e checar por memory leaks.
	- Threadcreate: Seções do programa que levaram a novoas threads no SO.
	- goroutine: Stack traces das goroutines.
	- ...

## References
https://k6.io/blog/performance-testing-grpc-services/
https://blog.golang.org/pprof
https://eltonminetto.dev/post/2020-04-08-golang-pprof/
https://k6.io/blog/comparing-best-open-source-load-testing-tools/
https://pkg.go.dev/github.com/bojand/ghz?utm_source=godoc