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)