Feathers: الخدمات المصغرة: الطريقة الموصى بها لإعادة تشكيل التطبيق عن طريق تقسيم الخدمات؟

تم إنشاؤها على ١٩ مايو ٢٠١٦  ·  27تعليقات  ·  مصدر: feathersjs/feathers

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

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

لكن ، ما زلت لا أستطيع العثور على معلومات حول كيفية التعامل مع حالة الاستخدام هذه في الريش.

من الناحية العملية ، أركز في البداية على موضوعين أساسيين:

  • الاتصال: أعتقد أنه يجب أن يكون وسيلة لاستخراج خدمة والسماح للتطبيق الأصلي بمواصلة الاتصال دون الحاجة إلى جهد كبير لإعادة الكتابة ، على سبيل المثال ، عن طريق استبدال الدعوات للخدمة بطلبات HTTP ، على سبيل المثال.
  • المصادقة: توضيحات حول كيفية تعامل الريش مع المصادقة تجاه الاتصال بين الخدمات بعد تقسيم الخدمة.

شكرا مقدما!

Documentation Question Scaling

التعليق الأكثر فائدة

أنت على حق ، ليس هناك الكثير من الوثائق حتى الآن وقد أنشأنا https://github.com/feathersjs/feathers/issues/157 منذ فترة قصيرة لتتبع ذلك. فيما يلي بعض أفكاري حول الموضوعين اللذين ذكرتهما:

لنفترض أن لدينا في البداية خادمًا بخدمتين ، ربما شيء من هذا القبيل

app.use('/users', memory())
  .use('/todos', memory());

تحصل خدمة المستخدمين على حركة مرور أكثر مما يمكن للخادم التعامل معه ، لذلك نريد نقلها إلى نظام آخر عن طريق إنشاء تطبيق آخر لها:

// server1
app.use('/users', memory());
// server2
app.use('/todos', memory());

بالنسبة لخدمة /todos للاتصال الآن بالخدمة البعيدة ، يمكننا استخدام Feathers كعميل للاتصال بها (مآخذ الويب سريعة وثنائية الاتجاه ، فلماذا لا تستخدمها للاتصال من خادم إلى خادم؟):

// server2
const client = require('feathers/client')
const socketClient = require('feathers-socketio/client');
const io = require('socket.io-client');

const socket = io('http://other-server.com');
const otherApp = client().configure(socketClient(socket));

app.use('/todos', memory())
 .use('/users', otherApp.service('users'));

سيؤدي ذلك إلى تمرير خدمة المستخدم بشفافية إلى الخدمة البعيدة من خلال اتصال websocket. لن يضطر أي شيء يستخدم نقطة النهاية الأصلية /users إلى تغيير أي شيء.

بالنسبة للمصادقة ، هناك العديد من الخيارات المختلفة. في السيناريو أعلاه ، فإن أسهل طريقة هي أن تكون server1 لإضافة عنوان IP للخوادم الأخرى إلى القائمة البيضاء فقط لأن server2 لا يزال هو نقطة الاتصال الوحيدة للعملاء. في النهاية ، يمكن أن يصبح server2 بوابة تتعامل مع مصادقة المستخدم ثم تقوم فقط بتمرير مكالمات الخدمة إلى الخوادم الأخرى (التي لا داعي للقلق بشأن المصادقة بخلاف التحقق من عنوان IP الأصلي).

ال 27 كومينتر

أنت على حق ، ليس هناك الكثير من الوثائق حتى الآن وقد أنشأنا https://github.com/feathersjs/feathers/issues/157 منذ فترة قصيرة لتتبع ذلك. فيما يلي بعض أفكاري حول الموضوعين اللذين ذكرتهما:

لنفترض أن لدينا في البداية خادمًا بخدمتين ، ربما شيء من هذا القبيل

app.use('/users', memory())
  .use('/todos', memory());

تحصل خدمة المستخدمين على حركة مرور أكثر مما يمكن للخادم التعامل معه ، لذلك نريد نقلها إلى نظام آخر عن طريق إنشاء تطبيق آخر لها:

// server1
app.use('/users', memory());
// server2
app.use('/todos', memory());

بالنسبة لخدمة /todos للاتصال الآن بالخدمة البعيدة ، يمكننا استخدام Feathers كعميل للاتصال بها (مآخذ الويب سريعة وثنائية الاتجاه ، فلماذا لا تستخدمها للاتصال من خادم إلى خادم؟):

// server2
const client = require('feathers/client')
const socketClient = require('feathers-socketio/client');
const io = require('socket.io-client');

