العودة إلى المدونة

بروكسي Nginx HTTP، وموازنة الحمل، والتخزين الوسيط، والتخزين المؤقت: نظرة عامة

بروكسي Nginx HTTP، وموازنة الحمل، والتخزين الوسيط، والتخزين المؤقت: نظرة عامة
مقدمة

Nginx هو خادم ويب عالي الأداء يُستخدم أيضًا كوكيل عكسي، ووكيل بريد، وموازن تحميل، وذاكرة تخزين مؤقت لـ HTTP. إن Nginx مجاني ومفتوح المصدر، مما يسمح لأي شخص بتنزيله واستخدامه في بيئة الخادم الخاصة به.

ربما تكون قد استخدمت Nginx بالفعل لخدمة مواقع الويب. في هذا البرنامج التعليمي، سنناقش القدرات الأخرى لـ Nginx. إن توكيل HTTP الخاصة بـ Nginx تتيح له تمرير الطلبات إلى خوادم HTTP الخلفية لمعالجتها. باستخدام هذه الميزة، يمكنك إعداد خوادم خلفية متعددة. وهي تتيح لك توسيع بنيتك التحتية حسب الحاجة للتعامل مع الارتفاع المفاجئ في طلبات العملاء.

مع تقدمنا في هذا البرنامج التعليمي، ستتعلم كيفية توسيع بنيتك التحتية باستخدام خصائص موازنة التحميل لـ Nginx، والتخزين المؤقت (buffering)، وحفظ الاستجابات في الذاكرة المؤقتة (caching) لتحسين أداء خادمك بالإضافة إلى ضمان تجربة أفضل للعملاء. فلنبدأ!

أولاً وقبل كل شيء، للبدء مع Nginx، ألقِ نظرة على برنامجنا التعليمي حول كيفية تثبيت Nginx على خادم Ubuntu الخاص بك.

معلومات عامة حول التوكيل

إذا كانت معرفتك بخوادم الويب تقتصر فقط على معالجة طلبات مواقع الويب وتقديم صفحات الويب، فقد تتساءل عن سبب حاجتنا إلى توكيل الطلبات. سنوضح أدناه الأسباب الكامنة وراء ذلك.

أحد أسباب توكيل الطلبات إلى خوادم أخرى من Nginx هو دعم قابلية التوسع لبنيتك التحتية. يتعامل Nginx افتراضيًا مع العديد من الاتصالات بشكل متزامن. وهذا يجعله مثاليًا ليكون نقطة الاتصال الأولى للعملاء. ومن ثم يمكنه تمرير الطلبات إلى خوادم خلفية مختلفة للتعامل مع المعالجة الفعلية لطلبات العملاء. وهذا ما يوزع الحمل. وبالتالي، فإنه يضمن لك إمكانية توسيع بنيتك التحتية قدر الإمكان. كما يتيح لك إيقاف تشغيل خوادم أخرى للصيانة بينما تستمر الخوادم الأخرى في خدمة الطلبات.

السبب الثاني الذي قد يجعلك ترغب في توكيل الطلبات إلى خوادم أخرى هو عندما تستخدم خوادم تطبيقات غير مناسبة للتعامل مع الطلبات مباشرة من العملاء في بيئات الإنتاج الفعلية. العديد من أطر العمل بما في ذلك خوادم الويب ليست مناسبة للأداء العالي مثل Nginx. إن السماح لـ Nginx بأن يكون نقطة الدخول وتوكيل الطلبات إلى هذه الخوادم منخفضة الأداء يمكن أن يضمن حصول مستخدميك على تجربة أفضل. بالإضافة إلى ذلك، يمكن أن يضمن أمانًا متزايدًا لتطبيقك.

تتضمن عملية توكيل الطلبات في Nginx معالجة طلب من خادم Nginx وتمريره إلى خوادم خلفية أخرى للمعالجة الفعلية. بمجرد أن تعالج الخوادم الخلفية الأخرى الطلب، فإنها تمرر النتيجة مرة أخرى إلى Nginx. ثم يرسل النتيجة كاستجابة للعميل. العميل في هذه الحالة هو متصفح ويب أو حتى تطبيق ويب للهاتف المحمول. يمكن أن تكون الخوادم الخلفية الأخرى خوادم محلية لا يمكن الوصول إليها علنًا على الإنترنت، أو خوادم بعيدة، أو حتى خوادم افتراضية أخرى ضمن تكوينات كتل خادم Nginx. يُشار إلى هذه الخوادم الأخرى التي يقوم Nginx بتوكيل الطلبات إليها باسم upstream servers.

يمكن لـ Nginx توكيل الطلبات إلى الخوادم التي تتواصل باستخدام بروتوكولات متعددة بما في ذلك HTTP(S)، وMemcached, SCGI, FastCGI، وuWSGI. لكل نوع من البروتوكولات، هناك مجموعات من التوجيهات. تركيزنا في هذا البرنامج التعليمي هو بروتوكول HTTP. يقوم Nginx بتحليل الطلبات ومكونات الرسائل إلى تنسيق يمكن لخادم المنبع تفسيره ومعالجته.

