أسئلة وأجوبة حول OpenResty | كيفية استخدام OpenResty في الممارسة العملية

API7.ai

February 10, 2023

OpenResty (NGINX + Lua)

  1. بعض الأسئلة والأجوبة حول OpenResty، بوابة API، و Lua
  2. أسئلة وأجوبة OpenResty | صلاحيات العمليات المميزة، مرحلة التنفيذ، والمزيد
  3. أسئلة وأجوبة OpenResty | بنية الشبكة للاختبار، ميزات متعلقة بـ SSL، DSL، أداة ab
  4. أسئلة وأجوبة OpenResty | التحميل الديناميكي، NYI، والتخزين المؤقت للـ Shared Dict

حتى الآن، لقد انتهينا من القسم الأخير من OpenResty، بوابة API للخدمات المصغرة. تهانينا على عدم التأخر، والتعلم والممارسة بنشاط، وترك أفكاركم بحماس.

لقد قمت باختيار بعض الأسئلة النموذجية والمثيرة للاهتمام هنا لمشاركتها معكم. دعونا نلقي نظرة على هذه الأسئلة الخمسة لليوم.

السؤال 1: كيفية استخدام OpenResty في الممارسة العملية

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

أود التحدث عن تقديم OpenResty في العمل، وهو موضوع يستحق النقاش.

يعتمد OpenResty على NGINX ويضيف وحدة lua-nginx-module C والعديد من مكتبات lua-resty، لذا فإن OpenResty هو بديل جيد لـ NGINX، وهي الطريقة الأرخص للبدء في استخدام OpenResty. بالطبع، هناك مخاطر مرتبطة بعملية الاستبدال هذه، لذا تحتاج إلى الانتباه إلى النقاط الثلاث التالية.

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

ثانيًا، الاختبار. الاختبار هو أحد أهم الجوانب. هناك مخاطر قليلة في استخدام OpenResty لاستبدال NGINX، ولكن المخاطر لا تزال موجودة. على سبيل المثال، ما إذا كانت هناك وحدات C مخصصة تحتاج إلى التجميع، إصدار openssl الذي يعتمد عليه OpenResty، وما إذا كانت التصحيحات التي يضعها OpenResty على NGINX ستؤثر على الأعمال. تحتاج إلى تكرار بعض حركة المرور التجارية للتحقق من ذلك.

ثالثًا، تبديل حركة المرور. بعد اجتياز التحقق الأساسي، لا يزال عليك التحقق من الإصدار التجريبي لحركة المرور الحقيقية على الإنترنت. للتراجع بسرعة، يمكننا فتح عدد قليل من الخوادم الجديدة لنشر OpenResty بدلاً من استبدال خدمة NGINX الأصلية مباشرة. إذا لم تكن هناك مشاكل، يمكننا إما ترقية الملف الثنائي بشكل مباشر أو إزالة واستبدال NGINX تدريجيًا من LB للترقية.

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

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

بشكل عام، من الجيد البدء باستبدال NGINX ثم الانتشار ببطء لاستخدام OpenResty.

السؤال 2: تغليف قاعدة البيانات لـ OpenResty

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

يمكنك أولاً تحليلها باستخدام SystemTap أو الأدوات الأخرى التي قدمناها في المقالات السابقة لمعرفة ما إذا كان تجميع عبارات SQL هو عنق الزجاجة في النظام. إذا لم يكن كذلك، فلا داعي لتحسينه. بعد كل شيء، التحسين المبكر هو أصل كل شر.

إذا كان عنق الزجاجة هو بالفعل تجميع عبارات SQL، فيمكننا استخدام عبارة prepare لقاعدة البيانات للقيام بالتحسين أو استخدام مصفوفة للقيام بالتجميع. ولكن دعم lua-resty-mysql لـ prepare في حالة TODO، لذا يمكننا فقط استخدام تجميع المصفوفات. هذه أيضًا مشكلة شائعة مع بعض مكتبات lua-resty، التي تنفذ معظم الوظائف وتعمل بشكل طبيعي ولكنها لا يتم تحديثها في الوقت المناسب. بالإضافة إلى عبارة prepare لقاعدة البيانات، فإن lua-resty-redis لا يدعم cluster.

