الگوی ضد: استفاده مجدد از خط‌مشی «سهمیه»

درحال مشاهده اسناد Apigee Edge هستید.
به اسناد Apigee X بروید.
اطلاعات

‫Apigee Edge امکان پیکربندی تعداد درخواست‌های مجاز برای «پراکسی میانای برنامه‌سازی کاربردی» را برای یک دوره زمانی خاص بااستفاده از خط‌مشی سهمیه فراهم می‌کند.

الگوی بد

اگر خط‌مشی سهمیه مجدداً استفاده شود، شمارنده سهمیه هر بار که خط‌مشی سهمیه اجرا می‌شود، صرف‌نظر از اینکه کجا استفاده می‌شود، کاهش می‌یابد. یعنی اگر خط‌مشی «سهمیه» مجدداً استفاده شود:

  • در همان جریان یا جریان‌های مختلف «پراکسی API»
  • در نقاط پایانی هدف مختلف یک «پراکسی API»

سپس شمارنده سهمیه هر بار که اجرا می‌شود کاهش می‌یابد و درنهایت خطاهای نقض سهمیه را خیلی زودتر از زمان موردانتظار برای بازه زمانی مشخص دریافت خواهیم کرد.

بیایید از مثال زیر برای توضیح نحوه عملکرد این ویژگی استفاده کنیم.

کارگزار میانای برنامه‌سازی کاربردی

فرض کنیم یک «پراکسی API» به‌نام «TestTargetServerQuota» داریم که ترافیک را براساس مسیر منبع به دو سرور مقصد مختلف هدایت می‌کند. و می‌خواهیم ترافیک API را به ۱۰ درخواست در دقیقه برای هریک از این سرورهای هدف محدود کنیم. جدولی که این سناریو را نشان می‌دهد در زیر آمده است:

مسیر منبع سرور هدف سهمیه
/target-us target-US.somedomain.com ‫۱۰ درخواست در دقیقه
/target-eu target-EU.somedomain.com ‫۱۰ درخواست در دقیقه

خط‌مشی سهمیه

ازآنجایی‌که سهمیه ترافیک برای هر دو سرور هدف یکسان است، خط‌مشی سهمیه واحدی به‌نام «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» در پیش‌جریان نقطه پایانی هدف «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» را در پیش‌جریان نقطه پایانی هدف دیگر «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 برای این «پراکسی API» با الگوی زیر دریافت کنیم:

مسیر منبع /target-us /target-eu همه
‫# درخواست 4 6 10

کمی بعد، یازدهمین درخواست API را با مسیر منبع /target-us دریافت می‌کنیم، مثلاً بعداز ۳۲ ثانیه.

انتظار داریم درخواست باموفقیت انجام شود، به شرطی که طبق سهمیه مجاز، هنوز ۶ درخواست میانای برنامه‌سازی کاربردی برای نقطه پایانی هدف target-us داشته باشیم.

اما در واقعیت، Quota violation error دریافت می‌کنیم.

دلیل: ازآنجایی‌که در هر دو نقطه پایانی هدف از خط‌مشی سهمیه یکسانی استفاده می‌کنیم، از یک شمارنده سهمیه واحد برای پیگیری درخواست‌های API که به هر دو نقطه پایانی هدف می‌رسند استفاده می‌شود. بنابراین، سهمیه ۱۰ درخواست در دقیقه را به‌صورت جمعی به‌جای نقطه پایانی هدف فردی مصرف می‌کنیم.

تأثیر

این ضدالگو می‌تواند منجر به عدم تطابق اساسی انتظارات شود و این تصور را ایجاد کند که محدودیت‌های سهمیه زودتر از موعد به پایان رسیده‌اند.

روال مطلوب

  • با تعریف یک خط‌مشی سهمیه واحد، از عناصر <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-EU» مانند قبل استفاده خواهیم کرد.
    • اکنون فرض کنیم اگر سرایند target_id مقدار «US» داشته باشد، درخواست‌ها به نقطه پایانی هدف «Target-US» هدایت می‌شوند.
    • به‌همین ترتیب، اگر سرایند target_id مقدار «EU» داشته باشد، درخواست‌ها به نقطه پایانی هدف «Target-EU» هدایت می‌شوند.
    • بنابراین حتی اگر از خط‌مشی سهمیه یکسانی در هر دو نقطه پایانی هدف استفاده کنیم، براساس مقدار <Identifier>، شمارنده‌های سهمیه جداگانه‌ای نگهداری می‌شود.
    • بنابراین، بااستفاده از عنصر <Identifier> می‌توانیم مطمئن شویم که هریک از نقاط پایانی هدف سهمیه مجاز ۱۰ درخواست را دریافت می‌کند.
  • از خط‌مشی «سهمیه» جداگانه‌ای در هریک از جریان‌ها/نقاط پایانی هدف/ «پراکسی‌های API» استفاده کنید تا مطمئن شوید که همیشه تعداد مجاز درخواست‌های API را دریافت می‌کنید. اکنون به همان مثال استفاده‌شده در بخش بالا نگاهی بیندازیم تا ببینیم چگونه می‌توانیم به سهمیه مجاز ۱۰ درخواست برای هریک از نقاط پایانی هدف دست یابیم.
    • خط‌مشی سهمیه جداگانه‌ای تعریف کنید، یکی برای هریک از نقاط پایانی هدف «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» از خط‌مشی سهمیه جداگانه استفاده می‌کنیم، شمارنده جداگانه‌ای نگهداری خواهد شد. این کار تضمین می‌کند که سهمیه مجاز ۱۰ درخواست API در دقیقه برای هریک از نقاط پایانی هدف را دریافت کنیم.
  • از عناصر <Class> یا <Identifier> برای اطمینان از حفظ چندین شمارنده یکتا استفاده کنید.