"O sistema está lento".
Que sysadmin/devops/SRE (ou seja lá qual o branding moderno para o responsável pela infra) não odeia essa declaração, porque ela não te diz absolutamente nada.
A aplicação está lenta? Ou é o servidor de aplicação? Ou o balanceador? Ou o storage?
E se a aplicação for distribuída, o problema fica 100 vezes maior.
A maneira moderna de fazer diagnóstico deste tipo de problema é usar Application Performance Monitoring, ou monitoramento de performance de aplicações, geralmente caríssimas, para entregar a resposta que você quer.
Mas o assunto não é este hoje; a ideia é tentar usar o cURL para identificar certos problemas de maneira mais ágil.
curl custom output
Você certamente está acostumado a usar cURL para testar conectividade com um site:
# Qual a versão do kubectl mais nova?
$ curl -L -s https://dl.k8s.io/release/stable.txt
v1.29.0
Ou ainda baixar um programa:
# Vamos baixar o kubectl!
$
$ curl -LO "https://dl.k8s.io/release/$LATEST/bin/linux/amd64/kubectl"
...
$ ls -l kubectl
-rw-r--r-- 1 marcelo marcelo 49704960 Dec 19 20:30 kubectl
Mas é possível customizar a saída com diversas coisas. A que mais uso é, de longe, a resposta HTTP:
$ curl www.google.com -so /dev/null -w '%{http_code}\n'
200
Uma maneira extremamente ineficiente de testar se uma aplicação está com problemas é disparar uma rajada de curl sobre ela e analisar a saída:
$ for i in {1..100} ; do
curl -so /dev/null 127.0.0.1 -w '%{http_code}\n' ;
done | sort | uniq -c
83 200
3 500
5 503
9 504
Como eu falei, é uma maneira extremamente ineficiente - você se daria melhor executando testes com uma ferramenta de verdade. Mas quando você está on-call com notebook e te acionam...
Este link tem as variáveis que podem ser usadas juntamente com o programa --write-out.
Variáveis de writeout para exibir tempos
Suponha que você queira saber quanto tempo um download demora, muita gente gosta de usar o comando time:
$ LATEST="$( curl -L -s https://dl.k8s.io/release/stable.txt )"
$ time curl -sLO "https://dl.k8s.io/release/$LATEST/bin/linux/amd64/kubectl"
real 0m0.523s
user 0m0.132s
sys 0m0.141s
Mas a melhor maneira é pedir para o próprio cURL trazer esta métrica!
$ LATEST="$( curl -L -s https://dl.k8s.io/release/stable.txt )"
$ curl -sLO -w '%{time_total}\n' \
"https://dl.k8s.io/release/$LATEST/bin/linux/amd64/kubectl"
0.441882
A parte interessante é que existem muitas variáveis diferentes de tempo para usar, o que pode ser um excelente recurso na depuração de certos problemas!
Este blog teve a ideia legal de criar um arquivo com o seguinte formato:
$ cat > curl-format.txt << EOF
time_namelookup: %{time_namelookup}\n
time_connect: %{time_connect}\n
time_appconnect: %{time_appconnect}\n
time_pretransfer: %{time_pretransfer}\n
time_redirect: %{time_redirect}\n
time_starttransfer: %{time_starttransfer}\n
———\n
time_total: %{time_total}\n
EOF
E agora podemos passar este arquivo para o cURL:
$ curl -w "@curl-format.txt" -o /dev/null -s http://devsres.com
time_namelookup: 0.000964
time_connect: 0.002114
time_appconnect: 0.000000
time_pretransfer: 0.002148
time_redirect: 0.000000
time_starttransfer: 0.010617
———
time_total: 0.010684
Genial, não é?
Bem, para achar genial, você precisa saber para que serve cada etapa e como usá-las em diagnóstico.
Vou usar o primeiro, time_namelookup apenas como exemplo!
time_namelookup
O poder de diagnóstico desta diretiva não pode ser mensurado!
Problemas de DNS tendem a ser de difícil diagnóstico para pessoas sem background de redes. Mas observe o seguinte teste em uma máquina que está "consistentemente lenta":
$ curl -w "@curl-format.txt" -o /dev/null -s http://devsres.com
time_namelookup: 5.139453
time_connect: 5.156280
time_appconnect: 0.000000
time_pretransfer: 5.156360
time_redirect: 0.000000
time_starttransfer: 5.172965
———
time_total: 5.173074
Apenas para referência, estes são os tempos esperados em um dia normal:
$ curl -w "@curl-format.txt" -o /dev/null -s http://devsres.com
time_namelookup: 0.046703
time_connect: 0.047609
time_appconnect: 0.000000
time_pretransfer: 0.047647
time_redirect: 0.000000
time_starttransfer: 0.050434
———
time_total: 0.050491
Sabe porque o primeiro teste levou mais de 5 segundos? Porque esse é o tempo padrão que o linux resolver espera para testar a resolução usando o seu servidor secundário!
(man resolv.conf)
timeout:nSets the amount of time the resolver will wait for a response from a remote name server before retrying the query via a different name server. This may not be the total time taken by any resolver API call and there is no guarantee that a single resolver API call maps to a single timeout. Measured in seconds, the default is RES_TIMEOUT (currently 5, see ). The value for this option is silently capped to 30.
Configurar múltiplos servidores DNS no seu /etc/resolv.conf é útil para garantir resiliência, mas o ambiente ficará severamente degradado caso o primeiro servidor falhe se precisar resolver nomes para seu funcionamento!
É possível reduzir esse tempo de timeout com a seguinte diretiva em seu resolv.conf:
$ cat /etc/resolv.conf
options timeout:1
nameserver 192.168.0.53
nameserver 1.1.1.1
nameserver 8.8.8.8
A configuração entra em vigor imediatamente:
$ curl -w "@curl-format.txt" -o /dev/null -s http://devsres.com
time_namelookup: 1.115452
time_connect: 1.135235
time_appconnect: 0.000000
time_pretransfer: 1.135265
time_redirect: 0.000000
time_starttransfer: 1.151118
———
time_total: 1.151194
Se não funcionar, talvez seja necessário ajudar esse parâmetro usando network manager.
Neste caso, usamos este parâmetro para permitir identificar que a causa do problema é o não funcionamento do servidor DNS do cliente, e não a aplicação! É um excelente primeiro teste a fazer para identificar se realmente há um problema no seu ambiente, antes de fazer dezenas de verificações e constatar que está tudo ok!
Top comments (0)