تحليل تمرير وكيل HTTP الأساسي

يتضمن أبسط أنواع الوكلاء تمرير طلب إلى خادم واحد يتواصل عبر HTTP. يُعرف هذا النوع من الوكلاء عمومًا باسم "proxy pass" ويتم التعامل معه بواسطة التوجيه المسمى بشكل مناسب proxy_pass داخل ملفات تكوين Nginx.

يظهر التوجيه proxy_pass داخل كتل الموقع (location blocks). وهو موجود أيضًا داخل كتل سياق الموقع وفي سياقات limit_except. عندما يطابق الطلب موقعًا يحتوي على توجيه proxy_pass بداخله، يذهب الطلب إلى عنوان URL الذي يحدده التوجيه. أدناه مثال على مقتطف التكوين:

proxy_pass_conf

في المثال أعلاه، ستنتقل الطلبات الموجهة إلى المنفذ 80 إلى localhost:3000:

nginx default page

توضح لقطة الشاشة أعلاه صفحة Nginx الافتراضية عند محاولة الوصول إلى localhost. بعد إعادة تشغيل خادم Nginx مع تفعيل توجيه proxy pass، ستنتقل جميع الطلبات إلى المنفذ 3000. يعمل تطبيق تجريبي على المنفذ 3000 والذي يمكنك رؤيته من الصورة أدناه ويمكنك الوصول إليه مباشرة من localhost دون تحديد المنفذ:

localhost after applying proy pass

في المثال التالي، لم يتم تحديد أي معرف URI في نهاية الخادم في تعريف proxy_pass. بالنسبة للتعريفات التي تطابق هذا النمط، سيتم تمرير معرف URI الذي يطلبه العميل إلى الخادم الرئيسي (upstream server) كما هو.

على سبيل المثال، عندما تتعامل هذه الكتلة مع طلب لـ /match/url/here، فإن معرف URI للطلب سينتقل إلى خادم example.com كـ http://example.com/match/url/here.

أدناه مثال على مقتطف تكوين بديل:

كما ترى في المقتطف أعلاه، قمنا بتعريف جزء URI في نهاية خادم الوكيل كـ new/url/prefix. عند تعريف URI في تعريف proxy_pass، يتم استبدال جزء الطلب الذي يطابق تعريف الموقع (location) بهذا الـ URI عند الانتقال إلى الخادم الرئيسي (upstream server) للمعالجة.

على سبيل المثال، ينتقل طلب لـ /match/url/here على خادم Nginx إلى الخادم الرئيسي كـ http://example.com/new/url/here. يتم استبدال /match/url بـ /new/url. ضع هذه النقطة في الاعتبار.

في بعض الحالات، لا يكون تمرير معرفات URI كما هو موضح أعلاه ممكنًا. في مثل هذه الحالات، يتجاهل Nginx معرف URI في نهاية تعريف proxy_pass. في النهاية، يتم تمرير إما الـ URI الأصلي من العميل أو الـ URI الذي تعدله التوجيهات الأخرى إلى الخادم الرئيسي.

مثال على ذلك هو عندما تطابق التعبيرات النمطية (regular expressions) الموقع (location). قد لا يتمكن Nginx من تحديد أي جزء من الـ URI يطابق التعبير. وبالتالي، فإنه يرسل الـ URI الأصلي لطلب العميل. يؤدي هذا إلى إعادة كتابة ومعالجة الـ URI الخاص بالعميل في نفس الكتلة. وفي مثل هذه الحالة، يتم تمرير الـ URI المعاد كتابته.

كيف يعالج Nginx الترويسات؟

تعتبر الترويسات حاسمة لكيفية معالجة الخادم للطلب. قد تتضمن بعض الترويسات معلومات المصادقة. لذلك، يجب أن نفهم كيف ستعالج عملية توكيل Nginx الترويسات. سيبدو طلب الوكيل من Nginx إلى الخادم الرئيسي مختلفًا عن الطلب الذي جاء مباشرة من العميل. وتنتج بعض هذه الاختلافات عن الترويسات التي تصاحب طلب الوكيل.

