Codoloper

آموزش برنامه‌نویسی به فارسی

یاد بگیر، پیشرفت کن، بساز.

منبع آموزشی برنامه‌نویسی به زبان فارسی - مستندات، دوره‌ها و مطالب کاربردی برای همه سطوح.

داکیومنت ها:

JavascriptHTMLCSSReact JSبیشتر
1// برنامه‌نویسی به فارسی
2import { learn } from 'codoloper'
3
4const developer = learn({
5"lang": "فارسی"
6"level": "همه سطوح"
7free: true
8})
بلاگ

مطالب جدید

تازه‌ترین مطالب آموزشی و خبرهای مرتبط.

Cache: کش چیه؟ چرا کش کنیم؟ یک لایه با سرعت بسیار بیشتر نوشته شده توسط عرفان دهقانی

Cache: کش چیه؟ چرا کش کنیم؟ یک لایه با سرعت بسیار بیشتر

فرض کن یک صفحه داری که برای ساختنش باید بری سراغ دیتابیس، چند تا جدول رو join کنی، نتیجه رو پردازش کنی، و بعد HTML بسازی. این کار شاید ۲۰۰ میلی‌ثانیه طول بکشه. حالا اگه این صفحه رو هزار نفر در ثانیه ببینن، و محتواش هر بار عوض نشه، داری همون کار سنگین رو هزار بار در ثانیه تکرار میکنی، درحالی‌که جواب همیشه یکیه. کش دقیقاً همین اتلاف رو حل میکنه: جواب رو یک بار حساب میکنی، جایی نگهش میداری که دسترسی بهش خیلی سریع‌تره، و دفعه‌های بعد به‌جای محاسبه‌ی دوباره، همون جواب آماده رو برمیگردونی.

این ایده به‌قدری پایه‌ایه که توی تقریباً هر لایه‌ای از یک سیستم، از مرورگر گرفته تا CDN تا سرور تا دیتابیس، یک نسخه‌ی متفاوت از همین ترفند رو میبینی.

کش توی مرورگر و سمت کاربر

اولین لایه‌ای که هر کاربر باهاش برخورد میکنه، کش مرورگره. وقتی یک فایل CSS یا تصویر یا فونت رو دانلود میکنی، مرورگر بر اساس هدرهای HTTP مثل Cache-Control و ETag تصمیم میگیره که آیا لازمه دوباره از سرور بگیرتش یا همون نسخه‌ی محلی رو نشون بده. برای همین دفعه‌ی دوم که یک سایت رو باز میکنی، خیلی سریع‌تر لود میشه — چون مرورگر اصلاً درخواست جدیدی نمیفرسته، یا اگه بفرسته، سرور فقط میگه «چیزی عوض نشده» (کد وضعیت ۳۰۴) و دوباره کل فایل رو نمیفرسته.

کش توی CDN

لایه‌ی بعدی که خیلی وقت‌ها دیده نمیشه، CDN است — سرویس‌هایی مثل Cloudflare یا ArvanCloud که یک نسخه از فایل‌های استاتیک سایتت (تصویر، CSS، JS، و حتی گاهی HTML) رو روی سرورهای پخش‌شده در نقاط مختلف جغرافیایی نگه میدارن. وقتی کاربری از یک شهر دیگه به سایتت وصل میشه، به‌جای این‌که درخواستش تا سرور اصلی بره، نزدیک‌ترین edge server جواب رو از کشش برمیگردونه. این هم سرعت رو بالا میبره و هم فشار روی سرور اصلی رو کم میکنه.

کش سمت سرور (Application Cache)

توی خود اپلیکیشن، معمولاً از ابزارهایی مثل Redis یا Memcached استفاده میشه تا نتیجه‌ی محاسبات سنگین یا کوئری‌های تکراری رو نگه دارن. مثلاً اگه یک API داری که لیست محصولات پرفروش رو برمیگردونه، به‌جای این‌که هر بار این لیست رو از دیتابیس محاسبه کنی، یک بار حسابش میکنی و توی Redis با یک TTL (زمان انقضا) ذخیره‌اش میکنی:

async function getTopProducts() {
  const cached = await redis.get('top_products');
  if (cached) return JSON.parse(cached);

  const products = await db.query('SELECT ... ORDER BY sales DESC LIMIT 10');
  await redis.set('top_products', JSON.stringify(products), 'EX', 300); // 5 دقیقه
  return products;
}

