طرح‌چه

کش (cache) | Nginx from scratch

۲۱ تیر ۱۴۰۴

کش (cache) | Nginx from scratch
کش کردن باعث می‌شود نیازی به پردازش مجدد برخی درخواست‌ها نباشد. در این حالت، پاسخ ذخیره‌شده در کش مستقیماً به کاربر ارائه می‌شود.

کش (cache) به معنی نگه‌داشتن نتایج درخواست‌ها (مثل فایل HTML، داده‌های JSON، تصاویر) برای مدت‌زمان مشخصی است؛ به‌طوری‌که اگر همان درخواست در آینده تکرار شود، دیگر نیازی به پردازش مجدد آن نباشد.

proxy_cache_path /var/cache/nginx levels=1:2
                                  keys_zone=my_cache:50m
                                  max_size=2g
                                  inactive=60m
                                  use_temp_path=off;
                                  

server {
    listen 80 default_server;
    
    proxy_cache_key $scheme$request_method$host$request_uri;

    location / {
        add_header X-Cache-Status $upstream_cache_status;
        proxy_pass http://backend;

        proxy_cache my_cache;
        proxy_cache_valid 10m;
    }
}

برای کش کردن درخواست ها ابتدا با استفاده از دستور proxy_cache_path یک مسیر برای ذخیره کش ها روی دیسک مشخص میکنیم. در این دستور پارامتر اول مسیر ذخیره شدن کش ها رو مشخص میکنه. پارامتر levels به صورت 1:2 مقدار دهی شده یعنی در مسیر ‍/var/cache/nginx/ برای ذخیره هر فایل کش ابتدا یک پوشه با یک کاراکتر میسازد و سپس درون آن پوشه دیگری با دو کاراکتر میسازد و در نهایت فایل کش را در آن ذخیره میکند.

قسمت keys_zone=my_cache:50m اسم فضای کش را my_cache میگذارد و 50 مگابایت برای ذخیره سازی متادیتای کش در نظر میگیرد. متادیتای کش شامل اطلاعاتی از قبیل کلیدهای کش, مسیر فایل ها و وضعیت کش بودن یا نبودن میشود.

قسمت max_size=2g مشخص میکنه که حداکثر سایز کش روی دیسک برابر با دو گیگابایت است.

قسمت inactive=60m مشخص میکنه اگه حداکثر تا 60 دقیقه هیچ درخواستی برای استفاده از کش نیاد, اون کش پاک میشه.

به‌طور پیش‌فرض، NGINX وقتی پاسخی از سرویس کال شده با proxy_pass می‌رسه، اون رو اول در مسیری موقت می‌نویسه (معمولاً /var/lib/nginx/tmp) و بعد به مسیر کش انتقال میده. در اینجا use_temp_path=off  مشخص کرده که این گزینه off یا غیر فعال بشه که باعث می‌شه مستقیم در مسیر کش نوشته بشه. با اینکار میزان درخواست ها روی دیسک کمتر میشه و باعث بهبود عملکرد میشه.

کش ها به صورت کلید و مقدار ذخیره میشوند. استفاده از ‍proxy_cache_key طریقه ساخته شدن کلید کش ها را مشخص میکنیم و در نهایت با استفاده از proxy_cache شروع به کش کردن در مسیری که مشخص کردیم میکنیم. دستور proxy_cache_valid هم طول عمر کش رو مشخص میکنه.

در nginx هرگاه یک درخواست دریافت شود ابتدا کلید مرتبط با درخواست مطابق با چیزی که در proxy_cache_key تعریف کردیم ساخته میشود و سپس چک میشود که آیا کش مرتبط با اون وجود دارد یا نه. اگر کش وجود نداشت درخواست به سرویس بکند زده میشود و سپس نتیجه حاصل کش میشود تا در درخواست های بعدی مورد استفاده قرار گیرد. اما اگر کش وجود داشته باشد به عنوان پاسخ به کاربر داده میشود و درخواست جدیدی به سرویس بکند زده نمیشود.

در سمت کلاینت توسط هدر X-Cache-Status میتوانیم تشخیص دهیم که آیا پاسخی که دریافت کردیم از کش آمده است یا نه. اگر مقدار آن برابر با hit باشد یعنی پاسخ از کش آمده است.

بعضی مواقع شرایطی وجود دارد که نمیخواهیم درخواست ها کش شوند. در این مواقع میتوان به صورت زیر از دستور های proxy_no_cache و proxy_cache_bypass استفاده کنیم:

proxy_cache_path /var/cache/nginx levels=1:2
                                  keys_zone=my_cache:50m
                                  max_size=2g
                                  inactive=60m
                                  use_temp_path=off;

set $skip_cache 0;

if ($request_uri ~* "/dashboard") {
    set $skip_cache 1;
}

server {
    listen 80 default_server;
    
    proxy_cache_key $scheme$request_method$host$request_uri;

    location / {
        add_header X-Cache-Status $upstream_cache_status;
        proxy_pass http://backend;

        proxy_cache my_cache;
        proxy_cache_valid 10m;

        proxy_cache_bypass $skip_cache;
        proxy_no_cache $skip_cache;	
    }
}

در مثال بالا با استفاده از دستور set یک متغیر با نام $skip_cache ایجاد کردیم. (نام متغیر ها در nginx با علامت دلار ‍$ شروع میشود) و مقدار اولیه این متغیر را برابر با 0 قرار دادیم. سپس یک دستور ‍if نوشتیم که چک میکند اگر در درخواست قسمتی با نام ‍/dashboard یافت شود مقدار متغیر را برابر با 1 قرار میدهد.

  • دستور ‍proxy_cache_bypass مشخص میکند چه زمانی رسپانس (response) یا پاسخ به یک درخواست نباید از کش خوانده شود. اگر مقداری را به این دستور پاس دهیم که غیر ‍0 یا غیر متن خالی (متن با طول صفر) باشد, این دستور فعال میشود و پاسخ به درخواست از کش خوانده نمی شود.

  • دستور proxy_no_cache مشخص میکند چه زمانی رسپانس (response) یا پاسخ به یک درخواست نباید درون کش ذخیره شود. اگر مقداری را به این دستور پاس دهیم که غیر 0 یا غیر متن خالی (متن با طول صفر) باشد, این دستور فعال میشود و پاسخ به درخواست درون کش ذخیره نمی شود.


قسمت قبل: مدیریت ترافیک | Nginx from scratch

قسمت بعد: ریدایرکت (redirect) و ریرایت (rewrite) | Nginx from scratch

دیدگاه ها