دسته بندی:

نصب سیستم Varnish Cache

Varnish Cache یک پروکسی معکوس و کش HTTP است که جلوی وب‌سرور شما (آپاچی، Nginx یا LiteSpeed) می‌نشیند، پاسخ صفحه‌ها را در حافظه رم نگه می‌دارد و درخواست‌های بعدی را بدون درگیر کردن PHP و دیتابیس پاسخ می‌دهد. نصب آن روی توزیع‌های امروزی یک خط است — dnf install varnish یا apt install varnish و سپس systemctl enable --now varnish — اما بخش سخت کار نصب نیست، بلکه تنظیم backend، مدیریت کوکی‌ها و باطل کردن کش است. مقایسه کوتاه گزینه‌های کش کنار هم در معرفی XCache، Varnish، APC و Memcached آمده است.

پیش از هر چیز: پروژه در سال ۲۰۲۶ نامش عوض شده است

اگر امروز دنبال مستندات بگردید به دو نام برمی‌خورید و این گیج‌کننده است. پروژه متن‌باز بالادستی از نسخه ۹ به Vinyl Cache تغییر نام داده و همراه آن نام همه ابزارها هم عوض شده است: varnishd به vinyld، varnishstat به vinylstat، varnishlog به vinyllog، varnishadm به vinyladm، varnishtop به vinyltop و به همین ترتیب. پوشه پیکربندی هم از /etc/varnish به /etc/vinyl-cache منتقل شده است.

در عین حال شرکت Varnish Software توزیع پایین‌دستی خودش را همچنان با نام Varnish Cache منتشر می‌کند. نکته عملی برای شما این است: بسته‌ای که امروز از مخزن توزیع‌های رایج نصب می‌کنید هنوز نام varnish و ابزارهای varnishd و varnishstat را دارد، چون این توزیع‌ها هنوز شاخه ۷ را ارائه می‌کنند (برای نمونه دبیان ۱۳ نسخه 7.7 را دارد). پس دستورهای این مقاله روی نصب معمولی شما کار می‌کنند؛ فقط اگر مستقیم از بالادست نسخه ۹ را نصب کردید، نام‌ها را با فهرست بالا جایگزین کنید.

Varnish دقیقاً کجای مسیر قرار می‌گیرد

ترتیب اجزا مهم‌ترین چیزی است که باید قبل از نصب بفهمید. مسیر یک درخواست در یک چیدمان معمول این‌طور است: در لایه اپلیکیشن هم کش شیء نقش جدایی دارد؛ نصب کش Memcached در لینوکس یکی از رایج‌ترین گزینه‌های آن است.

  • مرورگر کاربر درخواست HTTPS را به پورت 443 می‌فرستد.
  • یک لایه پایان‌دهنده TLS (مثل Nginx، HAProxy یا Hitch) گواهی را باز می‌کند و درخواست را به‌صورت HTTP ساده به Varnish می‌دهد.
  • Varnish روی پورت 6081 (یا 80) گوش می‌دهد. اگر نسخه کش‌شده صفحه را داشته باشد، همان‌جا پاسخ می‌دهد.
  • اگر نداشته باشد، درخواست را به backend یعنی وب‌سرور اصلی می‌فرستد که معمولاً روی 127.0.0.1:8080 منتقل می‌شود.

یعنی برای راه‌اندازی Varnish باید پورت شنود وب‌سرور فعلی را از 80 به 8080 تغییر دهید. این کار روی هاست اشتراکی ممکن نیست و به دسترسی روت نیاز دارد؛ اگر سایتتان روی یک VPS ایران با دسترسی کامل مدیریتی اجرا می‌شود، این تغییرات در اختیار خودتان است.

کی Varnish جواب می‌دهد و کی کش داخلی برنامه کافی است

Varnish وقتی بیشترین سود را دارد که بخش بزرگی از بازدیدکنندگان شما ناشناس باشند و همه یک HTML یکسان ببینند: خبرگزاری، وبلاگ، کاتالوگ محصول، صفحه‌های فرود. در این حالت به‌جای اجرای مکرر PHP و کوئری دیتابیس، پاسخ از رم برمی‌گردد و مصرف CPU سرور به‌شکل محسوسی پایین می‌آید.

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

HTTPS: تا نسخه ۸ نه، از نسخه ۹ بله

این بخش را با دقت بخوانید چون تقریباً همه راهنماهای موجود در وب هنوز حرف قدیمی را می‌زنند. سال‌ها نسخه متن‌باز Varnish اصلاً TLS نداشت و نمی‌توانست گواهی SSL را سرو کند؛ به همین دلیل همیشه توصیه می‌شد یک پایان‌دهنده TLS جلوی آن بگذارید. این حرف برای شاخه‌های ۷ و ۸ — یعنی همان چیزی که از مخزن توزیع نصب می‌کنید — همچنان درست است.

