ميكروسيرفيسز باستخدام JavaScript: الهندسة والممارسة من الألف إلى الياء

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا الميكروسيرفيسز باستخدام JavaScript؟

\n

تتجه تطوير الويب الحديث بشكل متزايد بعيدًا عن التطبيقات المتجانسة نحو بنية الميكروسيرفيسز. JavaScript، وبشكل أكثر تحديدًا بيئة الخادم الخاصة بها Node.js، مناسبة تمامًا لبناء الميكروسيرفيسز بفضل عدم التزامن، والنموذج الموجه بالأحداث، ومجتمع النظام البيئي الضخم. في هذه المقالة، سنشرح كيفية تصميم وتطوير ونشر الميكروسيرفيسز باستخدام JavaScript - من النظرية إلى الأمثلة العملية للكود.

\n\n

1. أساسيات هندسة الميكروسيرفيسز

\n

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

\n

مزايا الميكروسيرفيسز على Node.js

\n
    \n
  • قابلية التوسع: يتعامل Node.js بسهولة مع آلاف الاتصالات المتزامنة بفضل الإدخال/الإخراج غير المحظور.
  • \n
  • النماذج الأولية السريعة: تسمح حزم npm وأطر العمل (Express، Fastify، NestJS) بإنشاء REST/GraphQL API بسرعة.
  • \n
  • عزل الأخطاء: فشل في خدمة واحدة لا يشل التطبيق بأكمله.
  • \n
  • المرونة التقنية: يمكن للخدمات المختلفة استخدام إصدارات مختلفة من Node.js أو حتى لغات مختلفة.
  • \n
\n

المكونات الرئيسية

\n
    \n
  • API Gateway - نقطة دخول واحدة، تقوم بتوجيه الطلبات إلى الخدمات المناسبة.
  • \n
  • وسيط الرسائل (RabbitMQ، Redis، Kafka) - للتبادل غير المتزامن للبيانات.
  • \n
  • سجل الخدمات (Consul، etcd) - لاكتشاف الخدمات.
  • \n
  • الحاويات (Docker، Kubernetes) - لتوحيد البيئة.
  • \n
\n\n

2. الممارسة: إنشاء ميكروسيرفيسين

\n

سنشرح مثالاً لنظام الطلبات. سيكون لدينا ميكروسيرفيسان: user-service (إدارة المستخدمين) و order-service (إدارة الطلبات). سيتواصلان عبر REST API وبشكل غير متزامن عبر RabbitMQ.

\n\n

2.1. الخدمة الأساسية على Express

\n

لنبدأ بـ user-service. قم بتثبيت التبعيات:

\n
npm init -y\nnpm install express body-parser
\n

أنشئ ملف index.js:

\n
const express = require('express');\nconst bodyParser = require('body-parser');\nconst app = express();\nconst PORT = process.env.PORT || 3001;\n\napp.use(bodyParser.json());\n\nconst users = [];\n\napp.post('/users', (req, res) => {\n    const { name, email } = req.body;\n    const user = { id: users.length + 1, name, email };\n    users.push(user);\n    res.status(201).json(user);\n});\n\napp.get('/users/:id', (req, res) => {\n    const user = users.find(u => u.id === parseInt(req.params.id));\n    if (!user) return res.status(404).json({ error: 'User not found' });\n    res.json(user);\n});\n\napp.listen(PORT, () => {\n    console.log(`User service running on port ${PORT}`);\n});
\n

وبالمثل، أنشئ order-service على المنفذ 3002. سيحتوي على مصفوفة من الطلبات ونقطتي نهاية: POST /orders و GET /orders/:id.

\n\n

2.2. API Gateway

\n

لننشئ بوابة بسيطة على المنفذ 3000، تقوم بإعادة توجيه الطلبات بناءً على المسار:

\n
const express = require('express');\nconst httpProxy = require('http-proxy-middleware');\nconst app = express();\n\napp.use('/users', httpProxy.createProxyMiddleware({ target: 'http://localhost:3001', changeOrigin: true }));\napp.use('/orders', httpProxy.createProxyMiddleware({ target: 'http://localhost:3002', changeOrigin: true }));\n\napp.listen(3000, () => console.log('API Gateway on port 3000'));
\n

الآن جميع الطلبات إلى /users تذهب إلى user-service، والطلبات إلى /orders تذهب إلى order-service.

\n\n

2.3. التفاعل غير المتزامن مع RabbitMQ

\n

لنفترض أنه عند إنشاء ط

المدونات

توصيات الكتب