أثناء توكيل الطلب، سيقوم Nginx بإجراء تعديلات على ترويسات الطلب التي يتلقاها من العميل. وتشمل بعض هذه التعديلات ما يلي:

  • التخلص من جميع الترويسات الفارغة. الترويسات الفارغة تضخم الطلب فحسب، لذا لا فائدة من تمريرها إلى الخادم الرئيسي.

  • تعتبر أي ترويسات تحتوي على شرطات سفلية (underscores) غير صالحة افتراضيًا، وبالتالي يتم إزالتها من الطلب. إذا كنت ترغب في تغيير هذا السلوك والسماح لـ Nginx بتفسير الترويسات التي تحتوي على شرطات سفلية على أنها صالحة، فيمكنك تحديد التوجيه underscores_in_headers إلى "on". إذا لم تفعل ذلك، فلن تصل مثل هذه الترويسات من العميل إلى الخادم الرئيسي أبدًا.

  • يتم إعادة كتابة ترويسة "Host" إلى القيمة المحددة بواسطة متغير $proxy_host. هذا هو عنوان IP أو الاسم ورقم المنفذ للخادم الرئيسي، كما هو محدد بواسطة توجيه proxy_pass.

  • تتغير قيمة ترويسة "Connection" إلى "close". تحتوي ترويسة الاتصال على معلومات حول اتصال معين تم إنشاؤه بين طرفين. عندما يضبط Nginx قيمتها على close، فإنه يشير إلى الخادم الرئيسي بأن الاتصال سيغلق بمجرد الاستجابة للطلب الأصلي، وبالتالي لا ينبغي له أن يتوقع أن يكون اتصالاً مستمرًا.

إليك بعض النقاط التي يمكننا ملاحظتها من تعديلات ترويسة طلب الوكيل الموضحة أعلاه:

  • إذا كنت لا تريد تمرير ترويسة إلى خادم المنبع، فإن تعيينها إلى سلسلة فارغة سيؤدي إلى إزالتها تمامًا من الطلب.

  • إذا كان التطبيق في خادم المنبع الخاص بك سيعالج ترويسات غير قياسية، فتأكد من أن الترويسات لا تحتوي على شرطة سفلية. اختياريًا، يمكنك تعيين التوجيه underscores_in_headers إلى “on” في التكوين الخاص بك (صالح إما في سياق إعلان الخادم الافتراضي لتركيبة عنوان IP/المنفذ أو في سياق HTTP). سيضمن القيام بذلك عدم تمييز الترويسات على أنها غير صالحة وبالتالي سيتم تمريرها بالفعل إلى خادم المنبع.

  • تعد ترويسة “Host” مهمة للغاية في معظم حالات البروكسي. يتم تعيينها افتراضيًا على قيمة $proxy_host، وهو متغير يحتوي على اسم النطاق أو عنوان IP والمنفذ المسترد من مواصفات proxy_pass. يتم تحديد هذا العنوان افتراضيًا وسحبه مباشرةً من معلومات الاتصال. إنه العنوان الوحيد الذي يضمن Nginx أن خادم المنبع سيستجيب له.

فيما يلي القيم الأكثر شيوعًا لترويسة “Host”:

  • $host – متغير يتم تعيينه بترتيب الأفضلية لاسم المضيف من سطر الطلب نفسه، أو ترويسة “Host” من طلب العميل، أو اسم الخادم المطابق للطلب.

  • $http_host – متغير يقوم بتعيين ترويسة “Host” إلى ترويسة “Host” من طلب العميل. تتوفر الترويسات في طلب العميل دائمًا لـ Nginx كمتغيرات. تبدأ هذه المتغيرات ببادئة $http_، ثم يتبعها اسم الترويسة بأحرف صغيرة. في حين أن متغير $http_host سيعمل بشكل جيد في الغالب، عندما يفتقر طلب العميل إلى ترويسة “Host” صالحة، فقد يؤدي ذلك إلى فشل التمرير.

  • $proxy_host – متغير يقوم بتعيين ترويسة “Host” إلى اسم النطاق أو تركيبة عنوان IP والمنفذ المستردة من مواصفات proxy_pass. هذا هو السلوك الافتراضي، من وجهة نظر Nginx، وبالتالي يعتبر آمنًا. ومع ذلك، قد لا يكون هذا هو المطلوب من قبل الخادم لمعالجة الطلب بشكل صحيح.

ستتضمن معظم التكوينات تعيين ترويسة “Host” إلى متغير $host. إنه مرن للغاية وسيوفر ترويسات معبأة بدقة لخادم المنبع.

تعيين وتعديل الترويسات

يتيح لنا التوجيه proxy_set_header تعيين أو تعديل الترويسات لاتصالات البروكسي. في ترويسة “Host” التي تمت مناقشتها سابقًا، يمكننا القيام بما يلي لتعديل وإضافة ترويسات إضافية شائعة مع الطلبات الموجهة عبر البروكسي:

في مقتطف التكوين أعلاه، قمنا بتعيين ترويسة “Host” إلى المتغير $host الذي يحتوي على معلومات حول المضيف الأصلي المطلوب. وقمنا بتعيين ترويسة X-Forwarded-Proto بمعلومات حول مخطط (schema) الطلب الأصلي من العميل (يمكن أن يكون هذا إما طلب HTTP أو HTTPS).

