כללי VCL מותאמים אישית ל-Varnish: הגברת מהירות האתר והפחתת עומס השרת

תצורת Varnish סטנדרטית לרוב לא עומדת במשימה: היא שומרת במטמון תוכן מיותר או מפספסת עמודים חשובים, מה שמוביל לשיעור פגיעות נמוך ועומס יתר על השרת. אנחנו מפתחים כללי VCL מותאמים אישית שמכוונים את המטמון בדיוק לעסק שלך, מנרמלים בקשות ומבטיחים ביצועים יציבים גם בעומסי שיא. הצוות שלנו מוסר את הפרויקט במפתח מלא—מבדיקת מצב ועד הטמעה ותמיכה שוטפת.

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

אלה רק חלק מהסוגים הטכניים של אתרים שאנו עובדים איתם, ולכל אחד מהם יכולים להיות מאפיינים ופונקציונליות ספציפיים משלו, וכן ניתן להתאים אותם לצרכים ולמטרות הספציפיים של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
כללי VCL מותאמים אישית ל-Varnish: הגברת מהירות האתר והפחתת עומס השרת
מורכב
~2-3 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1359
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113
  • פיתוח אתר עבור SBH Partners
    פיתוח אתר עבור SBH Partners
    1201
  • פיתוח אתר עבור Red Pear
    פיתוח אתר עבור Red Pear
    619

כללי VCL מותאמים אישית ל-Varnish: הגדלת אחוז הפגיעות במטמון והפחתת עומס

תצורת Varnish ברירת מחדל עובדת לעיתים קרובות בצורה לא יעילה: היא שומרת במטמון הכל או נכשלת בשמירת דפים קריטיים, מתעלמת מכותרות הרשאה, ונשברת במקרי קצה עם עוגיות. התוצאה היא אחוז פגיעות נמוך (30–40%) ועומס יתר על השרת האחורי. אם אתם נתקלים בבעיה זו, בקשו ביקורת על תצורת ה-Varnish הנוכחית שלכם. עם ניסיון של למעלה מ-7 שנים ו-50+ פרויקטים המתמקדים באופטימיזציה, אנו מבטיחים הגדלת אחוז הפגיעות ל-90%+ תוך שמירה על כל הלוגיקה העסקית. אחד הלקוחות שלנו—חנות מסחר אלקטרוני עם 500,000 בקשות בשעה—ראה את אחוז הפגיעות שלו קופץ מ-35% ל-93% תוך יומיים בלבד לאחר יישום כללים מותאמים אישית. זה הפחית את העומס על השרת האחורי פי 8 וחסך עד 70% בעלויות השרת.

Varnish Cache משתמש ב-VCL כדי לתאר מדיניות שמירה במטמון.

כיצד כללי VCL מותאמים אישית מאיצים את האתר שלכם?

כללי VCL מותאמים אישית נותנים מענה לצרכים ספציפיים: בקרת מטמון מותנית, נורמליזציה של בקשות, עקיפת CDN למסלולים מסוימים, ניתוב לשרתים אחוריים שונים, ומצב חסד (grace mode) כאשר המקור אינו זמין. בואו נצלול להיבטים המרכזיים.

נורמליזציה של בקשות

ללא נורמליזציה, אותו משאב נשמר תחת עשרות מפתחות: /?utm_source=google, /?utm_source=facebook—אלה ערכי מטמון נפרדים למרות שהתוכן זהה. סטטיסטיקות מראות שכתובות URL עם תגי utm מבזבזות עד 30% משטח המטמון. נורמליזציה פותרת זאת.

vcl 4.1;
import std;
import directors;

backend default {
    .host = "127.0.0.1";
    .port = "8080";
    .connect_timeout = 2s;
    .first_byte_timeout = 60s;
    .between_bytes_timeout = 10s;
    .probe = {
        .url = "/healthz";
        .timeout = 1s;
        .interval = 5s;
        .window = 5;
        .threshold = 3;
    }
}

backend api {
    .host = "127.0.0.1";
    .port = "8081";
    .connect_timeout = 1s;
    .first_byte_timeout = 30s;
}

