برنامجك الأول في OpenResty: Hello World
API7.ai
September 9, 2022
عندما نبدأ في تعلم لغة تطوير جديدة، توفر لنا البرامج التعليمية حالة بسيطة مثل hello world
. لذا دعونا نتجاوز خطوة التثبيت أولاً ونرى كيفية كتابة هذه الحالة في OpenResty:
$ resty -e "ngx.say('hello world')"
hello world
يجب أن يكون هذا أبسط كود لـ hello world
قد رأيته على الإطلاق، مشابه لـ Python:
$ python -c 'print("hello world")'
hello world
وراء هذا الكود تظهر فلسفة OpenResty. يجب أن يكون الكود مختصرًا بما يكفي للتخلص من فكرة "من البداية إلى الاستسلام". ستركز هذه المقالة على حالة hello world
.
كما ذكرنا في مقالة ما الفرق بين OpenResty و NGINX، فإن OpenResty يعتمد على NGINX
. لذا قد يكون لديك سؤال: لماذا لا نرى ظل NGINX هنا؟ لا تقلق، دعنا نضيف سطرًا من الكود لنرى ما الذي يعمل خلف resty
:
$ resty -e "ngx.say('hello world'); ngx.sleep(10)" &
لقد أضفنا طريقة ngx.sleep حتى لا يخرج البرنامج بعد طباعة السلسلة hello world
. بهذه الطريقة، لدينا الفرصة لمعرفة:
$ ps -ef | grep nginx
root 15944 6380 0 13:59 pts/6 00:00:00 grep --color=auto nginx
وأخيرًا ظهرت عملية NGINX! يبدو أن أمر resty
يقوم بشكل أساسي ببدء خدمة NGINX، إذن ما هو resty
؟
قد لا يكون OpenResty مثبتًا على جهازك، لذا دعنا نعود إلى خطوات التثبيت التي تجاوزناها في البداية، ونقوم بتثبيت OpenResty قبل المتابعة.
التثبيت
مثل البرمجيات مفتوحة المصدر الأخرى، يمكننا تثبيت OpenResty بطرق مختلفة، مثل استخدام مدير الحزم الخاص بنظام التشغيل، أو التجميع من الكود المصدري، أو استخدام صورة Docker. ومع ذلك، أنصحك أولاً باستخدام مدير حزم مثل yum
، apt-get
، و brew
لتثبيت OpenResty. في هذه المقالة، سأستخدم نظام macOS كمثال:
$ brew tap openresty/brewbrew install openresty
استخدام أنظمة التشغيل الأخرى مشابه. أولاً، أضف عنوان URL لمستودع OpenResty إلى مدير الحزم، ثم استخدم مدير الحزم لتثبيت OpenResty. لمزيد من الخطوات التفصيلية، يمكنك الرجوع إلى الوثائق الرسمية.
ومع ذلك، هناك مشكلتان وراء هذا التثبيت الذي يبدو بسيطًا:
- لماذا لا أنصح باستخدام الكود المصدري لتثبيته؟
- لماذا لا يمكن تثبيته مباشرة من المستودع الرسمي لنظام التشغيل بل يجب إعداد مستودع آخر أولاً؟
يرجى التفكير في هذين السؤالين أولاً.
هنا أود أن أضيف شيئًا آخر. سأضع العديد من الأسئلة "لماذا" وراء المظاهر في هذه الدورة. أتمنى أن تفكر أثناء تعلم أشياء جديدة. لا يهم ما إذا كانت النتيجة صحيحة أم لا. لسوء الحظ، التفكير المستقل نادر أيضًا في المجال التقني. بسبب الاختلاف في مجال وعمق كل شخص في المجال التقني، سيكون لدى المعلمين آراء شخصية وأخطاء في المعرفة في أي دورة. يمكننا تشكيل نظامنا التقني الخاص من خلال طرح المزيد من الأسئلة "لماذا" في عملية التعلم وفهمها.
يستمتع العديد من المهندسين بالبناء من الأكواد المصدرية، وأنا أيضًا كنت كذلك منذ سنوات عديدة. ومع ذلك، عند استخدام مشروع مفتوح المصدر، كنت دائمًا أتمنى أن أتمكن من configure
و make
يدويًا من الكود المصدري وتعديل بعض معلمات التجميع. أشعر أن هذه هي أفضل طريقة لتناسب بيئة هذا الجهاز وتعظيم أدائه.
ولكن هذا ليس هو الحال في الواقع. في كل مرة أقوم بتجميع الكود المصدري، أواجه مشاكل بيئية غريبة، ولا يمكنني تثبيته إلا بعد التعثر. الآن أفهم أن هدفنا الأصلي هو استخدام المشاريع مفتوحة المصدر لحل احتياجات الأعمال. لا ينبغي أن نهدر الوقت والبيئة في القتال، ناهيك عن مديري الحزم وتكنولوجيا الحاويات. إنها بالضبط لمساعدتنا في حل هذه المشاكل.
لنعد إلى الموضوع. استخدام الكود المصدري لـ OpenResty للتثبيت ليس فقط خطوات معقدة، بل تحتاج إلى حل التبعيات الخارجية مثل PCRE
، OpenSSL
، وما إلى ذلك، ولكنك تحتاج أيضًا إلى ترقيع الإصدار المقابل من OpenSSL يدويًا. وإلا، سيكون هناك نقص في الوظائف عند التعامل مع جلسات SSL
. على سبيل المثال، واجهات برمجة تطبيقات Lua مثل ngx.sleep التي تسبب yield
لا يمكن استخدامها. إذا كنت تريد معرفة المزيد عن هذا الجزء، يمكنك الرجوع إلى الوثائق الرسمية لمزيد من المعلومات التفصيلية.
يقوم OpenResty بالحفاظ على هذه الترقيعات في نص حزمة OpenSSL بنفسه. عندما يقوم OpenResty بترقية إصدار OpenSSL
، يجب عليه إعادة إنشاء الترقيع المقابل وإجراء اختبارات رجوع كاملة.
Source0: https://www.openssl.org/source/openssl-%{version}.tar.gz
Patch0: https://raw.githubusercontent.com/openresty/openresty/master/patches/openssl-1.1.0d-sess_set_get_cb_yield.patch
Patch1: https://raw.githubusercontent.com/openresty/openresty/master/patches/openssl-1.1.0j-parallel_build_fix.patch
في الوقت نفسه، يمكننا إلقاء نظرة على نص الحزمة لـ OpenResty في CentOS لمعرفة ما إذا كانت هناك نقاط خفية أخرى:
BuildRequires: perl-File-Temp
BuildRequires: gcc, make, perl, systemtap-sdt-devel
BuildRequires: openresty-zlib-devel >= 1.2.11-3
BuildRequires: openresty-openssl-devel >= 1.1.0h-1
BuildRequires: openresty-pcre-devel >= 8.42-1
Requires: openresty-zlib >= 1.2.11-3
Requires: openresty-openssl >= 1.1.0h-1
Requires: openresty-pcre >= 8.42-1
كما ترى هنا، يحافظ OpenResty على إصداره الخاص من OpenSSL
وإصداره الخاص من zlib
و PCRE
. ومع ذلك، قام الأخيران بتعديل معلمات التجميع ولم يحتفظا بترقيعاتهما.
لذلك، مع مراعاة هذه العوامل، لا أنصح بتجميع OpenResty من الأكواد المصدرية إلا إذا كنت تعرف التفاصيل بالفعل.
يجب أن يكون واضحًا لك الآن لماذا لا أنصح بالتثبيت من الكود المصدري. عندما أجبنا على السؤال الأول، أجبنا أيضًا على السؤال الثاني: لماذا لا يمكن التثبيت مباشرة من مستودعات الحزم الرسمية لنظام التشغيل بل يجب إعداد مستودع آخر أولاً؟
هذا لأن المستودعات الرسمية لا ترغب في قبول حزم OpenSSL
، PCRE
، و zlib
التي يحتفظ بها أطراف ثالثة لمنعها من التسبب في ارتباك للمستخدمين الآخرين الذين لا يعرفون أي واحد يختارون. من ناحية أخرى، يحتاج OpenResty إلى إصدارات محددة من مكتبات OpenSSL
و PCRE
ليعمل بشكل طبيعي، والإصدارات الافتراضية للنظام قديمة نسبيًا.
واجهة سطر أوامر OpenResty
بعد تثبيت OpenResty، يتم تثبيت واجهة سطر أوامر OpenResty resty
بشكل افتراضي. إنها نص Perl
، وكما ذكرنا سابقًا، فإن أدوات نظام OpenResty مكتوبة جميعها بـ Perl
، وهو ما يحدده تفضيل المؤلف التقني لـ OpenResty.
$ which resty
/usr/local/bin/resty
$ head -n 1 /usr/local/bin/resty
#!/usr/bin/env perl
واجهة سطر أوامر resty
قوية جدًا، ويمكننا استخدام resty -h
أو قراءة الوثائق الرسمية للحصول على قائمة كاملة بالوظائف. بعد ذلك، سأقدم ميزتين مثيرتين للاهتمام.
$ resty --shdict='dogs 1m' -e 'local dict = ngx.shared.dogs dict:set("Tom", 56) print(dict:get("Tom"))'
56
يوضح المثال أعلاه تكوين Nginx
مع كود Lua
، والذي يقوم بإعداد واستعلام قاموس ذاكرة مشتركة. dogs 1m
هو تكوين Nginx
يعلن عن مساحة ذاكرة مشتركة باسم dogs
بحجم 1m
. يتم استخدام الذاكرة المشتركة كقاموس في كود Lua.
أيضًا، يتم استخدام المعلمات --http-include
و --main-include
لإعداد ملف تكوين NGINX
، لذا يمكننا إعادة كتابة المثال أعلاه على النحو التالي:
$ resty --http-conf 'lua_shared_dict dogs 1m;' -e 'local dict = ngx.shared.dogs dict:set("Tom", 56) print(dict:get("Tom"))'
أدوات التصحيح القياسية في عالم OpenResty، مثل gdb
، valgrind
، sysetmtap
، و Mozilla rr
يمكن أيضًا استخدامها مع resty
لتسهيل التطوير والاختبار العاديين. لديهم أوامر مقابلة لـ resty
، لذا فإن التطبيق الداخلي بسيط، مجرد طبقة إضافية من استدعاءات سطر الأوامر. لنأخذ valgrind
كمثال.
$ resty --valgrind -e "ngx.say('hello world'); "
ERROR: failed to run command "valgrind /usr/local/openresty/nginx/sbin/nginx -p /tmp/resty_rJeOWaYGIY/ -c conf/nginx.conf": No such file or directory
إنها ليست فقط قابلة للتطبيق في عالم OpenResty، بل هي أيضًا أدوات عامة للجانب الخادم، لذا دعونا نتعلمها خطوة بخطوة.
"hello world" أكثر رسمية
أول برنامج OpenResty كتبناه في البداية استخدم أمر resty
بدون عملية master
وبدون الاستماع على منافذ محددة. بعد ذلك، دعونا ننفذ برنامج hello world
آخر.
نحتاج إلى ثلاث خطوات على الأقل لإكماله.
- إنشاء دليل عمل.
- تعديل ملف تكوين
NGINX
لتضمين كودLua
فيه. - بدء خدمة
OpenResty
.
لنبدأ بإنشاء دليل عمل.
$ mkdir openresty-sample
$ cd openresty-sample
$ mkdir logs/ conf/
فيما يلي تكوين nginx.conf
بسيط مع توجيه content_by_lua
الخاص بـ OpenResty في الدليل الجذر، والذي يضمّن طريقة ngx.say.
events {
worker_connections 1024;
}
http {
server {
listen 8080;
location / {
content_by_lua '
ngx.say("hello, world")
';
}
}
}
يرجى التأكد من إضافة openresty إلى متغير البيئة PATH
أولاً؛ ثم بدء خدمة OpenResty:
$ openresty -p `pwd` -c conf/nginx.conf
إذا لم تحدث أية أخطاء، فقد تم بدء خدمة OpenResty بنجاح. يمكننا الوصول إليها باستخدام أمر cURL لرؤية النتائج المرتجعة.
$ curl -i 127.0.0.1:8080
HTTP/1.1 200 OK
Server: openresty/1.13.6.2
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
hello, world
تهانينا! لقد اكتمل برنامج Hello World
الرسمي في OpenResty!
الخلاصة
دعونا نراجع ما تعلمناه اليوم. أولاً، نبدأ بتثبيت OpenResty وواجهة سطر الأوامر بسطر بسيط من كود "hello, world"، وأخيرًا نبدأ عملية OpenResty ونشغل برنامج خلفي فعلي.
من بينها، resty
هو أداة سطر أوامر سنستخدمها بشكل متكرر في المستقبل. لذلك، يتم تشغيل كود العرض التوضيحي في الدورة باستخدامه، بدلاً من بدء خدمة OpenResty في الخلفية.
الأهم من ذلك، أن هناك العديد من التفاصيل الثقافية والتقنية المخفية وراء OpenResty، وهي تشبه جبل جليد يطفو على البحر. من خلال هذه الدورة، أتمنى أن أريكم OpenResty بشكل أكثر شمولاً، وليس فقط واجهات برمجة التطبيقات الظاهرة.