نقوم بتمرير عنوان IP الفعلي للعميل إلى X-Real-IP. يتيح ذلك لخادم المنبع اتخاذ القرارات المناسبة أو تخزين السجلات بناءً على مصدر IP الخاص بالعميل. تحتوي ترويسة X-Forwarded-For على قائمة بجميع عناوين IP التي تنتمي إلى الخوادم التي تم توجيه العميل من خلالها عبر البروكسي قبل الوصول إلى هذه النقطة. في مقتطف الكود أعلاه، قمنا بتعيينه إلى المتغير $proxy_add_x_forwarded_for. سيأخذ هذا المتغير قيمة ترويسة X-Forwarded-For الأصلية المأخوذة من العميل ويضيف عنوان IP الخاص بخادم بروكسي Nginx إلى النهاية.

إذا كنت ترغب في الإشارة إلى توجيهات proxy_set_header في أكثر من موقع (location) واحد، فيمكنك نقلها إلى سياق server أو http. ضع في اعتبارك مقتطف التكوين أدناه:

تحديد سياق Upstream لموازنة تحميل الاتصالات الممررة عبر البروكسي

حتى هذه النقطة، أصبح لديك فهم لكيفية عمل بروكسي http بسيط لخادم upstream خلفي واحد. لحسن الحظ، مع Nginx، يمكنك توسيع هذا التكوين عن طريق تحديد مجموعات من الخوادم الخلفية لتمرير الطلبات إليها لمعالجتها.

يوفر Nginx توجيهًا يسمى upstream يُستخدم لتحديد مجموعة من الخوادم. ضمن تكوين التوجيه، يجب عليك فقط تحديد الخوادم القادرة على معالجة طلب العميل. يتيح Nginx كخادم بروكسي توسيع البنية التحتية بأقل جهد. يجب تحديد توجيه upstream ضمن سياق http لتكوين Nginx الخاص بك.

فيما يلي مثال يوضح توجيه upstream:

في مقتطف رمز التكوين أعلاه، قمنا بتعريف سياق upstream يسمى several_backend_hosts. اسم السياق المحدد متاح الآن داخل ممرات البروكسي (proxy passes). يمكن استخدامه كما لو كان نطاقًا عاديًا كما هو موضح في المثال. داخل كتلة الخادم (server block)، نقوم بتمرير جميع الطلبات المقدمة إلى example.com/proxy-me/… إلى المجموعة التي حددناها باستخدام توجيه upstream، وفي هذه الحالة، several_backend_hosts. يتم تحديد مضيف داخل المجموعة لمعالجة الطلبات الواردة من خلال تطبيق خوارزمية قابلة للتكوين. بشكل افتراضي، يتبع التحديد عملية round-robin (دائرية) – حيث يتم توجيه كل طلب إلى مضيف مختلف بدوره.

كيفية تغيير خوارزمية موازنة Upstream

كما تم توضيحه أعلاه، تتبع عملية التحديد عملية round-robin. في هذا القسم، سنرى كيف يمكننا تعديل خوارزمية الموازنة المستخدمة بواسطة مجموعة upstream. لتعديل الخوارزمية، يمكنك تضمين توجيهات أو علامات أخرى داخل سياق upstream كما هو محدد أدناه:

  • (round-robin) – إذا لم يتم تحديد أي توجيه موازنة upstream آخر، فسيتم بشكل افتراضي تمرير الطلبات إلى كل خادم محدد في سياق upstream بالتتابع بدوره.

  • least_conn – يوجه هذا التوجيه الـ upstream لتحديد الخادم الخلفي الذي يحتوي على أقل عدد من الاتصالات النشطة. هذا قابل للتطبيق في الحالات التي قد تستمر فيها الاتصالات بخادم خلفي واحد لفترة من الوقت.

  • hash – هذا التوجيه شائع لبروكسي memcached. يتم تمرير الاتصالات إلى الخوادم الخلفية بناءً على قيمة مفتاح تجزئة (hash key) يتم توفيره عشوائيًا. يمكن أن تكون قيمة مفتاح التجزئة متغيرات أو نصوصًا أو مزيجًا من الاثنين معًا. وتصادف أن تكون hash هي طريقة الموازنة الوحيدة التي تتطلب إدخالاً من المستخدمين ليكون بمثابة المفتاح المستخدم للتجزئة.

  • ip_hash – يوجه هذا التوجيه الـ upstream لتوزيع الطلبات على خوادم مختلفة بناءً على عنوان IP الخاص بالعميل. تمثل البايتات الثلاثة الأولى (octets) من عنوان IP المفتاح لتحديد الخادم الذي يجب أن يعالج الطلب. من مزايا هذا التوجيه أن العملاء يميلون إلى تلقي نفس الخادم في كل مرة، مما يضمن اتساق الجلسة.

فيما يلي مثال على كيفية إضافة توجيه خوارزمية الموازنة إلى سياق upstream:

في المقتطف أعلاه، سيختار Nginx أيًا من الخوادم التي تحتوي على أقل عدد من الاتصالات لمعالجة الطلب الوارد. يتبع التوجيه ip_hash نفس الصيغة. بالنسبة لتوجيه hash، يجب عليك توفير مفتاح من اختيارك لإجراء التجزئة بناءً عليه، وإليك مثال على ذلك:

ستكون التجزئة المستخدمة هنا نتيجة لعنوان IP الخاص بالعميل’ ومنفذه. وتنفذ المعلمة الاختيارية consistent الـ خوارزمية التجزئة المتسقة ketama. يضمن ذلك الحد الأدنى من التأثير على ذاكرة التخزين المؤقت لديك في حال قمت بتغيير خوادم upstream الخاصة بك.

كيفية تحديد وزن الخادم للموازنة

بشكل افتراضي، عند الإعلان عن خوادم الخلفية (backend)، يتم وزن كل خادم بالتساوي. والافتراض هو أن كل خادم لديه الموارد والقدرات للتعامل مع نفس القدر من الحمل، وبالطبع، يأخذ هذا في الاعتبار أي خوارزمية موازنة تحددها في سياق upstream. لتغيير هذا السلوك الافتراضي، يمكنك تعيين وزن بديل لكل خادم أثناء الإعلان. دعنا نلقي نظرة على مثال:

في هذا المثال، سيتلقى host1.example.com ضعف حركة المرور التي يتلقاها الخادمان الآخران. يكون وزن كل خادم واحدًا بشكل افتراضي.

تحرير خوادم الخلفية باستخدام الذاكرة المؤقتة (Buffers)

أثناء تكوين الوكيل (proxying) في إعدادات الخادم الخاص بك، قد تشعر بالقلق بشأن تأثير الأداء الناتج عن إضافة المزيد من الخوادم إلى العملية. لحسن الحظ، يأتي Nginx مزودًا بميزات التخزين المؤقت (buffering) والتخزين المؤقت المؤقت (caching) التي يمكن أن تساعد في التخفيف من مشكلات الأداء هذه.

من المؤكد أن سرعة اتصالين مختلفين ستؤثر على تجربة العميل عند استخدام الوكيل للاتصال بخادم آخر:

  • الاتصال الأول يكون من العميل إلى وكيل Nginx.

  • الاتصال الثاني يكون من وكيل Nginx إلى خادم الخلفية (backend upstream).

يمكن لـ Nginx ضبط سلوكه للمساعدة في تحسين أي من الاتصالين حسب الحاجة.

إذا قمنا بإزالة الذاكرة المؤقتة (buffers)، يبدأ نقل البيانات من خادم الخلفية (upstream backend) إلى العميل فورًا عند وكيل Nginx. إذا كنت تعلم أن عملائك سريعون، فيمكنك إيقاف تشغيل التخزين المؤقت (buffering) تمامًا لضمان وصول البيانات إلى العميل بسرعة كافية. عند تشغيل التخزين المؤقت، يقوم وكيل Nginx بتخزين بيانات الاستجابة المستلمة من خادم الخلفية مؤقتًا. بعد ذلك، يرسل البيانات إلى العميل اعتمادًا على سرعته. بمجرد أن يحصل Nginx على الاستجابة في ذاكرته المؤقتة، يمكنه إغلاق الاتصال بخادم الخلفية. سيقوم بعد ذلك بتوزيع البيانات على العميل بالسرعة التي يدعمها العميل. وفي الوقت نفسه، يسمح ذلك لخادم الخلفية بمواصلة معالجة الطلبات الواردة الأخرى.