این الگو رو cache-aside میگن: اول کش رو چک میکنی، اگه خالی بود از منبع اصلی میگیری و توی کش میذاری. رایج‌ترین الگوی کش توی دنیای بک‌اند همینه، چون منطق ساده‌ست و کنترل کامل دستته.

کش توی دیتابیس

خود دیتابیس‌ها هم لایه‌های کش داخلی دارن که معمولاً کمتر بهشون فکر میکنیم. مثلاً PostgreSQL یک بخش به اسم shared buffers داره که صفحات پرکاربرد دیتابیس رو توی رم نگه میداره تا لازم نباشه هر بار از دیسک بخونه. MySQL هم مکانیزم‌های مشابهی داره. این یعنی حتی وقتی فکر میکنی داری «مستقیم از دیتابیس» میخونی، احتمالاً بخشی از اون داده از قبل توی حافظه‌ی خود دیتابیس کش شده و دیسک اصلاً درگیر نشده.

کش توی اپلیکیشن‌های موبایل

توی اپ‌های موبایل هم همین منطق تکرار میشه، فقط با اسم‌های دیگه. مثلاً یک اپلیکیشن ممکنه لیست محصولات یا فید خبری رو یک بار از سرور بگیره و توی حافظه‌ی محلی گوشی (یا یک دیتابیس سبک مثل SQLite) نگه داره، تا کاربر بدون اینترنت هم بتونه محتوای قبلی رو ببینه، و تا وقتی داده‌ی جدیدی نیومده، دوباره از سرور درخواست نده. این هم برای تجربه‌ی کاربری بهتره (لود سریع‌تر) و هم برای مصرف داده و باتری صرفه‌جویی میکنه.

چیزی که واقعاً برای یک مهندس نرم‌افزار جذابه: invalidation

جمله‌ی معروفی توی دنیای برنامه‌نویسی هست که میگه فقط دو چیز سخت توی علوم کامپیوتر وجود داره: invalidate کردن کش، نام‌گذاری متغیرها، و off-by-one errors. این جمله شوخیه، ولی نکته‌ی جدی پشتش اینه: نگه‌داشتن داده توی کش کار سختی نیست؛ سخت اینه که بفهمی دقیقاً کِی اون داده دیگه معتبر نیست و باید پاکش کنی یا آپدیتش کنی.

فرض کن قیمت یک محصول توی دیتابیس عوض بشه، ولی نسخه‌ی کش‌شده‌اش هنوز قیمت قدیمی رو نشون بده. اگه TTL طولانی گذاشته باشی، این عدم‌تطابق میتونه دقیقه‌ها یا حتی ساعت‌ها طول بکشه. راه‌حل‌های رایج برای این مشکل چندتاست: یکی این‌که هر وقت داده توی دیتابیس آپدیت شد، مستقیماً همون کلید رو از کش پاک کنی (invalidate on write). یکی دیگه اینه که از TTL کوتاه‌تر استفاده کنی تا حداکثر «قدیمی‌بودن» داده محدود باشه. روش سوم که پیچیده‌تره ولی قوی‌تره، استفاده از event-based invalidation است: وقتی یک تغییر توی سیستم اتفاق میفته، یک event منتشر میشه و هر سرویسی که کش مرتبط داره، خودش رو آپدیت میکنه.

یک مشکل کمتر شناخته‌شده: cache stampede

این یکی از اون چیزهاییه که وقتی برای اولین بار باهاش برخورد میکنی، واقعاً غافلگیرت میکنه. فرض کن یک کلید کش با TTL پنج دقیقه‌ای منقضی بشه، و دقیقاً همون لحظه هزار درخواست هم‌زمان برسه. چون کش خالیه، هر هزار درخواست میرن سراغ منبع اصلی (مثلاً دیتابیس) تا همون مقدار رو دوباره محاسبه کنن — درحالی‌که فقط یکی از این محاسبات کافی بود. این پدیده رو cache stampede یا thundering herd میگن، و میتونه یک دیتابیس سالم رو در عرض چند ثانیه از پا دربیاره.

راه‌حل رایج برای این مشکل یک قفل موقته: اولین درخواستی که میبینه کش خالیه، یک lock میگیره و شروع میکنه به محاسبه؛ بقیه‌ی درخواست‌ها یا منتظر میمونن تا اون قفل آزاد بشه، یا موقتاً همون مقدار قدیمی (حتی اگه منقضی شده) رو برمیگردونن تا محاسبه‌ی جدید تموم بشه. به این تکنیک دوم گاهی stale-while-revalidate میگن، و توی خیلی از CDN ها و کتابخانه‌های کش هم پیاده‌سازی شده.

سیاست‌های حذف: چه چیزی رو نگه داریم، چه چیزی رو دور بریزیم

چون حافظه‌ای که کش توش نگه‌داری میشه (چه RAM چه هر چیز دیگه) محدوده، وقتی کش پر میشه باید یک چیزی رو حذف کنی تا جا برای داده‌ی جدید باز بشه. رایج‌ترین سیاست LRU (Least Recently Used) است: چیزی که مدت طولانی‌تری استفاده نشده، اول حذف میشه. یک سیاست دیگه LFU (Least Frequently Used) است که به‌جای «آخرین بار کِی استفاده شده» به «چند بار استفاده شده» نگاه میکنه. انتخاب بین این دو به رفتار واقعی ترافیکت بستگی داره — مثلاً برای یک فید خبری که محتوای پرطرفدار مدام عوض میشه، LRU معمولاً منطقی‌تره؛ برای داده‌هایی که یک زیرمجموعه‌ی ثابت همیشه پرتکرارن، LFU میتونه بهتر عمل کنه.

جمع‌بندی

نکته‌ی جالب کش اینه که هیچ‌وقت یک تصمیم یک‌باره نیست. هر لایه‌ای از سیستم —از مرورگر تا CDN تا اپلیکیشن تا دیتابیس— نسخه‌ی خودش رو از همین ایده‌ی ساده پیاده میکنه: یک بار محاسبه کن، سریع نگه دار، و مراقب باش که کِی این نسخه‌ی سریع دیگه با واقعیت هم‌خونی نداره. بخش سخت کش هیچ‌وقت «نگه‌داشتن» نبوده؛ همیشه «دونستن کِی باید فراموشش کنی» بوده.

تفاوت Layout و Template در Next.js: کی و چرا باید از template.tsx استفاده کنیم؟ نوشته شده توسط Haleh Nakisa

تفاوت Layout و Template در Next.js: کی و چرا باید از template.tsx استفاده کنیم؟

اگر با App Router در Next.js کار کرده باشید، احتمالاً بیشتر وقت‌ها سراغ layout.tsx می‌روید. اما Next.js فایل دیگری به نام template.tsx هم در اختیار ما قرار داده که در ظاهر رفتاری بسیار مشابه دارد، ولی یک فرق ساختاری با Layout دارد.

در این مقاله بررسی می‌کنیم که template چیست، چه فرقی با layout دارد و چرا باید در استفاده از آن هوشمندانه عمل کنیم.

تفاوت کلیدی: حفظ State در برابر ساخت مجدد (Remount)

اصلی‌ترین تفاوت این دو کامپوننت، نحوه رفتار آن‌ها هنگام جابه‌جایی بین صفحات (Navigation) است:

  • فایل layout.tsx: هنگام جابه‌جایی بین routeهای هم‌سطح، ناپدید نمی‌شود، State خود را حفظ می‌کند و از اول رندر (Remount) نمی‌شود.

  • فایل template.tsx: با هر بار تغییر Route، کامپوننت template به‌طور کامل Unmount شده و یک نمونه (Instance) جدید از آن ساخته می‌شود. این یعنی تمامی Stateها و Effectهای درون آن ریست می‌شوند.

نکته: هرگاه یک template.tsx در یک پوشه داشته باشید، Next.js آن را دقیقاً به عنوان فرزندِ Layout و والدِ Page رندر می‌کند: Layout ➔ Template ➔ Page

چه زمانی باید از template.tsx استفاده کنیم؟

زمانی که عدم حفظ State و اجرای مجدد کد با هر تغییر صفحه رفتار مطلوب ما باشد!

۱. انیمیشن‌های ورود و خروج (Enter/Exit Animations)

یکی از کاربردی‌ترین سناریوها، صفحاتی مثل ورود و ثبت‌نام (Sign In / Sign Up) است. اگر در این صفحات وکتورها، المان‌های گرافیکی انتزاعی یا انیمیشن‌های موشن (مثلاً با Framer Motion) دارید و می‌خواهید کاربر با رفتن از فرم Sign In به Sign Up، دوباره اجرای کامل انیمیشن‌ها و ریست شدن حالت‌ها را تجربه کند، template.tsx گزینه انتخابی شماست.

