تقليل عدد طبقات العمارة من 5 إلى 2


أثناء العمل في العديد من المشاريع مفتوحة المصدر ، قررت يومًا ما تبسيط حياتي وتطوير وحدة Upstream للوحدة nginx ، والتي ساعدتني في إزالة الطبقات الضخمة من الهندسة المعمارية متعددة الطبقات. لقد كانت تجربة ممتعة أود مشاركتها في هذه المقالة. الرمز الخاص بي متاح للجميع هنا: github.com/tarantool/nginx_upstream_module . يمكنك التقاطها من الصفر أو تنزيل صورة Docker من هذا الرابط: hub.docker.com/r/tarantool/tarantool-nginx .

على جدول الأعمال:

  • مقدمة ونظرية.
  • كيفية استخدام هذه التقنيات.
  • تقييم الأداء.
  • روابط مفيدة.

مقدمة ونظرية




هذا ما تبدو عليه بنية الخدمات الصغيرة القياسية. تأتي طلبات المستخدم من خلال nginx إلى خادم التطبيق. يوجد منطق أعمال على الخادم يتفاعل معه المستخدمون.

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

قسمها إلى طبقات:

الطبقة الأولى - nginx.
الطبقة الثانية - خادم التطبيق.
الطبقة الثالثة - ذاكرة التخزين المؤقت.
الطبقة الرابعة - وكيل قاعدة البيانات. هذا الوكيل ضروري لضمان التسامح مع الخطأ والحفاظ على اتصال مستمر بقاعدة البيانات.
الطبقة الخامسة هي خادم قاعدة البيانات.

عند التفكير في هذه الطبقات ، اكتشفت كيفية استبعاد بعضها. لماذا؟ هناك أسباب عديدة. أحب الأشياء البسيطة المفهومة ؛ لا أحب دعم عدد كبير من الأنظمة المختلفة في مجال الإنتاج ؛ وأخيرًا وليس آخرًا ، كلما قل عدد الطبقات ، قل عدد نقاط الفشل. ونتيجة لذلك ، صنعت وحدة Tarantool Upstream تحت nginx ، مما ساعد على تقليل عدد الطبقات إلى طبقتين.



كيف يساعد تارانتول على تقليل عدد الطبقات؟ الطبقة الأولى هي nginx ، والطبقات الثانية والثالثة والخامسة تحل محل تارانتول. الطبقة الرابعة ، وكيل قاعدة البيانات ، موجودة الآن في nginx. الحيلة هي أن تارانتول هي قاعدة بيانات وذاكرة تخزين مؤقت وخادم تطبيق ، ثلاثة في واحد. تربط وحدة المنبع الخاصة بي nginx و Tarantool مع بعضها البعض وتسمح لهم بالعمل بسلاسة دون الطبقات الثلاث الأخرى.



هذا هو شكل الخدمة الجديدة. يرسل المستخدم طلبًا إلى REST أو JSON RPC في nginx باستخدام وحدة Tarantool Upstream. يمكن توصيل الوحدة مباشرة بـ Tarantool ، أو يمكن موازنة التحميل على العديد من خوادم Tarantool. بين nginx و Tarantool نستخدم بروتوكولًا فعالًا يعتمد على MSGPack. ستجد المزيد من المعلومات في هذه المقالة .

يمكنك أيضًا اتباع هذه الروابط لتنزيل Tarantool ووحدة nginx. ولكن أنصحك docker pull tarantool/tarantool-nginx خلال مدير الحزم docker pull tarantool/tarantool-nginx أو باستخدام صورة Docker ( docker pull tarantool/tarantool-nginx ).

صور عامل الميناء: hub.docker.com/r/tarantool/tarantool

وحدة المنبع Tarantool NginX

الحزم الثنائية: Tarantool - تنزيل

كود المصدر: تارانتول

tarantool / nginx_upstream_module

كيفية استخدام هذه التقنيات


