Blog

Estávamos limitando a taxa dos nossos próprios serviços

A API do Mythex permite 300 requisições por minuto a partir de um endereço de rede. Esse limite existe para nos proteger de uma pessoa ou script martelando a API. Em produção, ele passou a recusar os nossos próprios serviços, a parte da nossa borda que serve os apps publicados e o serviço que roda o agente de IA, porque cada um deles acessa a API a partir de poucos endereços. As requisições que carregam a nossa credencial interna agora estão isentas, e todos os outros continuam limitados exatamente como antes.

O sintoma

A API começou a responder algumas chamadas internas nossas com 429 Too Many Requests. Três tipos de chamada foram atingidos, e cada um importa para quem usa o Mythex:

  • Consultar qual app vive em um domínio personalizado. Quando um visitante abre um app publicado no próprio domínio, a nossa borda pergunta à API onde fica aquele site. Um 429 aí é um visitante que não consegue acessar um site.
  • Salvar um turno do agente em execução. Enquanto o agente trabalha, o progresso é salvo conforme avança, para que uma resposta sobreviva a uma atualização da página ou a uma conexão caída. Um 429 aí é progresso que não foi salvo.
  • Verificar o acesso a uma pré-visualização. A pré-visualização de um app que você está construindo tem uma barreira de acesso, e essa barreira consulta a API. Um 429 aí é uma pré-visualização que não abre.

Nenhuma dessas chamadas era de pessoas usando a API. Todas eram de nós mesmos.

Por que aconteceu

Um limite de taxa por endereço faz uma suposição: um endereço é, aproximadamente, um chamador. Para pessoas, isso é quase verdade. Para a nossa própria infraestrutura, está muito errado.

  • O serviço de borda que serve os apps publicados e as pré-visualizações acessa a API a partir de alguns poucos endereços de saída compartilhados. Cada visitante de cada app publicado, e cada verificação de pré-visualização, chega parecendo ter vindo de um desses poucos.
  • O orquestrador, o serviço que roda os turnos do agente, acessa a API a partir de um único endereço de contêiner. Cada turno em execução, de cada usuário, compartilha esse endereço.

Assim, o orçamento pensado para uma pessoa estava sendo dividido entre todo o tráfego de um serviço inteiro. Esses serviços o consumiram juntos, e o limitador fez o que foi configurado para fazer: recusou.

A correção

Nossos próprios serviços já provam quem são. Cada chamada interna carrega um token interno, e toda rota da seção interna da API verifica esse token antes de fazer qualquer coisa.

O limitador de taxa agora usa a mesma verificação. Uma requisição cujo token corresponde ao interno entra em uma lista de permitidos e não é contada no orçamento por endereço. Todo o resto é contado exatamente como antes: 300 requisições por minuto por endereço.

Dois detalhes impediram que isso virasse um buraco:

  1. Um token errado não recebe passe livre. A lista de permitidos só corresponde ao token interno real. Uma requisição com um token inventado é contada e limitada como qualquer outra, e as rotas internas continuam rejeitando-a com 401 Unauthorized.
  2. O limite em si não mudou. Não aumentamos o número para abrir espaço. Aumentá-lo teria escondido o problema até o tráfego crescer de novo, e enfraqueceria a proteção no caso para o qual o limite existe.

Movemos as configurações do limitador para uma pequena função e escrevemos testes contra ela. Um envia 20 requisições com o token interno a um limitador configurado para permitir 5, e espera que todas as 20 tenham sucesso. Outro envia requisições comuns a partir de um endereço e espera que as cinco primeiras tenham sucesso e as seguintes sejam recusadas. Um terceiro envia requisições com um token forjado e espera que sejam recusadas da mesma forma.

O que tiramos disso

  • Limites carregam suposições. "Um endereço, um chamador" está embutido em um limite por endereço. Isso deixa de ser verdade assim que os seus próprios serviços ficam atrás de endereços compartilhados, e muitos ficam: balanceadores de carga, redes de borda, contêineres, redes de escritório.
  • Distinga o seu próprio tráfego pela identidade, não pelo endereço. Endereços são por onde o tráfego chega, não quem o enviou. Nós já tínhamos uma credencial que prova que a chamada é nossa; o limitador simplesmente não olhava para ela.
  • Não resolva aumentando o número. Um limite maior teria feito os 429 sumirem por um tempo, protegido menos e falhado de novo depois.
  • Observe quem está sendo limitado. Um 429 que cai no seu próprio serviço é um relatório de bug sobre os seus limites, não um sinal de que o limitador está funcionando.

O que isso significa se você constrói no Mythex

Nada para mudar do seu lado. Apps publicados em domínios personalizados, turnos do agente e pré-visualizações não dependem mais de quão ocupado o resto do Mythex está. O tráfego do próprio app é assunto do seu app: o limite descrito aqui está na nossa API, não nos apps que você publica.

Se você mantém um backend próprio, a mesma armadilha vale para qualquer limite de taxa que você adicionar. Nossos guias sobre o que é uma API e a lista de verificação de segurança para apps criados com IA são um bom ponto de partida. E para outro caso de a nossa própria infraestrutura atrapalhar a si mesma, veja como chegamos a deploys com zero erros 502.

Mythex · Pricing · Crie qualquer coisa com IA · Templates de sites e apps · Mythex comparado · Glossário de criação de apps com IA · Ferramentas grátis para criar apps com IA · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)