עיצוב נגדי: שימוש חוזר במדיניות מכסה

כרגע מוצג התיעוד של Apigee Edge.
כניסה למסמכי התיעוד של Apigee X.
מידע

ב-Apigee Edge אפשר להגדיר את מספר הבקשות המותרות לשרת proxy ל-API לפרק זמן מסוים באמצעות מדיניות המכסה.

דוגמת עיצוב

אם משתמשים במדיניות Quota, מונה המכסות מצטמצם בכל פעם שמדיניות Quota מופעלת, ללא קשר לשימוש שלה. כלומר, אם עושים שימוש חוזר במדיניות מכסה:

  • בתוך אותו תהליך או תהליכי עבודה שונים של שרת proxy ל-API
  • נקודות קצה (endpoints) שונות של שרת proxy ל-API

לאחר מכן, מונה המכסות מצטמצם בכל פעם שמבצעים אותו, וכתוצאה מכך מתקבלות שגיאות של הפרת המכסה הרבה יותר מוקדם מהצפוי עבור פרק הזמן שצוין.

נשתמש בדוגמה הבאה כדי להסביר איך זה עובד.

שרת proxy ל-API

נניח שיש לנו שרת proxy ל-API בשם TestTargetServerQuota, שמנתב את תעבורת הנתונים לשני שרתי יעד שונים על סמך נתיב המשאב. אנחנו רוצים להגביל את תעבורת ה-API ל-10 בקשות לדקה לכל אחד משרתי היעד. הנה הטבלה שמתארת את התרחיש:

נתיב המשאב שרת היעד מכסה
/target-us target-US.somedomain.com 10 בקשות לדקה
/target-eu target-EU.somedomain.com 10 בקשות לדקה

מדיניות מכסה

מאחר שמכסת התעבורה זהה בשני שרתי היעד, אנחנו מגדירים מדיניות מכסה יחידה שנקראת "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" בתהליך המקדים של נקודת הקצה (endpoint) של היעד: "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" גם בתהליך המקדים של נקודת הקצה (endpoint) האחרת "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>

דפוס תנועה נכנסת

נניח שקיבלנו בסך הכול 10 בקשות API לשרת ה-API הזה במהלך 30 השניות הראשונות, לפי הדפוס הבא:

נתיב המשאב /target-us /target-eu הכול
# בקשות 4 6 10

בהמשך אנחנו מקבלים את בקשת ה-API ה-11 עם נתיב המשאב בתור /target-us, נניח אחרי 32 שניות.

אנחנו צופים שהבקשה תעבור בהצלחה בהנחה שעדיין יש לנו 6 בקשות API לנקודת הקצה target-us של היעד, בהתאם למכסה המותרת.

אבל במציאות, אנחנו מקבלים Quota violation error.

הסיבה: אנחנו משתמשים באותה מדיניות מכסה בשתי נקודות הקצה (endpoint) של היעד, ולכן מונה מכסה אחד משמש למעקב אחר בקשות ה-API שמגיעות לשתי נקודות הקצה (endpoint) של היעד. לכן אנחנו ממצים את המכסה של 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>
    
    • נמשיך להשתמש במדיניות המכסה הזו גם בנקודות הקצה של היעד 'Target-US' ו-'Target-EU'.
    • עכשיו נניח שאם הערך של הכותרת target_id הוא US, הבקשות ינותבו לנקודת הקצה של היעד 'Target-US'.
    • באופן דומה, אם הערך של הכותרת target_id הוא EU, הבקשות ינותבו לנקודת הקצה (endpoint) של היעד 'Target-EU'.
    • גם אם אנחנו משתמשים באותה מדיניות מכסות בשתי נקודות הקצה (endpoint) של היעד, מוני מכסות נפרדים נשמרים לפי הערך של <Identifier>.
    • לכן, באמצעות הרכיב <Identifier>, אנחנו יכולים לוודא שכל אחת מנקודות הקצה (endpoint) תקבל את המכסה המותרת של 10 בקשות.
  • כדי לוודא שתמיד מקבלים את המספר המותר של בקשות API, צריך להשתמש במדיניות מכסה נפרדת בכל אחת מהזרימות/נקודות הקצה (endpoint) של היעד/שרתי ה-API של ה-API. עכשיו נבחן את אותה דוגמה בקטע שלמעלה כדי לראות איך אפשר להגיע למכסה המותרת של 10 בקשות לכל אחת מנקודות הקצה.
    • צריך להגדיר מדיניות מכסה נפרדת, אחת לכל נקודות הקצה (endpoints) של היעד 'Target-US' ו-'Target-EU'

      מדיניות מכסה לנקודת קצה (endpoint) '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>
      

      מדיניות מכסה לנקודת קצה (Endpoint) '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 Endpoint '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 לדקה לכל אחת מנקודות הקצה (endpoint) של היעד.
  • צריך להשתמש ברכיבים <Class> או <Identifier> כדי להבטיח ניהול של מספר מונים ייחודיים.