const socket = io('http://other-server.com');
const otherApp = client().configure(socketClient(socket));

app.use('/todos', memory())
 .use('/users', otherApp.service('users'));

سيؤدي ذلك إلى تمرير خدمة المستخدم بشفافية إلى الخدمة البعيدة من خلال اتصال websocket. لن يضطر أي شيء يستخدم نقطة النهاية الأصلية /users إلى تغيير أي شيء.

بالنسبة للمصادقة ، هناك العديد من الخيارات المختلفة. في السيناريو أعلاه ، فإن أسهل طريقة هي أن تكون server1 لإضافة عنوان IP للخوادم الأخرى إلى القائمة البيضاء فقط لأن server2 لا يزال هو نقطة الاتصال الوحيدة للعملاء. في النهاية ، يمكن أن يصبح server2 بوابة تتعامل مع مصادقة المستخدم ثم تقوم فقط بتمرير مكالمات الخدمة إلى الخوادم الأخرى (التي لا داعي للقلق بشأن المصادقة بخلاف التحقق من عنوان IP الأصلي).

شكرا للإستجابة! هل تخطط لتغطية هذا الموضوع في المستندات الرسمية (ربما قسم فرعي من الأدلة)؟ اسمحوا لي أن أعرف ما إذا كان بإمكاني المساهمة في هذا الصدد.

بالتااكيد. ويمكننا بالتأكيد استخدام بعض المساعدة. ربما دعنا نجمع أولاً ما نود أن نراه في دليل ثم نجعل بعض التطبيقات التجريبية؟

💯daffl غير فرقعة جرا. هذا شيء أخطط لمعالجته رسميًا خلال الشهر المقبل أو نحو ذلك لأنني التزمت بتقديم عرض تقديمي عنه.

daffl الأسلوب الذي ذكرته باستخدام

نعم ولكن لماذا لا تستطيع الخدمات المهتمة الأخرى استخدام مآخذ الويب؟ نحن نفكر في إضافة موفرين آخرين (على سبيل المثال لخدمات المراسلة المختلفة) ولكن في الوقت الحالي يبدو أن مآخذ الويب سريعة بما يكفي ولا تتم كتابتها في أي مكان بحيث يمكن استخدامها فقط في المتصفح.

dafflekryski كما تصبح التطبيقات الموزعة الريش، فإننا بحاجة أيضا إلى معالجة قضايا مثل المعرضين للالأقل مرة واحدة تسليم (ACKS)، idempotency، والمعاملات، احداهما (الطوابير)، وما إلى ذلك هل تعتبر شيئا مثل "الريش المصرية- عامل؟ ".. أي. العمليات الخارجية التي تستهلك الأحداث من طابور amqp الدائم (أي rabbitmq) أو redis (باستخدام ie kue)؟

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

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

أي تقدم في هذا؟ أرغب حقًا في رؤية بعض الوثائق / مثال عملي. خاصة فيما يتعلق بكيفية التعامل مع المصادقة.

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

يا رجل ، يمكنني استخدام هذا بشكل سيء الآن: د

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

إذا كان لديك بضعة دولارات إضافية ، أعتقد أنه يمكن اعتبار هذا الكتاب موصى به للقراءة: https://www.amazon.com/Building-Microservices-Sam-Newman/dp/1491950358/ref=sr_1_1 ؟ ie = UTF8 & qid = 1469071253 & sr = 8-1 & الكلمات الرئيسية = الخدمات المصغرة

رفاق ، أي تحديثات على هذا؟ شكرا لك.

juanpujol ستكون أحدث المعلومات دائمًا في هذه التذكرة. شكرا للتحقق ، مع ذلك.

(ماركفوزي هنا)

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

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

نعم بالضبط ما قصدته. أميل إلى الاعتقاد بأن الفصل بين الخدمات حيث يكون لكل خدمة ديسيبل خاص بها هو طريقة مؤكدة لفرض التكوين عبر واجهة الخدمة بدلاً من مستوى ORM.

لكن Feathers أكثر عمومية من إطار عمل Microservices ، لذلك كل شيء جيد هنا. شكرا ديفيد! هذا يستمر في الظهور بشكل أفضل وأفضل كلما بحثت فيه! عمل رائع في كل مكان!

فكرت فقط في أن أذكر هذا هنا ، هل يحل بعض المشكلات التي تظهر عند استخدام الريش في بيئة خدمات متناهية الصغر. إنه التطبيق الأول فقط ولكن إذا كان لديك أي شيء تساهم به فلا تتردد في زيارة هذا الرابط https://github.com/zapur1/feathers-rabbitmq/issues/1

