Antipattern: ใช้นโยบายโควต้าซ้ำ

คุณกำลังดูเอกสารประกอบของ Apigee Edge
ไปที่ เอกสารประกอบของ Apigee X
info

Apigee Edge มีความสามารถในการกำหนดค่าจำนวนคำขอที่อนุญาตสำหรับพร็อกซี API สำหรับ ช่วงเวลาที่เฉพาะเจาะจงโดยใช้นโยบายโควต้า

รูปแบบที่ไม่แนะนำ

หากนำนโยบายโควต้ากลับมาใช้ซ้ำ ระบบจะลดตัวนับโควต้าลงทุกครั้งที่ นโยบายโควต้าทำงาน ไม่ว่านโยบายนั้นจะใช้ที่ใดก็ตาม นั่นคือหากนำนโยบายโควต้ากลับมาใช้ซ้ำ

  • ภายในโฟลว์เดียวกันหรือโฟลว์ต่างๆ ของพร็อกซี API
  • ในปลายทางเป้าหมายต่างๆ ของพร็อกซี API

ตัวนับโควต้าจะลดลงทุกครั้งที่นโยบายทำงาน และเราจะได้รับข้อผิดพลาดการละเมิดโควต้าเร็วกว่าที่คาดไว้สำหรับช่วงเวลาที่ระบุ

มาดูตัวอย่างต่อไปนี้เพื่ออธิบายวิธีการทำงาน

พร็อกซี API

สมมติว่าเรามีพร็อกซี API ชื่อ "TestTargetServerQuota" ซึ่งกำหนดเส้นทางการเข้าชมไปยังเซิร์ฟเวอร์เป้าหมาย 2 เครื่องที่แตกต่างกันตามเส้นทางทรัพยากร และเราต้องการจำกัดการเข้าชม API ไว้ที่ 10 คำขอต่อนาทีสำหรับเซิร์ฟเวอร์เป้าหมายแต่ละเครื่อง ตารางต่อไปนี้แสดงสถานการณ์นี้

เส้นทางทรัพยากร เซิร์ฟเวอร์เป้าหมาย Quota
/target-us target-US.somedomain.com 10 คำขอต่อนาที
/target-eu target-EU.somedomain.com 10 คำขอต่อนาที

นโยบายโควต้า

เนื่องจากโควต้าการเข้าชมของเซิร์ฟเวอร์เป้าหมายทั้ง 2 เครื่องเหมือนกัน เราจึงกำหนดนโยบายโควต้าเดียวชื่อ "Quota-Minute-Target-Server" ดังที่แสดงด้านล่าง

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

ปลายทางเป้าหมาย

มาใช้นโยบายโควต้า "Quota-Minute-Target-Server" ใน preflow ของปลายทางเป้าหมาย "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>

และนำนโยบายโควต้าเดียวกัน "Quota-Minute-Target-Server" กลับมาใช้ซ้ำใน preflow ของปลายทางเป้าหมายอื่น "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>

รูปแบบการเข้าชมขาเข้า

สมมติว่าเราได้รับคำขอ API ทั้งหมด 10 รายการสำหรับพร็อกซี API นี้ภายใน 30 วินาทีแรกตามรูปแบบต่อไปนี้

เส้นทางทรัพยากร /target-us /target-eu ทั้งหมด
จำนวนคำขอ 4 6 10

หลังจากนั้นไม่นาน เราได้รับคำขอ API รายการที่ 11 ที่มีเส้นทางทรัพยากรเป็น /target-us สมมติว่าหลังจากผ่านไป 32 วินาที

เราคาดว่าคำขอจะผ่านไปได้ด้วยดี โดยสมมติว่าเรายังมีคำขอ API 6 รายการสำหรับปลายทางเป้าหมาย target-us ตามโควต้าที่อนุญาต

อย่างไรก็ตาม ในความเป็นจริง เราได้รับ Quota violation error

