مرحبا يا هبر. في هذا المنشور نريد أن نتحدث عن كيف ولماذا نستخدم لغة برمجة تحمل الاسم الجميل Lua في IPONWEB.
Lua هي لغة برمجة مضمنة تستند إلى نص برمجي مع مترجم مجاني ومصدر مفتوح في C. تم تطويره في البرازيل في عام 1993 ، في قسم Tecgraf في الجامعة الكاثوليكية في ريو دي جانيرو ، وكان منشئوها DEL (لغة إدخال البيانات) و SOL (لغة كائن بسيط) وضعت هناك في وقت سابق. أحد الأجداد ، لغة SOL ، شارك بشكل غير مباشر في "معمودية" الوليد - تمت ترجمة "Sol" من البرتغالية إلى "شمس" ، وتمت تسمية اللغة الجديدة "Lua" ، "moon".
إن سهولة تضمين Lua في محركات مكتوبة بلغات "النظام" جعلت منها لغة برمجة مشهورة لألعاب الفيديو. على سبيل المثال ، يتم كتابة البرامج النصية في Lua في Grim Fandango و Baldur's Gate. من المحتمل أن أولئك الذين يلعبون في World of Warcraft قد سمعوا أيضًا عن Lua أكثر من مرة أو مرتين - فهناك إضافات للعبة مكتوبة تجعل الحياة أسهل للاعبين المتشددين ، والمراوح غير الرسمية ، والمشجعين لقياس فعاليتهم وغيرهم من سكان عالم اللعبة. خارج gamedev ، يتم استخدام Lua كلغة برمجة للأنظمة المدمجة (أجهزة التلفزيون والطابعات ولوحات السيارة) ، وكذلك التطبيقات ، على سبيل المثال ، VLC Media Player. يستخدم Lua أدوات مثل Tarantool و Redis و OpenResty كلغة مضمنة. تم استخدام Lua أيضًا كلغة امتداد لرموز فورتران الحاسوبية التي تحاكي السلوك الميكانيكي الحراري للوقود النووي.
لماذا لوا؟
IPONWEB هو مطور لمنصات محملة للغاية للشركات العاملة في مجال الإعلان عبر الإنترنت: DSP ، SSP ، وكالات الإعلان والمعلنين. تحدثنا بالتفصيل عن عملنا
في هذه المقالة . في البداية ، قمنا بتطوير منطق الأعمال الخاص بمنصاتنا في C ++ ، ولكن سرعان ما أدركنا أن هذا لم يكن الخيار الأفضل. لتقليل التكاليف ، يعد أداء المنصة أمرًا مهمًا ، وكذلك سرعة التطوير ، كما أن تطوير C ++ كان بطيئًا للغاية بالنسبة لنا ، كما تأثر تعقيد إضافة الوظائف أيضًا. قررنا عزل تفسير منطق العمل عن رمز الخادم ذي المستوى المنخفض ، وبدأنا في البحث عن لغة مناسبة لذلك ، واستقرنا على Lua. في عام 2008 ، تطبيقات جافا سكريبت التي كانت مناسبة لنا لم تكن موجودة بعد ، بيرل وبيثون وروبي كانت بطيئة للغاية ولم يكن من السهل دمجها. وكانت هناك لغة Lua ، ليست معروفة جيدًا ، ولكنها شائعة في تطوير اللعبة ، وما أردناه كان مشابهًا لاحتياجات مطوري الألعاب - لقد احتجنا إلى محرك سريع للعمليات منخفضة المستوى ولغة سريعة مضمنة بسهولة لمنطق الأعمال.
لوا هي حقا لغة سريعة جدا. يمكن
تحقيق زيادة إضافية في السرعة باستخدام
LuaJIT ، بيئة التشغيل لـ Lua 5.1 ، والتي تتضمن مترجم JIT للبحث عن المفقودين (نستخدم مفترق الطرق الخاص بنا ، والذي
كتبنا عنه بالفعل). نظرًا لأننا نكتب منطق الأعمال لأنظمة
RTB ، فإن السرعة أمر بالغ الأهمية بالنسبة لنا: في RTB ، في المتوسط ، هناك 120 مللي ثانية لمعالجة كل طلب وارد. في الوقت نفسه ، يتم تخصيص 10-15 مللي ثانية فقط لتنفيذ التعليمات البرمجية ، وبقية الوقت في انتظار استجابة من خدمات أخرى. على سبيل المثال ، إذا لم يلاحظ المستخدم تأخيرًا لمدة نصف ثانية عند تحميل موقع على الشبكة ، فإن هذه ال 500 مللي ثانية بالنسبة إلى RTB هي فترة ضخمة من الوقت. الإجابة على سؤال حول مدى سرعة لغة Lua: إنها سريعة بما يكفي حتى نتمكن من كتابة منطق العمل عليها لسنوات عديدة والبقاء في أعمال RTB. إذا كانت اللغة التي اخترناها لم تكن بالسرعة الكافية ، فلن يكون لدينا من يكتب منها. هل هذا يعني أنه لا يمكن كتابة RTB بلغات أخرى؟ لا يعني لكننا نكتب RTB في Lua ونتعامل بنجاح مع مهامنا التجارية وعملائنا. مثال جيد على سرعة Lua على الخادم هو
معيار OpenResty.
تتميز لغة Lua كلغة مضمنة بالعديد من المزايا: فهي أضيق الحدود ، مدمجة ، مع مكتبة قياسية صغيرة جدًا. تتكرر وظيفتها تمامًا في لغة C ، والتي توفر تفاعلًا سهلاً وسهلاً بين Lua و C. Lua لديها حد تسجيل دخول منخفض إلى حد ما مقارنة بالعديد من اللغات الأخرى: معظم المبرمجين الذين يأتون للعمل في IPONWEB لم يكتبوا إلى Lua من قبل ، لكن لديهم ما يكفي عدة أيام للانخراط بشكل كامل في العمل.
فيما يلي مثال بسيط لاستهداف جمهور الإعلان.
وهذه هي الطريقة التي يبدو بها معالج بسيط (معالج الأحداث).
local adm_cache = require 'modules.adm_cache'
لا توفر بساطة Lua تطورًا سريعًا فحسب ، بل تتيح لك أيضًا القيام بالكثير من العمل دون بذل مجهود كبير. تعد منصة IPONWEB حلاً عامًا مصممًا وفقًا لاحتياجات عميل معين ، بينما يمكن لمطور واحد ومدير واحد إجراء المشروع. قراءة التعليمات البرمجية على لوا لا يمكن للمطورين أنفسهم فقط ، ولكن أيضا مديري المشاريع ، وأحيانا العملاء. معا ، نكتشف المشكلة بسرعة ، ونجد السبب والحل. في كثير من الأحيان ، يقوم مدير المشروع بإبلاغ المطور بالمشكلة ويقترح على الفور طريقة لحلها.
في الوقت نفسه ، يمكن أن تكون بساطة لوا مخادعة ، في حين أن بساطتها وتناقصها جانب سلبي. إذا كان الرمز مكتوبًا ، على سبيل المثال ، في Perl أو Python ، فإن للمطور تحت تصرفه مستودعات ضخمة من الوحدات الجاهزة ، يحتوي Ruby على RubyGems ، والعديد من اللغات الأخرى بها مستودعات غنية. ولوا لديها
LuaRocks وثلاثة آلاف وحدات التي تكمن هناك. بالإضافة إلى ذلك ، حتى لو كان لدى LuaRocks الوحدة المناسبة ، فمن المحتمل جدًا أنك ستضطر إلى العمل بجد لاستخدامها في شركة معينة. يوفر Lua أدوات جيدة لإنشاء بيئة آمنة لتنفيذ التعليمات البرمجية (صناديق الحماية) ، وعند العمل في صناديق الحماية ، يمكن تعطيل بعض الوظائف. هذا يعني أن وحدات LuaRocks قد لا تعمل إذا كانت تستخدم وظائف محظورة بواسطة البيئة الآمنة للشركة. هذا هو ثمن الاكتناز والتضمين ، لكن الأمر يستحق الثمن - اللغات مع البطاريات ، على سبيل المثال ، بيثون ، لا يتم بناؤها بطريقة أكثر تعقيدًا من لوا.
كيف يعمل؟
أساس نظامنا الأساسي هو خادم HTTP قابل للتخصيص مع واجهة برمجة تطبيقات ملائمة وقابلة للتوسيع توفر مجموعة من الوظائف لمطور Lua ومصممة خصيصًا لمهام سوق الإعلانات. يعالج هذا الخادم مئات الملايين من الطلبات ويكتب تيرابايت من السجلات يوميًا. يتم توزيع الطلبات الواردة بالتساوي عبر مؤشرات ترابط النظام ، وداخل مؤشرات ترابط النظام صناديق رمل.

