Antipattern: إعادة استخدام سياسة الحصة

يتم الآن عرض مستندات Apigee Edge.
انتقِل إلى مستندات Apigee X.
المعلومات

تتيح Apigee Edge إمكانية ضبط عدد الطلبات المسموح بها لخادم وكيل واجهة برمجة التطبيقات لفترة زمنية محدّدة باستخدام سياسة الحصة.

مضادة للأنماط

في حال إعادة استخدام سياسة الحصة، سيتم تقليل عدّاد الحصص في كل مرة يتم فيها تنفيذ سياسة الحصة بصرف النظر عن مكان استخدامها. ويعني ذلك أنه إذا تمت إعادة استخدام سياسة الحصة:

  • ضمن المسار نفسه أو تدفقات مختلفة للخادم الوكيل لواجهة برمجة التطبيقات
  • في نقاط النهاية المستهدفة المختلفة لخادم وكيل واجهة برمجة التطبيقات

بعد ذلك، يتم تقليل عدّاد الحصة في كل مرة يتم فيها تنفيذه، وسينتهي الأمر بالحصول على أخطاء انتهاك الحصة أسرع بكثير مما كان متوقعًا خلال الفترة الزمنية المحددة.

لنستخدم المثال التالي لتوضيح آلية عمل ذلك.

الخادم الوكيل لواجهة برمجة التطبيقات

لنفترض أن لدينا خادمًا وكيلاً لواجهة برمجة تطبيقات اسمه "TestTargetServerSpeed"، يوجِّه الزيارات إلى خادمين مستهدفين مختلفَين استنادًا إلى مسار المورد. ونود أن نقصر زيارات واجهة برمجة التطبيقات على 10 طلبات في الدقيقة لكل خادم من هذه الخوادم المستهدفة. إليك الجدول الذي يصور هذا السيناريو:

مسار المورد الخادم الهدف الحصة
/target-us target-US.somedomain.com 10 طلبات في الدقيقة
/target-eu target-EU.somedomain.com 10 طلبات في الدقيقة

سياسة الحصة

ولأن حصة عدد الزيارات هي نفسها لكل من الخادمين المستهدفين، نحدد سياسة حصة واحدة باسم "حصة-دقيقة-استهداف-الخادم" كما هو موضح أدناه:

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

نقاط النهاية المستهدفة

لنستخدم سياسة الحصة "Data-Minute-Target-Server" في التدفق المسبق لنقطة النهاية المستهدفة "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>

أعِد استخدام سياسة الحصة نفسها "Deal-Minute-Target-Server" في التدفق السابق لنقطة النهاية المستهدفة الأخرى "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 طلبات من واجهة برمجة التطبيقات للخادم الوكيل لواجهة برمجة التطبيقات هذا خلال أول 30 ثانية على النحو التالي:

مسار المورد /target-us /target-eu الكل
# طلبًا 4 6 10

بعد ذلك بقليل، حصلنا على طلب واجهة برمجة التطبيقات الحادي عشر مع مسار المورد على النحو /target-us، على سبيل المثال، بعد 32 ثانية.

نتوقّع أن تتم معالجة الطلب بنجاح على افتراض أنّه لا يزال لدينا 6 طلبات من واجهة برمجة التطبيقات لنقطة النهاية المستهدَفة target-us وفقًا للحصة المسموح بها.

ولكننا في الواقع نحصل على Quota violation error.

السبب: بما أننا نستخدم سياسة الحصة نفسها في كل من نقطتَي النهاية الهدف، يتم استخدام عدّاد حصة واحد لتتبُّع طلبات واجهة برمجة التطبيقات التي تصل إلى نقطتَي النهاية الهدفَين. وبالتالي، نستنفد حصة 10 طلبات في الدقيقة بشكل جماعي بدلاً من نقطة النهاية الفردية المستهدفة.

التأثير

ويمكن أن يؤدي هذا النمط إلى عدم تطابق جذري في التوقعات، مما يؤدي إلى تصور أن حدود الحصة قد تم استنفادها مسبقًا.

أفضل ممارسة

  • استخدِم العنصرَين <Class> أو <Identifier> لضمان الاحتفاظ بعدّات فريدة ومتعدِّدة من خلال تحديد سياسة حصة واحدة. لنُعيد تحديد سياسة الحصة "Deal-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_id يحتوي على القيمة US، سيتم توجيه الطلبات إلى نقطة النهاية المستهدَفة "Target-US".
    • وبالمثل، إذا كان العنوان target_id يحتوي على القيمة "EU"، يتم توجيه الطلبات إلى نقطة النهاية المستهدَفة "Target-EU".
    • لذلك، حتى إذا استخدمنا سياسة الحصة نفسها في كل من نقطتَي النهاية المستهدفتَين، يتم الاحتفاظ بعدّادات حصص منفصلة استنادًا إلى قيمة <Identifier>.
    • وبالتالي، يتيح لنا استخدام العنصر <Identifier> ضمان حصول كل نقطة من نقاط النهاية المستهدفة على الحصة المسموح بها وهي 10 طلبات.
  • استخدِم سياسة حصة منفصلة في كل مسار من التدفقات/نقاط النهاية المستهدفة/الخوادم الوكيلة لواجهة برمجة التطبيقات لضمان حصولك دائمًا على العدد المسموح به من طلبات البيانات من واجهة برمجة التطبيقات. لنلقِ نظرة الآن على المثال نفسه المستخدَم في القسم أعلاه لنفهم كيف يمكننا الوصول إلى الحصة المسموح بها، وهي 10 طلبات لكل نقطة من نقاط النهاية المستهدفة.
    • تحديد سياسة حصة منفصلة لكل سياسة خاصة بنقطتي النهاية المستهدفتين "Target-US" و"استهداف-الاتحاد الأوروبي"

      سياسة الحصة لنقطة النهاية المستهدفة "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 طلبات من واجهة برمجة التطبيقات في الدقيقة لكل نقطة نهاية مستهدفة.
  • استخدِم العنصر <Class> أو <Identifier> لضمان الاحتفاظ بعدة عدّادات فريدة.