Chống lỗi: Sử dụng lại chính sách Hạn mức

Bạn đang xem tài liệu về Apigee Edge.
Chuyển đến tài liệu về Apigee X.
thông tin

Apigee Edge cho phép định cấu hình số lượng yêu cầu được phép đối với một Proxy API trong một khoảng thời gian cụ thể bằng cách sử dụng Chính sách về hạn mức.

Phản mẫu

Nếu bạn sử dụng lại Chính sách hạn mức, thì bộ đếm hạn mức sẽ giảm đi mỗi khi thực thi chính sách Hạn mức, bất kể chính sách đó được sử dụng ở đâu. Nghĩa là, nếu chính sách Hạn mức được sử dụng lại:

  • Trong cùng một luồng hoặc nhiều luồng của một Proxy API
  • Ở nhiều điểm cuối mục tiêu của một Proxy API

Sau đó, bộ đếm hạn mức sẽ giảm đi mỗi khi được thực thi, và chúng ta sẽ gặp lỗi vi phạm Hạn mức sớm hơn nhiều so với dự kiến trong khoảng thời gian đã chỉ định.

Hãy sử dụng ví dụ sau để giải thích cách hoạt động của tính năng này.

Proxy API

Giả sử chúng ta có một Proxy API có tên là "TestTargetServerQuota", giúp định tuyến lưu lượng truy cập đến hai máy chủ mục tiêu khác nhau dựa trên đường dẫn tài nguyên. Và chúng tôi muốn giới hạn lưu lượng truy cập API ở mức 10 yêu cầu mỗi phút cho mỗi máy chủ mục tiêu này. Dưới đây là bảng mô tả trường hợp này:

Đường dẫn tài nguyên Máy chủ mục tiêu Hạn mức
/target-us target-US.somedomain.com 10 yêu cầu mỗi phút
/target-eu target-EU.somedomain.com 10 yêu cầu mỗi phút

Chính sách về hạn mức

Vì hạn mức lưu lượng truy cập giống nhau cho cả hai máy chủ mục tiêu, nên chúng tôi xác định chính sách Hạn mức duy nhất có tên là "Hạn mức-phút-máy chủ-máy chủ" như sau:

<!-- /antipatterns/examples/1-8.xml -->
<Quota name="Quota-Minute-Target-Server">
  <Interval>1</Interval>
  <TimeUnit>minute</TimeUnit>
  <Distributed>true</Distributed>
  <Allow count="10"/>
</Quota>

Điểm cuối mục tiêu

Hãy sử dụng chính sách Hạn mức "Hạn mức-phút-máy chủ-máy chủ" trong quy trình trước của điểm cuối mục tiêu "Target-US":

<!-- /antipatterns/examples/1-9.xml -->
<TargetEndpoint name="Target-US">
  <PreFlow name="PreFlow">
    <Request>
      <Step>
        <Name>Quota-Minute-Target-Server</Name>
      </Step>
    </Request>
  </PreFlow>
  <HTTPTargetConnection>
    <URL>http://target-us.somedomain.com</URL>
  </HTTPTargetConnection>
</TargetEndpoint>

Đồng thời, sử dụng lại cùng một chính sách Hạn mức "Hạn mức-Phút-Máy chủ-Mục tiêu" trong quy trình trước của điểm cuối mục tiêu khác "Target-EU":

<!-- /antipatterns/examples/1-10.xml -->
<TargetEndpoint name="Target-EU">
  <PreFlow name="PreFlow">
    <Request>
      <Step>
        <Name>Quota-Minute-Target-Server</Name>
      </Step>
    </Request>
  <Response/>
  </PreFlow>
  <HTTPTargetConnection>
    <URL>http://target-us.somedomain.com</URL>
  </HTTPTargetConnection>
</TargetEndpoint>

Mẫu lưu lượng truy cập đến

Giả sử chúng ta nhận được tổng cộng 10 yêu cầu API cho Proxy API này trong vòng 30 giây đầu tiên theo mẫu sau:

Đường dẫn tài nguyên /target-us /target-eu Tất cả
# yêu cầu 4 6 10

Một chút sau, chúng ta sẽ nhận được yêu cầu API thứ 11 với đường dẫn tài nguyên là /target-us, giả sử là sau 32 giây.

Chúng tôi dự kiến yêu cầu sẽ diễn ra thành công nếu như chúng tôi vẫn còn 6 yêu cầu API cho điểm cuối mục tiêu target-us theo hạn mức cho phép.

Tuy nhiên, trong thực tế, chúng ta sẽ nhận được Quota violation error.

Lý do: Vì chúng tôi đang sử dụng cùng một chính sách Hạn mức cho cả hai điểm cuối mục tiêu, nên một bộ đếm hạn mức duy nhất được dùng để theo dõi các yêu cầu API nhắm đến cả hai điểm cuối mục tiêu. Do đó, chúng tôi sẽ sử dụng hết hạn mức 10 yêu cầu mỗi phút chung thay vì cho điểm cuối mục tiêu riêng lẻ.

Mức độ tác động

