No meu último post escrevi sobre o problema de Threadpool Starvation e o uso de dotnet-counters
para obter as métricas de performance de uma aplicação dotnet. Neste artigo, será usado o dotnet-monitor
como ferramenta para obter diversas informações de diagnóstico de aplicações dotnet. O foco será em métricas de performance da aplicação e para facilitar a visualização será utilizado o conjunto prometheus e grafana.
Para o artigo foi criado um laboratório usando docker compose e o código pode ser encontrado no github.
dotnet-monitor
dotnet-monitor é uma ferramenta de monitoramento em ambiente produtivo capaz de coletar artefatos como dumps, traces, logs e métricas. A ferramenta expõe uma API que disponibiliza extração de informações de diagnóstico sob demanda.
O runtime do dotnet expõe um endpoint de serviço para comunicação entre processos chamado de porta de diagnóstico. A tecnologia usada depende da plataforma. No Linux são utilizados sockets de domínio Unix como transporte. É dessa maneira que o dotnet-monitor
se comunica com as aplicações dotnet. No laboratório, a aplicação e o monitor são executados em diferentes containers e dessa forma é preciso que o monitor compartilhe um volume com a aplicação.
# docker-compose.yml
app:
...
environment:
DOTNET_DiagnosticPorts: /app/diag/dotnet-monitor.sock
volumes:
- "./:/app/"
monitor:
image: mcr.microsoft.com/dotnet/monitor:6
environment:
DOTNETMONITOR_Storage__DefaultSharedPath: /diag
DOTNETMONITOR_DiagnosticPort__ConnectionMode: listen
DOTNETMONITOR_DiagnosticPort__EndpointName: /diag/dotnet-monitor.sock
volumes:
- "./diag:/diag"
...
É possível executar a aplicação e o monitor com o comando:
docker compose up app
O endpoint de metrics exporta os valores no formato compatível do Prometheus e pode ser acessado no endereço http://localhost:52325/metrics.
Prometheus
Prometheus é uma ferramenta de monitoramento open source capaz de coletar e armazenar métricas como series de dados temporais.
Para o laboratório é usada a seguinte configuração:
# prometheus/prometheus.yml
scrape_configs:
...
- job_name: "monitor"
scrape_interval: 5s
metrics_path: "/metrics"
static_configs:
- targets: ["monitor:52323"]
Dessa forma, ao inicializar o container usando o docker compose o prometheus irá se conectar ao dotnet-monitor para coleta das métricas.
É possível navegar e visualizar as métricas na interface do Prometheus mas vamos usá-lo como fonte de dados para uma outra ferramenta focada em visualização.
Grafana
Grafana é uma ferramenta open source de visualização e monitoramento que permite a criação de dashboards. É possível usar várias tecnologias como fonte de dados, incluindo Prometheus.
Outro ponto interessante do grafana é a disponibilização de inúmeros dashboards pela comunidade que podem ser usados como base para monitoramento de sistemas e aplicações. Para o laboratório vamos usar o dotnet-monitor dashboard.
A configuração do grafana para o laboratório poderia ser feita manualmente via GUI mas para facilitar a reprodução usaremos arquivos de provisionamento para automatizar o setup.
A configuração do Prometheus como fonte de dados é feita pelo arquivo:
# grafana/provisioning/datasources/default.yaml
datasources:
- name: Prometheus
type: prometheus
access: proxy
# Access mode - proxy (server in the UI) or direct (browser in the UI).
url: http://prometheus:9090
jsonData:
httpMethod: POST
manageAlerts: true
prometheusType: Prometheus
prometheusVersion: 2.44.0
cacheLevel: "High"
disableRecordingRules: false
incrementalQueryOverlapWindow: 10m
E a configuração para permitir o provisionamento de dashboards é feita no arquivo:
# grafana/provisioning/dashboards/default.yaml
providers:
- name: "default"
folder: ""
type: file
options:
path: /var/lib/grafana/dashboards
Cada dashboard deve ter sua definição em JSON disponibilizado no caminho definido no arquivo anterior.
O arquivo docker-compose mapeia os volumes para os diretórios padrão de configurações esperada pelo grafana.
# docker-compose.yml
grafana:
image: grafana/grafana-oss
ports:
- "3000:3000"
volumes:
# https://grafana.com/docs/grafana/latest/administration/provisioning/
- "./grafana/provisioning/:/etc/grafana/provisioning/"
- "./grafana/dashboards/:/var/lib/grafana/dashboards/"
O próximo comando executa o grafana e o prometheus:
docker compose up grafana
O grafana pode ser acessado no endereço http://localhost:3000 (use admin/admin para login).
Testes de carga
Por último, podemos executar os testes de carga usando hey.
O comando docker compose up send-load-async
dispara uma série de requisições em um endpoint que utiliza o async/await do dotnet para reaproveitamento das threads e otimização de aplicações IO bound. Os gráficos abaixo mostram a quantidade se requisições processadas durante a execução do teste bem como as métricas relacionadas ao uso de threads pela aplicação.
Por sua vez, o comando docker compose up send-load-sync
realiza requisições em um endpoint que utiliza não utiliza o async/await e portanto realiza o bloqueio de threads em operações de IO. Os gráficos abaixo mostram o resultado do teste.
Conclusão
Os testes realizados mostram o potencial do dotnet-monitor para monitoramento de aplicações em ambientes produtivos. Os testes foram feitos usando o docker compose e a configuração para execução em kubernetes é similar, sendo que o monitor seria publicado como um sidecar da aplicação.
Tão importante quanto a extração das métricas é a possibilidade de visualizar e correlacionar esses dados para permitir o diagnóstico de problemas de performance. O par prometheus e grafana foram usados para esse meio por serem ferramentas conhecidas do mercado e facilitarem a reprodução em ambiente local para um laboratório.
Top comments (0)