@ zapur1 الذي يبدو واعدًا ... لقد قمت بنشر تعليق لبدء المناقشة

يمكنك أيضًا استخدام https://github.com/feathersjs/feathers-sync مع rabbitMQ أو Redis أو MongoDB كوسيط رسائل بين الخدمات لإبقائهم متزامنين جميعًا.

ekryski feathers-sync يحل قليلاً من مشكلة مختلفة ، ماذا لو كنت تريد فقط أن يتم استقبال حدث مرة واحدة في نطاق خدمة محددة (ليست خدمة Feathers ولكن خدمة بأسلوب الخدمات المصغرة)؟ إذا كان لديك مثيلات متعددة لخدمة واحدة تتلقى أحداثًا من تطبيق واجهة برمجة تطبيقات واحد ، فسيتلقى كل واحد الحدث الذي يحتمل أن يكرر الإجراءات التي يتم اتخاذها عند تلقي هذا الحدث عبر مثيلات متعددة من نفس الرمز بالضبط.

ekryski لقد

إذا قمت بتوصيل خدمة 1 بالخدمة 2 بواسطة socketClient ، لذلك إذا كانت خدمتي 2 لها مثيل متعدد ، فكيف يمكنني تنفيذ توازن الحمل :(

إذا قمت بإنشاء تطبيق منفصل على الخادم يتصل عبر socketClient ، فما هي أفضل طريقة للمصادقة بحيث تتوفر أي من الخدمات بغض النظر عن أي قيود تم إعدادها.

أضفت 2 سنت على هذا مع https://github.com/kalisio/feathers-distributed ، فهو يهدف إلى نشر تطبيقات N feathers التي تحتوي على خدمات مختلفة تتحدث معًا ، بحيث يمكنك تطوير كل واحدة بشكل مستقل. إنه يختلف عن https://github.com/feathersjs/feathers-sync الذي يهدف إلى نشر تطبيقات N feathers التي تحمل نفس الخدمات بقدر ما أفهم. كل هذا يثير مجموعة من الأسئلة مثل:

  • إدارة المصادقة
  • بوابة API وموازنة الحمل
  • استدعاء السنانير عن بعد
  • ...

daffl في المثال الذي أعطيته يتضمن الخادم 1 والخادم 2 ، كيف يمكنك تأمين خدمة /users في الخادم 2؟ إذا كانت لدينا هذه الخدمة محددة في الخادم 2 ، فيمكننا استخدام الخطافات في ملف ربط الخدمة المحدد ، ولكن نظرًا لأننا نقوم بعمل app.use('/users', otherApp.service('users')); ، فكيف نتأكد من أن المكالمات إلى هذه الخدمة من الخادم 2 ستتم فقط إذا تمت مصادقة المستخدم أولاً؟

تعديل:
Nvm ، أعتقد أن لدي فكرة: يمكننا القيام بشيء مثل const usersService = app.service('users') ثم usersService.hooks(hooks) حيث تحتوي الخطافات على خطاطيف المصادقة المطلوبة لتأمين نقطة النهاية بشكل صحيح؟

لقد كتبت المزيد حول كيفية إجراء المصادقة الموزعة في https://stackoverflow.com/questions/41076627/evaluating-featherjs-authentication-needs/41095638#41095638 :

هناك عدة طرق لتقسيم الخدمات لكل منها مزاياها وعيوبها. أحد الأشياء المهمة بشكل عام لـ Feathers هو أنه لا توجد جلسات ، فقط رموز ويب JSON. تعد JWTs عديمة الحالة ويمكن قراءتها بواسطة أي خادم يشارك نفس السر حتى لا يكون هناك مخزن جلسات مركزي. الخياران الرئيسيان اللذان يمكنني التفكير فيهما هما:

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

my50m

  1. كل عميل يتصل بكل خادم API يحتاجه باستخدام JWT. يتم إنشاء JWT بواسطة مصادقة منفصلة (أو مستخدم) API. هذا هو الحل الأكثر قابلية للتوسع نظرًا لأن العقبة الوحيدة هي استرداد أحدث معلومات المستخدم من خدمة المستخدمين الشائعة (والتي قد لا تكون ضرورية دائمًا). العيب هو أن الإدارة من جانب العميل أكثر تعقيدًا وأن المصادقة (على الأقل لـ JWT) يجب تكوينها على كل خادم. ومع ذلك ، نظرًا لانعدام الجنسية في JWT ، فلا داعي لوجود أي جلسات مشتركة.

lw1bg

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات