تفاوت کلیدی: حفظ State در برابر ساخت مجدد (Remount)
اصلیترین تفاوت این دو کامپوننت، نحوه رفتار آنها هنگام جابهجایی بین صفحات (Navigation) است:
فایل layout.tsx: هنگام جابهجایی بین routeهای همسطح، ناپدید نمیشود، State خود را حفظ میکند و از اول رندر (Remount) نمیشود.
فایل template.tsx: با هر بار تغییر Route، کامپوننت template بهطور کامل Unmount شده و یک نمونه (Instance) جدید از آن ساخته میشود. این یعنی تمامی Stateها و Effectهای درون آن ریست میشوند.
نکته: هرگاه یک template.tsx در یک پوشه داشته باشید، Next.js آن را دقیقاً به عنوان فرزندِ Layout و والدِ Page رندر میکند:
زمانی که عدم حفظ 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 استفاده کنید.
/api
/static
الگوریتمهای تقسیم ترافیک
خود لود بالانسر باید یک قانون داشته باشه که تصمیم بگیره کدوم درخواست بره کدوم سرور. رایجترینش 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 مشترک بین همهی سرورها نگه داری. این یکی از اون نکاتیه که تا خودت باهاش برخورد نکنی، احتمالاً موقع طراحی اولیه بهش فکر نمیکنی.
دو تغییر جانبی که کمتر دیده شد
همراه با 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 دقیقاً همون ردهایه که آنتروپیک میخواد بشه پیشفرض همه: قوی به اندازهی کافی، ولی نه به قیمتی که مجبورت کنه هر درخواست رو دو بار فکر کنی.
نکتهای که به نظرم برای کار خودمون توی این بلاگ مهمه: اگه داری pipeline ترجمه یا پردازش متن فارسی میسازی و هزینه برات مهمه، این مدل دقیقاً همونجاییه که باید نگاهش کنی. برای کارهایی که Pro واقعی لازم نیست ولی حجم بالاست، معمولاً Flash-Lite گزینهی منطقیتریه تا اینکه بخوای برای هر درخواست پول یک مدل سنگین رو بدی.
Gemini 3.5 Flash Cyber: تخصصی و محدود
این یکی جالبترین معرفیه، چون هدفش عمومی نیست. مدلی fine-tune شده روی پایهی Flash، مخصوص پیدا کردن و patch کردن آسیبپذیریهای امنیتی کد. فعلاً فقط در اختیار دولتها و پارتنرهای منتخب گوگل قرار میگیره، نه توسعهدهندهی عادی. این حرکت رو خیلیها به رقابت گوگل با آنتروپیک در حوزهی امنیت کد مرتبط میدونن، جایی که آنتروپیک با مدلهای سری Mythos یک قدم جلوتر بوده.
چیزی که بین خطها نوشته شده
گوگل همزمان با این عرضه گفته که pretraining نسل بعدی، یعنی Gemini 4، رو شروع کرده. یعنی درحالی که همه منتظر Pro هستن، تیم گوگل عملاً یک نسل جلوتر داره کار میکنه. این الگو رو قبلاً هم دیده بودیم — وقتی یک مدل میانی دیر میشه، شرکتها بهجای نگه داشتن کاربر توی خلأ، یک لایهی سبکتر و ارزونتر رو زودتر میفرستن تا هم بازار رو نگه دارن هم فشار رقابتی رو کم کنن.
برای من بهعنوان کسی که مدام بین مدلهای مختلف API سوییچ میکنه، نکتهی عملی این خبر اینه: اگه الان روی 3.5 Flash کار میکنی، مهاجرت به 3.6 Flash احتمالاً بدون درد سره — قیمت پایینتره و بنچمارکها بهتره. ولی اگه منتظر Pro بودی که یک جهش واقعی توی reasoning بدی، هنوز باید صبر کنی، و با توجه به سابقهی این تأخیرها بعید نیست چند هفتهی دیگه هم طول بکشه.
class Post extends Model
{
public function getRouteKeyName()
{
return 'slug';
}
}
اما در لاراول ۱۳.۲۱، میتوانید از اتریبیوت #[RouteKey] استفاده کنید که بسیار تمیزتر و خواناتر است:
use Illuminate\Database\Eloquent\Attributes\RouteKey;
#[RouteKey('slug')]
class Post extends Model
{
// ...
}
با این کار، وقتی در روتهای خود از Post استفاده میکنید، لاراول به صورت خودکار بر اساس ستون slug جستجو میکند. اگر این اتریبیوت وجود نداشته باشد، لاراول به صورت پیشفرض از id استفاده میکند.
این ویژگی توسط @nimnaherath در PR #60841 اضافه شده است.
قانون اعتبارسنجی base64
بالاخره لاراول یک قانون اعتبارسنجی اختصاصی برای رشتههای base64 اضافه کرد! این ویژگی مدتها در لیست درخواستهای توسعهدهندگان بود.
بسیاری از APIها و سرویسها از base64 برای ارسال دادههای باینری استفاده میکنند. تا پیش از این، توسعهدهندگان مجبور بودند از اعتبارسنجیهای سفارشی یا پکیجهای جانبی استفاده کنند. اما حالا لاراول به صورت داخلی این قابلیت را پشتیبانی میکند.
این قانون به صورت strict کار میکند:
رشته باید به درستی decode شود
پس از decode و encode مجدد، باید دقیقاً همان رشته اولیه تولید شود
این یعنی اشتباهات Padding یا کاراکترهای اضافی به راحتی شناسایی میشوند
این ویژگی توسط @lucasmichot در PR #60808 اضافه شده است.
اتریبیوت زمینهای #[RequestAttribute]
این یکی از کاربردیترین ویژگیهای این نسخه برای کسانی است که با Middlewareهای سفارشی کار میکنند.
مشکل چیست؟
وقتی یک Middleware مقدارهایی را روی $request->attributes ذخیره میکند (مثلاً اطلاعات سازمان یا Tenant بر اساس API Key)، برای دسترسی به آنها در کنترلر باید از روشهای دستی استفاده کنید:
public function index(Request $request)
{
$org = $request->attributes->get('org');
// ...
}
راهحل جدید
با اتریبیوت #[RequestAttribute] میتوانید این مقادیر را به صورت خودکار inject کنید:
use Illuminate\Container\Attributes\RequestAttribute;
class InventoryController
{
public function index(
#[RequestAttribute('org')] Organization $org
) {
return $this->inventoryService->getForOrg($org);
}
}
این ویژگی کد شما را تمیزتر میکند و از الگوی Dependency Injection به بهترین شکل استفاده میکند. این ویژگی توسط @cosmastech در PR #60847 اضافه شده است.
فرمتهای خروجی بیشتر برای کامپوننت Image
کامپوننت Image که در لاراول ۳.۲۰ معرفی شد، در این نسخه قابلیتهای بیشتری پیدا کرده است.
چه چیزی اضافه شده؟
تا پیش از این، کامپوننت Image فقط میتوانست خروجی WebP، JPG و JPEG تولید کند. اما حالا متدهای زیر اضافه شدهاند:
toPng()
toGif()
toAvif()
toBmp()
مثال استفاده
use Illuminate\Support\Facades\Image;
Image::fromUpload($request->file('avatar'))
->cover(400, 400)
->toAvif()
->quality(80)
->store('avatars');
اصلاح باگ مهم
این نسخه همچنین باگ Image::extension() را برطرف کرده است که قبلاً نگاشت MIME type برای image/avif را نداشت و برای فایلهای AVIF پسوند .bin تولید میکرد!
این ویژگی توسط @Tresor-Kasenda در PR #60713 اضافه شده است.
Application Builder قابل شخصیسازی
این یک بهبود فنی برای توسعهدهندگان پکیج است.
چه تغییری ایجاد شده؟
قبلاً متد Application::configure() کلاس ApplicationBuilder را به صورت hardcode شده استفاده میکرد. این یعنی اگر پکیجی میخواست Application لاراول را extend کند، مجبور بود کل متد را بازنویسی کند.
حالا یک protected static property به نام $applicationBuilder اضافه شده که به subclassها اجازه میدهد کلاس Builder سفارشی خود را ارائه دهند بدون اینکه نیاز باشد کل API را تغییر دهند.
این بهبود در PR #60848 اضافه شده است.
Subsplit کامپوننت Concurrency
کامپوننت Illuminate\Concurrency حالا به صورت یک subsplit جداگانه منتشر میشود. این یعنی توسعهدهندگان میتوانند این کامپوننت را به صورت یک پکیج مستقل (read-only) دریافت کنند، مشابه سایر کامپوننتهای Illuminate.
این تغییر در PR #60836 انجام شده است.
سایر اصلاحات و بهبودها
این نسخه شامل تعداد زیادی اصلاح باگ و بهبودهای کوچک است که در ادامه بررسی میکنیم:
Lost Connection: یک پیام خطای جدید برای از دست دادن اتصال شناسایی شده که امکان reconnect خودکار را فراهم میکند (PR #60819)
Question Marks: علامت سوال در Grammar::whereColumn() به درستی escape میشود (PR #60832)
لاگ و کش
LogManager: ارسال enum به LogManager::forgetChannel() دیگر TypeError نمیدهد (PR #60801)
RedisTaggedCache: متد decrement() حالا enum keys را به درستی مدیریت میکند (PR #60821)
رشتهها و Utilityها
Str::wordWrap(): حالا رشتههای multibyte را به درستی مدیریت میکند (PR #60814)
اتریبیوتها و Dependency Injection
Contextual Attribute Caching: کش کردن اتریبیوتهای زمینهای دیگر بین propertyهای یک کلاس تداخل ایجاد نمیکند (PR #60815)
Concurrency Exception: پارامترهای falsey در exceptionهای concurrency حفظ میشوند (PR #60822)
دستورات و Pipeline
Serve Command: پارس کردن پورت host در دستور serve اصلاح شده است (PR #60828)
Pipeline Hub: یک undefined index در Pipeline\Hub::pipe() برطرف شده است (PR #60802)
Jobها و Queue
InvalidPayloadException: پیامهای این exception حالا نام job و queue را شامل میشوند که دیباگ را آسانتر میکند (PR #60799)
مقایسه با نسخههای قبلی
لاراول ۱۳.۲۱ ادامه مسیر بهبود تجربه توسعهدهنده است. اگر به نسخه ۱۳.۲۰ نگاه کنیم، میبینیم که تیم لاراول بر روی:
Developer Experience: اتریبیوتهای جدید مثل #[RouteKey] و #[RequestAttribute] کد را خواناتر و نگهداری آن را آسانتر میکنند
Validation: اضافه شدن قانون base64 نشان میدهد که لاراول به نیازهای واقعی توسعهدهندگان گوش میدهد
Image Processing: پشتیبانی از فرمتهای مدرن مثل AVIF نشاندهنده بهروز بودن لاراول با استانداردهای وب است
مزایا و معایب بهروزرسانی
مزایا:
کاهش کد boilerplate با اتریبیوتهای جدید
اعتبارسنجی دقیقتر با قانون base64
انعطافپذیری بیشتر در پردازش تصاویر
دیباگ آسانتر با پیامهای خطای بهتر
ملاحظات:
این یک نسخه مینور است و تغییرات breaking change ندارد
برای استفاده از ویژگیهای جدید، باید PHP 8.1 یا بالاتر داشته باشید (به دلیل استفاده از Attributes)
جمعبندی نهایی و نگاه شخصی
به عنوان یک توسعهدهنده لاراول، باید بگویم که نسخه ۱۳.۲۱ یکی از آن نسخههایی است که واقعاً حس میکنید تیم لاراول به دقت به نیازهای روزمره ما گوش میدهد.
اتریبیوت #[RouteKey] چیزی است که سالها منتظرش بودیم - بالاخره نیازی نیست برای یک تنظیم ساده، یک متد کامل را override کنیم. قانون base64 هم دقیقاً همان چیزی است که در پروژههای واقعی به آن نیاز داریم.
اما چیزی که من را بیشتر تحت تأثیر قرار داد، اصلاح باگ Image::extension() برای AVIF است. این نشان میدهد تیم لاراول نه تنها ویژگیهای جدید اضافه میکند، بلکه به جزئیات و باگهای کوچک هم توجه میکند.
صادقانه بگویم، اگر از لاراول ۱۳ استفاده میکنید، این بهروزرسانی را حتماً انجام دهید. هیچ ریسکی ندارد (چون breaking change نیست) و ویژگیهای جدید آن واقعاً کار شما را آسانتر میکنند.
سوالات متداول
آیا این نسخه breaking change دارد؟ خیر، لاراول ۱۳.۲۱ یک نسخه مینور است و تمام ویژگیهای جدید آن backward compatible هستند. میتوانید بدون نگرانی بهروزرسانی کنید.
آیا برای استفاده از اتریبیوتهای جدید نیاز به PHP 8 دارم؟ بله، اتریبیوتهای کلاس (Class Attributes) در PHP 8.0 معرفی شدند. برای استفاده از #[RouteKey] و #[RequestAttribute] باید حداقل PHP 8.0 داشته باشید.
آیا کامپوننت Image جایگزین Intervention Image شده است؟ خیر، کامپوننت Image لاراول در واقع یک wrapper حول Intervention Image است که API سادهتر و یکپارچهتری ارائه میدهد. شما همچنان میتوانید مستقیماً از Intervention Image هم استفاده کنید.
چگونه به نسخه ۱۳.۲۱ بهروزرسانی کنم؟ کافی است در فایل composer.json نسخه لاراول را به ^13.21 تغییر دهید و سپس دستور composer update را اجرا کنید.
وقتی ویدیویی آپلود میشود، این سیستم آن را به بلوکهای کوچکتری به نام «شِرد» (Shard) تقسیم میکند. این بلوکها سپس در هزاران سرور مختلف در دیتاسنترهای گوناگون پخش میشوند. علاوه بر این، از هر بلوک حداقل سه نسخه (Replica) در مکانهای فیزیکی متفاوت ساخته میشود. اگر یکی از سرورها آتش بگیرد یا هارد دیسک آن از کار بیفتد، دو نسخه دیگر بلافاصله جایگزین آن میشوند و کاربر هیچگاه متوجه خرابی نمیشود.
راز دوم: جادوی فشردهسازی و کدکهای ویدیویی
چگونه یوتیوب این حجم عظیم را در خود جای میدهد؟ پاسخ در «فشردهسازی» نهفته است. ویدیوی خام آپلود شده توسط شما، حجمی وحشتناک دارد. یوتیوب بلافاصله پس از دریافت، آن را با استفاده از الگوریتمهای پیچیده ریاضی فشرده میکند.
یوتیوب از چندین «کدک» (Codec) استفاده میکند:
H.264: قدیمیتر اما با سازگاری بالا برای دستگاههای قدیمی.
VP9: کدک متنباز توسعهیافته توسط گوگل که فشردهسازی بهتری نسبت به H.264 دارد.
AV1: جدیدترین و کارآمدترین کدک. AV1 میتواند حجم ویدیو را تا ۳۰ درصد بیشتر از VP9 بدون افت کیفیت محسوس کاهش دهد. این یعنی صرفهجویی عظیم در پهنای باند و فضای ذخیرهسازی.
راز سوم: چگونه همه کیفیتها را همزمان دارد؟ (Transcoding و ABR)
این بخش جذابترین قسمت ماجراست. وقتی شما ویدیویی را با کیفیت ۱۰۸۰p آپلود میکنید، یوتیوب آن را به عنوان یک فایل واحد نگه نمیدارد.
۱. ترنسکدینگ (Transcoding): مزارع سروری یوتیوب (که اغلب از سختافزارهای تخصصی رمزنگاری ویدیو استفاده میکنند)، ویدیوی اصلی را میگیرند و آن را به چندین نسخه با رزولوشنهای مختلف (۱۴۴p, 240p, 360p, 480p, 720p, 1080p, 1440p, 2160p) تبدیل میکنند.
۲. قطعهقطعه کردن (Chunking): هر کدام از این نسخههای کیفیت، به تکههای بسیار کوچکی به مدت ۲ تا ۱۰ ثانیه تقسیم میشوند.
۳. استریم تطبیقی (Adaptive Bitrate Streaming - ABR): یوتیوب از پروتکلی به نام DASH استفاده میکند. پلیر یوتیوب در مرورگر یا اپلیکیشن شما، به طور مداوم سرعت اینترنتتان را رصد میکند. اگر اینترنت شما قوی باشد، تکههای ۱۰۸۰p را درخواست میکند. اگر اینترنت ضعیف شود، بدون اینکه ویدیو متوقف (Buffer) شود، به طور نامحسوس تکههای بعدی را با کیفیت ۴۸۰p درخواست میکند. این تغییر کیفیت همان چیزی است که گاهی در حین تماشای ویدیو آن را حس میکنید.
راز چهارم: نقش حیاتی CDN در تحویل سریع
حتی با فشردهسازی و قطعهقطعه کردن، اگر سرور یوتیوب در آمریکا باشد و شما در ایران باشید، تاخیر شبکه (Latency) باعث کندی میشود. اینجا شبکه توزیع محتوا (CDN) وارد عمل میشود.
گوگل یکی از بزرگترین CDNهای جهان را با نام Google Global Cache اداره میکند. آنها سرورهایی را در داخل دیتاسنترهای شرکتهای ارائهدهنده اینترنت (ISP) در سراسر جهان قرار میدهند. وقتی شما ویدیویی را تماشا میکنید، به احتمال زیاد آن تکههای چند ثانیهای را از سروری دریافت میکنید که از نظر فیزیکی فقط چند کیلومتر با شما فاصله دارد، نه چند هزار کیلومتر.
مقایسه یوتیوب با هاستینگ ویدیوی سنتی
در یک هاستینگ ویدیوی سنتی، معمولاً یک فایل واحد (مثلاً MP4) روی یک سرور ذخیره میشود. اگر اینترنت کاربر نوسان کند، ویدیو متوقف میشود تا بافر پر شود. کاربر نمیتواند کیفیت را به صورت پویا تغییر دهد و فشار زیادی به سرور اصلی وارد میشود.
در مقابل، معماری یوتیوب بر پایه توزیع، افزونگی (Redundancy) و تطبیقپذیری بنا شده است. این سیستم نه تنها تجربه کاربری را بدون وقفه نگه میدارد، بلکه بار ترافیکی را به بهینهترین شکل ممکن بین هزاران سرور تقسیم میکند.
مزایا و چالشهای این معماری عظیم
مزایا:
پایداری فوقالعاده: خرابی یک دیتاسنتر کل سرویس را از کار نمیاندازد.
تجربه کاربری یکپارچه: تغییر خودکار کیفیت بر اساس سرعت شبکه، بدون نیاز به توقف ویدیو.
بهینهسازی منابع: استفاده از کدکهایی مثل AV1 هزینههای پهنای باند گوگل را به شدت کاهش میدهد.
چالشها:
مصرف انرژی بالا: ترنسکدینگ و نگهداری دیتاسنترها در این مقیاس، مصرف برق بسیار بالایی دارد.
هزینه محاسباتی سنگین: پردازش ویدیو برای تولید چندین کیفیت و فرمت، نیازمند سختافزارهای گرانقیمت و تخصصی است.
پیچیدگی نگهداری: مدیریت هماهنگی بین میلیونها سرور و تریلیونها فایل کوچک، یکی از سختترین چالشهای مهندسی نرمافزار در جهان است.
جمعبندی نهایی و نگاه شخصی
به عنوان یک مهندس نرمافزار، هر بار که به معماری یوتیوب فکر میکنم، حس احترام عمیقی پیدا میکنم. این سیستم «جادو» نیست؛ نتیجه دههها تحقیق، شکست، و سرمایهگذاری عظیم روی الگوریتمهای فشردهسازی و سیستمهای توزیعشده است.
باید صادقانه بگویم که بسیاری از استارتاپها سعی کردهاند رقیب یوتیوب شوند، اما شکست خوردهاند. دلیل شکست آنها تکنولوژی نبود، بلکه ناتوانی در مدیریت هزینههای سرسامآور ذخیرهسازی و پهنای باند در این مقیاس بود. یوتیوب نه تنها یک پلتفرم محتوا، بلکه یک شاهکار مهندسی داده است که مرزهای ممکن را جابهجا کرده است.
سوالات متداول
چرا گاهی اوقات کیفیت ویدیو در یوتیوب خود به خود پایین میآید؟ این یک ویژگی است، نه باگ. پروتکل ABR (استریم تطبیقی) تشخیص میدهد که سرعت اینترنت شما لحظهای کاهش یافته است. برای جلوگیری از توقف ویدیو (Buffering)، پلیر به طور خودکار تکههای بعدی ویدیو را با کیفیت پایینتر درخواست میکند تا پخش روان باقی بماند.
آیا یوتیوب ویدیوهای قدیمی و کمبازدید را پاک میکند تا فضا آزاد شود؟ خیر. هزینه ذخیرهسازی داده در مقیاس گوگل نسبت به ارزش نگهداری آن داده ناچیز است. با این حال، یوتیوب از سیستمهای «ذخیرهسازی سرد» (Cold Storage) استفاده میکند. ویدیوهای قدیمی که به ندرت تماشا میشوند، به هارد دیسکهای کندتر اما بسیار ارزانتر منتقل میشوند و فقط در صورت درخواست کاربر، با کمی تاخیر اولیه در دسترس قرار میگیرند.
تفاوت اصلی کدک AV1 با نسلهای قبلی چیست؟ AV1 توسط اتحادیهای باز (شامل گوگل، نتفلیکس، آمازون و دیگران) توسعه یافته تا از پرداخت حق امتیاز (Royalty) معاف باشد. مهمتر از آن، الگوریتم فشردهسازی آن بسیار هوشمندتر است و میتواند ویدیوهایی با کیفیت مشابه را با حجمی حدود ۳۰ درصد کمتر از VP9 یا H.265 ارائه دهد که برای پخش ویدیو در موبایل و اینترنتهای ضعیفتر انقلابی است.
مشکل فقط تاخیر نیست. اگر هزاران کاربر همزمان از یک سرور واحد درخواست کنند، آن سرور به سرعت اشباع شده و سایت کند یا حتی از دسترس خارج میشود. CDN این دو مشکل را همزمان حل میکند:
کاهش فاصله فیزیکی: محتوا از نزدیکترین نقطه جغرافیایی به کاربر تحویل داده میشود.
توزیع بار ترافیکی: درخواستها بین صدها سرور پخش میشوند و هیچ سرور واحدی تحت فشار قرار نمیگیرد.
CDN چگونه کار میکند؟
معماری CDN بر پایه چند مفهوم کلیدی ساخته شده است:
سرورهای لبه (Edge Servers)
اینها سرورهای کوچکی هستند که در نقاط مختلف جغرافیایی (به نام PoP یا Point of Presence) قرار دارند. وظیفه آنها نگهداری نسخه کش شده از محتوای سایت اصلی است.
فرآیند تحویل محتوا
وقتی کاربری برای اولین بار صفحهای را درخواست میکند، سرور لبه آن را از سرور اصلی (Origin Server) میگیرد، ذخیره میکند و به کاربر تحویل میدهد. درخواستهای بعدی همان صفحه، مستقیماً از سرور لبه پاسخ داده میشوند و دیگر نیازی به ارتباط با سرور اصلی نیست.
قوانین کش (Cache Rules)
مدیر سایت میتواند تعیین کند چه محتوایی کش شود و برای چه مدت. فایلهای استاتیک مثل تصاویر، CSS و جاوا اسکریپت معمولاً برای مدت طولانی کش میشوند، در حالی که محتوای پویا ممکن است اصلاً کش نشود.
انواع CDN بر اساس روش ذخیرهسازی
دو روش اصلی برای تحویل محتوا در CDN وجود دارد:
Pull CDN
در این روش، سرور لبه فقط زمانی محتوا را از سرور اصلی میگیرد که کاربر آن را درخواست کند. یعنی اولین کاربری که از یک منطقه جغرافیایی خاص صفحهای را باز میکند، کمی تاخیر را تجربه میکند، اما کاربران بعدی از همان منطقه سرعت بالایی خواهند داشت. این روش برای سایتهایی با محتوای متنوع و پویا مناسب است.
Push CDN
در این روش، صاحب سایت خودش محتوا را به صورت دستی یا خودکار روی سرورهای لبه آپلود میکند. این روش برای سایتهایی که محتوای ثابت و مشخصی دارند (مثل فایلهای دانلودی یا ویدیوهای از پیش تعیین شده) بهتر عمل میکند و اولین کاربر هم سرعت بالایی را تجربه میکند.
مزایا و معایب استفاده از CDN
مزایا:
افزایش چشمگیر سرعت: کاهش Latency و بارگذاری سریعتر برای کاربران در سراسر جهان.
کاهش هزینه پهنای باند: با کش کردن محتوا، ترافیک سرور اصلی به شدت کاهش مییابد.
مقیاسپذیری بالا: سایت میتواند ترافیکهای ناگهانی و سنگین را بدون مشکل مدیریت کند.
امنیت بیشتر: اکثر CDNهای مدرن دارای فایروال، محافظت در برابر حملات DDoS و گواهینامه SSL رایگان هستند.
بهبود سئو: سرعت بارگذاری یکی از فاکتورهای مهم رتبهبندی گوگل است.
معایب:
هزینه اضافی: برای سایتهای بزرگ با ترافیک بالا، هزینه CDN میتواند قابل توجه باشد.
پیچیدگی پیکربندی: تنظیمات نادرست کش میتواند باعث نمایش محتوای قدیمی به کاربران شود.
وابستگی به سرویسدهنده: در صورت قطعی سراسری CDN، سایت شما نیز از دسترس خارج میشود.
محدودیت در محتوای پویا: صفحاتی که برای هر کاربر متفاوت هستند (مثل داشبورد کاربری) نمیتوانند به راحتی کش شوند.
مقایسه CDN با میزبانی سنتی
در میزبانی سنتی، تمام کاربران دنیا به یک سرور واحد متصل میشوند. این روش برای سایتهای کوچک و محلی کاملاً مناسب است، اما برای سایتهایی با مخاطبان جهانی، با مشکلات سرعت و پایداری مواجه میشود.
CDN در واقع یک لایه اضافی بین کاربر و سرور اصلی است. این دو تکنولوژی رقیب یکدیگر نیستند، بلکه مکمل هماند. شما همچنان به یک سرور اصلی نیاز دارید، اما CDN بار آن را کاهش میدهد و تجربه کاربری را بهبود میبخشد.
ارائهدهندگان معروف CDN
در بازار امروز، چند بازیگر اصلی وجود دارند:
Cloudflare: محبوبترین گزینه برای سایتهای کوچک و متوسط. پلن رایگان آن بسیار قدرتمند است و راهاندازی آن تنها با تغییر DNS امکانپذیر است.
Akamai: یکی از قدیمیترین و بزرگترین ارائهدهندگان CDN که بیشتر برای سازمانهای بزرگ و شرکتهای Enterprise مناسب است.
Fastly: معروف به CDN نسل جدید با قابلیت Real-time Purging. بسیاری از سایتهای بزرگ خبری و استریم از آن استفاده میکنند.
AWS CloudFront: برای کسانی که از زیرساخت آمازون استفاده میکنند، یکپارچگی بینظیری دارد.
BunnyCDN: یک گزینه اقتصادی با کیفیت بالا که در سالهای اخیر بسیار محبوب شده است.
جمعبندی نهایی و نگاه شخصی
به عنوان کسی که سالها با سایتهای مختلف کار کردهام، باید صادقانه بگویم که استفاده از CDN برای هر سایتی که مخاطبان جدی دارد، دیگر یک انتخاب نیست، بلکه یک ضرورت است. خودم شخصاً بعد از فعالسازی Cloudflare روی یکی از سایتهایم، کاهش ۴۰ درصدی زمان بارگذاری را تجربه کردم و این عدد اصلاً کوچک نیست.
با این حال، یک هشدار دوستانه بدهم: CDN جادو نمیکند. اگر سایت شما به دلیل کدهای بهینهنشده، تصاویر سنگین یا کوئریهای دیتابیس کند باشد، CDN فقط بخشی از مشکل را حل میکند. اول سایت خود را بهینه کنید، سپس از CDN به عنوان یک تقویتکننده استفاده کنید.
در نهایت، اگر تازه کار هستید، پیشنهاد میکنم با پلن رایگان Cloudflare شروع کنید. هم ساده است، هم امن و هم تاثیر آن را خیلی سریع مشاهده خواهید کرد.
سوالات متداول
آیا CDN برای سایتهای کوچک هم لازم است؟ برای سایتهای کوچک با مخاطبان محلی، CDN ضروری نیست اما میتواند مزایای امنیتی و سرعتی خوبی ارائه دهد. با پلنهای رایگان مثل Cloudflare، امتحان کردن آن هیچ هزینهای ندارد.
آیا CDN باعث میشود سایت همیشه در دسترس باشد؟ CDN به شدت در برابر حملات DDoS مقاومت میکند و اگر سرور اصلی شما برای لحظاتی از دسترس خارج شود، میتواند محتوای کش شده را تحویل دهد. اما اگر سرور اصلی برای مدت طولانی قطع باشد و محتوای پویا نیاز به دیتابیس داشته باشد، سایت با مشکل مواجه میشود.
آیا CDN روی سئو تاثیر مثبت دارد؟ بله. سرعت بارگذاری یکی از فاکتورهای رسمی رتبهبندی گوگل است و CDN با کاهش Latency و بهبود Core Web Vitals، میتواند به بهبود رتبه سایت کمک کند. همچنین SSL رایگان و محافظت در برابر حملات از دیگر مزایای غیرمستقیم آن برای سئو هستند.
آیا استفاده از CDN باعث میشود کاربران IP ما را نبینند؟ بله، وقتی از CDN استفاده میکنید، کاربران با IP سرورهای لبه CDN ارتباط برقرار میکنند و IP واقعی سرور اصلی شما پنهان میشود. این موضوع یک لایه امنیتی اضافی ایجاد میکند.
سیستم DNS چیست؟
سیستم نام دامنه یا DNS، دقیقاً برای حل همین مشکل طراحی شد. به زبان ساده، DNS دفترچه تلفن اینترنت است.
همانطور که شما شماره تلفن دوستتان را حفظ نیستید و نام او را در دفترچه تلفن جستجو میکنید تا شمارهاش را پیدا کنید، کامپیوتر شما هم نام دامنه (مثل codoloper.com) را به DNS میدهد تا آدرس IP معادل آن را دریافت کند.
این سیستم یک پایگاه داده عظیم، توزیعشده و سلسلهمراتبی در سراسر جهان است. هیچ سرور مرکزی و واحدی وجود ندارد که همه اطلاعات را نگه دارد. این توزیعشدگی باعث میشود اینترنت هرگز به دلیل خرابی یک سرور متوقف نشود.
DNS چگونه کار میکند؟
وقتی آدرسی را در مرورگر وارد میکنید، یک فرآیند چندمرحلهای و بسیار سریع آغاز میشود. بیایید این مسیر را قدم به قدم بررسی کنیم.
مراحل یک جستجوی DNS
۱. بررسی حافظه نهان (Cache): قبل از هر چیز، مرورگر و سیستم عامل شما بررسی میکنند که آیا آدرس IP این دامنه را قبلاً ذخیره کردهاند یا خیر. اگر پیدا شد، کار در همان لحظه تمام میشود.
۲. ارسال درخواست به Resolver: اگر در کش محلی نبود، درخواست به یک سرور DNS Resolver (معمولاً متعلق به ارائهدهنده اینترنت شما یا ISP) ارسال میشود. این سرور وظیفه دارد کل فرآیند جستجو را برای شما انجام دهد.
۳. مراجعه به سرور ریشه (Root Server): اگر Resolver هم آدرس را نداشت، به یکی از سرورهای ریشه در جهان مراجعه میکند. سرور ریشه آدرس را نمیداند، اما میداند که برای پیدا کردن پسوند com. باید به کجا مراجعه کند.
۴. مراجعه به سرور TLD: Resolver حالا به سرور TLD (Top-Level Domain) مخصوص com. میرود. سرور TLD هم آدرس دقیق را نمیداند، اما آدرس سرور مرجعی که مسئول دامنه شماست را در اختیار Resolver قرار میدهد.
۵. مراجعه به سرور مرجع (Authoritative Server): در مرحله آخر، Resolver به سرور مرجع دامنه شما متصل میشود. این سرور دقیقاً میداند که IP معادل نام دامنه شما چیست. آن را به Resolver برمیگرداند.
۶. ذخیره و تحویل: Resolver آدرس IP را در حافظه کش خود ذخیره میکند (برای درخواستهای بعدی) و آن را به مرورگر شما تحویل میدهد.
بعد از DNS: وقتی آدرس را پیدا کردیم
بسیاری از افراد فکر میکنند با پیدا شدن IP، کار تمام است. اما DNS فقط خط شروع مسابقه است. بعد از اینکه مرورگر IP سرور مقصد را به دست آورد، اتفاقات زیر رخ میدهد:
۱. ارتباط TCP: مرورگر یک اتصال TCP با سرور مقصد برقرار میکند تا از رسیدن صحیح دادهها اطمینان حاصل کند. ۲. دستدهی امنیتی (TLS/SSL): اگر سایت از پروتکل HTTPS استفاده کند، یک رمزنگاری امن بین مرورگر و سرور برقرار میشود. ۳. ارسال درخواست HTTP: مرورگر درخواست صفحه وب را به سرور میفرستد. ۴. دریافت پاسخ: سرور فایلهای HTML، CSS و جاوا اسکریپت را برمیگرداند و مرورگر آنها را رندر میکند.
بنابراین، DNS فقط وظیفه ترجمه نام به عدد را دارد و بقیه مسیر بر عهده پروتکلهای دیگر شبکه است.
مقایسه DNS سنتی با روشهای مدرن
DNS سنتی که در پورت ۵۳ کار میکند، سالهاست استفاده میشود. اما یک مشکل بزرگ دارد: ترافیک آن رمزنگاری نشده و به صورت متن ساده (Plain Text) ارسال میشود. این موضوع باعث مشکلات امنیتی و حریم خصوصی میشود.
به همین دلیل، پروتکلهای جدیدی معرفی شدهاند:
DoT (DNS over TLS): ترافیک DNS را از طریق پروتکل امن TLS رمزنگاری میکند.
DoH (DNS over HTTPS): ترافیک DNS را درون ترافیک HTTPS پنهان میکند. این روش باعث میشود ارائهدهندگان اینترنت نتوانند به راحتی درخواستهای DNS شما را رصد یا مسدود کنند.
در حالی که DNS سنتی سرعت بالاتری دارد (به دلیل سربار کمتر)، روشهای مدرن مثل DoH امنیت و حریم خصوصی بسیار بهتری را ارائه میدهند.
مزایا و چالشهای سیستم DNS
مزایا:
سهولت استفاده: نیاز به حفظ کردن اعداد پیچیده را از بین میبرد.
مقیاسپذیری: به دلیل ساختار توزیعشده، با رشد اینترنت هیچ مشکلی پیدا نمیکند.
انعطافپذیری: میتوانید IP سرور خود را تغییر دهید بدون اینکه کاربران نیاز باشد آدرس دامنه را تغییر دهند.
چالشها:
آسیبپذیری امنیتی: حملاتی مانند DNS Spoofing یا DNS Cache Poisoning میتوانند کاربران را به سایتهای جعلی هدایت کنند.
تاخیر (Latency): اگر سرور DNS Resolver کند باشد یا کش خالی باشد، چند میلیثانیه تاخیر در بارگذاری سایت ایجاد میشود.
حملات DDoS: سرورهای ریشه و TLD همواره در معرض حملات منع سرویس هستند.
جمعبندی نهایی و نگاه شخصی
به عنوان یک توسعهدهنده، همیشه وقتی به معماری DNS فکر میکنم، شگفتزده میشوم. ما هر روز دهها بار از آن استفاده میکنیم، اما تا زمانی که خراب نشود، متوجه حضورش نمیشویم. DNS یک شاهکار مهندسی است که توانست هرج و مرج روزهای اولیه اینترنت را به یک سیستم منظم و جهانی تبدیل کند.
صادقانه بگویم، اگرچه پروتکلهای جدید مثل DoH امنیت را بالا بردهاند، اما هنوز هم پیچیدگیهای مدیریت DNS برای کسبوکارهای بزرگ چالشبرانگیز است. با این حال، درک عمیق از نحوه کار DNS، نه تنها دید شما را به شبکه باز میکند، بلکه در عیبیابی مشکلات شبکه و سرور به شدت به شما کمک خواهد کرد. امیدوارم این مقاله توانسته باشد تصویر روشنی از این سیستم حیاتی در ذهن شما ایجاد کند.
سوالات متداول
چرا باید DNS پیشفرض خود را به 8.8.8.8 یا 1.1.1.1 تغییر دهیم؟ تغییر DNS به سرورهای عمومی مثل گوگل (8.8.8.8) یا کلادفلر (1.1.1.1) معمولاً به دو دلیل انجام میشود: اول، افزایش سرعت به دلیل زیرساخت قویتر این شرکتها، و دوم، دور زدن محدودیتها و جلوگیری از ردیابی درخواستهای DNS توسط ارائهدهنده اینترنت محلی.
منظور از DNS Propagation یا انتشار DNS چیست؟ وقتی رکوردهای DNS یک دامنه را تغییر میدهید، این تغییر بلافاصله در تمام سرورهای جهان اعمال نمیشود. سرورهای مختلف در سراسر جهان بر اساس زمان TTL (Time to Live) کش خود را آپدیت میکنند. این پروسه که به آن انتشار DNS میگویند، ممکن است از چند دقیقه تا ۴۸ ساعت طول بکشد.
آیا DNSSEC همان رمزنگاری DNS است؟ خیر. DNSSEC (Domain Name System Security Extensions) برای رمزنگاری ترافیک طراحی نشده است، بلکه برای امضای دیجیتال دادههای DNS استفاده میشود. DNSSEC تضمین میکند که آدرس IP دریافتی واقعاً متعلق به همان دامنه است و در مسیر دستکاری نشده است. برای رمزنگاری خود ترافیک باید از DoH یا DoT استفاده کنید.
مباحث پیشرفته تا Foreign Function and Memory
بخش پایانی و تخصصی این مستندات، شما را با قابلیتهای سطح پایین و مدرن جاوا آشنا میکند. از Threadهای مجازی (Virtual Threads) که انقلابی در مدیریت همزمانی و مقیاسپذیری ایجاد کردهاند، تا API بازتاب (Reflection) و در نهایت Foreign Function and Memory (FFM) API. این قابلیت پیشرفته به برنامههای جاوا اجازه میدهد تا بدون پیچیدگیها و خطرات قدیمی JNI، با کدها و دادههای خارج از محیط اجرای جاوا تعامل امن و کارآمدی داشته باشند.
چرا این منبع برای توسعهدهندگان ایرانی اهمیت دارد؟
دسترسی به یک مرجع مکتوب و منسجم به زبان فارسی، سرعت یادگیری را به شکل محسوسی افزایش میدهد. وقتی مفاهیم پیچیدهای مانند مدیریت حافظه یا برنامهنویسی تابعی به زبان مادری و با در نظر گرفتن دغدغههای بومی توضیح داده شوند، درک عمیقتری از آنها حاصل میشود. این مستندات نه تنها برای دانشجویان مهندسی کامپیوتر، بلکه برای برنامهنویسانی که قصد ارتقای مهارتهای خود یا آمادگی برای بازار کار جهانی را دارند، یک مرجع قابل اعتماد محسوب میشود.
مزایا و محدودیتهای این مستندات
مزایا:
پوشش کامل و پیوسته از مفاهیم مقدماتی تا مباحث پیشرفتهای مانند FFM.
استفاده از زبان ساده، روان و دور از پیچیدگیهای غیرضروری و آکادمیک.
دسترسی آسان، آنلاین و رایگان در پلتفرم Codoloper.
بهروز بودن محتوا و انعکاس ویژگیهای نسخههای جدید زبان جاوا.
محدودیتها:
این مستندات بیشتر بر روی مفاهیم زبانی و APIهای استاندارد تمرکز دارد و برای یادگیری فریمورکهای خاص سازمانی مانند Spring Boot نیاز به منابع تکمیلی خواهید داشت.
یادگیری برنامهنویسی نیازمند تمرین عملی است و این مستندات به تنهایی جایگزین نوشتن کد و انجام پروژههای واقعی نمیشود.
مقایسه با سایر منابع آموزشی
در مقایسه با کتابهای چاپی قدیمی که اغلب ترجمههای سنگین و نامفهومی دارند، این مستندات ساختاری مدرن، دستهبندی شده و کاربردی دارد. همچنین در مقایسه با ویدیوهای آموزشی پراکنده در اینترنت، این مرجع دارای یک مسیر یادگیری خطی و منسجم است که از سردرگمی مبتدیان جلوگیری میکند. اگرچه منابع انگلیسی رسمی کاملترین مرجع ممکن هستند، اما این نسخه فارسی توانسته است تعادل بسیار خوبی میان دقت فنی و سادگی بیان ایجاد کند و به عنوان یک مکمل قدرتمند عمل نماید.
جمعبندی نهایی و نگاه شخصی
به عنوان کسی که سالها در فضای توسعه نرمافزار فعالیت کردهام، همیشه جای خالی یک مرجع فارسی منسجم، بهروز و فنی را برای زبان جاوا احساس میکردم. انتشار این مستندات در پلتفرم Codoloper یک گام بلند و ارزشمند برای جامعه برنامهنویسی کشور است. صادقانه بگویم، هیچ منبع مکتوبی به تنهایی جایگزین تجربه عملی، دیباگ کردن کدها و مطالعه مستندات اصلی در سطوح بسیار پیشرفته نمیشود. اما این مجموعه فارسی میتواند به عنوان یک پل ارتباطی قدرتمند، شما را از سطح مقدماتی به درک عمیق مفاهیم مدرن جاوا برساند و از سردرگمیهای رایج جلوگیری کند. امیدواریم این مستندات برای شما مفید باشد و مسیر یادگیریتان را هموارتر و لذتبخشتر کند.
سوالات متداول
آیا این مستندات برای افراد کاملاً مبتدی مناسب است؟ بله، سرفصلها از نصب و راهاندازی محیط توسعه و مفاهیم اولیه شیگرایی شروع میشوند و به تدریج و با شیب ملایمی به مباحث پیشرفته میرسند.
آیا مباحث نسخههای جدید جاوا نیز پوشش داده شده است؟ بله، ویژگیهای مدرن جاوا مانند Threadهای مجازی، تطبیق الگو و API جدید FFM در این مستندات به طور ویژه و با رویکردی کاربردی مورد بررسی قرار گرفتهاند.
چگونه میتوانم به این مستندات دسترسی پیدا کنم؟ این مستندات به صورت کامل در پلتفرم Codoloper منتشر شده و با یک جستوجوی ساده در اینترنت قابل دسترسی و مطالعه است. همینجا هم با کلیک روی مستندات در نویگیشن بار میتوانید به راحتی به آن دسترسی داشته باشید.
آیا این منبع برای آمادگی در مصاحبههای شغلی کافی است؟ این مستندات پایههای فنی و مفاهیم کلیدی را به خوبی پوشش میدهد و برای مرور سریع مفاهیم قبل از مصاحبه بسیار عالی است. با این حال، توصیه میشود آن را با حل مسائل الگوریتمی و پیادهسازی پروژههای واقعی تکمیل کنید.
7.0.0 تا 7.0.1
SQL injection + RCE
7.0.2
7.1 beta
SQL injection + RCE
7.1 beta2
برای چک کردن نسخه: پایین هر صفحهی admin وردپرس نسخه رو میبینی، یا از Dashboard → Updates برو.
چطور آپدیت کنی
از Dashboard → Updates برو و دکمهی Update to 7.0.2 (یا نسخهی مربوط به branch ات) رو بزن. وردپرس بهخاطر شدت این آسیبپذیری، برای سایتهای تحت تأثیر forced auto-update فعال کرده — ولی حتماً خودت هم تأیید کن که آپدیت انجام شده. auto-update همیشه کامل اجرا نمیشه.
بعد از آپدیت، یه بار به Dashboard → Updates برگرد و مطمئن شو نسخهی جدید نصب شده.
اگه الان نمیتونی آپدیت کنی
اگه یه دلیل فنی هست که آپدیت فوری ممکن نیست (مثلاً نگران compatibility با پلاگین هستی)، دو اقدام موقت میتونی انجام بدی:
در WAF یا web server ات endpoint زیر رو block کن:
/wp-json/batch/v1
/?rest_route=/batch/v1
این دسترسی به batch endpoint رو میبنده و زنجیرهی RCE رو قطع میکنه. Cloudflare این rule رو از ساعت ۱۷:۰۳ UTC روز ۱۷ جولای برای همهی کاربراش — حتی پلن رایگان — فعال کرده.
ولی این یه راهحل موقته، نه جایگزین آپدیت. با این آسیبپذیریها، ساعتها اهمیت دارن.
چرا این بار جدیتر از معموله
اکثر آسیبپذیریهای وردپرس از پلاگینها یا تمها میان — نه از هستهی خود وردپرس. این یکی متفاوته: مشکل توی core هست، یعنی هر نصب وردپرس تحت تأثیر روی هر سرور، با هر پلاگین و تنظیماتی، هدف بالقوهایه. نیازی به هیچ تعاملی از طرف کاربر نیست، نیازی به guess کردن رمز نیست — یه درخواست HTTP ناشناس کافیه.
PoC عمومی بودن به این معنیه که حملات الان فعالترن. اگه هنوز آپدیت نکردی، این رو جدی بگیر.
از تجربهی شخصی: ArvanCloud برای مدت طولانی مطمئنترین انتخاب بود، ولی اخیراً Liara هم عملکرد بهتری داشته. هر دو رو چک کن و ببین کدوم توی لحظهای که داری کار میکنی بهتر جواب میده.
۳. میرور پکیج منیجرهای اپلیکیشن
باید مطمعن بشی که هر پکیج منیجری که استفاده میکنی داره از میرور های داخل ایران استفاده میکنه.
مثال میزنم اگر از npm استفاده میکنی برای پکیج های جاوا اسکریپتی / تایپ اسکریپتی باید بری میرور ایران ان پی ام رو پیدا کنی و ست کنی. چیزایی که الان کار میکنن لیارا و رانفلر هستند اما از اونجایی که رانفلر پول میگیره فقط در صورتی استفاده کنید که خیلی سرعت براتون مهمه وگرنه میرور های دیگه کارتون راه میندازن.
از پی اچ چی دارید و از کامپوزر استفاده میکنید همینطور.
کارگو برای راست. ناگت برای سی شارپ و هر چیزی خلاصه ببینید پکیج منیجرتون چیه و میرورشو به روشی که توضیح میدن ست کنید.
اگر پکیج منیجرتون لینک دانلود و یا وریفای پکیج هارو ذخیره میکنه در جایی - مثلا npm در package-lock اینکارو میکنه - مطمعن شید که اون لینک ها هم آپدین شدن مثلا برای ان پی ام:
اینجاست که ماجرا کمی دردسرتر میشه. مثلاً آرچ PostgreSQL 17 به بعد رو توی repo رسمیش نداره. معمولاً باید میرور رسمی خود PostgreSQL رو اضافه کنی — ولی اون میرور از ایران جواب نمیده.
راهحل: به devneeds.ir مراجعه کن. میرور ایرانی از نسخههای مختلف PostgreSQL اونجا هست که از نت ملی هم پاسخگوئه.
برای اوبونتو، PostgreSQL repository رسمی معمولاً توی apt بدون مشکل کار میکنه — ولی اگه روی نت ملی isolated هستی، اینجا هم باید میرور ایرانی پیدا کنی.
۵. تست روی سیستم خودت قبل از deploy
یه قدم که خیلیها رد میکنن اینه که همهی این تنظیمات رو روی ماشین محلی خودت هم چک کنی. اگه روی ماشین خودت با همین میرورها npm install بزنی و همه چیز دانلود بشه، با اطمینان بیشتری میتونی روی سرور هم همین کار رو بکنی.
این یه شبیهسازی سادهست: مطمئن میشی که lockfile ها درست هستن و هیچ dependency ای نیست که فقط از خارج قابل دسترسه.
SSL روی سرور ایرانی
این یه بحث جداست — و صادقانه بگم، راحت نیست. Let's Encrypt از ایران مشکل داره، و خیلی از راهحلهای خودکار SSL روی شبکهی ملی کار نمیکنن. devneeds.ir مستندات مربوط به ست کردن SSL در این شرایط رو داره — بهتره مستقیم از اونجا بخونی چون وضعیت ممکنه تغییر کرده باشه و اطلاعات بهروز باشه.
شوخی نیست — دردسره. ولی مجبوریم.
خلاصهی checklist
قبل از deploy روی هر سرور ایرانی:
میرور توزیع لینوکس → devneeds.ir یا ArvanCloud
میرور Docker daemon → ArvanCloud یا Liara
میرور پکیج منیجرها (npm، pip، Composer و بقیه) → liara.ir/mirrors
lockfile ها رو پاک و rebuild کن تا لینکها آپدیت بشن
پایگاه دادههای خارج از repo سیستم عامل → devneeds.ir چک کن
روی ماشین محلی با همین میرورها تست کن قبل از deploy
اگه اینها رو انجام بدی، احتمال اینکه deploy ات بدون مشکل بره بالاست — و مهمتر از اون، اگه یه روز نت قطع شد، میتونی بدون وابستگی به اینترنت خارجی آپدیت و نگهداری کنی. این آمادگی نباید ضروری باشه، ولی متأسفانه هست.
tool use: در مقایسه با بعضی رقبا مثل Gemini، follow-through بهتری در task های چندمرحلهای داره و hallucination کمتری گزارش شده.
چی ضعیفتره
نوشتن خلاقانه: اینجاست که مدلهایی مثل Claude هنوز جلوترن. اگه میخوای متنی بنویسی که ظرافت داشته باشه یا سبک خاصی داشته باشه، MiMo معمولاً نتیجهی معمولیتری میده. برای ترجمه خوبه، ولی برای خلق محتوای خلاقانهی فارسی همون ضعفی که اکثر مدلها دارن رو داره.
context طولانی: همونطور که گفتم، روی session های بلند focus ضعیف میشه. نه بهخاطر اینکه context window کوچیکه — بلکه بهخاطر اینکه attention روی اطلاعات اول session با پیشرفت مکالمه کمرنگتر میشه.
در دسترس بودن: روی همهی platform های غربی بهراحتی host نشده. بعضی کاربرها از محدودیتهای استفاده در تیرهای Pro شکایت دارن.
نسخههای اولیه: V1 و V2 اولیه مشکلاتی داشتن که V2.5 خیلیشون رو بهتر کرده. اگه چند ماه پیش امتحان کردی و نتیجه خوبی نگرفتی، ارزش داره دوباره V2.5 رو تست کنی.
کدوم نسخه برای چی
V2.5 non-Pro: برای اکثر کاربردهای روزانه — کدنویسی، ترجمه، تحلیل، task های متوسط. بهترین نسبت هزینه به کیفیت الان.
V2-Flash: وقتی سرعت مهمترین چیزه و میتونی کمی کیفیت بدی. برای agentic loop هایی که باید خیلی سریع iterate کنن.
V2-Pro / V2.5-Pro: برای task های خیلی سنگین با نیاز به reasoning عمیق. ولی باید بسنجی که آیا هزینهی اضافهاش نسبت به non-Pro توجیه داره — بعضی تستها میگن در کاربردهای روزانه فرق محسوسی نیست.
جمعبندی
MiMo یه رقیب جدی توی فضای open-weight است — نه بهخاطر اینکه در همه چیز بهترینه، بلکه چون نسبت هزینه به کیفیتش جذابه و توی task های خاص (کدنویسی، ترجمه، agentic کوتاهمدت) نتایج واقعاً خوبی میده.
اگه با فارسی کار میکنی یا دنبال یه مدل ارزون برای workflow های برنامهنویسی هستی، V2.5 non-Pro ارزش امتحان کردن داره. فقط انتظار نداشته باش که روی task های خلاقانهی پیچیده یا session های خیلی بلند همون نتیجه رو بده.
برای output هم:
$image->toWebp();
$image->toJpg()->quality(80);
$image->optimize(); // WebP با quality 70
$image->optimize('jpg', 85);
چون immutable هست، ساختن چند variant از یه عکس تمیزه:
دو driver داره — GD و Imagick — و میتونی per-image هم انتخاب کنی:
$image->usingGd();
$image->usingImagick();
یه نکتهی مهم: خود intervention/image بهعنوان suggested dependency اضافه شده، نه required. یعنی باید خودت نصبش کنی:
composer require intervention/image
ویژگی WithoutMiddleware
یه attribute جدید اضافه شده که counterpart ویژگی #[Middleware] هست. تا الان میتونستی روی کل controller یه middleware بذاری و برای بعضی method ها استثنا بدی. حالا این کار رو میتونی با attribute بکنی:
#[Middleware(EnsureTokenIsValid::class)]
class UserController
{
public function index()
{
// middleware اینجا اعمال میشه
}
#[WithoutMiddleware(EnsureTokenIsValid::class)]
public function profile()
{
// اینجا اعمال نمیشه
}
}
یه نکتهی ظریف: از ReflectionAttribute::IS_INSTANCEOF استفاده میکنه، یعنی subclass های اون middleware هم automatically exclude میشن.
پیشوند جداگانه برای Session در Redis
اگه هم SESSION_DRIVER و هم CACHE_STORE هر دو به Redis اشاره میکنن، تا الان session ها از همون prefix که برای cache تنظیم کردی استفاده میکردن. این debug کردن Redis keyspace رو مشکل میکرد.
حالا میتونی توی config/session.php یه prefix جداگانه بذاری:
cache store قبل از اعمال session prefix کلون میشه، پس این تغییر روی cache key ها تاثیر نمیذاره.
incrementEachQuietly و decrementEachQuietly
Eloquent قبلاً incrementQuietly() و decrementQuietly() داشت که یه column رو بدون trigger کردن model event تغییر میدادن. این نسخه نسخهی multi-column اینا رو اضافه کرده:
وقتی داری یه batch operation انجام میدی و نمیخوای event هایی مثل saved یا updated fire بشن، این دقیقاً چیزیه که میخوای.
Enum بهعنوان کلید WithoutOverlapping
WithoutOverlapping middleware برای queue jobs الان مستقیم enum قبول میکنه:
public function middleware(): array
{
return [new WithoutOverlapping($this->category)];
}
قبلاً باید enum رو به string تبدیل میکردی. این تغییر backward compatible هست.
بقیه چیزهای کوچیک ولی مفید
چند چیز دیگه که کمتر headline میگیرن ولی در عمل کاربرد دارن:
make:migration حالا timestamp prefix هایی میسازه که collision-free و مرتب هستن — مشکل قدیمی که دو migration همزمان ساختهشده اسم تکراری میگرفتن.
#[SensitiveParameter] به parameter هایی که secret حمل میکنن اضافه شده، یعنی password ها و token ها دیگه توی stack trace نمایش داده نمیشن.
Storage::assertEmpty() اضافه شده که توی test ها مفیده.
Str::containsAll() دیگه برای آرایهی خالی true برنمیگردونه — یه bug قدیمی که رفتار غیرمنطقی داشت.
Number::forHumans() دیگه برای عددهای خیلی کوچیک منفی، -0 برنمیگردونه.
upgrade کردن
تغییر breaking ای وجود نداره. اگه میخوای از Image facade استفاده کنی، فقط intervention/image رو نصب کن. بقیهی تغییرات opt-in هستن یا bug fix.
AI توی debugging هم کمک میکنه — ولی فقط اگه بدونی چه اطلاعاتی بهش بدی. اگه ندونی دنبال چی میگردی، error log رو copy میکنی توی chat و امیدوار میشی مدل جواب بده. گاهی میده. ولی این یه روش قابل اعتماد نیست.
یه نقطهی ظریف دربارهی سرعت
یه غلطفهمی وجود داره که «اصول یاد گرفتن» یعنی زمان زیادی میبره و در آخر هم مستقیماً استفاده نمیشه. ولی اصول قراره چیزی باشن که دیگه بهشون فکر نمیکنی — اتوماتیک تبدیل میشن به شهود.
وقتی یه توسعهدهنده باتجربه یه codebase جدید رو میبینه، میفهمه مشکل architecture کجاست — نه بهخاطر اینکه یه checklist داره، بلکه چون دیدهها و تجربههاش به یه حس تبدیل شدن. این همون چیزیه که با AI codingهای سطحی از دست میره.
هرچقدر اصول قویتر باشن، از AI هم بهتر استفاده میکنی. چون prompt های بهتری مینویسی، خروجی رو بهتر ارزیابی میکنی، و زودتر میفهمی کِی باید از مدل کمک بخوای و کِی باید خودت فکر کنی.
اصول چه چیزی نیستن
اینجا یه تفاوت مهم هست که باید مشخص بشه: یاد گرفتن اصول با حفظ کردن syntax یه زبان یا دونستن تمام APIهای یه فریمورک فرق داره. دومی رو الان واقعاً AI بهتر از تو میدونه. اگه نمیدونی Array.reduce چطور کار میکنه، بپرس. اگه نمیدونی کدوم CSS property برای این استفاده میشه، بپرس.
ولی اینکه چرا state management پیچیده میشه، چرا database query ات کند شده، چرا این race condition فقط توی production اتفاق میافته — اینا رو باید بفهمی. اینا قراره بخشی از طرز فکر تو بشن، نه اینکه هر بار از صفر از مدل بپرسی.
جواب سوال اول
پس چرا باید اصول یاد بگیری؟
نه برای اینکه AI کدت رو بنویسه و تو باید بدونی که نوشته. نه برای اینکه شاید یه روز AI نباشه — هست و بیشتر هم میشه.
بلکه چون کار یه توسعهدهنده همیشه بیشتر از نوشتن کد بوده. طراحی سیستم، تصمیمگیری، تشخیص مشکل، ارزیابی trade-off ها — اینا هنوز جایی هستن که ابزار جایگزین فکر نمیشه. AI سرعت رو بالا میبره، ولی اگه نقطهی شروع ضعیف باشه، فقط سریعتر به جای اشتباه میرسی.
اصول یاد میگیری تا بتونی از AI درست استفاده کنی — نه بهرغم اینکه AI هست.
یه workflow که در عمل کار میکنه
یه الگوی ساده که در عمل جواب داده:
برای کارهای کوچیک (یه function، یه refactor کوچیک، یه bug): مستقیم از chat استفاده کن. context لازم نیست زیاد باشه، نتیجه سریعه، و راحت review میشه.
برای کارهای متوسط (یه feature جدید، یه سرویس): یه prompt با جزئیات کافی بنویس — معماری، محدودیتها، output مورد انتظار. بعد خروجی رو بگیر و review کن. اگه چیزی جا افتاده یا جور نیست، iteration کن.
برای کارهای بزرگ و پیچیده: اینجاست که agent ها معنی پیدا میکنن. یه agent مثل Hermes یا Claude Code میتونه یه task چندمرحلهای رو مدیریت کنه — ولی فقط اگه بهش context کافی بدی، skill های مرتبط بهش دادی، و حواست به کارش باشه. «بذار agent همه چیز رو بسازه و من بعداً نگاه کنم» یه workflow نیست — یه روش برای ساختن چیزیه که نمیفهمیش.
دربارهی دسترسی و مرزها
یه چیزی که از تجربهی مستقیم یاد گرفتم: به agent هایی که به filesystem دسترسی دارن، sudo ندید. نه بهخاطر اینکه agent بد نیت داره — بلکه چون وقتی یه task پیچیده انجام میده و اشتباه میکنه، sudo یعنی اشتباهش جبرانناپذیره. یه دیتابیس محلی پاک میشه. یه پوشه حذف میشه. این چیزیه که «بعید نیست» — اتفاق میافته.
محدود کردن دسترسی یه لایهی safety net هست، نه بیاعتمادی به ابزار.
دربارهی مدلها و هزینه
اکثر کارهای روزانهی یه توسعهدهندهی معمولی به بهترین و گرانترین مدل نیاز ندارن. توضیح یه مفهوم، بررسی یه کد، نوشتن یه test، refactor کوچیک — اینا رو مدلهای ارزونتر هم خوب انجام میدن.
جاهایی که مدل قویتر فرق میکنه: وقتی task پیچیدهست و نیاز به چندین مرحله reasoning داره، وقتی context بزرگه، یا وقتی agent باید خودش تصمیم بگیره چه مرحلهای بعدی باشه. برای بقیه، مدل ارزانتر کافیه — و ترکیب ابزارهایی مثل 9Router با agentها میتونه هزینه رو به حداقل برسونه.
یه جمله خلاصه
workflow سالم با AI یعنی تو هنوز توسعهدهندهای — ابزار هم بیشتر شده. یعنی هنوز میفهمی چی میسازی، هنوز review میکنی، و هنوز تصمیم میگیری. AI سرعت رو بالا میبره — ولی اگه فقط سرعت بالا بره بدون اینکه بفهمی داری کجا میری، سریعتر گم میشی.