عندما يصل الطلب إلى الخادم ، يتم إنشاء
coroutine داخل الصندوق الرمل الذي سقط فيه هذا الطلب ، والذي يعالج الطلب. تعمل Coroutines بشكل مستقل عن بعضها البعض ، يتم وضع قائمة انتظار لكل coroutine قيد التنفيذ. يجب ألا يتجاوز عمر كل coroutine (إجمالي وقت معالجة الطلب ، مع مراعاة الاستجابة المتوقعة للخدمات المعنية: قاعدة البيانات ، والمقاييس ، وخادم الميزانية) 120 مللي ثانية.

باختصار ، يمكن وصف عملية معالجة الطلب على النحو التالي:
- يتم تحليل كل طلب مستلم ويمرر شيكًا قياسيًا للتأكد من صحته.
- تم إطلاق Corutin ، وهو المسؤول عن معالجة هذا الطلب. داخل كل رمل ، هناك العديد من coroutines في أوضاع مختلفة.
- طلب بدء المعالجة ، والذي يمكن أن يكون له نتيجتين:
- اكتملت المعالجة بنجاح.
- Corutin ينقل التحكم إلى الخادم. يحدث هذا عادة عندما ينتظر coroutine استجابة من الخدمات الأخرى. في مثل هذه الحالات ، يتم تعليق عمل corutin حتى يصل الرد أو تنتهي مدة الانتظار. عند نقل التحكم ، يبدأ الخادم بمعالجة الطلب التالي. يمكن أن يكون هذا إما طلبًا جديدًا أو طلبًا يتلقى استجابة من جميع الخدمات المعنية ومستعدًا لتنفيذ التعليمات البرمجية. يتم تحديد ترتيب معالجة الطلبات حسب متطلبات منطق الأعمال.