sub vcl_recv {
    # Удаляем маркетинговые параметры
    if (req.url ~ "(\\?|&)(utm_source|utm_medium|utm_campaign|utm_term|utm_content|fbclid|gclid|yclid|_ga|mc_eid)=") {
        set req.url = regsuball(req.url, "&(utm_source|utm_medium|utm_campaign|utm_term|utm_content|fbclid|gclid|yclid|_ga|mc_eid)=[^&]*", "");
        set req.url = regsuball(req.url, "\\?(utm_source|utm_medium|utm_campaign|utm_term|utm_content|fbclid|gclid|yclid|_ga|mc_eid)=[^&]*&", "?");
        set req.url = regsub(req.url, "\\?$", "");
    }

    # Нормализуем Accept-Encoding
    if (req.http.Accept-Encoding) {
        if (req.url ~ "\\.(jpg|jpeg|png|gif|webp|gz|tgz|bz2|tbz|mp3|ogg|swf|flv|mp4|woff2?)$") {
            unset req.http.Accept-Encoding;
        } else if (req.http.Accept-Encoding ~ "br") {
            set req.http.Accept-Encoding = "br";
        } else if (req.http.Accept-Encoding ~ "gzip") {
            set req.http.Accept-Encoding = "gzip";
        } else {
            unset req.http.Accept-Encoding;
        }
    }

    # Нормализуем cookies
    if (req.http.Cookie) {
        set req.http.Cookie = ";" + req.http.Cookie;
        set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
        set req.http.Cookie = regsuball(req.http.Cookie, ";(session|auth_token|XSRF-TOKEN)=", "; \\1=");
        set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
        set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
        if (req.http.Cookie == "") {
            unset req.http.Cookie;
        }
    }

    # Определение типа устройства для адаптивного кэша
    if (req.http.User-Agent ~ "(?i)mobile|android|iphone|ipod|blackberry|opera mini|iemobile") {
        set req.http.X-Device-Type = "mobile";
    } else {
        set req.http.X-Device-Type = "desktop";
    }

    # Маршрутизация по типу контента
    if (req.url ~ "^/api/") {
        return(pass);
    }
    if (req.http.Authorization || req.http.Cookie ~ "auth_token=") {
        return(pass);
    }
    if (req.method != "GET" && req.method != "HEAD") {
        return(pass);
    }
    if (req.url ~ "\\.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot|webp|avif)(\\?.*)?$") {
        unset req.http.Cookie;
        return(hash);
    }
    return(hash);
}

sub vcl_hash {
    hash_data(req.url);
    if (req.http.host) {
        hash_data(req.http.host);
    }
    hash_data(req.http.X-Device-Type);
    return(lookup);
}

מהו מצב חסד וכיצד הוא עובד?

מצב חסד מאפשר לשרת מטמון מיושן בזמן שהשרת האחורי עמוס או לא זמין זמנית. זה קריטי לאתרים עם תעבורה גבוהה.

sub vcl_backend_response {
    set beresp.grace = 24h;
    if (beresp.status >= 500) {
        set beresp.ttl = 0s;
        set beresp.grace = 60s;
        return(deliver);
    }
    # Кастомный TTL по типу контента
    if (bereq.url ~ "^/news/") {
        set beresp.ttl = 10m;
    } else if (bereq.url ~ "^/static/") {
        set beresp.ttl = 30d;
        unset beresp.http.Set-Cookie;
    } else if (bereq.url ~ "^/product/") {
        set beresp.ttl = 1h;
    } else {
        set beresp.ttl = 5m;
    }
    if (beresp.http.Cache-Control ~ "no-store|private") {
        set beresp.uncacheable = true;
        return(deliver);
    }
}

sub vcl_hit {
    if (obj.ttl >= 0s) {
        return(deliver);
    }
    if (obj.ttl + obj.grace > 0s) {
        return(deliver);
    }
    return(restart);
}

כיצד ליישם פסילת מטמון באמצעות VCL?

ניקוי מבוסס תגים (באמצעות xkey) הוא הגישה הנכונה עבור CMS עם תלותיות בין אובייקטים.

import xkey;

acl purge_acl {
    "127.0.0.1";
}

sub vcl_recv {
    if (req.method == "PURGE") {
        if (!client.ip ~ purge_acl) {
            return(synth(405, "Not allowed"));
        }
        return(purge);
    }
    if (req.method == "XKEY-PURGE") {
        if (!client.ip ~ purge_acl) {
            return(synth(405, "Not allowed"));
        }
        set req.http.n-gone = xkey.softpurge(req.http.xkey-purge);
        return(synth(200, "Purged " + req.http.n-gone + " objects"));
    }
}

sub vcl_backend_response {
    if (beresp.http.Surrogate-Key) {
        set beresp.http.xkey = beresp.http.Surrogate-Key;
    }
}

השוואה בין שיטות פסילה:

שיטה מהירות רמת פירוט מתאים ביותר ל
PURGE לפי URL מיידי גבוהה (URL בודד) עדכונים בודדים
PURGE לפי תגים (xkey) מיידי בינונית (כל האובייקטים עם התג) עדכונים בכמות גדולה (קטגוריות)
ניקוי מלא של המטמון דורש חימום נמוכה (כל המטמון) שינויים גלובליים נדירים

ניפוי באגים וניטור

