يُستعمل Varnish Cache بكثرة لتخبئة محتوى مواقع الويب لتسريع أداء المواقع وتخفيض الحمولة على الخادوم الأصل (origin-server). لطالما شجعنا على استعمال التّخبئة لتسريع أداء تطبيقات الويب وتسهيل قابلية التوسع (Scalability) وضمان الاستقراريّة إضافة إلى الفوائد الأخرى التي تأتي مع هذه الإجراءات من تحسين لتجربة المُستخدم إلى التوفير في الموارد. لكن رغم ذلك فلا نزال بحاجة إلى التأكيد على أهميّة التّخبئة. وفي بعض الأحيان، قد يعني الأمر شرح كيفيّة استعمال Varnish Cache وما يُميّزه عن بقيّة التقنيات الأخرى.
الأمور الغريبة التي تُميّز Varnish Cache
Varnish Cache عبارة عن خادوم HTTP بنظام HTTP خلفي له قدرة على تقديم الملفّات. يعتمد على هندسة سلسليّة (threaded architecture)، دون حلقة أحداث (event loop). ولأن شيفرة الكتابة قادرة على استعمال استدعاءات النظام الحاصرة (blocking system calls)، فذلك يجعله أسهل استعمالا من Apache أو NGINX، التي يتطلّب استعمالها التعامل مع حلقة أحداث.
يقوم Varnish Cache بالتسجيل (logging) على الذاكرة عوضا عن القرص الصلب، تم تصميمه بهذه الطّريقة لأن تسجيل 10000 من عمليات HTTP كل ثانية على القرص الصلب أمر يتطلب الكثير من الموارد.
يقوم Varnish بتسجيل جميع التّفاصيل (حوالي 200 سطر لكل طلب) على الذاكرة مُباشرة. إن لم يتم طلب التفاصيل المُسجّلة فستتم الكتابة فوقها (overwrite). يعتبر Varnish التطبيق الوحيد الذي يتخذ هذا المسلك.
المرونة: استعمال VCL
الميّزة الكبرى لـ Varnish Cashe هي لغة الضّبط الخاصّة به. تمّ إنشاء لغةVCL (Varnish Configuration Language) منذ أكثر من 11 عاما لتدعم النسخة الأولى من Varnish Cache. على عكس Apache أو بقيّة البرمجيّات، فـVarnish Cache لا يعتمد على إعداد تقليدي.بل يعتمد عوضا عن ذلك على مجموعة من السّياسات التي تُكتب بهذه اللغة. تتم ترجمة هذه السيّاسات إلى شيفرة ثنائية، تُحمّل هذه الشيفرة ويتمّ تشغيلها بعد ذلك.
يقول مهندس Varnish Cache Poul-Henning Kamp بأنVCL أُنشأت لتكون مجموعة أدوات يمكن استعمالها حسب الحاجة، وليس قطعة موحدة يُمكن إضافتها إلى بيئة العمل. في يومنا الحالي، هناك أكثر من 100 وحدة (modules) لـ VCL يمكن استعمالها ببساطة. في الحقيقة، ففي ملتقيات Varnish Summits هناك دائما ورشة عمل لتعليم الأشخاص كيفيّة كتابة وحدات خاصّة.
تعتبر لغة VCL من أكبر الأسباب التي تجعل النّاس تستعمل وتتعلّق بـVarnish Cache. إذ تفتح المرونة التي توفرها اللغة الأبواب للقيام بأي شيء قد يرغب أحدهم بفعله، ما يمحو القيود التي عادة ما تأتي مع البرمجيّات التقليديّة.
إذا، ما هي أهم الأدوات التي توفّرها VCL وكيف يُمكننا الاستفادة منها؟
التنطيف Purging
لا يدعم Varnish تنظيف المحتوى عند إعداده لأول مرّة، إذ لا يُمكنك تنزيله وتنصيبه ثمّ استعمال نظام تنظيف دون أية خطوات إضافيّة. عوضا عن تمكين إعدادات افتراضيّة، يتوجب على مستخدمي Varnish Cache العمل على تفعيل الميزات المرغوبة كل على حدة، لكن إعداد نظام تنظيف أمر بسيط، ويمكنك الحصول على النتيجة التي ترغبها.
sub vcl_recv { if (req.method == "PURGE") { return (purge); } } إن لم ترغب بتمكين الأشخاص على الأنترنت من تنظيف المحتوى على نظام تخبئتك، فسيتوجب عليك ضبط حدّ الوصول ACL كما يلي: acl purge { "localhost"; "192.168.55.0"/24; } sub vcl_recv { if (req.method == "PURGE") { if (!client.ip ~ purge) { return(synth(405,"Not allowed.")); } return (purge); } }
إضافة ميزة لـVarnish Cache: خنق الرّبط السّاخن (Hot linking)
يسمح إطار العمل الخاص بـVarnish للمستخدمين بإضافة أية ميزة يحتاجون إليها. أول ميّزة أضيفت هي استعمال VCL للحد من الرّبط السّاخن. الرّبط السّاخن هو عمليّة سرقة موارد أحدهم على الويب وكتابة مقال يستخدم صورا مرفوعة على خادوم الضّحية ليدفع تكاليف استخدام الموارد. يسمح Varnish للخوادم بإيقاف هذه العملية عند استعمال الرّبط السّاخن للموارد الخاصة بالخادم دون إذن. على سبيل المثال، يمكن لـVarnish وضع سقف لعدد مرّات حدوث هذا الأمر كل ثانيّة عبر استخدام وحدة من وحدات Varnish (VMOD) باسم vsthrottle
لإضافة الخنق (throttling). يمكن القيام بالأمر عبر استيراد وتحميل الوحدة. شيفرة VCL أسفله تُوضّح كيفيّة الحدّ من الرّبط السّاخن. في هذا المثال، نقوم بتطبيق ثلاثة قواعد. القاعدة الأولى تتحقّق من أن عنوان URL المطلوب يبدأ بـ/assets/
. القاعدتان الثانيّة والثّالثة تحميان مجلّد الملفات السّاكنة من الرّبط السّاخن. يتمّ هذا عبر التحقق ممّا إذا كان المُحيل referrer
طرفا غير مُتوقّع، وما إن طلبت أسماء نطاق أخرى ملفّاتك لأكثر من 10 مرّات خلال 60 ثانيّة. ما سبق عبارة عن دالّة الخنق، يُستعمل رابط URL كمفتاح للخنق.الحدّ المسموح به هو 10 مرّات كلّ 60 ثانيّة. يُمكن تقديم الملفات السّاكنة غير المُشار إليها، وعندما يحصل ذلك، فسيتم إرسال خطأ 403 مع منع الربط السّاخن. يُمكن كذلك توسيع الخنق لاستعمال memcache، وذلك ليحصل المستخدم على المُحاسبة الرّئيسيّة (central accounting) في العنقود (cluster).
import vsthrottle;
(..)
if (req.url ~
"^/assets/" &&
(req.http.referer !~
"^http://www.example.com/") &&
vsthrottle.is_denied(req.url, 10, 60s) {
return(error(403,"Hotlinking prohibited");
}
التّعامل مع ملفات تعريف الارتباط (cookies)
لن يقوم Varnish بتخبئة المحتوى الذي يُطلَبُ باستعمال ملفّات تعريف الارتباط. ولن يستجيب إلى طلب محتوى مخبّأ إن كان الطّلب متعلّقا بملف تعريف ارتباط. عوضا عن هذا، يُمكن استعمال وحدة VMOD لحذف ملفّ تعريف الارتباط. المحترفون يستعملون تعبيرا نمطيّا (regular expression) لترشيح ملفات تعريف الارتباط. ولأنّنا لسنا محترفين، فـVarnish يوفّر وحدة باسم cookie
تبدو كما يلي:
import cookie;
sub vcl_recv {
cookie.parse ("cookie1: value1; cookie2: value2");
cookie.filter_except("cookie1");
// get_string() will now yield
// "cookie1: cookie2: value2;"; }
لا يقوم Varnish بإنشاء ترويسة (header) ملف تعريف ارتباط. وإن رأى بأن النظام الخلفي قد أرسل شيفرة إنشاء ملفّ تعريف ارتباط، فلن يقوم بتخبئته. الحل أن تحذف ترويسة Set-Cookie أو إصلاح الخادوم الخلفي.
- ترويسات Set-Cookie تقوم بتعطيل ملفّات تعريف الارتباط.
- الحلّ: احذف ترويسة Set-Cookie أو أصلح النّظام الخلفيّ.
نمط الإمهال Grace Mode
يُمكن نمط الإمهال Varnish من تقديم محتوى قديم إن لم يكن المحتوى الجديد جاهزا أو مُتوفّرا. يساهم هذا في تحسين الأداء عبر إعادة تحميل المحتوى من النظام الخلفيّ بشكل غير متزامن (asynchronous).
في الوقت الذي تم فيه تقديم Varnish 1.0 كحل لنظام تخبئة لموقع الجريدة النرويجيّة Verdens Gang، كانت هناك مشاكل كبرى بسبب التكتّلات السلسليّة (threading pileups). كانت الصفحة الرّئيسيّة للموقع تُقدّم 3000 مرّة كلّ ثانيّة، لكن نظام إدارة المُحتوى (CMS) كان بطيئا، إذ كان يأخذ 3 ثوان لإعادة توليد الصّفحة الرّئيسيّة. في بعض المواقع، إن اتّبعت طلبات التّعليقات (RFC)، فسيقوم وسيط (proxy) التّخبئة بإلغاء الصّفحة الرّئيسيّة أو سيحدث انقضاء وقت (time out). عندها سيأتي مُستخدم آخر وسيتوجب جلب نسخة جديدة من الصّفحة الرّئيسيّة. يقوم Varnish بهذا عبر عمليّة التئام التّخبئة (coalescing). إذ يتم وضع المستخدمين الجدد عند وصولهم على قائمة انتظار. (أنظمة التّخبئة الأخرى تُرسل المُستخدمين إلى النظام الخلفيّ ما يقتل الخادم). إن تّمت إضافة 3000 مُستخدم إلى قائمة الانتظار كلّ ثانيّة، فبعد ثلاثة ثوان، سيكون الطابور عبارة عن 9000 مستخدم ينتظرون النظام الخلفي لجلب المحتوى. في البداية، كان Varnish يأخذ المحتوى المطلوب، ويقوم بالتواصل مع السّلاسل (Thread) الـ9000 التي تمّ إنشاؤها، ويُحاول دفع كل شيء دفعة واحدة. سمّي هذا الحدث بالقطيع الصّاخب (thundering herd). وكانت النّتيجة موت الخادوم فورا.
لحلّ هذه المُشكلة، قرّر Varnish استعمال الصفحة الرّئيسيّة القديمة عوضا عن انتظار الخادوم لإعادة توليد المحتوى. لن يهتم أحد إن كان المحتوى قديما بـ20 ثانيّة، إلا في حالة كانت البيانات التي تقدّمها متعلّقة بمعلومات ماليّة وترغب عرضها في الوقت الفعلي.
تغيّرت التّفاصيل المتعلّقة بـGrace خلال السنوات الماضيّة. في Varnish 4.0 (إن تمّ تفعيله) فستبدو كما يلي:
sub vcl_backend_response { set beresp.grace = 2m; }
يتم ربط Grace مع كائن الإجابة الخلفيّة (backend response object). إن تم تحديد القيمة في دقيقتين (2m) فسيُبقي Grace على الكائن لدقيقتين بعد انقضاء الـTPL. إن تم طلب الكائن خلال هذا الوقت، فسيتم تفضيل تقديم ما هو مُخبّأ عوضا عن إرسال طلب جديد إلى النظام الخلفيّ. سيتم استعمال الكائن وإعادة تحميله بعدها بشكل غير متزامن.
تفاصيل Grace
لا يتطلب فهم Varnish Cache النظر إلى الشّيفرة المصدريّة، عوضا عن ذلك، يتم توفير VCL افتراضيّ يُمكن الاعتماد عليه لإضافة أية تفاصيل أخرى حسب الحاجة. فبِميّزة مثل Grace يُمكن للمُستخدمين قراءة شيفرة VCL والنظر إلى التفاصيل:
Insert code
sub vcl_hit {
if (obj.ttl >= 0s) {
// A pure unadulterated hit, deliver it
return (deliver);
}
if (obj.ttl + obj.grace > 0s) {
// Object is in grace, deliver it
// Automatically triggers a background fetch
return (deliver);
}
// fetch & deliver once we get the result
return (fetch);
}
إن كان الكائن VCL يحمل قيمة أكبر من 0 ثوان، هذا يعني بأنّ الـTTL موجب، سيتمّ الرجوع والتّقديم. إن كانتا كل من قيمتي TTL وGrace أكبر من 0 ثوان، فهذا يعني بأنّها ضمن Grace وسيقوم Varnish بتقديمها. إن كانتا كل من قيمتي TTL وGrace أصغر من 0 ثوان، فسيتّم طلب الصّفحة من النّظام الخلفيّ.
تعديل كيفيّة عمل Grace
يُمكن للمؤسّسات التي تكون بحاجة إلى تقديم معلومات ماليّة وتأبى عرض معلومات قديمة للمُستخدم أن تُغيّر من كيفيّة عمل Grace. في المثال التّالي، لم يتغيّر الجزء الأول، في الجزء الثّاني نقوم بالتقديم في حالة لم يكن الخادوم الخلفيّ على ما يرام وكانت كلا من قيمتي TTL و Grace أكبر من 0 ثانيّة.
sub vcl_hit { if (obj.ttl >= 0s) {
// A pure unadulterated hit, deliver it
return (deliver);
}
if (!std.healthy(req.backend_hint) &&
(obj.ttl + obj.grace > 0s)) {
return (deliver);
}
// fetch & deliver once we get the result
return (fetch);
}
*بضعة معلومات إضافيّة:
-
beresp
: كائن الطّلب الخلفّيbackend request object
. -
req
: كائن الطّلبrequest object
. يُستعمل فيvcl_recv
. -
bereq
: كائن الطّلب الخلفيbackend request object
. يُستعمل فيvcl_backed_fetch
. -
beresp
: كائن الإجابة الخلفيّة. يُستعمل فيvcl_backend_response
. -
resp
: كائن الإجابةresponse object
. يُستعمل فيvcl_deliver
. -
obj
: الكائن الأصلي في الذّاكرة. يُستعمل فيvcl_hit
. -
للمزيد من التّفاصيل استعمل
man(7) vcl
.
آلة الحالة (state machine)
يمرّ كل طلب عبر عدّة حالات. يُمكن تشغيل شيفرة مخصّصة في كل حالة لتعديل كائنات الطّلب. بعد تنفيذ الشّيفرة المخصّصة، يقوم Varnish باتّخاذ قرار ما إذا كان نجاحا (Hit) أو إخفاقا (Miss) بعدها يتم تشغيل إمّا VCL hit
أو VCL Miss
. في حالة النّجاح سيقوم Varnish بتقديم المحتوى. والإخفاقات تُعيد الطّلب من النظام الخلفي. 90% من التّغييرات التي يُحدثها المُستخدمون تحدث هنا.
كيفيّة التّضبيط (Tuning) على Linux
يتم تحديد الانضباطيات (Tunables) على Linux بشكل محافظ، ونجد SOMAXCONN
و TCP_MAX_SYN_Backlog
أكثرها مشقّة.
عند الانصات (listen) إلى المقابس (socket)، يأخذ Varnish بضعة ثوان للانصات للنّداء. إن كانت السّلاسل مشغولة، فستبدأ النّواة (kernel) بالتّكتّل (queue). لا يُسمَحُ لهذا التّكتّل بأن ينمو إلى ما وراء قيمة SOMAXCONN
. سيطلب Varnish 1024 اتّصالا على تكتّل عمق الانصات (listen depth queue)، لكنّ النواة تقوم بإبطال ذلك لتحصل على 928 فقط. ولأنّ Varnish يعمل بصلاحيات الجذر (root)، فمن الممكن تقرير عمق انصات خاصّ، لكنّ Linux أدرى بما هو أفضل. قد يرغب المُستخدمون بالرّفع من هذا الحدّ إن أرادوا تخفيض خطر رفض الاتّصالات عند انقضاء عمق الانصات. سيتوجّب على المستخدم اتخاذ قرار ما إذا كان عدم التّقديم وتقديم صفحة خطأ أفضل أو لا. يقوم TCP_MAX_SYN_Backlog
بتعريف عدد الاتّصالات البارزة التي يُمكن لها أن تكون بداخل إقامة الاتّصال (handshake) الثّلاثي الأطراف قبل أن تقرّر النواة بأنّها تحت الهجوم. القيمة الافتراضيّة هي 128. لكن في حالة دخل جمع كبير من النّاس إلى موقعك دفعة واحدة فقد تحصل على أكثر من 128 اتّصال TCP كلّ ثانيّة.
لا تقم بتعديل tcp_tw_recycle
. تأكّد بأنّك تعرف ما تفعله قبل لمس الإعدادات وابحث على الويب قبل ذلك. إذ أنّ الكثير من العفاريت (demons) تعتمد على هذه القيّم.
مساحات العمل (Work spaces) في Linux
في Varnish، الذاكرة المحليّة متواجدة في كلّ سلسلة. ولأنّ التّراجع (rollback) يستنزف الموارد، فإنّنا لا نتراجع كلّما احتجنا إلى قليل من المساحة في الذّاكرة. عوضا عن ذلك، نقوم بتعيين مُسبق للذّاكرة على كلّ سلسلة إن كان للمستخدم العديد من سياسات VCL التي قد تستنزف مساحة العمل بأكملها.
لا يقوم Varnish بتتبّع الاتّصال، وحدة التّعاقد (contract module) بطيئة للغاية. يتمّ افتراضيّا تشغيل خمسة سلاسل. يُمكن إنشاء سلاسل جديدة بسرعة نسبيّا، لكن إن كنت تخطّط لفتح ألف اتّصال كلّ ثانيّة أي ألف سلسلة، ففي هذه الحالة لديك مُعطى (parameter) لتخصيص سلاسل مُسبقا.
خلاصة:
- احذر عند التّعامل مع مساحات العمل.
- لا تقم بتتبّع الاتّصالات (connection tracking).
- ارفع معدّل السّلاسل إلى طلب واحد في الثانيّة لكل سلسلة.
الموازنة بين ما هو غريب وما هو رائع في Varnish Cache
المرونة القويّة والمميّزات التّي يتمتّع بهاVarnish Cache لا تأتي في حزمة جاهزة (ما قد يجده البعض غريبا)، لذا فقد لا يكون الحلّ الأنسب للجميع. لكنّ المرونة التي يتمتّع بها قد تُغيّر من مجريات الأمور عند الرغبة في تخصيص والتّحكم بأداء المواقع وقابليّة توسيعها.
ترجمة -بتصرّف- للمقال Getting started with web app accelerator Varnish Cache لصاحبه Per Buer.
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.