استخدام كوروتين هو موضوع آخر مثير للاهتمام يستحق مناقشة مفصلة. على سبيل المثال ، تفاصيل
هذه المقالة كيف يمكن استخدام corutins لإنشاء cutscenes في ألعاب الفيديو. وينبغي أن يكرس coroutines على خادم التطبيق مقالة منفصلة ، وربما في المستقبل سنفعل ذلك.
ما التالي؟
وبعد ذلك ، ربما ، سيتم توسيع استخدام Lua في IPONWEB. لدينا أفكار حول كيفية الاستمرار في استخدام Lua في أعمالنا ، وعندما يتم تنفيذ هذه الأفكار ، سنشارك بالتأكيد تجارب جديدة. يمكن أن تساعدنا راحة Lua وقدراته كلغة برمجة مضمنة ، على وجه الخصوص ، في تسريع معالجة بيانات العميل. ولكن هذا لا يزال من مجال الخطط والتوقعات.
بإيجاز ، يمكننا القول أن اختيارنا لمنطق لغة العمل ، الذي تم إجراؤه قبل 11 عامًا ، ما زال يبرر نفسه ، مما يسمح لنا بالتعامل بنجاح مع مهام أعمالنا ومساعدتنا في حل مشكلات عملائنا. نظرًا لسهولة القراءة وسهولة الاندماج وسرعة وسهولة التعلم ، فإن Lua كانت ولا تزال واحدة من أفضل لغات البرمجة النصية التي لا يقتصر نطاقها على تطوير اللعبة بأي حال من الأحوال. ومن الأمثلة على ذلك منطق عمل IPONWEB المكتوب عليه.