sub vcl_deliver {
    if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT";
        set resp.http.X-Cache-Hits = obj.hits;
    } else {
        set resp.http.X-Cache = "MISS";
    }
    set resp.http.X-Served-By = server.hostname;
    unset resp.http.X-Powered-By;
    unset resp.http.Server;
    unset resp.http.X-Varnish;
    unset resp.http.Via;
}
פקודות לניפוי באגים ב-VCL

ניטור באמצעות vcl 4.1; import std; import directors; backend default { .host = "127.0.0.1"; .port = "8080"; .connect_timeout = 2s; .first_byte_timeout = 60s; .between_bytes_timeout = 10s; .probe = { .url = "/healthz"; .timeout = 1s; .interval = 5s; .window = 5; .threshold = 3; } } backend api { .host = "127.0.0.1"; .port = "8081"; .connect_timeout = 1s; .first_byte_timeout = 30s; } sub vcl_recv { # Удаляем маркетинговые параметры if (req.url ~ "(\\?|&)(utm_source|utm_medium|utm_campaign|utm_term|utm_content|fbclid|gclid|yclid|_ga|mc_eid)=") { set req.url = regsuball(req.url, "&(utm_source|utm_medium|utm_campaign|utm_term|utm_content|fbclid|gclid|yclid|_ga|mc_eid)=[^&]*", ""); set req.url = regsuball(req.url, "\\?(utm_source|utm_medium|utm_campaign|utm_term|utm_content|fbclid|gclid|yclid|_ga|mc_eid)=[^&]*&", "?"); set req.url = regsub(req.url, "\\?$", ""); } # Нормализуем Accept-Encoding if (req.http.Accept-Encoding) { if (req.url ~ "\\.(jpg|jpeg|png|gif|webp|gz|tgz|bz2|tbz|mp3|ogg|swf|flv|mp4|woff2?)$") { unset req.http.Accept-Encoding; } else if (req.http.Accept-Encoding ~ "br") { set req.http.Accept-Encoding = "br"; } else if (req.http.Accept-Encoding ~ "gzip") { set req.http.Accept-Encoding = "gzip"; } else { unset req.http.Accept-Encoding; } } # Нормализуем cookies if (req.http.Cookie) { set req.http.Cookie = ";" + req.http.Cookie; set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";"); set req.http.Cookie = regsuball(req.http.Cookie, ";(session|auth_token|XSRF-TOKEN)=", "; \\1="); set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", ""); set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", ""); if (req.http.Cookie == "") { unset req.http.Cookie; } } # Определение типа устройства для адаптивного кэша if (req.http.User-Agent ~ "(?i)mobile|android|iphone|ipod|blackberry|opera mini|iemobile") { set req.http.X-Device-Type = "mobile"; } else { set req.http.X-Device-Type = "desktop"; } # Маршрутизация по типу контента if (req.url ~ "^/api/") { return(pass); } if (req.http.Authorization || req.http.Cookie ~ "auth_token=") { return(pass); } if (req.method != "GET" && req.method != "HEAD") { return(pass); } if (req.url ~ "\\.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot|webp|avif)(\\?.*)?$") { unset req.http.Cookie; return(hash); } return(hash); } sub vcl_hash { hash_data(req.url); if (req.http.host) { hash_data(req.http.host); } hash_data(req.http.X-Device-Type); return(lookup); } ו-sub vcl_backend_response { set beresp.grace = 24h; if (beresp.status >= 500) { set beresp.ttl = 0s; set beresp.grace = 60s; return(deliver); } # Кастомный TTL по типу контента if (bereq.url ~ "^/news/") { set beresp.ttl = 10m; } else if (bereq.url ~ "^/static/") { set beresp.ttl = 30d; unset beresp.http.Set-Cookie; } else if (bereq.url ~ "^/product/") { set beresp.ttl = 1h; } else { set beresp.ttl = 5m; } if (beresp.http.Cache-Control ~ "no-store|private") { set beresp.uncacheable = true; return(deliver); } } sub vcl_hit { if (obj.ttl >= 0s) { return(deliver); } if (obj.ttl + obj.grace > 0s) { return(deliver); } return(restart); } :

# Текущий hit rate
varnishstat -f MAIN.cache_hit,MAIN.cache_miss

# Живой лог с фильтрацией по URL
varnishlog -q 'ReqURL ~ "^/news/"' -g request

# Топ cache miss по URL
varnishtop -i ReqURL -q 'VCL_call eq "MISS"'

מדוע נורמליזציה של בקשות קריטית לאחוז הפגיעות?

נורמליזציה של בקשות היא הבסיס לשמירה יעילה במטמון. בלעדיה, אחוז הפגיעות יכול להיות מתחת ל-50% אפילו עם TTL מוגדר כראוי. לדוגמה, כתובות URL עם תגי utm מבזבזות עד 30% משטח המטמון. נורמליזציה גם מונעת בעיות עם תוכן תלוי-עוגיות ושמירה לא נכונה של דפים דינמיים. כללי VCL מותאמים אישית מגדילים את אחוז הפגיעות פי 2–3 בהשוואה לתצורת ברירת מחדל, כפי שאושר בפרויקטים שלנו.

כיצד להגדיר נורמליזציה של בקשות?

  1. זיהוי פרמטרים להסרה (utm, fbclid, gclid וכו').
  2. כתיבת import xkey; acl purge_acl { "127.0.0.1"; } sub vcl_recv { if (req.method == "PURGE") { if (!client.ip ~ purge_acl) { return(synth(405, "Not allowed")); } return(purge); } if (req.method == "XKEY-PURGE") { if (!client.ip ~ purge_acl) { return(synth(405, "Not allowed")); } set req.http.n-gone = xkey.softpurge(req.http.xkey-purge); return(synth(200, "Purged " + req.http.n-gone + " objects")); } } sub vcl_backend_response { if (beresp.http.Surrogate-Key) { set beresp.http.xkey = beresp.http.Surrogate-Key; } } שמסירה פרמטרים אלה מ-sub vcl_deliver { if (obj.hits > 0) { set resp.http.X-Cache = "HIT"; set resp.http.X-Cache-Hits = obj.hits; } else { set resp.http.X-Cache = "MISS"; } set resp.http.X-Served-By = server.hostname; unset resp.http.X-Powered-By; unset resp.http.Server; unset resp.http.X-Varnish; unset resp.http.Via; } .
  3. נורמליזציה של varnishstat—תעדוף br, ולאחר מכן gzip.
  4. עיבוד עוגיות: הסרת כולן מלבד אלו החיוניות לסשן.
  5. הוספת גיבוב מודע-מכשיר להפרדה בין מובייל לדסקטופ.
  6. בדיקה עם varnishlog וניטור.

תהליך היישום

פרויקט טיפוסי של כללי VCL מותאמים אישית כולל את השלבים הבאים:

  • ניתוח (1–2 ימים): ביקורת על התעבורה הנוכחית, ניתוח כותרות תגובה מהשרת האחורי, זיהוי דפוסים שאינם ניתנים לשמירה במטמון (עוגיות, Cache-Control: private).
  • עיצוב (יום אחד): פיתוח ארכיטקטורת כללי VCL, הגדרת מפתחות מטמון, תקופות חסד וניתוב.
  • יישום (2–3 ימים): כתיבת סקריפטים של VCL, הגדרת בדיקות בריאות, אינטגרציה עם CDN.
  • בדיקות (יום אחד): אימות בסביבת staging עם # Текущий hit rate varnishstat -f MAIN.cache_hit,MAIN.cache_miss # Живой лог с фильтрацией по URL varnishlog -q 'ReqURL ~ "^/news/"' -g request # Топ cache miss по URL varnishtop -i ReqURL -q 'VCL_call eq "MISS"' , מדידת אחוז פגיעות, השוואה לקו הבסיס.
  • פריסה (יום אחד): העלאה לסביבת הייצור, הגדרת ניטור, תיעוד.

מקרים מורכבים (בדיקות A/B באמצעות Varnish, שילובי ESI, שמירה רב-שכבתית עם Nginx) מוסיפים 3–5 ימים.

היקף העבודה

  • כללי VCL מותאמים אישית המותאמים לארכיטקטורת הפרויקט.
  • נורמליזציה של URL, עוגיות ו-Accept-Encoding.
  • מצב חסד ו-stale-while-revalidate.
  • פסילת מטמון באמצעות PURGE/xkey.
  • אינטגרציה עם CDN ומערכות פריסה.
  • בדיקות עומס והגדרת ניטור (varnishstat, מדדים).
  • תיעוד הכללים המיושמים והליכי הפסילה.

השוואה: תצורת ברירת מחדל מול VCL מותאם אישית

פרמטר תצורת ברירת מחדל כללי VCL מותאמים אישית
אחוז פגיעות 30–40% 85–95%
נורמליזציה של URL לא מלאה (utm, fbclid, עוגיות עודפות)
מצב חסד אין ניתן להגדרה (24 שעות+)
פסילה רק ניקוי מלא PURGE לפי URL ותגים
שמירה מודעת-מכשיר לא כן (אובייקטים נפרדים למובייל/דסקטופ)
עומס על השרת האחורי גבוה מופחת פי 5–10

בקשו ביקורת על תצורת ה-Varnish הנוכחית שלכם—נזהה צווארי בקבוק ונציע פתרונות מותאמים אישית. צרו קשר לקבלת הצעה מותאמת.