۲. لاگ‌برداری و Analytics بر اساس بازدید صفحه

اگر نیاز دارید با هربار ورود کاربر به هرکدام از صفحات فرعی، یک useEffect اجرا شده و اطلاعاتی مثل Page View ارسال شود.

۳. ریست شدن فرم‌ها یا Stateهای وابسته به Route

وقتی می‌خواهید با جابه‌جایی بین مسیرها، حالت‌های ورودی کاربر کلاً پاک شوند.

نمونه کد عملی

برای تعریف پروپ‌های کامپوننت در ری‌اکت و نکست، استفاده از type ساختار تمیزتر و یکدست‌تری ایجاد می‌کند:

// app/auth/template.tsx
import { ReactNode } from 'react';

type TemplateProps = {
  children: ReactNode;
};

export default function AuthTemplate({ children }: TemplateProps) {
  return (
    <div className="auth-container animate-fade-in">
      {/* المان گرافیکی یا وکتور دارای انیمیشن که در هر تغییر مسیر دوباره اجرا می‌شود */}
      <div className="vector-illustration" />
      <main>{children}</main>
    </div>
  );
}

چرا باید با احتیاط از آن استفاده کرد؟

استفاده بی‌مورد از template.tsx به جای layout.tsx می‌تواند روی تجربه کاربری و عملکرد برنامه تأثیر منفی بگذارد:

  • افت فریم و انیمیشن‌های اضافی: اگر المان‌های سنگینی درون Template قرار دهید، با هر جابه‌جایی کوچک فریم‌ها مجدداً ساخته می‌شوند که می‌تواند باعث Perceived Latency (حس کندی) شود.

  • از دست رفتن Scroll Position یا حالت‌های داخلی: فرم‌ها یا کامپوننت‌هایی که انتظار دارید حالتشان حفظ شود، با هر Navigation کلاً ریست خواهند شد.

خلاصه تصمیم‌گیری

  • اگر می‌خواهید هدر، فوتر، Sidebar یا Stateها ثابت بمانند ➔ از layout.tsx استفاده کنید.

  • اگر می‌خواهید با هر تغییر مسیر، انیمیشن‌ها مجدداً اجرا شده و Effectها ریست شوند ➔ از template.tsx استفاده کنید.

لود بالانسر: از یک سرور تنها تا چیزی که هیچ‌وقت down نمیشه نوشته شده توسط عرفان دهقانی

لود بالانسر: از یک سرور تنها تا چیزی که هیچ‌وقت down نمیشه

اکثر پروژه‌ها همین‌طور شروع میشن: یک سرور ساده روی یک VPS معمولی، کاربر کم، همه‌چیز روبه‌راه. مشکل معمولاً از جایی شروع میشه که یک اتفاق باعث میشه ترافیک چند برابر بشه — یک پست وایرال، یک کمپین تبلیغاتی، یا فقط رشد طبیعی کاربر — و همون یک سرور شروع میکنه به کند شدن و timeout دادن. راه‌حلی که خیلی‌ها اول امتحان میکنن اضافه‌کردن منابع به همون سرور است: رم بیشتر، CPU بیشتر. این کار یک‌مدت جواب میده، ولی زیاد طول نمیکشه که همون مشکل دوباره برگرده. نکته اینه که این مسیر یک سقف داره، و لود بالانسر دقیقاً همون‌جایی وارد میشه که این سقف رو کنار میزنه: به‌جای یک سرور بزرگ‌تر، چند سرور کوچک‌تر که ترافیک بینشون تقسیم بشه.

قبل از لود بالانسر: مقیاس عمودی

قبل از این‌که مفهوم load balancing جا بیفته، راه‌حل رایج برای مقابله با ترافیک بالا چیزی بود به اسم مقیاس عمودی یا vertical scaling: سرور موجود رو قوی‌تر میکردی. رم بیشتر، هسته‌ی پردازشی بیشتر، دیسک سریع‌تر. این روش یک مشکل بزرگ داره: یک سقف فیزیکی وجود داره. حتی اگه پول بی‌نهایت هم داشته باشی، یک سرور فیزیکی یا مجازی یک جایی به حداکثر ظرفیتش میرسه. علاوه بر این، این مدل یک نقطه‌ی شکست واحد داره؛ اگه همون یک سرور بخوابه، کل سرویس از دسترس خارج میشه.