اما از نسخه ۹ که در اسفند ۱۴۰۴ (مارس ۲۰۲۶) منتشر شد، پشتیبانی TLS به‌صورت داخلی اضافه شده است. دو راه دارید:

  • یک فایل پیکربندی با قالب Hitch بنویسید و آن را با سوییچ -A بدهید: varnishd -a :80 -A /etc/varnish/tls.cfg. داخل آن فایل یک بلوک frontend و مسیر گواهی با pem-file تعریف می‌شود.
  • یا مستقیم یک شنونده HTTPS تعریف کنید: varnishd -a :80,http -a :443,https و گواهی را در زمان اجرا با varnishadm tls.cert.load و سپس varnishadm tls.cert.commit بارگذاری کنید.

در همین نسخه اتصال رمزنگاری‌شده به backend هم ممکن شده است؛ کافی است در تعریف backend مقدار .ssl = 1; را اضافه کنید. قبل از اینکه روی هر کدام از این‌ها حساب کنید، نسخه نصب‌شده را با varnishd -V ببینید. اگر شاخه ۷ یا ۸ است، این سوییچ‌ها وجود ندارند و همچنان به یک پایان‌دهنده بیرونی نیاز دارید.

وقتی پایان‌دهنده بیرونی دارید، هدر پروتکل را به Varnish و از آنجا به backend منتقل کنید تا برنامه بداند درخواست اصلی HTTPS بوده است؛ در Nginx با proxy_set_header X-Forwarded-Proto $scheme; و در VCL با نگه داشتن همان هدر در vcl_recv. بدون این کار وردپرس یا لاراول ممکن است کاربر را در حلقه ریدایرکت بیندازند.

نصب روی یک توزیع امروزی با systemd

دستور chkconfig که در راهنماهای قدیمی می‌بینید مربوط به CentOS 6 است؛ آن توزیع سال‌هاست پایان پشتیبانی شده و آن دستور دیگر جایی ندارد. روی هر توزیع پشتیبانی‌شده امروز (AlmaLinux و Rocky Linux 9/10، Debian 13، Ubuntu 24.04 و 26.04) مدیریت سرویس با systemd انجام می‌شود:

  • خانواده RHEL: dnf -y install varnish
  • خانواده Debian: apt update && apt -y install varnish
  • فعال‌سازی و اجرا: systemctl enable --now varnish
  • بررسی وضعیت: systemctl status varnish

دقت کنید که دبیان ۱۲ در تیر ۱۴۰۵ به پایان پشتیبانی عادی رسید، پس اگر هنوز روی آن هستید ارتقا به دبیان ۱۳ مقدم بر نصب Varnish است.

نسخه‌ای که در مخازن خود توزیع هست پایدار اما عقب‌تر از بالادست است. شاخه ۷ از اسفند ۱۴۰۴ دیگر پشتیبانی نمی‌شود و شاخه‌های زنده امروز ۹، ۸ و ۶ (نسخه LTS) هستند. برای یک سایت معمولی همان بسته توزیع کافی است، چون وصله‌های امنیتی را از کانال خود توزیع می‌گیرید؛ اما اگر به TLS داخلی، یک VMOD خاص یا قابلیت‌های تازه نیاز دارید، مخزن رسمی پروژه را اضافه کنید و نسخه را از آنجا نصب کنید.

پارامترهای اجرا در بسته‌های امروزی داخل یونیت systemd تعریف شده‌اند، نه در /etc/sysconfig/varnish که یادگار نسل CentOS بود. برای تغییر پورت شنود یا اندازه حافظه کش، فایل یونیت را مستقیم ویرایش نکنید (با به‌روزرسانی بسته بازنویسی می‌شود) و به‌جای آن از override استفاده کنید:

  • systemctl edit varnish را اجرا کنید تا یک فایل drop-in ساخته شود.
  • اول یک خط خالی ExecStart= بگذارید و بعد خط ExecStart= جدید را بنویسید. اگر این خط خالی را جا بیندازید، systemd با خطای بیش از یک ExecStart سرویس را بالا نمی‌آورد.
  • نمونه پارامترها: -a :80 -T localhost:6082 -f /etc/varnish/default.vcl -s malloc,2g
  • بعد از تغییر: systemctl daemon-reload && systemctl restart varnish

مقدار malloc را متناسب با رم آزاد سرور بگذارید، نه بیشتر؛ اگر Varnish سیستم را به swap بیندازد نتیجه برعکس می‌شود. برای سایت‌های پرترافیک که مجموعه صفحه‌های داغشان چند گیگابایت است، رم کافی معمولاً دلیل اصلی رفتن به سمت سرور اختصاصی ایران است.

پیکربندی backend و تست VCL