Điều này có thể dẫn đến sự không phù hợp cơ bản về các kỳ vọng, dẫn đến nhận thức rằng hạn mức đã hết trước thời hạn.

Phương pháp hay nhất

  • Sử dụng các phần tử <Class> hoặc <Identifier> để đảm bảo duy trì nhiều bộ đếm duy nhất bằng cách xác định một chính sách Hạn mức duy nhất. Hãy xác định lại chính sách Hạn mức "Hạn mức-phút-máy chủ-máy chủ" mà chúng ta vừa giải thích trong phần trước bằng cách sử dụng tiêu đề target_id làm <Identifier> cho như bên dưới:
    <!-- /antipatterns/examples/1-11.xml -->
    <Quota name="Quota-Minute-Target-Server">
      <Interval>1</Interval>
      <TimeUnit>minute</TimeUnit>
      <Allow count="10"/>
      <Identifier ref="request.header.target_id"/>
      <Distributed>true</Distributed>
    </Quota>
    
    • Chúng tôi sẽ tiếp tục sử dụng chính sách Hạn mức này trong cả điểm cuối mục tiêu "Target-US" và "Target-EU" như trước đây.
    • Bây giờ, giả sử nếu tiêu đề target_id có giá trị "US" thì các yêu cầu được chuyển đến điểm cuối mục tiêu "Target-US".
    • Tương tự như vậy, nếu tiêu đề target_id có giá trị "EU", thì các yêu cầu sẽ được chuyển đến điểm cuối mục tiêu "Target-EU".
    • Vì vậy, ngay cả khi chúng tôi sử dụng cùng một chính sách Hạn mức trong cả hai điểm cuối mục tiêu, các bộ đếm hạn mức riêng biệt vẫn được duy trì dựa trên giá trị <Identifier>.
    • Do đó, bằng cách sử dụng phần tử <Identifier>, chúng ta có thể đảm bảo rằng mỗi điểm cuối mục tiêu nhận được hạn mức cho phép là 10 yêu cầu.
  • Sử dụng chính sách Hạn mức riêng biệt trong mỗi luồng/điểm cuối mục tiêu/Uỷ quyền API để đảm bảo rằng bạn luôn nhận được số lượng yêu cầu API được cho phép. Bây giờ, hãy xem ví dụ tương tự ở phần trên để xem cách chúng ta có thể đạt được hạn mức cho phép là 10 yêu cầu cho mỗi điểm cuối mục tiêu.
    • Xác định một chính sách Hạn mức riêng, mỗi chính sách cho một điểm cuối mục tiêu "Target-US" và "Target-EU"

      Chính sách hạn mức cho Thiết bị đầu cuối mục tiêu “Target-US”:

      <!-- /antipatterns/examples/1-12.xml -->
      <Quota name="Quota-Minute-Target-Server-US">
        <Interval>1</Interval>
        <TimeUnit>minute</TimeUnit>
        <Distributed>true</Distributed>
        <Allow count="10"/>
      </Quota>
      

      Chính sách hạn mức cho Điểm cuối mục tiêu “Target-EU”:

      <!-- /antipatterns/examples/1-13.xml -->
      <Quota name="Quota-Minute-Target-Server-EU">
        <Interval>1</Interval>
        <TimeUnit>minute</TimeUnit>
        <Distributed>true</Distributed>
        <Allow count="10"/>
      </Quota>
      
    • Hãy sử dụng chính sách hạn mức tương ứng trong phần định nghĩa về điểm cuối mục tiêu như dưới đây:

      Điểm cuối mục tiêu "Target-US":

      <!-- /antipatterns/examples/1-14.xml -->
      <TargetEndpoint name="Target-US">
        <PreFlow name="PreFlow">
          <Request>
            <Step>
              <Name>Quota-Minute-Target-Server-US</Name>
            </Step>
          </Request>
          <Response/>
        </PreFlow>
        <HTTPTargetConnection>
          <URL>http://target-us.somedomain.com</URL>
        </HTTPTargetConnection>
      </TargetEndpoint>
      

      Điểm cuối mục tiêu “Target-EU”:

      <!-- /antipatterns/examples/1-15.xml -->
      <TargetEndpoint name="Target-EU">
        <PreFlow name="PreFlow">
          <Request>
            <Step>
              <Name>Quota-Minute-Target-Server-EU</Name>
            </Step>
          </Request>
          <Response/>
        </PreFlow>
        <HTTPTargetConnection>
          <URL>http://target-eu.somedomain.com</URL>
        </HTTPTargetConnection>
      </TargetEndpoint>
      
    • Vì chúng tôi đang sử dụng chính sách Hạn mức riêng biệt trong các điểm cuối mục tiêu "Target-US" và "Target-EU", nên một bộ đếm riêng sẽ được duy trì. Điều này đảm bảo rằng chúng ta nhận được hạn mức cho phép là 10 yêu cầu API mỗi phút cho mỗi điểm cuối mục tiêu.
  • Sử dụng các phần tử <Class> hoặc <Identifier> để đảm bảo duy trì nhiều bộ đếm duy nhất.