ایزی ریت
ورود / ثبت‌نامورود

مدیریت خطا در API مالی و Rate Limit؛ الگوهایی که سیستم را سرپا نگه می‌دارد

مدیریت خطا در API مالی: معنی 401، 403، 429 و 5xx، تلاش مجدد با تأخیر افزایشی و Jitter، Circuit Breaker، نمایش آخرین نرخ معتبر و پایش؛ با کد پایتون و جاوااسکریپت.

تینا نجفی
· نویسنده مالی و اقتصادی
انتشار ۱۴ آبان ۱۴۰۵، ۱۶:۰۰ · ۴ دقیقه مطالعه
مدیریت خطا در API مالی و محدودیت نرخ درخواست (Rate Limit)
خلاصه در سه خط
  • خطاها دو دسته‌اند: دائمی (401، 403، 422) که تلاش مجدد ندارند و موقت (429، 5xx، Timeout) که با تأخیر دوباره امتحان می‌شوند.
  • برای 429 تا زمان `meta.reset_at` صبر کنید؛ تلاش مکرر فقط وضعیت را بدتر می‌کند.
  • در هیچ خطایی صفحه نباید خالی شود: آخرین نرخ معتبر را با زمانش نشان دهید و قدیمی بودنش را اعلام کنید.

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

i
API ایزی‌ریت
این راهنما با API قیمت ارز و طلای ایزی‌ریت کار می‌کند؛ مستندات کامل، نمونه‌کد و کلید رایگان در صفحهٔ API است.
★
پاسخ کوتاه
برای 401 و 403 تلاش مجدد نکنید و به تیم خبر دهید. برای 429 تا meta.reset_at صبر کنید. برای 5xx و Timeout حداکثر ۳ بار با تأخیر افزایشی (۱، ۲، ۴ ثانیه + کمی تصادفی) تلاش کنید. در همهٔ حالت‌ها آخرین نرخ معتبر را با برچسب زمان نشان دهید.

این مقاله بخشی از راهنمای کامل API قیمت ارز و طلا است.

کدهای خطا و معنی هر کدام

کدمعنی در EZRateدائمی یا موقتکار درست
400 / 422پارامتر نامعتبر (مثلاً نماد اشتباه یا quote ناشناخته)دائمیدرخواست را اصلاح کنید؛ پیام خطا فیلد مشکل‌دار را می‌گوید
401 invalid_api_keyکلید نیامده، اشتباه است یا باطل شدهدائمیتوقف و هشدار به تیم
403 forbiddenIP یا دامنهٔ درخواست در فهرست مجاز کلید نیستدائمیتنظیم محدودیت کلید در پنل
404نماد یا مسیر وجود ندارددائمیفهرست نمادها را از /assets بخوانید
429 rate_limitedسهمیهٔ روزانه یا ماهانه تمام شدهموقت تا زمان مشخصصبر تا meta.reset_at
5xxخطای موقت سرورموقتتلاش مجدد با تأخیر
Timeout یا خطای شبکهپاسخ نرسیدموقتتلاش مجدد با تأخیر

الگوی ۱: تلاش مجدد با تأخیر افزایشی و Jitter

اگر هزار کلاینت هم‌زمان خطا بگیرند و همه دقیقاً بعد از یک ثانیه دوباره تلاش کنند، موج دوم از موج اول بزرگ‌تر است. تأخیر افزایشی (۱، ۲، ۴ ثانیه) به‌همراه کمی تصادفی‌سازی (Jitter) این موج‌ها را پخش می‌کند:

python
import random, time, requests

TRANSIENT = {500, 502, 503, 504}

def get_with_retry(url, headers, params=None, tries=3):
    for i in range(tries):
        try:
            r = requests.get(url, headers=headers, params=params, timeout=8)
        except (requests.Timeout, requests.ConnectionError):
            r = None
        if r is not None and r.status_code not in TRANSIENT:
            return r                                   # موفق یا خطای دائمی/429: تصمیم با فراخواننده
        time.sleep((2 ** i) + random.uniform(0, 0.5))  # 1s، 2s، 4s + jitter
    raise RuntimeError("API unavailable after retries")
!
هشدار
هرگز روی 401 یا 403 حلقهٔ تلاش مجدد نگذارید. این خطاها با تکرار درست نمی‌شوند و فقط لاگ‌ها را پر می‌کنند.

الگوی ۲: مدیریت 429 و پایش سهمیه

وقتی سهمیه تمام می‌شود، پاسخ 429 در meta.reset_at زمان باز شدن دوباره را می‌گوید. تا آن زمان درخواست نفرستید. بهتر از آن، جلوی رسیدن به این وضعیت را بگیرید: مسیر GET /usage مصرف امروز و این ماه را می‌دهد و از سهمیه کم نمی‌شود. یک بررسی ساعتی کافی است تا قبل از تمام شدن سهمیه هشدار بگیرید:

javascript
const u = await (await fetch("https://api.ezrate.me/v1/usage", {
  headers: { "X-API-Key": process.env.EZRATE_KEY } })).json()
console.log(JSON.stringify(u.data))   // مصرف و سقف امروز و این ماه
// اگر مصرف امروز از ۸۰٪ سقف گذشت، به تیم هشدار بدهید

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

الگوی ۳: Circuit Breaker