تجميع السلاسل ومكتبات lua-resty هي نوع المشاكل التي يريد OpenResty حلها تمامًا باستخدام DSL - باستخدام تقنيات المترجم لتوليد مصفوفات تلقائيًا لتجميع السلاسل، وإخفاء هذه التفاصيل عن المستخدمين في المستوى الأعلى؛ باستخدام DSL wirelang لتوليد تلقائيًا لمختلف مكتبات الاتصال الشبكي lua-resty، مما يلغي الحاجة إلى الكتابة اليدوية.

يبدو هذا رائعًا، أليس كذلك؟ ولكن يجب أن نواجه مشكلة: الكود المولد تلقائيًا غير صديق للمطورين. إذا كنت تريد تعلم أو تعديل الكود المولد، عليك تعلم تقنيات المترجم و DSL قد لا تكون مفتوحة المصدر، مما يجعل حاجز المشاركة في المجتمع أعلى وأعلى.

السؤال 3: إطار عمل ويب لـ OpenResty

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

في مستودع awesome-resty، يمكننا أن نرى أن هناك فئة خاصة لإطار عمل ويب، هناك 20 مشروعًا مفتوح المصدر، ولكن معظمها راكد. من بينها، Lapis، lor و vanilla هي ثلاثة مشاريع يمكنك تجربتها لمعرفة أي منها أكثر ملاءمة.

بالفعل، بدون إطار عمل ويب قوي لدعمه، فإن OpenResty مثقل عند التعامل مع المشاريع الكبيرة، وهو أحد الأسباب التي تجعل عددًا قليلاً من الأشخاص يستخدمون OpenResty لأنظمة الأعمال.

السؤال 4: كيفية تغيير content-length في رأس الاستجابة بعد تعديل جسم الاستجابة؟

الوصف: إذا كنت بحاجة إلى تعديل محتوى جسم الاستجابة، يمكنني فقط إجراء تغييرات في مرشح الجسم، ولكن هذا سيؤدي إلى عدم تطابق طول الجسم مع طول content-length. كيف يجب أن أتعامل مع ذلك؟

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

فيما يلي نموذج للكود:

server {
    listen 8080;
    location /test {
            proxy_pass http://api7.ai;
            header_filter_by_lua_block {
                     ngx.header.content_length = nil
            }
            body_filter_by_lua_block {
                    ngx.arg[1] = ngx.arg[1] .. "abc"
            }
     }
}

كما ترى من هذا الكود، في مرحلة مرشح الجسم، يمثل ngx.arg[1] جسم الاستجابة. إذا أضفنا السلسلة abc بعدها، فإن رأس طول المحتوى سيكون غير دقيق، لذا يمكننا تعطيله في مرحلة مرشح الرأس.

أيضًا، يوضح هذا المثال كيفية عمل المراحل المختلفة لـ OpenResty معًا، وهو ما آمل أن تلاحظه وتفكر فيه.

السؤال 5: مسارات حزم Lua في OpenResty

الوصف: يبدو أن lua_package_path تم تكوينه كمسار البحث لاعتمادات Lua. بالنسبة لـ content_by_lua_file، قمت بتجربة ووجدت أنه يبحث فقط تحت البادئة بناءً على المسار النسبي للملف المقدم من التوجيه، وليس تحت lua_package_path. لا أعرف إذا كان فهمي صحيحًا.

يستخدم lua_package_path لتحميل وحدات Lua، على سبيل المثال، عندما نستدعي require 'cjson'، سنذهب إلى الدليل المحدد في lua_package_path ونبحث عن وحدة cjson. في المقابل، content_by_lua_file يتبعه مسار ملف على القرص.

location /test {
     content_by_lua_file /path/test.lua;
 }

إذا لم يكن هذا مسارًا مطلقًا ولكن مسارًا نسبيًا.

 content_by_lua_file path/test.lua;

ثم سيتم تجميعها باستخدام الدليل -p المحدد عند بدء OpenResty للحصول على المسار المطلق.

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