بعد از لود بالانسر: مقیاس افقی

لود بالانسر اومد تا یک مسیر جایگزین باز کنه: مقیاس افقی یا horizontal scaling. به‌جای یک سرور قوی، چند سرور معمولی رو کنار هم میذاری و یک لایه‌ی جلویی به اسم load balancer درخواست‌های ورودی رو بینشون پخش میکنه. کاربر اصلاً نمیفهمه پشت صحنه چند سرور داره کار میکنه؛ فقط یک آدرس یا دامنه میبینه.

نتیجه‌ی این تغییر دو چیزه: اول، دیگه سقف فیزیکی وجود نداره — هر وقت ترافیک بالا رفت، یک سرور دیگه اضافه میکنی. دوم، دیگه نقطه‌ی شکست واحد نداری؛ اگه یکی از سرورها بخوابه، لود بالانسر خودش میفهمه و ترافیک رو به بقیه‌ی سرورها هدایت میکنه، بدون این‌که کاربر چیزی متوجه بشه.

لایه‌ی ۴ در مقابل لایه‌ی ۷

لود بالانسرها معمولاً روی دو سطح کار میکنن. لود بالانسر لایه‌ی ۴ (L4) روی سطح transport کار میکنه، یعنی فقط IP و پورت رو میبینه و بدون این‌که وارد محتوای درخواست بشه، ترافیک رو پخش میکنه. سریع‌تره چون کار کمتری انجام میده، ولی هوشمندی کمتری داره.

لود بالانسر لایه‌ی ۷ (L7) روی سطح application کار میکنه، یعنی میتونه محتوای درخواست HTTP رو ببینه — مسیر URL، هدرها، کوکی‌ها — و بر همون اساس تصمیم بگیره کدوم سرور جواب بده. مثلاً میتونی بگی درخواست‌هایی که مسیرشون با /api شروع میشه برن سراغ یک گروه از سرورها، و درخواست‌های /static برن سراغ یک گروه دیگه. این انعطاف هزینه داره: کمی کندتر از L4 است چون باید محتوای درخواست رو parse کنه.

الگوریتم‌های تقسیم ترافیک

خود لود بالانسر باید یک قانون داشته باشه که تصمیم بگیره کدوم درخواست بره کدوم سرور. رایج‌ترینش round robin است: درخواست‌ها به‌ترتیب و دوره‌ای بین سرورها پخش میشن، بدون توجه به این‌که هر سرور الان چقدر مشغوله. ساده‌ست ولی همیشه منصفانه نیست — اگه یک درخواست سنگین‌تر باشه و روی یک سرور طول بکشه، اون سرور همچنان درخواست بعدی رو هم میگیره.

الگوریتم least connections این مشکل رو حل میکنه: درخواست جدید میره سراغ سروری که الان کمترین تعداد کانکشن فعال رو داره. برای ترافیکی که مدت زمان پردازش درخواست‌هاش خیلی متفاوته (مثلاً بعضی درخواست‌ها سریع جواب داده میشن، بعضی طول میکشن)، این روش عادلانه‌تره.

یک روش دیگه IP hash است، جایی که بر اساس IP کاربر یک هش محاسبه میشه و همیشه همون کاربر به همون سرور فرستاده میشه. این برای موقعیت‌هایی مفیده که session کاربر روی یک سرور خاص ذخیره شده و باید همیشه همون کاربر به همون سرور برسه — البته این خودش یک ضعف داره، چون اگه توزیع IP ها نامتوازن باشه، بعضی سرورها بیشتر از بقیه بار میگیرن.

ابزارهای واقعی

اگه بخوای خودت یک لود بالانسر راه بندازی، دو تا از رایج‌ترین گزینه‌ها Nginx و HAProxy هستن. یک تنظیم ساده‌ی Nginx برای پخش ترافیک بین سه سرور backend این‌شکلیه:

upstream backend_servers {
    least_conn;
    server 10.0.0.1:3000;
    server 10.0.0.2:3000;
    server 10.0.0.3:3000;
}

server {
    listen 80;
    location / {
        proxy_pass http://backend_servers;
    }
}

