NodeJS: أفضل الممارسات للإنتاج

هذه محاولة لإدراج أهم الممارسات لتطوير ونشر على NodeJs.

لقد كنت أعمل على هذه التكنولوجيا لفترة من الوقت بنفسي. أدرك إمكاناتها الضخمة ومكانتها في عملية التطوير. مع المنافسة الشديدة من لغات مثل Python و Golang ، أثبتت NodeJS فائدتها في حالات الاستخدام المناسبة.

قبل الخوض في أفضل الممارسات practices ، أود أن أقدم مقدمة مختصرة عن ماهية نمط الخدمة المجهرية. ثم خذ المحادثة أبعد من هناك.

لذلك ، ما هي الخدمات الصغيرة؟

خدمات Microservices - المعروفة أيضًا باسم هندسة microservice - هي أسلوب معماري يقوم بتكوين تطبيق كمجموعة من الخدمات التي:

  • صيانة عالية وقابلة للاختبار
  • المتباعدة
  • قابلة للنشر بشكل مستقل
  • نظمت حول القدرات التجارية.

تمكن بنية الخدمات المصغرة من التوصيل / النشر المستمر للتطبيقات الكبيرة والمعقدة. كما أنه يمكّن المؤسسة من تطوير مكدس التكنولوجيا الخاص بها.

كيفية تحديد ما إذا كنت بحاجة إلى خدمات microservices

في البداية ، عندما تبدأ العمل على MVP ، قد لا تحتاج إلى استخدام خدمات microservices. قد لا يكون تحجيم محور Y جدول أعمالك الآن. ولكن عندما يبدأ المنتج في النضج وفي بعض الأحيان في وقت مبكر حيث يتعين عليك التعامل مع القياس ، فإن التحلل في الوحدات الوظيفية يكون أكثر منطقية لأن الأعمال نفسها تتحلل. ستكون هذه هي النقطة الصحيحة لبدء النظر في نمط بنية الخدمات الصغيرة.

الكتاب الذي أوصي به بشدة هو كريس ريتشاردسون هنا: http://bit.ly/2EmJDYt.

يتم النظر إلى الخدمات الصغرية بشكل شائع أثناء استبدال تطبيق متجانس كان شائعًا جدًا حتى وقت قريب عندما بدأت حلول النقل بالحاويات مثل Docker في حكم عالم DevOps. ولكن أكثر عن ذلك لاحقا.

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

لذلك ، ما هو المجال حسب DDD؟

كل مشكلة تحاول حلها هي مجال.

ينقسم كل مجال إلى سياقات محددة بشكل متبادل. هذه السياقات ليست سوى مجالات منفصلة لتلك المشكلة بالذات.

في نمط microservice ، يرتبط كل سياق محدد بـ microservice. تساعدك أنماط DDD على فهم التعقيد في المجال. بالنسبة لنموذج المجال لكل سياق محدد ، يمكنك تحديد وتعريف
الكيانات ، كائنات القيمة ، والمجاميع التي تصمم نطاقك.

بناءً على تعقيد برنامجك ، يمكنك اختيار مبادئ DDD أو تنفيذ نهج أكثر بساطة.

والهدف من ذلك هو تحقيق نموذج مجال مترابط للغاية وغير مترابط. لهذا اتبع هذا النهج:

كانت هذه مقدمة موجزة عن DDD. لمعرفة المزيد حول هذا الموضوع ، أوصي بشدة بقراءة كتاب إريك إيفانز الممتاز http://bit.ly/2Eoy17l.

المضي قدما.

آمل أن تكونوا متمسكين بي.

من هنا فصاعدًا ، سأتحدث أكثر عن الممارسات الخاصة بـ NodeJS. وما أقصده هو أن الخدمات المصغرة و DDD تساعدك على تقييم الإمكانات الحقيقية لـ NodeJS مع ذلك. إنها كاملة في حد ذاتها. كيف؟ سنرى.

الذي تصميم نمط لاستخدام أثناء استخدام NodeJs

تتعلق أنماط التصميم بتصميم البرامج باستخدام معايير معينة معروفة لعدد من المطورين.

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

يسهل هذا النمط فصل منطق MVC مع تسهيل التعامل مع تعريف النموذج وتفاعل النموذج مع بقية المنطق.

إنها تتكون من:

  1. المتحكم: يعالج الطلب والرد والسمات المرتبطة فقط. لن يكون له أي منطق أعمال أو تعريف نموذج أو جمعيات نموذج أيضًا. (اسم المجلد: وحدات التحكم)
  2. الخدمة: أنه يحتوي على منطق الأعمال لخدمة microservice الخاص بك. ينتقل التحكم من وحدة التحكم إلى الخدمة. إنها علاقة 1: 1 بين وحدة التحكم وخدماتها وعلاقة 1: العديد من العلاقات بين الخدمة والمستودعات. (اسم المجلد: الخدمات)
  3. المستودع: يتفاعل مع الطرز التي تعد جزءًا من مجلد النموذج. سيتم تشكيل أي استعلام إلى قاعدة البيانات من خلال طبقة النموذج هنا. لن يكون لها أي منطق تجاري. (اسم المجلد: المستودعات)
  4. الموديل: يحتوي على تعريف النموذج والجمعيات والوظائف الافتراضية (على سبيل المثال في النمس)
  5. الأدوات المساعدة: سيحتوي هذا على فئات / وظائف مساعدة يمكن استخدامها كخدمات. على سبيل المثال: أداة Redis لها كل الوظائف المطلوبة للتفاعل مع Redis. (اسم المجلد: الأدوات المساعدة)
  6. حالة الاختبار: سيشمل ذلك حالات اختبار الوحدة مقابل طرق التحكم لضمان أقصى تغطية للكود. (اسم المجلد: المواصفات)

