Limitação de taxa

Veja nesta página como usar a infraestrutura de serviços para implementar a limitação de taxa para serviços gerenciados integrados à Service Management API.

Um serviço gerenciado pode atender a muitos consumidores de serviços. Para proteger a capacidade do sistema e garantir o uso justo, um serviço gerenciado geralmente usa limitação de taxa para distribuir a capacidade entre os consumidores de serviços. Com as APIs Service Management e Service Control, é possível gerenciar e aplicar a limitação de taxa.

Como configurar limites de taxa

Para usar o recurso de limitação de taxa, configure _quota metrics_ e _quota limits_ na configuração de serviço no projeto produtor de serviço.

Atualmente, o limite de taxa suportado é o número de solicitações por minuto por consumidor de serviço, em que o consumidor de serviço é um projeto do Google Cloud identificado por uma chave de API, um ID de projeto ou um número de projeto. Para a limitação de taxa, o conceito de solicitação não é transparente. Um serviço pode escolher uma solicitação HTTP como uma solicitação ou um byte de carga útil como uma solicitação. O recurso de limitação de taxa é independente da semântica de uma solicitação.

Métricas de cota

Uma métrica é um contador escolhido para medir um determinado valor ao longo do tempo. Por exemplo, o número de solicitações HTTP que um serviço recebe é uma métrica. Uma métrica de cota é usada para fins de limitação de cota e taxa. Quando ocorre uma atividade com um serviço, uma ou mais métricas de cota podem aumentar. Quando o valor da métrica atinge o limite de cota predefinido, o serviço deve rejeitar a atividade com um erro 429.

Limites de cota

Um limite de cota representa um limite aplicável em uma métrica de cota. Por exemplo, o número de solicitações por consumidor do serviço por minuto é um limite de cota. No momento, o único tipo de limite de cota suportado é por minuto por consumidor, especificamente 1/min/{project}.

O limite de taxa real de um par (serviço, consumidor) é controlado por três configurações:

  • limite padrão especificado para o serviço gerenciado
  • modificação do produtor do serviço para o consumidor do serviço
  • modificação do consumidor do serviço para o consumidor do serviço

O limite de taxa efetivo é o seguinte:

  • O limite padrão, se não houver modificação.
  • A modificação do produtor do serviço, se houver uma modificação do produtor, mas nenhuma modificação do consumidor do serviço.
  • O mínimo (modificação do consumidor do serviço, limite padrão), se houver uma modificação do consumidor, mas nenhuma modificação do produtor do serviço.
  • O mínimo (modificação do consumidor e do produtor do serviço), se houver modificações de produtor e consumidor do serviço.

Como impor limitação de taxa

Para impor a limitação de taxa, cada servidor que pertence a um serviço gerenciado precisa chamar o método services.allocateQuota da API Service Control regularmente. Se a resposta do método services.allocateQuota indicar que o uso está acima do limite, o servidor rejeitará a solicitação recebida com um erro 429. Para mais informações, consulte a documentação de referência do método services.allocateQuota.

Recomenda-se que cada servidor use lote, cache e lógica preditiva para melhorar o desempenho e a confiabilidade do sistema. Em geral, um servidor precisa chamar somente o método services.allocateQuota uma vez por segundo para a mesma tupla (serviço, consumidor, métrica).

O exemplo a seguir demonstra como chamar o método services.allocateQuota para verificar a limitação de taxa. Os parâmetros de solicitação importantes que precisam ser definidos corretamente são nome do serviço, código do consumidor, nome da métrica e valor da métrica. O método services.allocateQuota tentará aumentar o uso na quantidade especificada para a tupla (serviço, consumidor, métrica). Se o uso aumentado for superior ao limite, um erro será retornado. O exemplo a seguir usa o comando gcurl para demonstrar a chamada. Para saber como configurar isso, consulte Primeiros passos com a API Service Control.

gcurl -d '{
  "allocateOperation": {
    "operationId": "123e4567-e89b-12d3-a456-426655440000",
    "methodName": "google.example.hello.v1.HelloService.GetHello",
    "consumerId": "project:endpointsapis-consumer",
    "quotaMetrics": [{
      "metricName": "endpointsapis.appspot.com/requests",
      "metricValues": [{
        "int64Value": 1
      }]
    }],
    "quotaMode": "NORMAL"
  }
}' https://servicecontrol.googleapis.com/v1/services/endpointsapis.appspot.com:allocateQuota
{
  "operationId": "123e4567-e89b-12d3-a456-426655440000",
  "quotaMetrics": [
    {
      "metricName": "serviceruntime.googleapis.com/api/consumer/quota_used_count",
      "metricValues": [
        {
          "labels": {
            "/quota_name": "endpointsapis.appspot.com/requests"
          },
          "int64Value": "1"
        }
      ]
    }
  ],
  "serviceConfigId": "2017-09-10r0"
}

Como lidar com erros

Se o código de resposta HTTP for 200 e a resposta contiver RESOURCE_EXHAUSTED QuotaError, seu servidor rejeitará a solicitação com um erro 429. Se a resposta não tiver nenhum erro de cota, o servidor continuará exibindo as solicitações recebidas. Para todos os outros erros de cota, o servidor deverá rejeitar a solicitação com um erro 409. Devido aos riscos de segurança, você precisa ter muito cuidado com as informações de erro incluídas na mensagem de erro.

Para todos os outros códigos de resposta HTTP, é provável que seu servidor tenha algum bug de programação. É recomendável que o servidor continue a veicular as solicitações recebidas enquanto você depura o problema. Se o método services.allocateQuota retornar algum erro inesperado, o serviço deverá registrar o erro e aceitar as solicitações de entrada. Você pode depurar o erro mais tarde.

Fail open

O recurso de limitação de taxa serve para proteger o serviço gerenciado contra sobrecarga e distribuir a capacidade do serviço de modo justo entre os consumidores do serviço. Como a maioria dos consumidores do serviço não deve atingir os respectivos limites de taxa durante as operações normais, o serviço gerenciado deverá aceitar todas as solicitações recebidas se o próprio recurso de limitação de taxa não estiver disponível, o que também é chamado de fail open. Isso impede que a disponibilidade do serviço seja afetada pelo sistema de limitação de taxa.

Se você usar o método services.allocateQuota, o serviço deverá ignorar os erros 500, 503 e 504 sem nenhuma nova tentativa. Para evitar uma forte dependência do recurso de limitação de taxa, a API Service Control emitirá regularmente uma quantidade limitada de injeções de erro.