اینجا least_conn مشخص میکنه از الگوریتم least connections استفاده بشه، و هر درخواستی که به این سرور برسه بین این سه backend پخش میشه. HAProxy هم همین کار رو میکنه، ولی معمولاً برای سناریوهای پیچیده‌تر و ترافیک بسیار بالا انتخاب اول خیلی از تیم‌هاست، چون از ابتدا برای همین کار طراحی شده و قابلیت‌های health check و مانیتورینگش قوی‌تره.

اگه نخوای خودت این لایه رو مدیریت کنی، سرویس‌های ابری مثل Cloudflare یک لود بالانسر مدیریت‌شده ارائه میدن که هم روی لایه‌ی DNS کار میکنه (یعنی حتی قبل از رسیدن ترافیک به سرورهات، بین چند دیتاسنتر جغرافیایی پخشش میکنه) و هم health check خودکار داره؛ اگه یک سرور جواب نده، خودش به‌صورت خودکار از چرخه خارجش میکنه تا برگرده.

چند لود بالانسر مرجع که ارزش دیدن دارن

تا اینجا از Nginx و HAProxy و Cloudflare گفتم، ولی چند تا نمونه‌ی دیگه هست که دیدنشون برای یک مهندس نرم‌افزار واقعاً جالبه، چون هرکدوم یک مسئله‌ی متفاوت رو حل کردن.

اولیش Maglev گوگله. این یک لود بالانسر لایه‌ی ۴ نرم‌افزاریه که گوگل خودش ساخته و یک مقاله‌ی مهندسی دربارش منتشر کرده. نکته‌ی جالب Maglev اینه که به‌جای این‌که از هش معمولی استفاده کنه، از یک روش به اسم consistent hashing با یک جدول lookup بزرگ استفاده میکنه. چرا این مهمه؟ چون وقتی یک backend اضافه یا حذف میشه، اکثر connection های موجود همچنان به همون backend قبلی‌شون میرسن — فقط بخش کوچیکی جابه‌جا میشه. توی یک لود بالانسر ساده با mod hash، اضافه‌کردن یا حذف یک سرور میتونه تقریباً همه‌ی mapping ها رو به‌هم بریزه، که برای سرویس‌هایی که connection طولانی دارن فاجعه‌ست.

دومی Envoy Proxy است، که اولین بار توی Lyft ساخته شد و بعد به یکی از پروژه‌های اصلی CNCF تبدیل شد. چیزی که Envoy رو خاص میکنه اینه که configuration اش رو میشه به‌صورت داینامیک و از راه دور، از طریق یک API به اسم xDS، تغییر داد، بدون این‌که پروسه ری‌استارت بشه. این دقیقاً همون چیزیه که service mesh هایی مثل Istio بهش نیاز دارن: هزاران sidecar proxy که هر کدوم کنار یک سرویس نشستن، و باید بتونن بدون downtime روت‌ها و policy هاشون رو آپدیت کنن.

سومی AWS است، که سه نوع لود بالانسر جدا ارائه میده و این خودش نشونه‌ی خوبیه که چرا تفکیک لایه‌ها مهمه: Network Load Balancer (NLB) برای لایه‌ی ۴ با تأخیر خیلی پایین، Application Load Balancer (ALB) برای لایه‌ی ۷ با قابلیت‌هایی مثل روتینگ بر اساس path یا host header، و Classic Load Balancer که نسخه‌ی قدیمی‌تر و امروز کمتر توصیه‌شده‌ست. این‌که AWS این سه رو جدا از هم نگه داشته، نشون میده هیچ لود بالانسر «همه‌کاره» ای وجود نداره؛ انتخاب درست کاملاً به نوع ترافیک بستگی داره.

چهارمی که شاید برای خیلی از دولوپرها آشناتر باشه، خود Kubernetes است. سرویس‌های Kubernetes از یک کامپوننت به اسم kube-proxy استفاده میکنن که روی هر node اجرا میشه و ترافیک بین Pod ها رو با استفاده از iptables یا IPVS پخش میکنه. جالبیش اینه که این لود بالانسینگ کاملاً decentralized اتفاق میفته — هیچ نقطه‌ی مرکزی وجود نداره که همه‌ی ترافیک از اون رد بشه، برخلاف مدل سنتی که یک لود بالانسر جلوی همه‌چیز میشینه.