เหตุผล: เนื่องจากเราใช้นโยบายโควต้าเดียวกันในปลายทางเป้าหมายทั้ง 2 แห่ง ระบบจึงใช้ตัวนับโควต้าเดียวเพื่อติดตามคำขอ API ที่ส่งไปยังปลายทางเป้าหมายทั้ง 2 แห่ง ดังนั้น เราจึงใช้โควต้า 10 คำขอต่อนาทีจนหมดโดยรวมแทนที่จะเป็นสำหรับปลายทางเป้าหมายแต่ละแห่ง

ผลกระทบ

รูปแบบที่ไม่แนะนำนี้อาจทำให้เกิดความคลาดเคลื่อนของความคาดหวังอย่างมาก ซึ่งนำไปสู่ความเข้าใจว่าขีดจำกัดโควต้าหมดลงก่อนเวลาอันควร

แนวทางปฏิบัติแนะนำ

  • ใช้องค์ประกอบ <Class> หรือ <Identifier> เพื่อให้แน่ใจว่าระบบจะเก็บตัวนับที่ไม่ซ้ำกันหลายรายการไว้โดยการกำหนด นโยบายโควต้า เดียว มานิยามนโยบายโควต้า "Quota-Minute-Target-Server" ที่เราเพิ่งอธิบายไว้ในส่วนก่อนหน้าใหม่โดยใช้ส่วนหัว target_id เป็น <Identifier> ดังที่แสดงด้านล่าง
    <!-- /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>
    • เราจะใช้นโยบายโควต้านี้ในปลายทางเป้าหมายทั้ง 2 แห่ง "Target-US" และ “Target-EU” ต่อไปเช่นเดิม
    • ตอนนี้สมมติว่าหากส่วนหัว target_id มีค่าเป็น "US" ระบบจะกำหนดเส้นทางคำขอไปยัง ปลายทางเป้าหมาย "Target-US"
    • ในทำนองเดียวกัน หากส่วนหัว target_id มีค่าเป็น "EU" ระบบจะกำหนดเส้นทางคำขอไปยังปลายทางเป้าหมาย "Target-EU"
    • ดังนั้น แม้ว่าเราจะใช้นโยบายโควต้าเดียวกันในปลายทางเป้าหมายทั้ง 2 แห่ง ระบบก็จะเก็บตัวนับโควต้าแยกกันไว้ ตามค่า <Identifier>
    • ดังนั้น การใช้ <Identifier> จะช่วยให้มั่นใจได้ว่าปลายทางเป้าหมายแต่ละแห่ง ได้รับโควต้าที่อนุญาต 10 คำขอ
  • ใช้นโยบายโควต้าแยกกันในแต่ละโฟลว์/ปลายทางเป้าหมาย/พร็อกซี API เพื่อให้แน่ใจว่าคุณ ได้รับจำนวนคำขอ API ที่อนุญาตเสมอ ตอนนี้มาดูตัวอย่างเดียวกันที่ใช้ใน ส่วนด้านบนเพื่อดูวิธีที่เราจะได้รับโควต้าที่อนุญาต 10 คำขอสำหรับปลายทางเป้าหมาย แต่ละแห่ง
    • กำหนดนโยบายโควต้าแยกกัน 1 นโยบายสำหรับปลายทางเป้าหมาย "Target-US" และ “Target-EU”

      นโยบายโควต้าสำหรับปลายทางเป้าหมาย "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>

      นโยบายโควต้าสำหรับปลายทางเป้าหมาย "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>
    • ใช้นโยบายโควต้าที่เกี่ยวข้องในการกำหนดปลายทางเป้าหมายดังที่แสดงด้านล่าง

      ปลายทางเป้าหมาย "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>

      ปลายทางเป้าหมาย "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>
    • เนื่องจากเราใช้นโยบายโควต้าแยกกันในปลายทางเป้าหมาย "Target-US" และ "Target-EU" ระบบจึงจะเก็บตัวนับแยกกันไว้ ซึ่งจะช่วยให้มั่นใจได้ว่าเราจะได้รับโควต้าที่อนุญาต 10 คำขอ API ต่อนาทีสำหรับปลายทางเป้าหมายแต่ละแห่ง
  • ใช้องค์ประกอบ <Class> หรือ <Identifier> เพื่อให้แน่ใจว่าระบบจะเก็บตัวนับที่ไม่ซ้ำกันหลายรายการไว้