بشكل افتراضي، سيكون التخزين المؤقت (buffering) مفعلاً في Nginx. وذلك لأننا لا نستطيع معرفة سرعات اتصال العملاء. يميل العملاء إلى امتلاك اتصالات مختلفة قد تكون أبطأ. أدناه، سنحدد التوجيهات المختلفة التي يمكننا تحديدها لضبط سلوك التخزين المؤقت لـ Nginx. يمكن تحديد التوجيهات في سياقات http أو server أو location، ومع ذلك، يجب أن تلاحظ أنه يتم تكوين توجيهات الحجم لكل طلب. وبالتالي، فإن زيادتها بما يتجاوز ما هو ضروري تمامًا يمكن أن يؤثر على أداء خادمك عندما يكون هناك عدد كبير جدًا من طلبات العملاء الواردة. إليك التوجيهات:

  • proxy_buffering – التوجيه الذي يتحكم في ما إذا كان التخزين المؤقت نشطًا لسياق معين والسياقات الفرعية له. التكوين الافتراضي لـ proxy_buffering هو “on”.

  • proxy_buffer_size – التوجيه الذي يحدد حجم المخزن المؤقت لتخزين الرؤوس الموجودة في الاستجابة من خادم الخلفية (backend server). تشكل الرؤوس الجزء الأول من الاستجابة من خادم الخلفية. التخزين المؤقت لهذه الرؤوس منفصل عن بقية الاستجابة. افتراضيًا، يكون الحجم المحدد لهذا المخزن المؤقت هو نفسه حجم proxy_buffers. ومع ذلك، إذا كانت معلومات الرأس صغيرة، يمكنك تعيين الحجم إلى قيمة أقل.

  • proxy_buffers – التوجيه الذي يتحكم في عدد (المعامل الأول) وحجم (المعامل الثاني) المخازن المؤقتة للاستجابات التي تم تمريرها عبر البروكسي. يحدد التكوين الافتراضي 8 مخازن مؤقتة بحجم مساوٍ لصفحة ذاكرة واحدة (إما 4k أو 8k). يمكنك السماح بتخزين المزيد من المعلومات مؤقتًا عن طريق زيادة عدد المخازن المؤقتة.

  • proxy_max_temp_file_size – التوجيه الذي يحدد الحد الأقصى لحجم الملف المؤقت على القرص، لكل طلب. يتم إنشاء الملفات المؤقتة عندما تكون استجابة upstream كبيرة جدًا بحيث لا تتسع في المخزن المؤقت.

  • proxy_busy_buffers_size – التوجيه الذي يحدد الحد الأقصى لحجم المخازن المؤقتة التي يمكن تمريرها على أنها "جاهزة للعميل" وبالتالي تكون مشغولة. يمكن للعميل قراءة البيانات من مخزن مؤقت واحد فقط في كل مرة. ومع ذلك، تكون المخازن المؤقتة في قائمة انتظار لإرسالها إلى العميل في دفعات. يمكنك تحديد حجم مساحة المخزن المؤقت المسموح لها بأن تكون في هذه الحالة عن طريق تعديل هذا التوجيه.

  • proxy_temp_file_write_size – التوجيه الذي يحدد كمية البيانات التي سيقوم Nginx بكتابتها في الملف المؤقت دفعة واحدة عندما تكون الاستجابة من خادم backend upstream كبيرة جدًا بحيث لا تتسع في المخازن المؤقتة المكونة.

  • proxy_temp_path – التوجيه الذي يحدد المسار إلى الموقع على القرص حيث يجب على Nginx تخزين أي ملفات مؤقتة عندما تكون الاستجابة من خادم backend upstream كبيرة جدًا بحيث لا تتسع في المخازن المؤقتة المكونة.

إن Nginx قابل للتخصيص بدرجة كبيرة، حيث يوفر لك العديد من التوجيهات لضبط سلوك التخزين المؤقت. في معظم الحالات، ستعمل القيم الافتراضية بشكل جيد تمامًا. وفي الوقت نفسه، من الجيد معرفة أنه يمكنك ضبط بعض هذه القيم لتناسب تطبيقك المخصص. ستحتاج في الغالب إلى ضبط توجيهات proxy_buffers و proxy_buffer_size.

فيما يلي مثال يزيد من عدد مخازن البروكسي المؤقتة المتاحة لكل طلب upstream. يقوم بذلك مع تقليل حجم المخزن المؤقت الذي يخزن الرؤوس:

دعنا نرى كيف يمكنك تقديم البيانات بشكل أسرع للعملاء السريعين عن طريق إيقاف تشغيل التخزين المؤقت تمامًا. إذا حدث أن عميلك ليس سريعًا بما يكفي، فسيستخدم Nginx المخازن المؤقتة تلقائيًا. ومع ذلك، فإنه سيقوم أولاً بدفع البيانات إلى العميل بدلاً من انتظار تجمعات المخازن المؤقتة (buffer pools). يأتي هذا التكوين مع عيب؛ حيث يتسبب هذا التكوين في بقاء اتصال خادم upstream مفتوحًا للعملاء البطيئين حتى يتلقى العميل جميع بيانات الاستجابة. إذا تم تعيين التخزين المؤقت على “off”، فسيتم استخدام المخزن المؤقت المحدد بواسطة توجيه proxy_buffer_size فقط. إليك مقتطف يوضح كيفية تحديد إيقاف تشغيل التخزين المؤقت:

  • تهيئة بنية تحتية عالية التوفر (HA) (إعداد اختياري)

يمكنك إضافة مجموعة احتياطية من موازنات التحميل إلى تكوين بروكسي Nginx لضمان كونه أكثر قوة وبالتالي عالي الإتاحة. إعداد الإتاحة العالية (HA) هو بنية تحتية لا تحتوي على نقطة فشل واحدة. موازنات التحميل هي جزء من هذا التكوين. مع وجود أكثر من موازن تحميل واحد، يمكنك منع وقت التوقف المحتمل في حالة فشل أحد موازنات التحميل أو خروجه عن الخدمة لإجراء الصيانة.

كيفية تنفيذ التخزين المؤقت لبروكسي Nginx لتقليل أوقات الاستجابة

في القسم السابق، ناقشنا كيفية استخدام التخزين المؤقت المؤقت (buffering) لتحرير خوادم الخلفية للتعامل مع المزيد من الطلبات. يأتي Nginx بميزة أخرى تتيح لنا تخزين بيانات الاستجابة مؤقتًا من الخلفية. وهي تلغي تمامًا الحاجة إلى الاتصال بالخادم الرئيسي (upstream) لجميع الطلبات الواردة.

