Práticas recomendadas para o desempenho de microsserviço

O desenvolvimento de software gira em torno de compensações, e os microsserviços não são exceção. O que você ganha na implantação do código e na independência da operação é compensado pelas despesas gerais de desempenho. Nesta seção, são apresentadas algumas recomendações para as etapas que você pode realizar para minimizar esse impacto.

Transformar as operações do CRUD em microsserviços

Os microsserviços são particularmente adequados para entidades que são acessadas com o padrão "criar, recuperar, atualizar, excluir" (CRUD, na sigla em inglês). Ao trabalhar com essas entidades, você normalmente usa apenas uma por vez, como um usuário, e executa apenas uma das ações CRUD da mesma maneira. Portanto, você só precisa de uma única chamada de microsserviço para a operação. Procure entidades que tenham operações CRUD mais um conjunto de métodos comerciais que possam ser utilizados em muitas partes do aplicativo. Essas entidades são bons candidatos para microsserviços.

Oferecer APIs em lote

Além das APIs de estilo CRUD, você ainda pode oferecer um bom desempenho de microsserviço para grupos de entidades por meio do fornecimento de APIs em lote. Por exemplo, em vez de apenas expor um método GET API que recupera um único usuário, forneça uma API que leva um conjunto de códigos de usuário e retorna um dicionário de usuários correspondentes:

Solicitação:

/user-service/v1/?userId=ABC123&userId=DEF456&userId=GHI789

Resposta:

{
  "ABC123": {
    "userId": "ABC123",
    "firstName": "Jake",
    … },
  "DEF456": {
    "userId": "DEF456",
    "firstName": "Sue",
    … },
  "GHI789": {
    "userId": "GHI789",
    "firstName": "Ted",
    … }
}

O SDK do App Engine é compatível com muitas APIs em lote, como a capacidade de buscar muitas entidades do Cloud Datastore por meio de um único RPC, de modo que a manutenção desses tipos de APIs em lote possa ser muito eficiente.

Usar solicitações assíncronas

Muitas vezes, você precisará interagir com muitos microsserviços para compor uma resposta. Por exemplo, talvez seja necessário buscar as preferências do usuário conectado, bem como os detalhes da empresa. Geralmente, essas informações não dependem umas das outras, e é possível buscá-las em paralelo. A biblioteca Urlfetch no SDK do App Engine é compatível com solicitações assíncronas, permitindo que você chame microsserviços em paralelo.

Usar a rota mais curta

Dependendo de como você chama Urlfetch, é possível causar o uso de diferentes infraestruturas e rotas. Para usar a rota de melhor desempenho, considere as seguintes recomendações:

Use *.appspot.com, não um domínio personalizado
Um domínio personalizado faz com que uma rota diferente seja usada ao rotear por meio da infraestrutura do Google. Como suas chamadas de microsserviços são internas, é fácil de fazer e funciona melhor se você usar o nome de host my-app.appspot.com.
Defina follow_redirects como False
Defina explicitamente follow_redirects=False ao chamar Urlfetch, porque isso evita um serviço mais pesado projetado para seguir os redirecionamentos. Os pontos de extremidade da API não precisam redirecionar os clientes, porque são os próprios microsserviços deles, e pontos de extremidade só precisam retornar as respostas HTTP de série 200, 400 e 500.
Prefira serviços dentro de um projeto em vários projetos
Existem bons motivos para usar vários projetos ao criar um aplicativo com base em microsserviços, mas, se o desempenho é o objetivo principal, use serviços dentro de um único projeto. Os serviços de um projeto são hospedados no mesmo data center e, embora a capacidade na rede de data center do Google seja excelente, as chamadas locais são mais rápidas.

Evitar o chatter durante a execução da segurança

Não é bom para o desempenho usar mecanismos de segurança que envolvam muita comunicação desnecessária para autenticar a API de chamada. Por exemplo, se o microsserviço precisar validar um tíquete do aplicativo por meio de outra chamada ao aplicativo, você terá feito muitas chamadas para conseguir os dados.

Uma implementação OAuth2 pode amortizar esse custo ao longo do tempo usando tokens de atualização e armazenando em cache um token de acesso entre chamadas de Urlfetch. No entanto, se o token de acesso em cache for armazenado em memcache, você precisará ter sobrecarga de memcache para buscá-lo. Para evitar essa sobrecarga, é possível armazenar em cache o token de acesso na memória da instância. No entanto, você ainda verá a atividade do OAuth2 com frequência, uma vez que cada nova instância negocia um token de acesso. Lembre-se de que as instâncias do App Engine são adicionadas e encerradas constantemente. Um híbrido de cache de instância e memcache ajudará a reduzir esse problema, mas a solução começa a ficar mais complexa.

Outra abordagem que funciona bem é compartilhar um token secreto entre microsserviços, por exemplo, transmitido como um cabeçalho HTTP personalizado. Nessa abordagem, cada microsserviço pode ter um token exclusivo para cada autor da chamada. Normalmente, os segredos compartilhados são uma opção questionável para implementações de segurança, mas, como todos os microsserviços estão no mesmo aplicativo, torna-se um problema menor por causa dos ganhos de desempenho. Com um segredo compartilhado, o microsserviço só precisa realizar uma comparação de string do segredo recebido em comparação a um dicionário supostamente na memória e que a execução da segurança seja muito leve.

Se todos os microsserviços estão no App Engine, você também pode inspecionar o cabeçalho X-Appengine-Inbound-Appid de entrada. Esse cabeçalho é adicionado pela infraestrutura Urlfetch ao fazer uma solicitação para outro projeto do App Engine e não pode ser configurado por uma parte externa. Dependendo do requisito de segurança, os microsserviços podem inspecionar esse cabeçalho de entrada para impor a política de segurança.

Acompanhar solicitações de microsserviço

À medida que você cria o aplicativo com base em microsserviços, começa a acumular sobrecarga de chamadas sucessivas de Urlfetch. Quando isso acontece, é possível usar o Cloud Trace para entender quais chamadas estão sendo feitas e onde a sobrecarga está. O Cloud Trace também pode ajudar a identificar onde os microsserviços independentes estão sendo chamados em série, possibilitando refatorar o código para executar essas buscas em paralelo.

Um recurso útil do Cloud Trace é iniciado quando são usados vários serviços em um único projeto. À medida que as chamadas são feitas entre os serviços de microsserviço no projeto, o Cloud Trace recolhe todas as chamadas em um único gráfico de chamadas para permitir que você visualize toda a solicitação de ponta a ponta como um único rastreamento.

Google Cloud Trace

Observe que, no exemplo acima, as chamadas para o pref-service e o user-service são realizadas em paralelo usando um Urlfetch assíncrono, de modo que os RPCs apareçam juntos na visualização. No entanto, essa ainda é uma ferramenta valiosa para diagnosticar latência.

Próximas etapas

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Ambiente padrão do App Engine para Java