Apigee에서는 할당량 정책을 사용하여 특정 기간 동안 API 프록시에 허용되는 요청 수를 구성할 수 있습니다.
안티패턴
할당량 정책이 재사용되면 할당량 정책이 사용되는 위치와 상관없이 실행될 때마다 할당량 카운터가 줄어듭니다. 즉, 할당량 정책이 다음과 같이 재사용되는 경우입니다.
API 프록시의 동일한 흐름 또는 다른 흐름 내에서
API 프록시의 다른 대상 엔드포인트에서
그러면 할당량 카운터가 실행될 때마다 감소하여 결국 지정된 시간 간격에 대해 예상한 것보다 훨씬 빨리 할당량 초과 오류가 발생합니다.
다음 예시를 통해 작동 방식을 설명해 보겠습니다.
API 프록시
리소스 경로에 따라 트래픽을 서로 다른 두 개의 대상 서버로 라우팅하는 'TestTargetServerQuota'라는 API 프록시가 있다고 가정해 보겠습니다. 그리고 API 트래픽을 각 대상 서버에 분당 10개의 요청으로 제한하려고 합니다. 다음은 이 시나리오를 설명하는 표입니다.
리소스 경로
대상 서버
할당량
/target-us
target-US.somedomain.com
요청 10개/분
/target-eu
target-EU.somedomain.com
요청 10개/분
할당량 정책
두 대상 서버의 트래픽 할당량이 동일하므로 아래와 같이 'Quota-Minute-Target-Server'라는 단일 할당량 정책을 정의합니다.
다음 패턴의 처음 30초 안에 이 API 프록시에 대해 총 10회의 API 요청을 받는다고 가정해 보겠습니다.
리소스 경로
/target-us
/target-eu
전체
요청 수
4
6
10
잠시 후인 32초 후에 리소스 경로가 /target-us인 11번째 API 요청을 받습니다.
대상 엔드포인트 target-us에 여전히 6개의 API 요청이 허용되는 할당량으로 남아있다고 가정하면 요청이 성공적으로 처리될 것으로 예상됩니다.
하지만 실제로는 Quota violation error가 발생합니다.
이유: 두 개의 대상 엔드포인트에서 동일한 할당량 정책을 사용하므로 두 개의 대상 엔드포인트에 모두 적용되는 API 요청을 추적하는 데 단일 할당량 카운터가 사용됩니다. 따라서 개별 대상 엔드포인트가 아니라 분당 요청 10개의 할당량이 소진됩니다.
영향
이러한 안티패턴은 근본적인 기대 수준의 불일치를 초래하여 할당량 한도가 조기에 소진되었다고 인식하게 만듭니다.
권장사항
<Class> 또는 <Identifier> 요소를 사용해서 단일 할당량 정책을 정의하여 여러 개의 고유한 카운터가 유지되도록 합니다. 아래와 같이 target_id 헤더를 <Identifier>로 사용하여 이전 섹션에서 설명한 할당량 정책 'Quota-Minute-Target-Server'를 다시 정의하겠습니다.
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["이해하기 어려움","hardToUnderstand","thumb-down"],["잘못된 정보 또는 샘플 코드","incorrectInformationOrSampleCode","thumb-down"],["필요한 정보/샘플이 없음","missingTheInformationSamplesINeed","thumb-down"],["번역 문제","translationIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-09-05(UTC)"],[[["\u003cp\u003eReusing a single Apigee Quota policy across multiple flows or target endpoints causes the quota counter to decrement each time it's executed, leading to unexpected quota violations.\u003c/p\u003e\n"],["\u003cp\u003eWhen a Quota policy is reused in different target endpoints, a single counter tracks requests collectively, instead of separately for each endpoint, potentially exhausting the quota limit prematurely.\u003c/p\u003e\n"],["\u003cp\u003eTo maintain individual quota counters when reusing a Quota policy, use the \u003ccode\u003e<Identifier>\u003c/code\u003e element, such as referencing a header value, to differentiate between the contexts in which the policy is executed.\u003c/p\u003e\n"],["\u003cp\u003eAn alternative to reusing a Quota policy is to define separate Quota policies for each flow or target endpoint, ensuring that each endpoint has its own dedicated counter to accurately track and enforce the specified quota.\u003c/p\u003e\n"]]],[],null,["# Antipattern: Re-use a Quota policy\n\n*You're viewing **Apigee** and **Apigee hybrid** documentation.\nView [Apigee Edge](https://docs.apigee.com/api-platform/antipatterns/reusing-quota) documentation.*\n\nApigee provides the ability to configure the number of allowed requests for an API Proxy for\na specific period of time using the [Quota policy](/apigee/docs/api-platform/reference/policies/quota-policy).\n\nAntipattern\n-----------\n\nIf a [Quota policy](/apigee/docs/api-platform/reference/policies/quota-policy) is reused, then the quota counter will be decremented each time the\nQuota policy gets executed irrespective of where it is used. That is, if a Quota policy is\nreused:\n\n- Within the same flow or different flows of an API proxy\n- In different target endpoints of an API proxy\n\nThen the quota counter gets decremented each time it is executed and we will end up getting\nQuota violation errors much earlier than the expected for the specified interval of time.\n\nLet's use the following example to explain how this works.\n\n### API Proxy\n\nLet's say we have an API proxy named \"TestTargetServerQuota\", which routes traffic to two\ndifferent target servers based on the resource path. And we would like to restrict the API traffic\nto 10 requests per minute for each of these target servers. Here's the table that depicts this\nscenario:\n\n### Quota policy\n\nSince the traffic quota is same for both the target servers, we define single Quota policy\nnamed \"Quota-Minute-Target-Server\" as shown below: \n\n```world-of-warcraft-toc\n\u003c!-- /antipatterns/examples/1-8.xml --\u003e\n\u003cQuota name=\"Quota-Minute-Target-Server\"\u003e\n \u003cInterval\u003e1\u003c/Interval\u003e\n \u003cTimeUnit\u003eminute\u003c/TimeUnit\u003e\n \u003cDistributed\u003etrue\u003c/Distributed\u003e\n \u003cAllow count=\"10\"/\u003e\n\u003c/Quota\u003e\n```\n\n### Target endpoints\n\nLet's use the Quota policy \"Quota-Minute-Target-Server\" in the preflow of the target endpoint\n\"Target-US\": \n\n```world-of-warcraft-toc\n\u003c!-- /antipatterns/examples/1-9.xml --\u003e\n\u003cTargetEndpoint name=\"Target-US\"\u003e\n \u003cPreFlow name=\"PreFlow\"\u003e\n \u003cRequest\u003e\n \u003cStep\u003e\n \u003cName\u003eQuota-Minute-Target-Server\u003c/Name\u003e\n \u003c/Step\u003e\n \u003c/Request\u003e\n \u003c/PreFlow\u003e\n \u003cHTTPTargetConnection\u003e\n \u003cURL\u003ehttp://target-us.somedomain.com\u003c/URL\u003e\n \u003c/HTTPTargetConnection\u003e\n\u003c/TargetEndpoint\u003e\n```\n\nAnd reuse the same Quota policy \"Quota-Minute-Target-Server\" in the preflow of the other target\nendpoint \"Target-EU\" as well: \n\n```world-of-warcraft-toc\n\u003c!-- /antipatterns/examples/1-10.xml --\u003e\n\u003cTargetEndpoint name=\"Target-EU\"\u003e\n \u003cPreFlow name=\"PreFlow\"\u003e\n \u003cRequest\u003e\n \u003cStep\u003e\n \u003cName\u003eQuota-Minute-Target-Server\u003c/Name\u003e\n \u003c/Step\u003e\n \u003c/Request\u003e\n \u003cResponse/\u003e\n \u003c/PreFlow\u003e\n \u003cHTTPTargetConnection\u003e\n \u003cURL\u003ehttp://target-us.somedomain.com\u003c/URL\u003e\n \u003c/HTTPTargetConnection\u003e\n\u003c/TargetEndpoint\u003e\n```\n\n### Incoming traffic pattern\n\nLet's say we get a total of 10 API requests for this API proxy within the first 30 seconds in\nthe following pattern:\n\nA little later, we get the 11th API request with the resource path as `/target-us`,\nlet's say after 32 seconds.\n\nWe expect the request to go through successfully assuming that we still have 6 API requests for\nthe target endpoint `target-us` as per the quota allowed.\n\nHowever, in reality, we get a `Quota violation error`.\n\n**Reason:** Since we are using the same Quota policy in both the target endpoints, a\nsingle quota counter is used to track the API requests hitting both the target endpoints. Thus we\nexhaust the quota of 10 requests per minute collectively rather than for the individual target\nendpoint.\n\nImpact\n------\n\nThis antipattern can result in a fundamental mismatch of expectations, leading to a perception\nthat the quota limits got exhausted ahead of time.\n\nBest practice\n-------------\n\n- Use the `\u003cClass\u003e` or `\u003cIdentifier\u003e` elements to ensure multiple, unique counters are maintained by defining a single [Quota policy](/apigee/docs/api-platform/reference/policies/quota-policy). Let's redefine the Quota policy \"Quota-Minute-Target-Server\" that we just explained in the previous section by using the header `target_id` as the `\u003cIdentifier\u003e` for as shown below: \n\n ```world-of-warcraft-toc\n \u003c!-- /antipatterns/examples/1-11.xml --\u003e\n \u003cQuota name=\"Quota-Minute-Target-Server\"\u003e\n \u003cInterval\u003e1\u003c/Interval\u003e\n \u003cTimeUnit\u003eminute\u003c/TimeUnit\u003e\n \u003cAllow count=\"10\"/\u003e\n \u003cIdentifier ref=\"request.header.target_id\"/\u003e\n \u003cDistributed\u003etrue\u003c/Distributed\u003e\n \u003c/Quota\u003e\n ```\n - We will continue to use this Quota policy in both the target endpoints \"Target-US\" and \"Target-EU\" as before.\n - Now let's say if the header `target_id` has a value \"US\" then the requests are routed to the target endpoint \"Target-US\".\n - Similarly if the header `target_id` has a value \"EU\" then the requests are routed to the target endpoint \"Target-EU\".\n - So even if we use the same Quota policy in both the target endpoints, separate quota counters are maintained based on the `\u003cIdentifier\u003e` value.\n - Therefore, by using the `\u003cIdentifier\u003e` element we can ensure that each of the target endpoints get the allowed quota of 10 requests.\n- Use separate Quota policy in each of the flows/target endpoints/API Proxies to ensure that you always get the allowed count of API requests. Let's now look at the same example used in the above section to see how we can achieve the allowed quota of 10 requests for each of the target endpoints.\n - Define a separate Quota policy, one each for the target endpoints \"Target-US\" and \"Target-EU\" Quota policy for Target Endpoint \"Target-US\":\n\n ```world-of-warcraft-toc\n \u003c!-- /antipatterns/examples/1-12.xml --\u003e\n \u003cQuota name=\"Quota-Minute-Target-Server-US\"\u003e\n \u003cInterval\u003e1\u003c/Interval\u003e\n \u003cTimeUnit\u003eminute\u003c/TimeUnit\u003e\n \u003cDistributed\u003etrue\u003c/Distributed\u003e\n \u003cAllow count=\"10\"/\u003e\n \u003c/Quota\u003e\n ```\n\n Quota policy for Target Endpoint \"Target-EU\": \n\n ```world-of-warcraft-toc\n \u003c!-- /antipatterns/examples/1-13.xml --\u003e\n \u003cQuota name=\"Quota-Minute-Target-Server-EU\"\u003e\n \u003cInterval\u003e1\u003c/Interval\u003e\n \u003cTimeUnit\u003eminute\u003c/TimeUnit\u003e\n \u003cDistributed\u003etrue\u003c/Distributed\u003e\n \u003cAllow count=\"10\"/\u003e\n \u003c/Quota\u003e\n ```\n - Use the respective quota policy in the definition of the target endpoints as shown below: Target Endpoint \"Target-US\":\n\n ```world-of-warcraft-toc\n \u003c!-- /antipatterns/examples/1-14.xml --\u003e\n \u003cTargetEndpoint name=\"Target-US\"\u003e\n \u003cPreFlow name=\"PreFlow\"\u003e\n \u003cRequest\u003e\n \u003cStep\u003e\n \u003cName\u003eQuota-Minute-Target-Server-US\u003c/Name\u003e\n \u003c/Step\u003e\n \u003c/Request\u003e\n \u003cResponse/\u003e\n \u003c/PreFlow\u003e\n \u003cHTTPTargetConnection\u003e\n \u003cURL\u003ehttp://target-us.somedomain.com\u003c/URL\u003e\n \u003c/HTTPTargetConnection\u003e\n \u003c/TargetEndpoint\u003e\n ```\n\n Target Endpoint \"Target-EU\": \n\n ```world-of-warcraft-toc\n \u003c!-- /antipatterns/examples/1-15.xml --\u003e\n \u003cTargetEndpoint name=\"Target-EU\"\u003e\n \u003cPreFlow name=\"PreFlow\"\u003e\n \u003cRequest\u003e\n \u003cStep\u003e\n \u003cName\u003eQuota-Minute-Target-Server-EU\u003c/Name\u003e\n \u003c/Step\u003e\n \u003c/Request\u003e\n \u003cResponse/\u003e\n \u003c/PreFlow\u003e\n \u003cHTTPTargetConnection\u003e\n \u003cURL\u003ehttp://target-eu.somedomain.com\u003c/URL\u003e\n \u003c/HTTPTargetConnection\u003e\n \u003c/TargetEndpoint\u003e\n ```\n - Since we are using separate Quota policy in the target endpoints \"Target-US\" and \"Target-EU\", a separate counter will be maintained. This ensures that we get the allowed quota of 10 API requests per minute for each of the target endpoints.\n- Use the `\u003cClass\u003e` or `\u003cIdentifier\u003e` elements to ensure multiple, unique counters are maintained."]]