قلب پیکربندی فایل /etc/varnish/default.vcl است. حداقل چیزی که باید تعریف کنید مقصد backend است:

backend default { .host = "127.0.0.1"; .port = "8080"; }

قبل از هر ری‌استارت، پیکربندی را کامپایل و اعتبارسنجی کنید تا سرویس با خطا بالا نیاید: varnishd -C -f /etc/varnish/default.vcl > /dev/null. اگر خروجی خطایی نداشت، پیکربندی سالم است.

برای اعمال تغییرات VCL بدون خالی شدن کش و بدون قطعی، به‌جای restart نسخه جدید را بارگذاری و فعال کنید: varnishadm vcl.load v2 /etc/varnish/default.vcl و سپس varnishadm vcl.use v2. بسته‌های دبیان و اوبونتو یک اسکریپت آماده هم برای همین کار دارند که در مسیر /usr/share/varnish/varnishreload نصب می‌شود و روی PATH نیست، پس باید با مسیر کامل صدایش بزنید.

باطل کردن کش: TTL، PURGE و BAN

بزرگ‌ترین دردسر هر کش، محتوای کهنه است. Varnish سه سازوکار دارد:

  • انقضای زمانی: مدت ماندگاری از هدرهای Cache-Control و s-maxage پاسخ backend گرفته می‌شود یا در vcl_backend_response با set beresp.ttl تعیین می‌شود.
  • PURGE: حذف نقطه‌ای یک آدرس مشخص. باید در vcl_recv متد PURGE را بپذیرید، آن را با یک acl فقط به IP خود سرور محدود کنید و return (purge); بزنید. افزونه‌های کش وردپرس دقیقاً از همین روش برای پاک کردن یک نوشته پس از ویرایش استفاده می‌کنند.
  • BAN: باطل کردن گروهی با الگو، مثل varnishadm ban 'req.url ~ "^/category/"' برای وقتی که یک بخش کامل تغییر کرده است.

در کنار این‌ها beresp.grace را فراموش نکنید؛ با تنظیم آن، اگر backend موقتاً از دسترس خارج شود Varnish نسخه کمی کهنه را سرو می‌کند به‌جای اینکه به کاربر خطای ۵۰۳ نشان دهد.

چرا صفحه‌ها کش نمی‌شوند: کوکی‌ها

رایج‌ترین شکایت بعد از نصب این است که نرخ hit تقریباً صفر می‌ماند. دلیلش تقریباً همیشه کوکی است: منطق پیش‌فرض Varnish درخواستی که هدر Cookie دارد و پاسخی که Set-Cookie برمی‌گرداند را کش نمی‌کند. چون ابزارهای تحلیلی برای هر بازدیدکننده کوکی می‌گذارند، عملاً هیچ چیزی کش نمی‌شود.

راه‌حل، پاک کردن کوکی‌های بی‌ربط در vcl_recv و نگه داشتن فقط کوکی‌های واقعی نشست است. همچنین مسیرهای مدیریتی و تراکنشی را صراحتاً از کش خارج کنید؛ در وردپرس /wp-admin/ و /wp-login.php و در فروشگاه‌ها صفحه‌های سبد خرید و پرداخت.

پایش و اندازه‌گیری نتیجه

بدون عدد، نمی‌دانید Varnish کار می‌کند یا نه. ابزارهای همراه بسته این کار را می‌کنند:

  • varnishstat برای شمارنده‌های زنده؛ نسبت MAIN.cache_hit به مجموع hit و miss همان نرخ اصابت کش است.
  • varnishlog برای دیدن جزئیات یک درخواست و فهمیدن دلیل miss شدن آن.
  • varnishtop -i ReqURL برای یافتن پرتکرارترین آدرس‌ها.

از بیرون هم اثر کار را بسنجید: هدر Age در پاسخ باید بزرگ‌تر از صفر باشد و TTFB باید کاهش پیدا کند. برای یک اندازه‌گیری سریع بیرونی می‌توانید از ابزار رایگان بررسی سلامت سایت استفاده کنید که TTFB، زنجیره ریدایرکت و هدرهای سرور را گزارش می‌دهد.

جمع‌بندی

Varnish یک لایه کش جلوی وب‌سرور است که برای محتوای عمومی و پربازدید بازدهی چشمگیری دارد. نصبش با systemd ساده است، ولی قبل از آن سه تصمیم را بگیرید: TLS کجا پایان می‌یابد (بیرون، یا از نسخه ۹ داخل خود Varnish)، وب‌سرور روی چه پورتی منتقل می‌شود، و کش هر صفحه چطور باطل می‌شود. اگر این سه را روشن نکنید، Varnish یا چیزی کش نمی‌کند یا محتوای کهنه نشان می‌دهد.

ارسال نظر