Reverse proxy مقابل forward proxy
الـ forward proxy يعمل لصالح العميل. المتصفح مُعَدّ لاستخدامه، وهو يجلب الإنترنت نيابةً عن المتصفح — تصفية خروج الشركات، ومعظم ما يقصده الناس حين يبحثون عن "proxy".
الـ reverse proxy يعمل لصالح الخادم. لا فكرة لدى العملاء عن وجوده؛ يحلّون اسم المضيف لديك، وهو يجيب، ويقرر ماذا يفعل بالطلب. تطبيقك قد يكون على جهاز آخر، أو في حاوية، أو موزَّعًا على عشرة منها.
التمييز مهم لأن نتائج البحث تطمسه. إن كانت صفحة عن "خوادم proxy" تتحدث عن فتح المواقع المحجوبة، فهي ليست عن الشيء الذي يقف أمام تطبيقك.
ما تكسبه فعليًا
إنهاء TLS. الشهادات تعيش في مكان واحد بدل كل خادم تطبيق. التجديد يصبح مهمة واحدة.
التوجيه. اسم مضيف واحد، وعدة خلفيات (backends): /api إلى خدمة Node، و/ إلى WordPress، و/static إلى تخزين الكائنات. العميل يرى موقعًا واحدًا.
التخزين المؤقت. الوسيط يجيب عن الطلبات المتكررة بنفسه. هذا أكبر مكسب أداء منفرد متاح لمعظم المواقع، والأكثر تركًا معطَّلًا.
الضغط. Brotli أو gzip يُطبَّق مرة واحدة عند حافة حزمتك بدل كل تطبيق على حدة.
تحديد معدل الطلبات والتصفية. مكان لفرض الحدود وحجب الزيارات قبل وصولها إلى شيفرة تكلّف مالًا لتشغيلها.
إخفاء الأصل. إن كان خادم تطبيقك يمكن الوصول إليه فقط من الوسيط، فعلى الهجمات أن تمر عبر الباب الذي تتحكم به.
مكان لتغيير السلوك. إعادة توجيه، وإعادة كتابة ترويسات، وصفحات صيانة لا تتطلب نشر تطبيق.
إعداد nginx عامل
الحد الأدنى الصحيح فعليًا — الترويسات أدناه ليست زخرفة اختيارية، بل ما يجعل تطبيقك يرى العميل بدل الوسيط:
``` server { listen 443 ssl; server_name example.com;
ssl_certificate /etc/ssl/example.com/fullchain.pem; ssl_certificate_key /etc/ssl/example.com/privkey.pem;
location / { proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } ```
Host — بدونها ترى الخلفية (backend) عنوان 127.0.0.1 وأي رابط مطلق تبنيه يكون خاطئًا.
X-Forwarded-For وX-Real-IP — بدونهما يأتي كل طلب في سجل تطبيقك من الوسيط، وأي منطق حسب عنوان IP لديك يُطبَّق بصمت على الوسيط بدل الزائر.
X-Forwarded-Proto — بدونها يظن تطبيق خلف إنهاء TLS أنه على HTTP عادي ويولّد روابط http://، ما يُنتج حلقة إعادة توجيه تكلّف الجميع بعد ظهر كامل على الأقل مرة واحدة.
زوج Upgrade — بدونه لا تعمل WebSockets، والعطل يبدو كخلل في التطبيق لا في الوسيط.
التخزين المؤقت عند الوسيط، باختصار
يستطيع nginx تخزين استجابات upstream مؤقتًا بـ proxy_cache. الآليات بسيطة بما يكفي: أعلن مسار تخزين مؤقت، وفعّله في الـ location، وقرر ما يُخزَّن ولأي مدة.
``` proxy_cache_path /var/cache/nginx keys_zone=site:50m max_size=5g inactive=24h;
location / { proxy_cache site; proxy_cache_valid 200 10m; proxy_cache_key "$scheme$request_method$host$request_uri"; add_header X-Cache-Status $upstream_cache_status; proxy_pass http://127.0.0.1:3000; } ```
أمران يحددان ما إذا كان هذا يساعد أم يضر.
مفتاح التخزين المؤقت. الافتراضي يتضمن الرابط الكامل، فـ ?utm_source=twitter يُنشئ إدخالًا منفصلًا عن الرابط النظيف. حملة واحدة يمكن أن تُجزّئ تخزينك المؤقت إلى آلاف النسخ من صفحة واحدة وتُسقط معدل الإصابة إلى الصفر. أزل المعاملات التي لا تغيّر الاستجابة.
التفريغ. لا يملك nginx مفتوح المصدر آلية تفريغ؛ فإما تنتظر مدة الصلاحية (TTL) أو تحذف الملفات من مجلد التخزين المؤقت يدويًا، على كل جهاز. هذه عادةً هي النقطة التي يبدأ عندها "نحن نُشغّل وسيطنا الخاص" بالإيلام، لأن نشر تصحيح والانتظار عشر دقائق حتى يظهر ليس سير عمل يستمتع به أحد.
ما يكلّفه تشغيل واحد خاص بك فعليًا
nginx واحد أمام تطبيق واحد رخيص ومعقول تمامًا. التكلفة تصل لاحقًا، على أجزاء.
إنه جهاز واحد. الـ reverse proxy الذي هو الطريق الوحيد للدخول هو أيضًا الشيء الوحيد الذي يجب أن يبقى يعمل. جعله زائدًا عن الحاجة (redundant) يعني جهازًا ثانيًا، وعنوانًا عائمًا أو تجاوز فشل DNS، وإعدادًا مطابقًا على كليهما.
الشهادات. التجديد الآلي مشكلة محلولة إلى أن يفشل خطّاف التجديد على العقدة الثانية بصمت وتكتشف الأمر من تحذير متصفح.
إبطال التخزين المؤقت عبر العقد. بوسيطين لديك تخزينان مؤقتان، والتفريغ يعني فعله على كليهما، بموثوقية، من خط نشرك.
إنه في مكان واحد. زوارك ليسوا كذلك. وسيط في مركز بيانات واحد لا يمكنه أن يكون قريبًا من مستخدمين في دولة أخرى؛ تلك مشكلة فيزيائية لا مشكلة إعداد.
الضبط الدقيق مستمر. أحجام المخازن المؤقتة، والمهل الزمنية، وkeepalive نحو upstreams، واتصالات العمال — كل واحد منها جيد عند زياراتك الحالية وخاطئ عند عشرة أضعافها.
متى تُسلّم المهمة
الـ CDN هو reverse proxy يُشغّله شخص آخر في مواقع كثيرة. الوظائف نفسها — إنهاء TLS، والتخزين المؤقت، والضغط، والتصفية، والتوجيه — والفروق هي الأجزاء التي كانت صعبة: الجغرافيا، والتكرار (redundancy)، والتفريغ الفوري عبر كل عقدة.
الخط المعقول هو هذا. أبقِ وسيطك الخاص طالما يؤدي عملًا محليًا: التوجيه بين خدمات داخل جهاز واحد أو عنقود واحد، وتشغيل قواعد تعتمد على حالة داخلية. سلّم الجانب المواجه للعامة حين تجد نفسك تحل مشكلات توزيع: عقدة ثانية للتكرار، وتفريغ تخزين مؤقت عبر أجهزة، وزوار في دولة أخرى ينتظرون رحلة ذهاب وإياب إلى خادمك.
معظم الفرق تنتهي بكليهما، وهذا هو الترتيب المعقول: CDN يواجه الإنترنت، وnginx صغير بالداخل يؤدي التوجيه الذي يجيده. ما لا تريده هو إنفاق ربع سنة تعيد فيه بناء، بشكل سيئ، الأجزاء التي يمنحك إياها CDN من اليوم الأول.
الأسئلة الشائعة حول Reverse proxy
هل الـ reverse proxy هو نفسه موازن التحميل (load balancer)؟
يتداخلان. موازن التحميل يوزّع الطلبات عبر عدة خلفيات (backends)؛ أما reverse proxy فينهي TLS أيضًا، ويخزّن مؤقتًا، ويعيد الكتابة، ويصفّي. nginx يؤدي كليهما، ولهذا يُستخدم المصطلحان أحدهما مكان الآخر. إن كانت المهمة الوحيدة توزيع الزيارات عبر خوادم متطابقة، فـ"موازن التحميل" هي الكلمة الأدق.
هل يُبطئ الـ reverse proxy موقعي؟
يضيف محطة، تُقاس بأجزاء من الثانية (ميلي ثوانٍ أحادية الرقم) حين يكون الوسيط قريبًا من الأصل، ويزيل أكثر من ذلك بكثير حين يكون التخزين المؤقت مفعّلًا — استجابة مخزَّنة مؤقتًا لا تسافر إلى تطبيقك إطلاقًا. الحالة التي يضر فيها هي وسيط في منطقة مختلفة عن مستخدميك وعن أصلك معًا.
لماذا يرى تطبيقي عنوان IP الخاص بالوسيط بدل الزائر؟
لأن ترويسات إعادة التوجيه مفقودة، أو لأن التطبيق غير مُعَدّ لتصديقها. النصفان كلاهما ضروري: الوسيط يرسل X-Forwarded-For، وعلى الإطار (framework) أن يُخبَر بعناوين الوسيط التي يمكنه تصديقها. تصديق الترويسة من أي مصدر يتيح للعميل تزييف عنوان IP الخاص به.
هل يمكنني تخزين صفحات المستخدمين المسجَّلين مؤقتًا؟
ليس افتراضيًا، وعادةً لا ينبغي أن تريد ذلك — هذه هي الطريقة التي يرى بها مستخدم لوحة تحكم مستخدم آخر. النمط المعتاد هو تجاوز التخزين المؤقت حين يكون ملف تعريف ارتباط جلسة موجودًا والتخزين المؤقت بقوة للزوار المجهولين، وهم معظم الزيارات على أغلب المواقع.
كيف أُفرّغ تخزين وسيط nginx المؤقت؟
لا يملك nginx مفتوح المصدر توجيه تفريغ. الخيارات هي حذف الملفات المعنية من مجلد التخزين المؤقت على كل عقدة، أو استخدام وحدة تفريغ من طرف ثالث، أو انتظار مدة الصلاحية (TTL). التفريغ عند الطلب عبر الأجهزة هو أحد الأشياء الملموسة التي تكسبها بنقل طبقة التخزين المؤقت إلى CDN.