블로그

우리 자신의 서비스에 속도 제한을 걸고 있었습니다

Mythex의 API는 한 네트워크 주소에서 분당 300개의 요청을 허용합니다. 이 제한은 한 사람이나 스크립트가 API를 두들기는 것으로부터 우리를 보호하기 위해 존재합니다. 그런데 프로덕션에서는 이 제한이 오히려 우리 자신의 서비스를 막기 시작했습니다. 게시된 앱을 제공하는 엣지 부분과 AI 에이전트를 실행하는 서비스, 이 둘은 각각 소수의 주소에서만 API에 접근하기 때문입니다. 이제 내부 자격 증명을 가진 요청은 제한에서 면제되고, 그 밖의 모든 요청은 이전과 똑같이 제한됩니다.

증상

API가 내부 호출 중 일부에 429 Too Many Requests로 응답하기 시작했습니다. 세 종류의 호출이 영향을 받았고, 각각은 Mythex를 사용하는 누군가에게 중요합니다.

  • 커스텀 도메인에 어떤 앱이 연결되어 있는지 조회하기. 방문자가 자체 도메인에서 게시된 앱을 열면, 엣지가 API에 그 사이트가 어디 있는지 묻습니다. 여기서 429가 나면 방문자가 사이트에 접근하지 못합니다.
  • 실행 중인 에이전트 턴 저장하기. 에이전트가 작업하는 동안 진행 상황이 계속 저장되므로, 새로고침이나 연결 끊김 후에도 답변이 남습니다. 여기서 429가 나면 저장되지 않은 진행 상황이 생깁니다.
  • 미리보기 접근 확인하기. 빌드 중인 앱의 미리보기는 접근 제어가 걸려 있고, 그 게이트가 API에 묻습니다. 여기서 429가 나면 미리보기가 열리지 않습니다.

이 중 어느 것도 API를 호출하는 사람이 아니었습니다. 모두 우리 자신이었습니다.

왜 이런 일이 생겼나

IP별 속도 제한은 하나의 가정을 합니다. 주소 하나는 대략 호출자 한 명이라는 것입니다. 사람에게는 이 정도면 충분히 가깝습니다. 우리 자신의 인프라에는 완전히 틀린 가정입니다.

  • 게시된 앱과 미리보기를 제공하는 엣지 서비스는 공유된 소수의 나가는 주소로 API에 접근합니다. 모든 게시된 앱의 모든 방문자, 그리고 모든 미리보기 확인이 그 소수의 주소 중 하나에서 온 것처럼 보입니다.
  • 오케스트레이터, 즉 에이전트 턴을 실행하는 서비스는 컨테이너 주소 하나로 API에 접근합니다. 실행 중인 모든 턴, 모든 사용자가 그 주소를 공유합니다.

그래서 한 사람을 위해 만들어진 예산이 서비스 전체의 트래픽에 나뉘어 쓰였습니다. 그 서비스들이 합쳐서 예산을 다 써 버렸고, 제한 장치는 시키는 대로 그들을 거부했습니다.

수정

우리 서비스는 이미 자신이 누구인지 증명합니다. 모든 내부 호출은 내부 토큰을 함께 보내고, API의 내부 영역에 있는 모든 라우트는 무엇을 하기 전에 그 토큰을 확인합니다.

속도 제한기도 이제 같은 확인을 사용합니다. 내부 토큰과 일치하는 요청은 허용 목록에 올라 있어서 IP별 예산에 포함되지 않습니다. 그 밖의 모든 것은 이전과 정확히 같이 계산됩니다. IP당 분당 300개입니다.

이것이 구멍이 되지 않도록 두 가지 세부 사항을 지켰습니다.

  1. 잘못된 토큰은 통과하지 못합니다. 허용 목록은 진짜 내부 토큰에만 일치합니다. 가짜 토큰이 담긴 요청은 다른 모든 요청과 똑같이 계산되고 제한되며, 내부 라우트는 여전히 401 Unauthorized로 거부합니다.
  2. 제한값 자체는 바꾸지 않았습니다. 여유를 만들려고 숫자를 올리지 않았습니다. 숫자를 올리면 트래픽이 다시 늘어날 때까지 문제가 가려질 뿐이고, 제한이 존재하는 이유인 상황에 대한 보호도 약해졌을 것입니다.

제한기의 설정을 작은 함수 하나로 모으고, 그것을 대상으로 테스트를 작성했습니다. 하나는 내부 토큰을 담은 요청 20개를 5개까지 허용하는 제한기에 보내고, 20개 모두 성공해야 한다고 기대합니다. 다른 하나는 한 주소에서 평범한 요청을 보내고, 처음 5개는 성공하고 그 이후는 거부되어야 한다고 기대합니다. 세 번째는 위조된 토큰을 가진 요청을 보내고, 같은 방식으로 거부되어야 한다고 기대합니다.

우리가 얻은 교훈

  • 제한에는 가정이 들어 있습니다. “주소 하나, 호출자 하나”는 IP별 제한에 내장되어 있습니다. 자신의 서비스가 공유 주소 뒤에 놓이는 순간 이 가정은 참이 아닙니다. 로드 밸런서, 엣지 네트워크, 컨테이너, 사무실 네트워크 등 많은 곳이 그렇습니다.
  • 자신의 트래픽은 주소가 아니라 신원으로 구분하세요. 주소는 트래픽이 도착하는 방식이지, 누가 보냈는지를 말해 주지 않습니다. 우리에게는 호출이 우리 것임을 증명하는 자격 증명이 이미 있었고, 제한기가 그것을 보고 있지 않았을 뿐입니다.
  • 숫자를 올려서 해결하지 마세요. 제한값을 올리면 429가 잠시 사라지겠지만, 보호는 줄어들고 나중에 다시 실패합니다.
  • 누가 제한되고 있는지 보세요. 우리 자신의 서비스에 떨어지는 429는 제한 장치가 작동하고 있다는 증거가 아니라, 제한값에 대한 버그 보고입니다.

Mythex에서 빌드한다면

여러분 쪽에서 바꿀 것은 없습니다. 커스텀 도메인의 게시된 앱, 에이전트 턴, 미리보기는 이제 나머지 Mythex가 얼마나 바쁜지에 의존하지 않습니다. 여기서 설명한 제한은 우리 API에 대한 것이지, 여러분이 게시하는 앱에 대한 것이 아닙니다. 여러분의 앱이 받는 트래픽은 여러분의 앱의 문제입니다.

직접 백엔드를 운영한다면, 여러분이 추가하는 모든 속도 제한에도 같은 함정이 적용됩니다. 시작하기 좋은 곳은 API란 무엇인가와 AI 앱을 위한 보안 체크리스트입니다. 우리 인프라가 스스로 길을 막은 또 다른 사례는 배포를 502 0개로 낮춘 방법을 참고하세요.

Mythex · Pricing · AI로 무엇이든 만들기 · 웹사이트 및 앱 템플릿 · Mythex 비교 · AI 앱 개발 용어집 · 무료 AI 앱 개발 도구 · 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 (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)