وقتی API چند بار پشت سر هم خطا داد، ادامهٔ تلاش در هر درخواست فقط زمان پاسخ سایت شما را بالا می‌برد. Circuit Breaker مثل فیوز برق عمل می‌کند: بعد از چند خطای پیاپی، برای مدتی کوتاه اصلاً درخواست نمی‌فرستد و مستقیم از کش جواب می‌دهد؛ سپس یک درخواست آزمایشی می‌فرستد و اگر موفق بود، به حالت عادی برمی‌گردد:

javascript
class Breaker {
  constructor(limit = 3, coolMs = 60_000) { Object.assign(this, { limit, coolMs, fails: 0, openUntil: 0 }) }
  async call(fn, fallback) {
    if (Date.now() < this.openUntil) return fallback()          // باز: فقط کش
    try {
      const v = await fn()
      this.fails = 0
      return v
    } catch (e) {
      if (++this.fails >= this.limit) this.openUntil = Date.now() + this.coolMs
      return fallback()
    }
  }
}
const breaker = new Breaker()
const rates = await breaker.call(fetchRatesFromApi, () => readLastGoodRates())
نمودار حالت‌های Circuit Breaker: بسته، باز، نیمه‌باز
سه حالت فیوز در برابر خطاهای پیاپی

الگوی ۴: آخرین مقدار معتبر و صداقت با کاربر

در سیستم‌های مالی، نشان دادن عدد قدیمی بدون اعلام آن، از نشان ندادن عدد بدتر است. هر جا آخرین مقدار معتبر را نمایش می‌دهید، زمانش را هم بگویید و اگر از حدی قدیمی‌تر است، آن را متمایز کنید:

عمر نرخنمایش پیشنهادی
کمتر از ۵ دقیقهعادی، با ساعت به‌روزرسانی
۵ تا ۶۰ دقیقهعدد با رنگ کم‌رنگ‌تر و عبارت «آخرین به‌روزرسانی: …»
بیشتر از یک ساعتهشدار صریح «نرخ‌ها موقتاً به‌روز نمی‌شوند» و توقف هر محاسبهٔ خودکار مالی

الگوی ۵: Timeout را خودتان تعیین کنید

بدون timeout، یک درخواست معلق می‌تواند پروسهٔ PHP یا Node.js شما را دقیقه‌ها نگه دارد و در ساعت شلوغ همهٔ ظرفیت سرور را بگیرد. برای درخواست نرخ، ۵ تا ۸ ثانیه کافی است. در پایتون با timeout=، در Node.js با AbortSignal.timeout() و در لاراول با ->timeout().

پایش و هشدار

  • تعداد خطا به تفکیک کد را ثبت کنید؛ افزایش ناگهانی 401 یعنی کلید عوض شده یا باطل شده است.
  • سن آخرین نرخ معتبر را پایش کنید؛ اگر از ۱۰ دقیقه گذشت، هشدار بفرستید.
  • وضعیت Circuit Breaker را در داشبورد نشان دهید.
  • نسخهٔ انگلیسی با تمرکز بر SLA و Failover در Financial API Failover Strategies آمده است.

نرخ‌های لحظه‌ای مرتبط با این مطلب: قیمت دلار، قیمت طلای ۱۸ عیار، قیمت سکه امامی.

مهم‌ترین اصل مدیریت خطا در API مالی چیست؟
اینکه هیچ خطایی صفحه یا سیستم شما را خالی یا قفل نکند و همیشه آخرین عدد معتبر با زمانش در دسترس باشد.
چند بار تلاش مجدد کافی است؟
برای خطاهای موقت سه بار با تأخیر افزایشی. بیشتر از آن معمولاً فقط زمان پاسخ را بالا می‌برد.
چطور بفهمم سهمیه‌ام رو به اتمام است؟
مسیر GET /usage مصرف امروز و این ماه را برمی‌گرداند و خودش از سهمیه کم نمی‌شود.
خطای 403 با اینکه کلید درست است یعنی چه؟
احتمالاً برای کلید محدودیت IP یا دامنه گذاشته‌اید و درخواست از جای دیگری آمده است. تنظیمات کلید را در پنل بررسی کنید.
تینا نجفی
من در رشته مدیریت مالی تحصیل کرده‌ام و علاقه اصلی من به موضوعات مرتبط با بازار ارز، طلا، بانکداری و تجارت بین‌المللی است. در طول فعالیت حرفه‌ای خود، درباره موضوعات مالی و خدمات ارزی مطالعه و تحقیق کرده‌ام و تلاش می‌کنم مفاهیم پیچیده مالی را به شکل ساده و کاربردی توضیح دهم. در تهیه مطالب، سعی می‌کنم اطلاعات را از منابع معتبر بررسی کرده و محتوایی ارائه دهم که برای کاربران قابل فهم و قابل استفاده باشد.
همهٔ مطالب نویسنده ←

نظرات (۰)

نظرها پس از تأیید نمایش داده می‌شوند؛ برای ارسال، ورود به حساب لازم است.

مطالب مرتبط

API و برنامه‌نویسی
وب سرویس نرخ درهم و لیر و یورو؛ راهنمای بازرگانی، گردشگری و دانشجویی
API و برنامه‌نویسی
نرخ تتر برای صرافی ارز دیجیتال؛ نرخ مرجع، اسپرد و ترمز اضطراری
API و برنامه‌نویسی
کش کردن API قیمت ارز با Redis؛ سایت سریع‌تر و مصرف سهمیهٔ کمتر