اگه بخوای یک قدم عمیق‌تر بری، سراغ Linux Virtual Server (LVS) و IPVS برو — این تکنولوژی مستقیم توی kernel لینوکس پیاده‌سازی شده و پایه‌ی خیلی از لود بالانسرهای بزرگ‌مقیاس دنیا از جمله همون kube-proxy است. چیزی که این رو برای یک مهندس جالب میکنه اینه که کل تصمیم‌گیری لود بالانسینگ توی kernel space اتفاق میفته، نه توی user space، که یعنی سربار (overhead) به‌شدت پایین‌تر از یک reverse proxy معمولیه.

نکته‌ای که معمولاً فراموش میشه

چیزی که خیلی از تیم‌ها موقع راه‌اندازی اولین لود بالانسرشون فراموش میکنن، مدیریت session است. اگه اپلیکیشنت session رو توی حافظه‌ی خود سرور نگه میداره (نه توی یک دیتابیس یا Redis مشترک)، وقتی کاربر بار دوم درخواست بده و لود بالانسر اون رو به یک سرور دیگه بفرسته، session گم میشه و کاربر عملاً logout میشه. راه‌حل درست این نیست که مجبور کنی کاربر همیشه به همون سرور برسه (چون این کار انعطاف لود بالانسر رو از بین میبره)؛ راه‌حل درست اینه که session رو از حافظه‌ی محلی سرور جدا کنی و توی یک storage مشترک بین همه‌ی سرورها نگه داری. این یکی از اون نکاتیه که تا خودت باهاش برخورد نکنی، احتمالاً موقع طراحی اولیه بهش فکر نمیکنی.

Claude Opus 5 اومد؛ آنتروپیک این بار روی قیمت شرط بسته نه فقط روی هوش نوشته شده توسط عرفان دهقانی

Claude Opus 5 اومد؛ آنتروپیک این بار روی قیمت شرط بسته نه فقط روی هوش

امروز، جمعه ۲ مرداد (۲۴ ژوئیه ۲۰۲۶)، آنتروپیک رسماً Claude Opus 5 رو معرفی کرد. این چهارمین مدلیه که آنتروپیک توی کمتر از دو ماه منتشر میکنه — بعد از Mythos 5، Fable 5، و Sonnet 5 که همه توی ژوئن اومده بودن. ولی نکته‌ای که Opus 5 رو از بقیه متمایز میکنه اینه که آنتروپیک این بار داستان رو حول محور «هوش خام» نچیده؛ حول محور اقتصاد مصرف روزانه چیده.

پیام اصلی: نزدیک به Fable 5، با نصف قیمت

آنتروپیک خودش Opus 5 رو این‌طور توصیف کرده: مدلی متفکر و proactive که به هوش Fable 5 —قوی‌ترین مدل فعلی آنتروپیک— نزدیک میشه، اون‌هم با نصف هزینه. این جمله رو باید دقیق خوند: آنتروپیک ادعا نکرده Opus 5 از Fable 5 جلو زده. Fable همچنان مدل مرجع برای پروژه‌های سنگین و کارهایی که قراره روزها بدون دخالت انسان به‌صورت خودکار ادامه پیدا کنن باقی می‌مونه. Opus 5 برای یک رده‌ی متفاوت ساخته شده: کارهای روزمره‌ای که حجمشون بالاست ولی نیازی به سقف مطلق هوش ندارن.

قیمت هم دقیقاً همینو نشون میده: $5 روی هر میلیون توکن ورودی و $25 روی خروجی، یعنی دقیقاً همون قیمت Opus 4.8. آنتروپیک مدل قوی‌تری داده بدون این‌که قیمت رو تغییر بده، به‌جای این‌که مثل قبل با هر نسخه‌ی جدید قیمت رو ببره بالا.

چرا این تغییر مسیر مهمه

طبق گزارش‌های چند رسانه از جمله Fortune، این جابه‌جایی به یک نگرانی واقعی توی بازار برمیگرده: مشتری‌های سازمانی این چند ماه از هزینه‌ی بالای مدل‌های frontier، مخصوصاً Fable 5، گله داشتن. Fable روی بعضی کارها burn rate بالایی داشت، یعنی برای رسیدن به یک جواب توکن زیادی مصرف میکرد، و همین باعث میشد بودجه‌ی تخصیص‌داده‌شده زودتر از موعد تموم بشه. Opus 5 دقیقاً جواب همین مشکله.

