Otimizar um app Go
Neste guia de início rápido, você implanta um aplicativo Go intencionalmente ineficiente configurado para coletar dados de perfis. Você usa a interface do Profiler para visualizar os dados do perfil e identificar possíveis otimizações. Em seguida, você modifica o aplicativo, o implanta e avalia o efeito da modificação.
Antes de começar
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Enable the required API.
- Para abrir o Cloud Shell, na barra de ferramentas do Console do Google Cloud, clique
em Ativar o Cloud Shell:
Após alguns instantes, uma sessão do Cloud Shell é aberta no Console do Google Cloud:
Exemplo de aplicativo
O objetivo principal é maximizar o número de consultas por segundo que o servidor pode processar. O objetivo secundário é reduzir o uso da memória ao eliminar alocações de memória desnecessárias.
O servidor, usando um framework gRPC, recebe uma palavra ou frase e retorna o número de vezes que a palavra ou frase aparece nas obras de Shakespeare.
O número médio de consultas por segundo que o servidor pode processar é determinado pelo teste de carga do servidor. Para cada rodada de testes, um simulador de cliente é chamado e instruído a emitir 20 consultas sequenciais. Na conclusão de uma rodada, são exibidos o número de consultas enviadas pelo simulador de cliente, o tempo decorrido e o número médio de consultas por segundo.
O código do servidor é intencionalmente ineficiente.
Como executar o aplicativo de amostra
Faça o download e execute o aplicativo de amostra:
No Cloud Shell, execute os seguintes comandos:
git clone https://github.com/GoogleCloudPlatform/golang-samples.git cd golang-samples/profiler/shakesapp
Execute o aplicativo com a versão definida como
1
e o número de rodadas definido como 15:go run . -version 1 -num_rounds 15
Depois de um ou dois minutos, os dados do perfil são exibidos. Os dados do perfil são semelhantes ao exemplo a seguir:
Na captura de tela, observe que o Tipo de perfil está definido como
CPU time
. Isso indica que os dados de uso da CPU são exibidos no gráfico em degradê.O resultado da amostra exibido no Cloud Shell é mostrado abaixo:
$ go run . -version 1 -num_rounds 15 2020/08/27 17:27:34 Simulating client requests, round 1 2020/08/27 17:27:34 Stackdriver Profiler Go Agent version: 20200618 2020/08/27 17:27:34 profiler has started 2020/08/27 17:27:34 creating a new profile via profiler service 2020/08/27 17:27:51 Simulated 20 requests in 17.3s, rate of 1.156069 reqs / sec 2020/08/27 17:27:51 Simulating client requests, round 2 2020/08/27 17:28:10 Simulated 20 requests in 19.02s, rate of 1.051525 reqs / sec 2020/08/27 17:28:10 Simulating client requests, round 3 2020/08/27 17:28:29 Simulated 20 requests in 18.71s, rate of 1.068947 reqs / sec ... 2020/08/27 17:44:32 Simulating client requests, round 14 2020/08/27 17:46:04 Simulated 20 requests in 1m32.23s, rate of 0.216849 reqs / sec 2020/08/27 17:46:04 Simulating client requests, round 15 2020/08/27 17:47:52 Simulated 20 requests in 1m48.03s, rate of 0.185134 reqs / sec
A resposta do Cloud Shell exibe o tempo decorrido de cada iteração e a taxa média de solicitações. Quando o aplicativo é iniciado, a entrada "Simulou 20 solicitações em 17,3s, taxa de 1,156069 solicitações / s" indica que o servidor está executando cerca de uma solicitação por segundo. Na última rodada, a entrada "Simulou 20 solicitações em 1m48.03s, taxa de 0,185134 solicitações / s" indica que o servidor está executando cerca de uma solicitação a cada cinco segundos.
Como usar perfis de tempo de CPU para maximizar consultas por segundo
Uma abordagem para maximizar o número de consultas por segundo é identificar métodos com uso intensivo da CPU e otimizar suas implementações. Nesta seção, você usa perfis de tempo de CPU para identificar um método que consome muita CPU no servidor.
Como identificar o uso do tempo de CPU
O frame raiz do gráfico em degradê lista o tempo total de CPU usado pelo aplicativo durante o intervalo de coleta de 10 segundos:
Neste exemplo, o serviço usou 2.37 s
. Quando o sistema é executado em um único
núcleo, o uso de tempo de CPU de 2,37 segundos corresponde a 23,7% de utilização desse
núcleo. Saiba mais em
Tipos de criação de perfil disponíveis.
Como modificar o aplicativo
Como avaliar a alteração
Para avaliar a alteração, faça o seguinte:
Execute o aplicativo com a versão definida como
2
:go run . -version 2 -num_rounds 40
Uma seção posterior mostra que, com a otimização, o tempo necessário para executar uma única rodada é muito menor do que o do aplicativo não modificado. Para garantir a execução do aplicativo por um tempo suficiente para coletar e fazer o upload de perfis, o número de rodadas será maior.
Aguarde a conclusão do aplicativo e, em seguida, visualize os dados do perfil para essa versão do aplicativo:
- Clique em AGORA para carregar os dados mais recentes do perfil. Saiba mais em Intervalo de tempo.
- No menu Versão, selecione 2.
Por exemplo, o gráfico de chama é:
Nessa figura, o frame principal mostra um valor de 7.8 s
. Como resultado da
alteração da função de correspondência de strings, o tempo de CPU usado pelo aplicativo
aumentou de 2,37 segundos para 7,8 segundos, ou, o aplicativo passou do uso
de 23,7% para 78% de um núcleo da CPU.
A largura do frame é uma medida proporcional do uso do tempo de CPU. Neste
exemplo, a largura do frame para GetMatchCount
indica que a função
usa cerca de 49% de todo o tempo de CPU usado pelo aplicativo.
No gráfico de chama original,
esse mesmo frame tinha cerca de 72% da largura do gráfico.
Para ver o uso exato de tempo de CPU, use a dica do frame ou
a lista de funções de foco:
A saída no Cloud Shell mostra que a versão modificada está concluindo cerca de 5,8 solicitações por segundo:
$ go run . -version 2 -num_rounds 40 2020/08/27 18:21:40 Simulating client requests, round 1 2020/08/27 18:21:40 Stackdriver Profiler Go Agent version: 20200618 2020/08/27 18:21:40 profiler has started 2020/08/27 18:21:40 creating a new profile via profiler service 2020/08/27 18:21:44 Simulated 20 requests in 3.67s, rate of 5.449591 reqs / sec 2020/08/27 18:21:44 Simulating client requests, round 2 2020/08/27 18:21:47 Simulated 20 requests in 3.72s, rate of 5.376344 reqs / sec 2020/08/27 18:21:47 Simulating client requests, round 3 2020/08/27 18:21:51 Simulated 20 requests in 3.58s, rate of 5.586592 reqs / sec ... 2020/08/27 18:23:51 Simulating client requests, round 39 2020/08/27 18:23:54 Simulated 20 requests in 3.46s, rate of 5.780347 reqs / sec 2020/08/27 18:23:54 Simulating client requests, round 40 2020/08/27 18:23:58 Simulated 20 requests in 3.4s, rate of 5.882353 reqs / sec
A pequena alteração no aplicativo teve dois efeitos diferentes:
O número de solicitações por segundo aumentou de menos de 1 por segundo para 5,8 por segundo.
O tempo de CPU por solicitação, calculado pela divisão do uso da CPU pelo número de solicitações por segundo, foi reduzido de 13,4% para 23,7%.
Observe que o tempo de CPU por solicitação diminuiu, embora seu uso tenha aumentado por 2,37 segundos, que corresponde a 23,7% de utilização de um único núcleo de CPU, para 7,8 segundos, 78% de um núcleo de CPU.
Como usar perfis de heap alocada para melhorar o uso de recursos
Esta seção ilustra como você pode usar o heap e os perfis de heap alocados para identificar um método de uso intensivo de alocação no aplicativo:
Os perfis de pilha mostram a quantidade de memória alocada no heap do programa no momento em que o perfil é coletado.
Os perfis de heap alocados mostram a quantidade total de memória que foi alocada no heap do programa durante o intervalo em que o perfil foi coletado. Ao dividir esses valores por 10 segundos, o intervalo de coleta de perfis, é possível interpretá-los como taxas de alocação.
Como ativar a coleta de perfis de heap
Execute o aplicativo com a versão do aplicativo definida como
3
e ative a coleção de perfis de heap e de heap alocados.go run . -version 3 -num_rounds 40 -heap -heap_alloc
Aguarde a conclusão do aplicativo e, em seguida, visualize os dados do perfil para essa versão do aplicativo:
- Clique em AGORA para carregar os dados mais recentes do perfil.
- No menu Versão, selecione 3.
- No menu Tipo de criador de perfil, selecione Heap alocada.
Por exemplo, o gráfico de chama é:
Como identificar a taxa de alocação de heap
O frame raiz exibe a quantidade total de heap que foi alocada durante os 10 segundos em que um perfil foi coletado, na média de todos os perfis. Nesse exemplo, o frame raiz mostra que, em média, 1,535 GiB de memória foi alocado.
Como modificar o aplicativo
Como avaliar a alteração
Para avaliar a alteração, faça o seguinte:
Execute o aplicativo com a versão definida como
4
:go run . -version 4 -num_rounds 60 -heap -heap_alloc
Aguarde a conclusão do aplicativo e, em seguida, visualize os dados do perfil para essa versão do aplicativo:
- Clique em AGORA para carregar os dados mais recentes do perfil.
- No menu Versão, selecione 4.
- No menu Tipo de criador de perfil, selecione Heap alocada.
Para quantificar o efeito da alteração de
readFiles
na taxa de alocação de heap, compare os perfis de heap alocados da versão 4 com os coletados para 3:A dica do frame raiz mostra que, com a versão 4, a quantidade média de memória alocada durante a coleta do perfil diminuiu em 1,301 GiB em comparação com a versão 3. A dica de
readFiles.func1
mostra uma diminuição de 1,045 GiB:Para quantificar o efeito na coleta de lixo, configure uma comparação de perfis de tempo de CPU. Na captura de tela a seguir, um filtro é aplicado para mostrar as pilhas do coletor de lixo do Go
runtime.gcBgMarkWorker.*
. A captura de tela mostra que o uso da CPU para coleta de lixo é reduzido para 4,97% de 16,8%.Para determinar se há um impacto da alteração no número de solicitações por segundo manipuladas pelo aplicativo, veja a saída no Cloud Shell. Neste exemplo, a versão 4 conclui até 15 solicitações por segundo, significativamente mais que as 5,8 solicitações por segundo da versão 3:
$ go run . -version 4 -num_rounds 60 -heap -heap_alloc 2020/08/27 21:51:42 Simulating client requests, round 1 2020/08/27 21:51:42 Stackdriver Profiler Go Agent version: 20200618 2020/08/27 21:51:42 profiler has started 2020/08/27 21:51:42 creating a new profile via profiler service 2020/08/27 21:51:44 Simulated 20 requests in 1.47s, rate of 13.605442 reqs / sec 2020/08/27 21:51:44 Simulating client requests, round 2 2020/08/27 21:51:45 Simulated 20 requests in 1.3s, rate of 15.384615 reqs / sec 2020/08/27 21:51:45 Simulating client requests, round 3 2020/08/27 21:51:46 Simulated 20 requests in 1.31s, rate of 15.267176 reqs / sec ...
O aumento nas consultas por segundo exibido pelo aplicativo pode ocorrer devido à redução do tempo na coleta de lixo.
Você pode entender melhor o efeito da modificação para
readFiles
visualizando os perfis de heap. Uma comparação dos perfis da heap para a versão 4 com a versão 3 mostra que o uso de heap diminuiu para 18,47 MiB de 70,95 MiB:
Resumo
Neste guia de início rápido, os tempos de CPU e de heap alocados foram usados para identificar possíveis otimizações para um aplicativo. Os objetivos eram: maximizar o número de solicitações por segundo e eliminar alocações desnecessárias.
Ao usar perfis de tempo de CPU, uma função de uso intensivo da CPU foi identificada. Depois de aplicar uma alteração simples, a taxa de solicitação do servidor aumentou para 5,8 por segundo, de aproximadamente 1 por segundo.
Ao usar perfis de heap alocados, a função
shakesapp/server.go
readFiles
foi identificada como tendo uma alta taxa de alocação. Depois de otimizarreadFiles
, a taxa de solicitação do servidor aumentou para 15 solicitações por segundo e a quantidade média de memória alocada durante a coleta de 10 segundos de perfil diminuiu 1,301 GiB.
A seguir
Saiba mais sobre como os perfis são coletados e enviados para seu projeto do Google Cloud em Coleta de perfis.
Leia nossos recursos sobre DevOps e conheça nosso programa de pesquisa.
- Como criar perfis de aplicativos Go
- Como criar perfis de aplicativos Java
- Como criar perfis de aplicativos Node.js
- Como criar perfis de aplicativos Python
- Como criar perfis de aplicativos em execução fora do Google Cloud