هنا مثال لملف nginx.conf. كما ترون ، هذا nginx المنبع العادي. هنا لدينا tnt_pass ، الذي tnt_pass nginx مباشرة tnt_pass المسار الذي يجب وضعه فيه.

nginx-tnt.conf
 http { # upstream upstream tnt { server 127.0.0.1:3301; keepalive 1000; } server { listen 8081; # gateway location /api/do { tnt_pass_http_request parse_args; tnt_pass tnt; } } } 

فيما يلي روابط الوثائق:

nginx.org/en/docs/http/ngx_http_upstream_module.html
github.com/tarantool/nginx_upstream_module/blob/master/README.md

تكوين مجموعة من nginx و Tarantool ، ثم ماذا؟ الآن نحن بحاجة إلى تسجيل وظيفة معالج لخدمتنا ووضعها في ملف. أضعه في ملف "app.lua".

إليك رابطًا لوثائق Tarantool : tarantool.io/en/doc/1.9/book/box/data_model/#index

 -- Bootstrap Tarantool box.cfg { listen='*:3301' } -- Grants box.once('grants', function() box.schema.user.grant('guest', 'read,write,execute', 'universe') end) -- Global variable hello_str = 'Hello' -- function function api(http_request) local str = hello_str if http_request.method == 'GET' then str = 'Goodbye' end return 'first', 2, { str .. 'world!' }, http_request.args end 

الآن فكر في كود لوا.

لدينا Box.cfg {} يقول Tarantool بدء الاستماع على المنفذ 3301، ولكن يمكن أن يستغرق غيرها من المعالم.

Box.once Tarantool استدعاء دالة مرة واحدة.

function api () هي وظيفة سأتصل بها قريبًا. يأخذ طلب HTTP كوسيطة أولى ويعيد مصفوفة من القيم.

لقد حفظت هذا الرمز في ملف وسمته "app.lua". يمكنك تنفيذه بمجرد تشغيل تطبيق Tarantool.

$> tarantool app.lua

نسمي وظيفتنا باستخدام طلب GET. أنا استخدم "wget" لهذا الغرض. بشكل افتراضي ، يحفظ "wget" الاستجابة لملف. ولقراءة البيانات من الملف ، أستخدم "قطة".

 $ wget '0.0.0.0:8081/api/do?arg_1=1&arg_2=2' $ cat do* { “id”:0, # — unique identifier of the request “result”: [ # — is what our Tarantool function returns [“first”], [2], [{ “request”:{“arg_2”:”2",”arg_1":”1"} “1”:”Goodbye world!” }] ]} 

تقييم الأداء


تم إجراء التقييم على بيانات من الإنتاج. الإدخال عبارة عن كائن JSON كبير. يبلغ متوسط ​​حجم هذا الشيء 2 كيلو بايت. خادم فردي ، وحدة معالجة مركزية رباعية النواة ، 90 جيجابايت من ذاكرة الوصول العشوائي ، OS Ubuntu 14.04.1 LTS.

لهذا الاختبار نستخدم عامل nginx واحد فقط. هذا العامل هو موازن مع خوارزمية ROUND-ROBIN بسيطة. يقوم بموازنة الحمل بين عقدتي تارانتول. يتم قياس الحمل باستخدام التقطيع.

توضح هذه الرسوم البيانية عدد القراءات في الثانية. يظهر الرسم البياني العلوي التأخيرات (بالمللي ثانية).



وتظهر هذه الرسوم البيانية عدد عمليات الكتابة في الثانية. يُظهر الرسم البياني العلوي حالات التأخير (بالمللي ثانية)



مثير للإعجاب!

في المقالة التالية سأتحدث بالتفصيل عن REST و JSON RPC.

النسخة الإنجليزية من المقال: hackernoon.com/shrink-the-number-of-tiers-in-a-multitier-arch architecture-from-5-to-2-c59b7bf46c86

Source: https://habr.com/ru/post/ar417829/


All Articles