تنفيذ التخزين المؤقت للبروكسي

يتيح لنا توجيه proxy_cache_path إعداد ذاكرة تخزين مؤقت عن طريق تحديد مساحة على القرص لاستخدامها لتخزين المحتوى الذي تم تمريره عبر البروكسي. يتم تعريف توجيه proxy_cache_path في سياق http.

مقتطف رمز التكوين أدناه هو مثال على كيفية تنفيذ نظام التخزين المؤقت:

في مقتطف الرمز هذا، استخدمنا توجيه proxy_cache_path لتحديد دليل على نظام الملفات سيحتوي على ذاكرة التخزين المؤقت الخاصة بنا. الدليل /var/lib/nginx/cache هو الدليل الذي قمنا بتعيينه في هذه الحالة. أنت حر في تحديد مسار دليل من اختيارك. استخدم الأوامر التالية لإنشاء الأدلة التي اخترتها، مع الأذونات والملكية الصحيحة:

في مقتطف الرمز، تحدد معلمة levels= تنظيم ذاكرة التخزين المؤقت. سيقوم Nginx بإنشاء مفتاح تخزين مؤقت عن طريق تجزئة قيمة المفتاح (المحددة باستخدام توجيه proxy_cache_key). تشير المستويات التي حددناها (1:2) إلى أنه سيتم إنشاء دليل من حرف واحد (أي الحرف الأخير من القيمة المجزأة) مع دليل فرعي من حرفين (مأخوذ من الحرفين التاليين من نهاية القيمة المجزأة). في معظم الحالات، لن يهمك هذا الأمر. ومع ذلك، من الجيد معرفة كيف يساعد ذلك Nginx في العثور بسرعة على القيم ذات الصلة.

تحدد معلمة keys_zone= اسم منطقة التخزين المؤقت، وفي حالتنا قمنا بتسميتها backendcache. هنا، نحدد أيضًا مقدار البيانات التعريفية (metadata) التي نريد تخزينها. في هذا المثال، نقوم بتخزين 8 ميجابايت من المفاتيح. يمكن لـ Nginx تخزين ما يقرب من 8000 إدخال لكل ميجابايت. تحدد معلمة max_size الحد الأقصى لحجم البيانات المخزنة مؤقتًا الفعلية، وهو 50 ميجابايت في مثالنا.

يجب أيضًا أن تلاحظ توجيه proxy_cache_key المستخدم. يحدد هذا التوجيه المفتاح الذي سنستخدمه لتخزين القيم المخزنة مؤقتًا. سنستخدم نفس المفتاح للتحقق مما إذا كان الطلب موجودًا داخل ذاكرة التخزين المؤقت. لقد حددنا أن يكون هذا المفتاح مزيجًا من المخطط (http أو https)، وطريقة طلب HTTP، والمضيف والمسار (URI) المطلوبين.

بالإضافة إلى ذلك، استخدمنا توجيه proxy_cache_valid. يمكن تحديد هذا التوجيه عدة مرات لرموز حالة مختلفة. يتيح لنا تحديد مدة تخزين القيم اعتمادًا على رمز الحالة. في مقتطف الرمز، حددنا 10 دقائق لرموز النجاح ودقيقة واحدة لاستجابات 404.

بما أننا قمنا بتكوين منطقة التخزين المؤقت، فإن الخطوة التالية هي تفعيل التكوين عن طريق إخبار Nginx بمتى يجب استخدام ذاكرة التخزين المؤقت. أدناه مقتطف تكوين يوضح كيف يمكننا تنفيذ استخدام ذاكرة التخزين المؤقت هذه:

في التوجيه proxy_cache، قمنا بتحديد وجوب استخدام منطقة التخزين المؤقت backendcache لهذا السياق. إذا اخترت اسمًا مختلفًا في تكوين التخزين المؤقت، فهنا هو المكان الذي ستقوم باستبداله فيه. لكل إدخال صالح، سيتحقق Nginx من التخزين المؤقت قبل تمرير الطلب إلى خادم المنبع الخلفي (backend upstream).

نقوم بتعريف التوجيه proxy_cache_bypass لاستخدام المتغير $http_cache_control. يخبر هذا المتغير الخادم ما إذا كان ينبغي عليه الاستجابة باستجابة مخزنة مؤقتًا أو بنسخة جديدة غير مخزنة مؤقتًا من المورد. يتيح الإعداد المناسب لهذا التوجيه لـ Nginx معالجة الأنواع المختلفة من الطلبات الواردة من العملاء بشكل صحيح.