لقراءة المزيد حول هذا الموضوع ، يمكنك الرجوع إلى هذا الرابط: http://bit.ly/2TrSyRS

حسنا ، أخبرني عن الوحدات العنقودية

يعمل مثيل واحد من Node.js في مؤشر ترابط واحد. للاستفادة من الأنظمة متعددة النواة ، قد يرغب المستخدم في بعض الأحيان في إطلاق مجموعة من عمليات Node.js لمعالجة الحمل.

تسمح وحدة الكتلة بإنشاء عمليات فرعية سهلة تشترك فيها جميع منافذ الخادم.

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

كيفية التعامل مع تدفق التحكم في NodeJS

أثناء استخدام عمليات الاسترجاعات أو الوعود ، قد تكون المكتبات التالية مفيدة:

  1. Async (https://www.npmjs.com/package/async)
  2. Vasync (مع تتبع أفضل للعملية) https://www.npmjs.com/package/vasync
  3. بلوبيرد (التعامل مع الوعود على سبيل المثال. Promise.all إلخ) https://www.npmjs.com/package/bluebird

والحلقات؟

  • حلقة السلسلة: تنفيذ كل خطوة واحدة تلو الأخرى بالترتيب
  • تأخر حلقة: حلقة مع مهلة
  • حلقة متوازية: جمع كل الوعود في حلقة وتنفيذها بالتوازي

وما هي بعض أدوات الفحص المفيدة؟

تقوم أدوات الفحص بتحليل الشفرة بشكل ثابت (دون تشغيلها). وهي تحدد الأخطاء المحتملة أو الأنماط الخطرة. أنماط مثل استخدام المتغيرات غير المعلنة ، أو عبارات "الحالة" داخل مفتاح التبديل بدون عبارة "فاصل".

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

أمثلة من linters هي Javascript lint و JS lint.

حسنًا ، كيف نتعامل مع التسجيل؟

بعض حزم npm شائعة الاستخدام هي:

  • وينستون (https://www.npmjs.com/package/winston)
  • Bunyan (https://www.npmjs.com/package/bunyan)

تنسيق التسجيل المحتمل:

بالنسبة للأنظمة الموزعة مثل الخدمات الصغيرة ، ترغب في استكشاف التتبع الموزع باستخدام ZipKin وما إلى ذلك.

ملاحظة على حزم NPM: يجب عليك استخدام حزمة فقط إذا كان يحل مشكلة بالنسبة لك لا يمكنك حلها بنفسك. قم بإجراء عمليات تدقيق npm بانتظام لإيجاد مشكلات هامة في تبعيات npm.

معالجة الاستثناءات غير المعلنة

بشكل افتراضي ، يعالج Node.js مثل هذه الاستثناءات عن طريق طباعة تتبع المكدس إلى stderr والخروج باستخدام الكود 1 ، متجاوزًا أي عملية تم ضبطها مسبقًا. exitCode

ملاحظة: تؤدي إضافة معالج للحدث "uncaughtException" إلى تجاوز هذا السلوك الافتراضي.

بدلاً من ذلك ، قم بتغيير process.exitCode في معالج "uncaughtException" والذي سينتج عنه إنهاء العملية برمز الخروج المتاح. خلاف ذلك ، في وجود مثل هذا المعالج ، سيتم إنهاء العملية بالرقم 0.

process.exit (0) - الإنهاء الناجح
process.exit (1) - الإنهاء غير الناجح

معالجة الرفض غير المعالج

تعد الوعود في كل مكان في كود Node.js وأحيانًا تكون مقيدة بالسلاسل إلى قائمة طويلة جدًا من الوظائف التي تُرجع الوعود وما إلى ذلك.

يؤدي عدم استخدام معالج رفض .catch (...) مناسب إلى إصدار حدث unhandledRejection. إذا لم يتم اكتشافها وتفتيشها بشكل صحيح ، فقد تسلب نفسك من فرصتك الوحيدة لاكتشاف المشكلة وربما حلها.

نصيحة إضافية:

console.time () و console.timeEnd ()

يحتوي عنصر التحكم على أساليب time () و timeEnd () التي تساعد في تحليل أداء أجزاء التعليمات البرمجية الخاصة بك.

هذا ليس حلاً للإنتاج ولكن يمكن استخدامه عندما لا يكون لديك أدوات أفضل.

شكرا جزيلا على وقتك.
اشترك في النشرة الإخبارية بلدي

مقالات رائعة أخرى عن مواضيع مماثلة:

  1. https://microservices.io
  2. https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/microservice-ddd-cqrs-patterns/ddd-oriented-microservice