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

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

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

نقوش

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

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

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

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

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

لنفترض أن لدينا خادم وكيل لواجهة برمجة تطبيقات باسم "TestTargetServerCoupon"، وهو يوجِّه الزيارات إلى الخوادم المستهدفة المختلفة بناءً على مسار المورد. ونرغب في تقييد عدد زيارات واجهة برمجة التطبيقات إلى 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>

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

لنستخدم سياسة الحصة "الحصة المستندة إلى الخادم" في عملية التدفق المسبق لنقطة النهاية المستهدفة. "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>

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