تم أيضًا تحديد ترويسة إضافية تسمى X-Proxy-Cache. تحتوي هذه الترويسة على قيمة المتغير $upstream_cache_status. وهي تعطينا معلومات حول ما إذا كان الطلب قد أدى إلى إصابة التخزين المؤقت (cache hit)، أو خطأ التخزين المؤقت (cache miss)، أو ما إذا كان قد تم تجاوز التخزين المؤقت صراحةً. يمكن أن تكون هذه المعلومات مفيدة للعميل وحاسمة أثناء تصحيح أخطاء التطبيقات.

نقاط هامة حول نتائج التخزين المؤقت

بينما سيؤدي التخزين المؤقت إلى تحسين أداء خادم الوكيل بشكل كبير، يجب عليك مراعاة ما يلي عند تنفيذ التخزين المؤقت:

لا ينبغي تخزين أي بيانات متعلقة بالمعلومات الشخصية للمستخدم’ مؤقتًا، لتجنب السيناريوهات التي تكون فيها بيانات أحد المستخدمين مرئية لمستخدم آخر.

يجب أن تأخذ خوادم الخلفية الخاصة بك في الاعتبار جميع العناصر الديناميكية لموقعك الإلكتروني. لدينا العديد من ترويسات Cache-Control التي يمكننا تحديدها في استجابتنا لخدمة أغراض مختلفة. دعنا نناقشها:

  • no-cache – يحدد أنه يجب على الوكيل التحقق مما إذا كانت البيانات قد تغيرت في الخلفية قبل تقديم الاستجابة. هذا ينطبق على البيانات الديناميكية والهامة. يتم التحقق من ترويسة البيانات التعريفية المجزأة ETag في كل طلب، وإذا أرجعت الخلفية نفس قيمة التجزئة، فسيتم تقديم القيمة السابقة.

  • no-store – يحدد عدم التخزين المؤقت لأي بيانات مستلمة، وبالتالي، سيذهب كل طلب إلى الخادم للحصول على بيانات جديدة. هذا هو الأكثر أمانًا للبيانات الحساسة.

  • private – يحدد أنه لا ينبغي لأي مساحة تخزين مؤقت مشتركة تخزين البيانات مؤقتًا. يمكنك استخدام هذه الترويسة لتحديد التخزين المؤقت في متصفح المستخدم، ولكن أيضًا لإبلاغ خادم الوكيل باعتبار البيانات غير صالحة للطلبات اللاحقة.

  • public – يحدد استجابة عامة ويسمح بالتخزين المؤقت عند أي نقطة في الاتصال.

يمكنك تحديد المدة التي تريد أن يستمر فيها التخزين المؤقت بالثواني باستخدام ترويسة max-age. يمكن أن تساعدك الترويسات المختلفة المحددة أعلاه في تنفيذ التخزين المؤقت مع الحفاظ على أمان البيانات الحساسة، وتحديث البيانات الديناميكية، والأهم من ذلك، تحسين أداء الخادم’ الخاص بك.

إذا كانت خوادم الخلفية لديك تقوم بتشغيل خوادم Nginx، فيمكنك تحديد المدة التي يجب أن يكون فيها التخزين المؤقت صالحًا داخل كتل الخادم (server blocks). يمكنك القيام بذلك عن طريق إضافة التوجيه expires إلى التكوين كما هو موضح أدناه:

تسمح الكتلة الأولى بتخزين المحتوى مؤقتًا لمدة 59 دقيقة، بينما تشير الكتلة الثانية إلى عدم التخزين المؤقت. تنطبق هذه الإعدادات على خيارات ترويسات Cache-Control، على سبيل المثال، "no-cache" للكتلة الثانية.

يمكنك استخدام التوجيه add-header لتعيين قيم إضافية:

الخاتمة

في هذا البرنامج التعليمي، تعرفنا على الميزات القوية لـ Nginx. يعد Nginx خادم ويب، والأهم من ذلك، وكيلًا عكسيًا (reverse proxy). إن تصميم Nginx يجعله قادرًا على التعامل مع آلاف الاتصالات المتزامنة. وهذا يجعله مثاليًا لموازنة التحميل (load balancing). وبسبب هذا التصميم، فإن توجيه الطلبات إلى خوادم خلفية أخرى لمعالجتها أمر بسيط للغاية.

باستخدام المعرفة المكتسبة من هذا البرنامج التعليمي، يجب أن تكون قادرًا على إعداد خوادم وكيلة وموازنات تحميل معقدة، وذلك بفضل مرونة Nginx.

إليك بعض الموارد التي يمكنك العثور عليها في مدونتنا والتي يمكن أن تساعدك في التعرف أكثر على Nginx:

حوسبة سعيدة!

author

Pranay Kapgate

المؤلف · CloudSigma

Preslav Dobrev هو مصمم إبداعي في CloudSigma، يركز على هوية أعمال متسقة باستخدام قنوات التسويق التقليدية والمبتكرة. هو بارع في دمج الرؤية الفنية مع التسويق الاستراتيجي لخلق سرد قصصي مؤثر للعلامة التجارية.

التعليقات

لا توجد تعليقات بعد. كن أول من يعلق.