برای همین آنتروپیک روی Opus 5 یک قابلیت effort گذاشته: تنظیمی که بهت اجازه میده بین سرعت/هزینه و عمق استدلال مدل جابه‌جا بشی. اگه کار ساده و تکراریه، effort رو پایین میاری و توکن کمتری خرج میشه؛ اگه کار پیچیده‌ست، effort رو بالا میبری. این دقیقاً همون فلسفه‌ای‌یه که این چند وقت پشت Gemini 3.6 Flash هم دیدیم: به‌جای این‌که مدل رو یک بلوک یکپارچه در نظر بگیری، هزینه رو بر اساس واقعی‌بودن نیاز تنظیم میکنی.

جایگاه Opus 5 توی خانواده‌ی Claude

Opus 5 حالا مدل پیش‌فرض روی Claude Max شده و قوی‌ترین مدل در دسترس روی Claude Pro. یعنی برای اکثر کاربرهای پولی، این مدلیه که پیش‌فرض باهاش کار میکنن، نه Fable 5. آنتروپیک گفته Opus 5 نسبت به نسل قبل با رفت‌وبرگشت کمتری کار رو تموم میکنه — کار خودش رو راستی‌آزمایی میکنه و بدون دخالت اضافه از خطا برمیگرده، که برای کسی که داره روی workflow های agentic کار میکنه (دقیقاً مثل چیزی که ما با Hermes Agent دنبالش هستیم) نکته‌ی قابل توجهیه.

دو تغییر جانبی که کمتر دیده شد

همراه با Opus 5، آنتروپیک دو تغییر دیگه هم روی پلتفرمش اعمال کرده که شاید برای دولوپرها حتی مهم‌تر از خود مدل باشه:

اول، امکان تغییر ابزارهای در دسترس مدل وسط یک مکالمه، بدون این‌که prompt cache باطل بشه. تا قبل از این، اگه توی یک کانورسیشن میخواستی لیست ابزارها رو عوض کنی، کش مکالمه از بین می‌رفت و هزینه‌ی پردازش دوباره بالا می‌رفت. حالا این محدودیت برداشته شده.

دوم، قابلیت fallback خودکار روی API. اگه یک درخواست توسط کلاسیفایرهای ایمنی روی Opus 5 یا Fable 5 پرچم بخوره، به‌جای این‌که درخواست رد بشه، میتونی تنظیم کنی که به‌صورت خودکار به بهترین مدل جایگزین در دسترس هدایت بشه. این یعنی کمتر پیش میاد یک اپلیکیشن production به‌خاطر یک ریجکشن مقطعی از کار بیفته.

زمینه‌ی رقابتی

این عرضه توی بحبوحه‌ی یک رقابت شدید بین‌المللی اتفاق افتاده. طبق گزارش BigGo Finance، چند روز قبل از Opus 5، مدل Kimi K3 معرفی شده بود، و علی‌بابا هم Qwen 3.8 Max Preview رو با ۲.۴ تریلیون پارامتر رونمایی کرده. Z.AI هم از GLM 5.5 —با بیش از یک تریلیون پارامتر و context window یک میلیون توکنی— برای عرضه در آگوست خبر داده. نکته‌ی مهم این مدل‌های چینی اینه که اغلب به‌صورت open-weight منتشر میشن، یعنی هرکسی میتونه دانلودشون کنه و شخصی‌سازی کنه؛ چیزی که آنتروپیک و OpenAI معمولاً ازش پرهیز میکنن.

جمع‌بندی: باید سوییچ کنیم؟

اگه الان روی Opus 4.8 کار میکنی، مهاجرت به Opus 5 هزینه‌ی اضافه‌ای نداره چون قیمت‌گذاری عوض نشده، و طبق ادعای آنتروپیک کیفیت بالاتر رفته. اگه پروژه‌ای داری که واقعاً به سقف مطلق هوش نیاز داره —مثل کاری که قراره روزها بدون نظارت جلو بره— همچنان باید سراغ Fable 5 بری. ولی برای اکثر کارهای روزمره، از تولید محتوا گرفته تا کدنویسی و اتوماسیون، Opus 5 دقیقاً همون رده‌ایه که آنتروپیک میخواد بشه پیش‌فرض همه: قوی به اندازه‌ی کافی، ولی نه به قیمتی که مجبورت کنه هر درخواست رو دو بار فکر کنی.