برنامه نویسی

جداسازی یکپارچه‌ها به میکروسرویس‌ها با پرچم‌های ویژگی

Summarize this content to 400 words in Persian Lang
نوشته شده توسط Kayode Adeniyi✏️

“مونولیت” اصطلاحی است برای توصیف معماری نرم افزاری که در آن یک برنامه کاربردی به عنوان یک واحد واحد و غیر قابل تقسیم ساخته می شود. در این معماری، تمام اجزاء به طور محکم و به هم وابسته هستند.

رویکرد یکپارچه از اوایل دهه 1960 زمانی که در ابتدا در نرم‌افزار پردازش دسته‌ای برای رایانه‌های مرکزی به کار گرفته شد، در توسعه برنامه‌های کاربردی پایه‌ای بود. اهمیت آن تا اواخر دهه 90 ادامه یافت، به ویژه در نرم افزارهای سازمانی که در آن کد سمت سرور اغلب یکپارچه باقی می ماند، علی رغم محاسبات مشتری-سرور که رابط را از منطق تجاری جدا می کرد. چارچوب هایی مانند Ruby on Rails که قرارداد را بر پیکربندی اولویت می دهد، معماری یکپارچه را بیشتر محبوب کرده است.

با این حال، با گسترش پایگاه های کد و پایگاه های کاربر، چالش های مهمی با یکپارچه ها پدیدار شده است. مسائلی مانند مقیاس‌پذیری، پیچیدگی کد و تنگناهای استقرار به طور فزاینده‌ای مانع از تحویل و نگهداری کارآمد نرم‌افزار شده‌اند که باعث کاوش در معماری‌های جایگزین شده است.

معماری میکروسرویس ها به عنوان راه حلی برای بسیاری از این چالش ها پدیدار شده است که مقیاس پذیری پیشرفته ای را ارائه می دهد و گلوگاه های استقرار را کاهش می دهد. علیرغم مزایای آن، گذار از معماری یکپارچه به معماری میکروسرویس چالش‌های اساسی را به همراه دارد، در درجه اول پیچیدگی جداسازی یک برنامه کاملاً یکپارچه.

در این مقاله، نحوه تجزیه موثر یک برنامه یکپارچه را به میکروسرویس ها با استفاده از ویژگی flags و Flagsmith به عنوان ابزار پرچم گذاری ویژگی بررسی خواهیم کرد. ساختن یک باطن Node.js یکپارچه، جدا کردن آن به میکروسرویس‌ها و انتقال درخواست‌های API از یکپارچه به میکروسرویس‌ها با استفاده از پرچم‌گذاری ویژگی در یک محیط محلی را نشان خواهیم داد.

معمولاً اولین سوال در تلاش برای تبدیل یک برنامه monolith به میکروسرویس ها این است که…

نحوه جدا کردن یک برنامه

دشواری جداسازی یک برنامه یکپارچه به عوامل متعددی مانند اندازه پایگاه کد، پیچیدگی کد، زبان برنامه نویسی، منطق تجاری و عملکردهای اصلی که یک برنامه کاربردی انجام می دهد بستگی دارد. تأثیر این معیارها در برنامه های کاربردی متفاوت است، بنابراین باید به صورت موردی در نظر گرفته شود.

برای درک بهتر این موضوع، اجازه دهید یک نسخه نمایشی برای یک برنامه یکپارچه ایجاد کنیم که می‌خواهیم آن را بر اساس معیارهای جداسازی به واحدهای تقسیم‌پذیر تبدیل کنیم.

نسخه ی نمایشی یکپارچه: مورد استفاده کتابفروشی

بیایید عملکردهای اساسی یک برنامه کاربردی یکپارچه را که نشان دهنده یک کتابفروشی است، فرض کنیم که در آن کاربران می توانند خود را ثبت نام کنند، کتاب ها را جستجو کنند، کتاب ها را به سبد خرید اضافه کنند، و اشتراک کتاب های صوتی را خریداری کنند.

با توجه به کسب و کار موفق آنها و ویژگی کتاب صوتی، فروش کتابفروشی شروع به افزایش کرده است و تعداد کاربران فروشگاه به صورت هفتگی افزایش می یابد. با توجه به افزایش ترافیک، فروشگاه شروع به تعطیلی هایی کرده است که ممکن است بر فروش آن تأثیر بگذارد. بنابراین، این پلتفرم تصمیم گرفته است به میکروسرویس ها مهاجرت کند تا همه چیز را ثابت نگه دارد. این امر مستلزم زمان، تلاش و مهمتر از همه، برنامه ای برای نحوه انتقال برنامه های کاربردی آنها به میکروسرویس ها است.

برای جداسازی برنامه ریزی کنید

مرحله 1: زمینه های محدود را شناسایی کنید ابتدا، ما باید “مناطق” یا زمینه های محدود در کتابفروشی را درک و تعریف کنیم. بیایید آن را تجزیه کنیم:

مدیریت کاربر: ثبت نام، ورود، پروفایل کاربری
کاتالوگ محصولات: لیست محصولات، دسته بندی ها، موجودی
سبد خرید: افزودن/حذف اقلام، مشاهده سبد خرید
پردازش سفارش: پرداخت، پیگیری سفارش
فرایند پرداخت: رسیدگی به پرداخت ها

مرحله 2: ایجاد مرزهای میکروسرویس در مرحله بعد، ما یک میکروسرویس جداگانه برای هر زمینه محدود ایجاد می کنیم:

خدمات کاربر: همه چیز مربوط به کاربران را مدیریت می کند
خدمات محصول: محصولات و موجودی را کنترل می کند
خدمات سبد خرید: سبد خرید را مدیریت می کند
سفارش خدمات: سفارشات را پردازش می کند
خدمات پرداخت: پرداخت ها را پردازش می کند

مرحله 3: جداسازی پایگاه داده هر میکروسرویس پایگاه داده خود را خواهد داشت که استقلال سرویس را تضمین می کند و مالکیت داده ها را شفاف می کند. مرحله 4: توسعه API برای ارتباطات هر میکروسرویس APIهای REST خود را برای ارتباطات بین سرویسی خواهد داشت که باعث می‌شود سرویس‌ها به‌طور ضعیفی مرتبط شوند. مرحله 5: اصلاح تدریجی و مهاجرت برنامه monolith به تدریج اصلاح می شود و به موازات برنامه monolith به کار می رود، از سرویس های کمتر بحرانی شروع می شود تا در صورت خرابی چیزی، خطر و شعاع انفجار به حداقل برسد. مثال: جدا کردن کاتالوگ محصولات

استخراج منطق محصول: منطق مدیریت محصول را به سرویس محصول جدید منتقل کنید
راه اندازی پایگاه داده محصول: یک پایگاه داده جداگانه برای داده های محصول ایجاد کنید
توسعه API محصول: ایجاد یک API برای عملیات محصول (CRUD)
کد یکپارچه Refactor: کد مدیریت محصول جدید را به عنوان یک سرویس جداگانه موازی با یکپارچه بنویسید
تست: سرویس محصول را به طور مستقل و با سایر بخش های یکپارچه آزمایش کنید
استقرار: سرویس محصول را مستقر کرده و بر عملکرد آن نظارت کنید

این فرآیند را برای هر میکروسرویس تکرار کنید. مرحله 6: ارتباطات بین خدماتی را پیاده سازی کنید در این مرحله از REST APIها و در صورت لزوم از صف های پیام (مانند RabbitMQ) برای ارتباطات بین سرویس استفاده خواهیم کرد. مثال: خدمات سفارش و تعامل خدمات محصول

Order Service برای بررسی در دسترس بودن محصول قبل از سفارش، با Product Service API تماس می گیرد
اگر کالایی در دسترس باشد، خدمات سفارش به پردازش سفارش ادامه می‌دهد

همانطور که می بینید، یک طرح تعمیم یافته می تواند برای مهاجرت برنامه ها از معماری های قدیمی به معماری های جدید بسیار مفید باشد، اما چالش ها پس از تبدیل یک monolith به یک میکروسرویس همچنان ظاهر می شوند.

و این است…

مسئله مسیریابی مجدد درخواست های API

یکی از چالش های بزرگ با تبدیل یکپارچه به یک میکروسرویس، شروع مسیریابی مجدد درخواست های API به برنامه جدید در حال تولید است. این با خطر اختلال در سرویس‌های موجود و تجربه کاربری بدی همراه است که ممکن است نرخ پرش را برای یک برنامه افزایش دهد، بنابراین باید با کمترین زمان از کار افتادگی، بسیار کارآمد مدیریت شود. برای رسیدن به این هدف، استراتژی‌های زیادی وجود دارد که می‌توانیم از آن‌ها استفاده کنیم، مانند استقرار آبی/سبز یا قناری، و پرچم‌گذاری ویژگی‌ها.

در بخش‌های بعدی، بررسی خواهیم کرد که چگونه پرچم‌گذاری ویژگی می‌تواند به ما در مسیریابی مجدد درخواست‌های API کمک کند.

پرچم گذاری ویژگی به عنوان ابزاری در انتقال برنامه

هنگام انتقال از معماری‌های یکپارچه به میکروسرویس‌ها، پرچم‌گذاری ویژگی یک ابزار حیاتی است. این به توسعه‌دهندگان اجازه می‌دهد تا ویژگی‌ها را در یک برنامه زنده بدون استقرار کد جدید روشن یا خاموش کنند و انعطاف‌پذیری و کنترل فرآیند انتشار را افزایش دهند. این روش از کاهش ریسک و مهاجرت تدریجی پشتیبانی می کند و ادغام و تحویل مداوم را تسهیل می کند و آن را برای شیوه های توسعه نرم افزار مدرن ضروری می کند.

پرچم‌گذاری ویژگی مزایایی از قبیل:

مسیریابی ترافیک کنترل شده: پرچم‌گذاری ویژگی به کنترل مسیریابی درخواست‌های API بین یکپارچه‌ها و میکروسرویس‌ها کمک می‌کند و آزمایش قوی را برای تأیید عملکرد نقاط پایانی میکروسرویس بدون ایجاد اختلال در کل سیستم امکان‌پذیر می‌سازد.
مهاجرت تدریجی: همچنین شما را قادر می سازد تا به صورت تدریجی ویژگی ها یا نقاط پایانی را تغییر دهید. می‌توانید بخش کوچکی از عملکرد را به یک میکروسرویس منتقل کنید، پرچم ویژگی مربوطه را فعال کنید و عملکرد آن را قبل از ادامه مهاجرت تأیید کنید.
کاهش خطر: حتی بعد از همه اقدامات پیشگیرانه، همیشه احتمال خراب شدن چیزی پس از چنین مهاجرت هایی وجود دارد. بنابراین، کاهش ریسک در چنین مواقعی ضروری است. اگر سرویس جدیدی با مشکل مواجه شد، می‌توانید به سرعت پرچم ویژگی را غیرفعال کنید و بدون نیاز به بازگشت، ترافیک را به نسخه monolith برگردانید.
تست A/B برای میکروسرویس ها: پرچم‌های ویژگی همچنین به ما اجازه می‌دهند تا تست A/B را روی میکروسرویس‌ها انجام دهیم. می‌توانید بخشی از ترافیک را به میکروسرویس جدید هدایت کنید، در حالی که بقیه را روی یکپارچه نگه‌دارید، کارایی و قابلیت اطمینان را قبل از انجام کامل مقایسه کنید.

اکنون که دیدی جامع از قابلیت‌های پرچم‌های ویژگی داریم، بیایید از آنها در بخش بعدی استفاده کنیم.

آزمایشگاه: جدا کردن یک نمونه گره یکپارچه به میکروسرویس ها

در این آزمایشگاه، ابتدا یک نمونه پشتیبان Node.js به صورت یکپارچه ایجاد خواهید کرد که دارای نقاط پایانی برای مدیریت است. کاربران و سفارشات. بعد، شما یک را ایجاد خواهید کرد api-gateway و Flagsmith SDK را با آن یکپارچه کنید، عملکرد monolith را به میکروسرویس ها جدا کنید، و در نهایت کل برنامه را برای اجرا و آزمایش آن داکر کنید.

برای پیگیری، به درک موارد زیر نیاز دارید:

Node.js و سرور Express
جاوا اسکریپت
Docker و Docker Compose
REST APIها

ابتدا باید یک پروژه در Flagsmith ایجاد کنیم. یک حساب کاربری (رایگان) ایجاد کنید و در اینجا وارد Flagsmith شوید که فقط چند دقیقه طول می کشد. پس از ورود به سیستم، یک پروژه جدید مانند شکل زیر ایجاد کنید: من نام آن را “مونو به میکرو” گذاشته ام، اما شما می توانید از هر نامی که دوست دارید استفاده کنید.

در مرحله بعد، دو پرچم ویژگی برای میکروسرویس های خود به شرح زیر ایجاد کنید: واکشی کلید محیطی برای ادغام SDK از بخش کلیدهای SDK در نوار منو سمت چپ. شما باید یک کلید محیط سمت سرور ایجاد کنید و آن را ایمن نگه دارید:

اکنون همه چیزهایی را که برای شروع کار نیاز داریم در اختیار داریم…

کدگذاری پروژه

یک پوشه ایجاد کنید و نام آن را بگذارید monolith با دستور زیر:

mkdir monolith

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

├── docker-compose.yml
├── microservices/
│ ├── api-gateway/
│ ├── order-service/
│ └── user-service/
└── monolith/

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

NB، هنگام راه اندازی پروژه های زیر، به یاد داشته باشید که وارد کنید app.js در قسمت نقطه ورودی برای لغو نام پیش فرض index.js، زیرا ما استفاده می کنیم app.js در این راهنما

سپس یک پروژه Node ایجاد کنید و دستور زیر را اجرا کنید:

yarn init

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در package.json فایل، اضافه کردن a scripts موضوع به شرح زیر است:

“scripts”: {
“start”: “node app.js”,
“test”: “nodemon app.js”
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ایجاد کنید app.js در ریشه دایرکتوری قرار دهید و کد زیر را اضافه کنید:

// app.js
const express = require(“express”);
const app = express();
const port = 3000;

// Hardcoded data
const users = [
{ id: 1, name: “Alice” },
{ id: 2, name: “Bob” },
{ id: 3, name: “Charlie” },
];

const orders = [
{ id: 1, item: “Laptop”, quantity: 1, userId: 1 },
{ id: 2, item: “Phone”, quantity: 2, userId: 2 },
{ id: 3, item: “Book”, quantity: 3, userId: 3 },
];

// Routes
app.get(“/users”, (req, res) => {
console.log(“User list from monolith app”, users);
res.json(users);
});

app.get(“/orders”, (req, res) => {
console.log(“Order list from monolith app”, orders);
res.json(orders);
});

app.listen(port, () => {
console.log(`Monolith listening at http://localhost:${port}`);
});

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

سپس دستور زیر را برای نصب چند وابستگی ضروری اجرا کنید:

yarn add express nodemon

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در همان دایرکتوری یک Dockerfile ایجاد کنید و کد زیر را اضافه کنید:

FROM node:18-alpine
RUN apk –no-cache add \
bash \
g++ \
python3
WORKDIR /usr/app
COPY package.json .
RUN yarn install
COPY . .

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اکنون که نمونه برنامه یکپارچه شما با برخی از نقاط پایانی و داده های رمزگذاری شده ساخته شده است، می توانید نقطه پایانی برنامه را با اجرای دستور زیر آزمایش کنید:

yarn test

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این خروجی مورد انتظار است:

برای آزمایش نقاط پایانی، Postman را باز کنید و نقاط پایانی زیر را بزنید: orders-endpoint: http://localhost:3000/orders users-endpoint: http://localhost:3000/users این خروجی مورد انتظار برای است user-service: و این نتیجه مورد انتظار برای order-service:

ما برنامه monolith را با موفقیت آزمایش کردیم، بنابراین اکنون زمان تبدیل آن به میکروسرویس است. ما برنامه را بر اساس عملکردها جدا خواهیم کرد. در حال حاضر، اپلیکیشن monolith را می توان به دو قابلیت متمایز تقسیم کرد: اول، سرویس سفارش، که سفارشات را مدیریت می کند و داده های رمزگذاری شده را برای سفارش ها ارائه می دهد، و دوم، سرویس کاربر، که داده های کاربر کد سخت را ارائه می دهد.

همانطور که می بینید، میکروسرویس هایی که ما در حال ساختن آن ها هستیم، هر کدام مسئولیت یک کار واحد را بر عهده خواهند داشت (این یکی از اصول اصلی جداسازی یک برنامه یکپارچه است).

بیایید به کدنویسی ادامه دهیم…

ایجاد سرویس سفارشات

در کنار دایرکتوری monolith، یک دایرکتوری جدید به نام ایجاد کنید microservices و داخل آن یک Node.js ایجاد کنید order-service پروژه را با اجرای دستورات زیر انجام دهید:

mkdir order-service
cd order-service
yarn init

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

برای نصب چند وابستگی ضروری دستور زیر را اجرا کنید:

yarn add express nodemon

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در package.json file، a اضافه کنید scripts موضوع به شرح زیر است:

“scripts”: {
“start”: “node app.js”,
“test”: “nodemon app.js”
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ایجاد کنید app.js در ریشه دایرکتوری قرار دهید و کد زیر را اضافه کنید:

// app.js
const express = require(“express”);
const app = express();
const port = 3002;

const orders = [
{ id: 1, item: “Laptop”, quantity: 1, userId: 1 },
{ id: 2, item: “Phone”, quantity: 2, userId: 2 },
{ id: 3, item: “Book”, quantity: 3, userId: 3 },
];

app.get(“/orders”, (req, res) => {
console.log(“Order list from microservice app”, orders);
res.json(orders);
});

app.listen(port, () => {
console.log(`Order Microservice listening at http://localhost:${port}`);
});

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در همان دایرکتوری یک Dockerfile ایجاد کنید و کد زیر را اضافه کنید:

FROM node:18-alpine
RUN apk –no-cache add \
bash \
g++ \
python3
WORKDIR /usr/app
COPY package.json .
RUN yarn install
COPY . .

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ایجاد سرویس کاربران

حالا بیایید ایجاد کنیم user-service. در همان دایرکتوری ایجاد خواهد شد order-service، تقریباً همه چیز به جز نقاط پایانی یکسان است. بنابراین، مراحل قبلی مورد استفاده برای ایجاد را تکرار کنید order-service و جایگزین کنید app.js فایل با کد زیر:

// app.js
const express = require(“express”);
const app = express();
const port = 3001;

// Hardcoded data
const users = [
{ id: 1, name: “Alice” },
{ id: 2, name: “Bob” },
{ id: 3, name: “Charlie” },
];

// Routes
app.get(“/users”, (req, res) => {
console.log(“User list from microservice app”, users);
res.json(users);
});

app.listen(port, () => {
console.log(`User microservice listening at http://localhost:${port}`);
});

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ایجاد api-gateway سرویس

در این آخرین مرحله، ما api-gateway به عنوان یک رابط برای تعامل با میکروسرویس های ما عمل می کند و با Flagsmith SDK ادغام می شود.

از آنجایی که این یک برنامه Node.js خواهد بود، مراحل قبلی را برای ایجاد میکروسرویس ها تکرار کنید و فایل نقطه ورودی را جایگزین کنید (app.js) با کد زیر. به یاد داشته باشید که آن را Dockerize کنید زیرا ما تمام خدمات خود را از docker-compose اجرا خواهیم کرد:

// app.js
const express = require(“express”);
const axios = require(“axios”);
const Flagsmith = require(“flagsmith-nodejs”);
const app = express();
const port = 8080;

const flagsmith = new Flagsmith({
environmentKey: “”,
});

// Users route
app.get(“/users”, async (req, res) => {

const flags = await flagsmith.getEnvironmentFlags();
var isEnabled = flags.isFeatureEnabled(“use_user_microservice”);

if (isEnabled) {
const response = await axios.get(“http://user-service:3001/users”);
console.log(“Response from user microservice”, response.data);
res.status(200).json(response.data);

}
else {
const response = await axios.get(“http://monolith-service:3000/users”);
console.log(“Response from monolith service”, response.data);
res.status(200).json(response.data);
}
});

// Orders route
app.get(“/orders”, async (req, res) => {

const flags = await flagsmith.getEnvironmentFlags();
var isEnabled = flags.isFeatureEnabled(“use_order_microservice”);

if (isEnabled) {
const response = await axios.get(“http://order-service:3002/orders”);
console.log(“Response from order microservice”, response.data);
res.status(200).json(response.data);

} else {
const response = await axios.get(“http://monolith-service:3000/orders”);
console.log(“Response from monolith service”, response.data);
res.status(200).json(response.data);
}
});

app.listen(port, () => {
console.log(`API Gateway listening at http://localhost:${port}`);
});

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

توضیح مختصری از api-gateway

کد بالا دو تابع GET دارد: یکی داده های کاربر و دیگری داده های سفارش را واکشی می کند. تصمیمات مسیریابی بر اساس مقدار پرچم دریافت شده از Flagsmith است. اگر پرچم true باشد، ترافیک به سمت میکروسرویس ها هدایت می شود. در غیر این صورت، به برنامه monolith ادامه خواهد داد.

پرچم هایی که در حساب کاربری خود برای هر دو سرویس ایجاد کردم به شرح زیر بود: 1. use_user_microservices 2. use_order_microservices برای اینکه Flagsmith SDK کار کند، باید کلید SDK ایجاد شده از حساب خود را اضافه کنید و از آن در کد استفاده کنید.

ایجاد فایل docker-compose

برای اجرای موازی مونولیت و میکروسرویس ها، باید یک فایل docker-compose بنویسیم تا دید و کنترل بهتری داشته باشیم. ما هر چهار سرویس را به‌عنوان کانتینرهای Docker اجرا می‌کنیم و سپس درخواست‌های API خود را با استفاده از Flagsmith SDK که در مرحله قبل ادغام کردیم، تغییر می‌دهیم.

یک فایل docker-compose که در آن دایرکتوری ها، monolith و microservice ها قرار دارند ایجاد کنید و کد زیر را کپی کنید:

version: “3”

services:
api-gateway:
build: ./microservices/api-gateway
container_name: api-gateway
command: yarn start
hostname: api-gateway
restart: always
ports:
– 8080:8080

monolith-service:
build: ./monolith
container_name: monolith-service
command: yarn start
hostname: monolith-service
restart: always

user-service:
build: ./microservices/user-service/
container_name: user-service
command: yarn start
hostname: user-service
restart: always

order-service:
build: ./microservices/order-service/
container_name: order-service
command: yarn start
hostname: order-service
restart: always

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اکنون دستور زیر را اجرا کنید و تمام کانتینرها شروع به کار خواهند کرد:

docker compose up -d –build

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این خروجی مورد انتظار است:

همه سرورها در حال اجرا هستند و اکنون می‌توانیم پرچم‌گذاری ویژگی Flagsmith را در عمل مشاهده کنیم.

در حال حاضر، هر دو پرچم ما خاموش هستند، بنابراین اگر یک API را بزنید، دروازه درخواست را به برنامه monolith ارسال می کند. برای تست سریع آن، دستور curl را روی آن اجرا کنید api-gateway نقطه پایانی مانند این:

curl http://localhost:8080/users

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

همانطور که در خروجی زیر مشاهده می شود، درخواست به کانتینر یکپارچه هدایت می شود:

آن را تأیید کنید، سیاهههای مربوط به کانتینر را باز کنید api-gateway، و پاسخی مشابه با آنچه در بالا نشان داده شده است خواهید دید.

حالا بیایید به Flagsmith برویم و پرچم ویژگی را روشن کنیم user-service:

ما دوباره همان نقطه پایانی را آزمایش می کنیم، اما این بار اگر آن را باز کنید api-gateway گزارش های کانتینر، یک اعلان متفاوت خواهید دید که نشان می دهد درخواست به جای برنامه monolith به میکروسرویس ارسال شده است:

همانطور که می بینید، علامت گذاری ویژگی در عمل است. ما فقط یک لحظه ترافیک نقطه پایانی را از یکپارچه به میکروسرویس هدایت کردیم.

در حال حاضر، پرچم برای order-service خاموش است، به این معنی که اگر ما به نقطه پایانی دستورات از خود ضربه بزنیم api-gateway، به جای میکروسرویس باید از اپلیکیشن monolith پاسخ بگیریم. سعی کنید نقطه پایانی زیر را زده و خروجی را در قسمت مشاهده کنید api-gateway سیاههها:

curl http://localhost:8080/orders

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در اینجا خروجی مورد انتظار است:

همانطور که می بینید، ما با موفقیت از قابلیت پرچم گذاری ویژگی Flagsmith برای انتقال درخواست API از monolith به میکروسرویس ها استفاده کرده ایم. اگرچه این یک نمایش در مقیاس کوچک است، این مفهوم را می توان تکرار کرد و در محیط های تولیدی مانند Kubernetes برای نمایش نقاط پایانی و خدماتی که اخیراً به میکروسرویس ها تغییر یافته اند، در معرض دید کاربر قرار می گیرد.

پرچم‌گذاری ویژگی Flagsmith می‌تواند در کاهش زمان از کار افتادگی در طول مهاجرت، انجام تست A/B و تسهیل استقرار قناری بسیار مفید باشد.

نتیجه

در این مقاله، تاریخچه مختصری از معماری های کاربردی را پوشش دادیم و ظهور معماری میکروسرویس را بررسی کردیم. ما همچنین یک برنامه وب کتابفروشی ایجاد کردیم تا کاربرد عملی این مفاهیم را نشان دهیم.

در طول نمایش، موضوع تغییر مسیر ترافیک و اینکه Flagsmith چگونه می تواند به حل این مشکل کمک کند را پوشش دادیم. در نهایت، ما یک برنامه آزمایشی را پیاده‌سازی کردیم که در آن دیدیم که چگونه پرچم‌گذاری ویژگی Flagsmith می‌تواند برای تغییر مسیر ترافیک از یک monolith به microservices در یک محیط محلی مفید باشد، که می‌تواند به عنوان مرجعی برای پیاده‌سازی‌های مشابه در یک محیط تولید عمل کند.

برای مطالعه بیشتر در مورد Flagsmith، برای شروع به مستندات رسمی مراجعه کنید.

فقط در دهه 200✓ نظارت بر درخواست های شبکه ناموفق و کند در حال تولید است

استقرار یک برنامه وب یا وب سایت مبتنی بر Node بخش آسانی است. اطمینان از اینکه نمونه Node شما همچنان به ارائه منابع به برنامه شما ادامه می دهد، جایی است که همه چیز سخت تر می شود. اگر می‌خواهید مطمئن شوید درخواست‌ها به پشتیبان یا خدمات شخص ثالث موفقیت‌آمیز هستند، LogRocket را امتحان کنید.

LogRocket مانند یک DVR برای برنامه های وب و تلفن همراه است که به معنای واقعی کلمه هر اتفاقی را که هنگام تعامل کاربر با برنامه شما اتفاق می افتد ضبط می کند. به جای حدس زدن چرایی مشکلات، می‌توانید درخواست‌های شبکه مشکل‌ساز را جمع‌آوری کرده و گزارش دهید تا به سرعت علت اصلی را درک کنید.

LogRocket برنامه شما را برای ضبط زمان‌بندی عملکرد پایه مانند زمان بارگذاری صفحه، زمان تا اولین بایت، درخواست‌های شبکه کند و همچنین گزارش‌های Redux، NgRx، و اقدامات/وضعیت Vuex را ابزار می‌کند. نظارت را به صورت رایگان شروع کنید.

نوشته شده توسط Kayode Adeniyi✏️

“مونولیت” اصطلاحی است برای توصیف معماری نرم افزاری که در آن یک برنامه کاربردی به عنوان یک واحد واحد و غیر قابل تقسیم ساخته می شود. در این معماری، تمام اجزاء به طور محکم و به هم وابسته هستند.

رویکرد یکپارچه از اوایل دهه 1960 زمانی که در ابتدا در نرم‌افزار پردازش دسته‌ای برای رایانه‌های مرکزی به کار گرفته شد، در توسعه برنامه‌های کاربردی پایه‌ای بود. اهمیت آن تا اواخر دهه 90 ادامه یافت، به ویژه در نرم افزارهای سازمانی که در آن کد سمت سرور اغلب یکپارچه باقی می ماند، علی رغم محاسبات مشتری-سرور که رابط را از منطق تجاری جدا می کرد. چارچوب هایی مانند Ruby on Rails که قرارداد را بر پیکربندی اولویت می دهد، معماری یکپارچه را بیشتر محبوب کرده است.

با این حال، با گسترش پایگاه های کد و پایگاه های کاربر، چالش های مهمی با یکپارچه ها پدیدار شده است. مسائلی مانند مقیاس‌پذیری، پیچیدگی کد و تنگناهای استقرار به طور فزاینده‌ای مانع از تحویل و نگهداری کارآمد نرم‌افزار شده‌اند که باعث کاوش در معماری‌های جایگزین شده است.

معماری میکروسرویس ها به عنوان راه حلی برای بسیاری از این چالش ها پدیدار شده است که مقیاس پذیری پیشرفته ای را ارائه می دهد و گلوگاه های استقرار را کاهش می دهد. علیرغم مزایای آن، گذار از معماری یکپارچه به معماری میکروسرویس چالش‌های اساسی را به همراه دارد، در درجه اول پیچیدگی جداسازی یک برنامه کاملاً یکپارچه.

در این مقاله، نحوه تجزیه موثر یک برنامه یکپارچه را به میکروسرویس ها با استفاده از ویژگی flags و Flagsmith به عنوان ابزار پرچم گذاری ویژگی بررسی خواهیم کرد. ساختن یک باطن Node.js یکپارچه، جدا کردن آن به میکروسرویس‌ها و انتقال درخواست‌های API از یکپارچه به میکروسرویس‌ها با استفاده از پرچم‌گذاری ویژگی در یک محیط محلی را نشان خواهیم داد.

معمولاً اولین سوال در تلاش برای تبدیل یک برنامه monolith به میکروسرویس ها این است که…

نحوه جدا کردن یک برنامه

دشواری جداسازی یک برنامه یکپارچه به عوامل متعددی مانند اندازه پایگاه کد، پیچیدگی کد، زبان برنامه نویسی، منطق تجاری و عملکردهای اصلی که یک برنامه کاربردی انجام می دهد بستگی دارد. تأثیر این معیارها در برنامه های کاربردی متفاوت است، بنابراین باید به صورت موردی در نظر گرفته شود.

برای درک بهتر این موضوع، اجازه دهید یک نسخه نمایشی برای یک برنامه یکپارچه ایجاد کنیم که می‌خواهیم آن را بر اساس معیارهای جداسازی به واحدهای تقسیم‌پذیر تبدیل کنیم.

نسخه ی نمایشی یکپارچه: مورد استفاده کتابفروشی

بیایید عملکردهای اساسی یک برنامه کاربردی یکپارچه را که نشان دهنده یک کتابفروشی است، فرض کنیم که در آن کاربران می توانند خود را ثبت نام کنند، کتاب ها را جستجو کنند، کتاب ها را به سبد خرید اضافه کنند، و اشتراک کتاب های صوتی را خریداری کنند.

با توجه به کسب و کار موفق آنها و ویژگی کتاب صوتی، فروش کتابفروشی شروع به افزایش کرده است و تعداد کاربران فروشگاه به صورت هفتگی افزایش می یابد. با توجه به افزایش ترافیک، فروشگاه شروع به تعطیلی هایی کرده است که ممکن است بر فروش آن تأثیر بگذارد. بنابراین، این پلتفرم تصمیم گرفته است به میکروسرویس ها مهاجرت کند تا همه چیز را ثابت نگه دارد. این امر مستلزم زمان، تلاش و مهمتر از همه، برنامه ای برای نحوه انتقال برنامه های کاربردی آنها به میکروسرویس ها است.

برای جداسازی برنامه ریزی کنید

مرحله 1: زمینه های محدود را شناسایی کنید ابتدا، ما باید “مناطق” یا زمینه های محدود در کتابفروشی را درک و تعریف کنیم. بیایید آن را تجزیه کنیم:

  • مدیریت کاربر: ثبت نام، ورود، پروفایل کاربری
  • کاتالوگ محصولات: لیست محصولات، دسته بندی ها، موجودی
  • سبد خرید: افزودن/حذف اقلام، مشاهده سبد خرید
  • پردازش سفارش: پرداخت، پیگیری سفارش
  • فرایند پرداخت: رسیدگی به پرداخت ها

مرحله 2: ایجاد مرزهای میکروسرویس در مرحله بعد، ما یک میکروسرویس جداگانه برای هر زمینه محدود ایجاد می کنیم:

  1. خدمات کاربر: همه چیز مربوط به کاربران را مدیریت می کند
  2. خدمات محصول: محصولات و موجودی را کنترل می کند
  3. خدمات سبد خرید: سبد خرید را مدیریت می کند
  4. سفارش خدمات: سفارشات را پردازش می کند
  5. خدمات پرداخت: پرداخت ها را پردازش می کند

مرحله 3: جداسازی پایگاه داده هر میکروسرویس پایگاه داده خود را خواهد داشت که استقلال سرویس را تضمین می کند و مالکیت داده ها را شفاف می کند. مرحله 4: توسعه API برای ارتباطات هر میکروسرویس APIهای REST خود را برای ارتباطات بین سرویسی خواهد داشت که باعث می‌شود سرویس‌ها به‌طور ضعیفی مرتبط شوند. مرحله 5: اصلاح تدریجی و مهاجرت برنامه monolith به تدریج اصلاح می شود و به موازات برنامه monolith به کار می رود، از سرویس های کمتر بحرانی شروع می شود تا در صورت خرابی چیزی، خطر و شعاع انفجار به حداقل برسد. مثال: جدا کردن کاتالوگ محصولات

  1. استخراج منطق محصول: منطق مدیریت محصول را به سرویس محصول جدید منتقل کنید
  2. راه اندازی پایگاه داده محصول: یک پایگاه داده جداگانه برای داده های محصول ایجاد کنید
  3. توسعه API محصول: ایجاد یک API برای عملیات محصول (CRUD)
  4. کد یکپارچه Refactor: کد مدیریت محصول جدید را به عنوان یک سرویس جداگانه موازی با یکپارچه بنویسید
  5. تست: سرویس محصول را به طور مستقل و با سایر بخش های یکپارچه آزمایش کنید
  6. استقرار: سرویس محصول را مستقر کرده و بر عملکرد آن نظارت کنید

این فرآیند را برای هر میکروسرویس تکرار کنید. مرحله 6: ارتباطات بین خدماتی را پیاده سازی کنید در این مرحله از REST APIها و در صورت لزوم از صف های پیام (مانند RabbitMQ) برای ارتباطات بین سرویس استفاده خواهیم کرد. مثال: خدمات سفارش و تعامل خدمات محصول

  • Order Service برای بررسی در دسترس بودن محصول قبل از سفارش، با Product Service API تماس می گیرد
  • اگر کالایی در دسترس باشد، خدمات سفارش به پردازش سفارش ادامه می‌دهد

همانطور که می بینید، یک طرح تعمیم یافته می تواند برای مهاجرت برنامه ها از معماری های قدیمی به معماری های جدید بسیار مفید باشد، اما چالش ها پس از تبدیل یک monolith به یک میکروسرویس همچنان ظاهر می شوند.

و این است…

مسئله مسیریابی مجدد درخواست های API

یکی از چالش های بزرگ با تبدیل یکپارچه به یک میکروسرویس، شروع مسیریابی مجدد درخواست های API به برنامه جدید در حال تولید است. این با خطر اختلال در سرویس‌های موجود و تجربه کاربری بدی همراه است که ممکن است نرخ پرش را برای یک برنامه افزایش دهد، بنابراین باید با کمترین زمان از کار افتادگی، بسیار کارآمد مدیریت شود. برای رسیدن به این هدف، استراتژی‌های زیادی وجود دارد که می‌توانیم از آن‌ها استفاده کنیم، مانند استقرار آبی/سبز یا قناری، و پرچم‌گذاری ویژگی‌ها.

در بخش‌های بعدی، بررسی خواهیم کرد که چگونه پرچم‌گذاری ویژگی می‌تواند به ما در مسیریابی مجدد درخواست‌های API کمک کند.

پرچم گذاری ویژگی به عنوان ابزاری در انتقال برنامه

هنگام انتقال از معماری‌های یکپارچه به میکروسرویس‌ها، پرچم‌گذاری ویژگی یک ابزار حیاتی است. این به توسعه‌دهندگان اجازه می‌دهد تا ویژگی‌ها را در یک برنامه زنده بدون استقرار کد جدید روشن یا خاموش کنند و انعطاف‌پذیری و کنترل فرآیند انتشار را افزایش دهند. این روش از کاهش ریسک و مهاجرت تدریجی پشتیبانی می کند و ادغام و تحویل مداوم را تسهیل می کند و آن را برای شیوه های توسعه نرم افزار مدرن ضروری می کند.

پرچم‌گذاری ویژگی مزایایی از قبیل:

  • مسیریابی ترافیک کنترل شده: پرچم‌گذاری ویژگی به کنترل مسیریابی درخواست‌های API بین یکپارچه‌ها و میکروسرویس‌ها کمک می‌کند و آزمایش قوی را برای تأیید عملکرد نقاط پایانی میکروسرویس بدون ایجاد اختلال در کل سیستم امکان‌پذیر می‌سازد.
  • مهاجرت تدریجی: همچنین شما را قادر می سازد تا به صورت تدریجی ویژگی ها یا نقاط پایانی را تغییر دهید. می‌توانید بخش کوچکی از عملکرد را به یک میکروسرویس منتقل کنید، پرچم ویژگی مربوطه را فعال کنید و عملکرد آن را قبل از ادامه مهاجرت تأیید کنید.
  • کاهش خطر: حتی بعد از همه اقدامات پیشگیرانه، همیشه احتمال خراب شدن چیزی پس از چنین مهاجرت هایی وجود دارد. بنابراین، کاهش ریسک در چنین مواقعی ضروری است. اگر سرویس جدیدی با مشکل مواجه شد، می‌توانید به سرعت پرچم ویژگی را غیرفعال کنید و بدون نیاز به بازگشت، ترافیک را به نسخه monolith برگردانید.
  • تست A/B برای میکروسرویس ها: پرچم‌های ویژگی همچنین به ما اجازه می‌دهند تا تست A/B را روی میکروسرویس‌ها انجام دهیم. می‌توانید بخشی از ترافیک را به میکروسرویس جدید هدایت کنید، در حالی که بقیه را روی یکپارچه نگه‌دارید، کارایی و قابلیت اطمینان را قبل از انجام کامل مقایسه کنید.

اکنون که دیدی جامع از قابلیت‌های پرچم‌های ویژگی داریم، بیایید از آنها در بخش بعدی استفاده کنیم.

آزمایشگاه: جدا کردن یک نمونه گره یکپارچه به میکروسرویس ها

در این آزمایشگاه، ابتدا یک نمونه پشتیبان Node.js به صورت یکپارچه ایجاد خواهید کرد که دارای نقاط پایانی برای مدیریت است. کاربران و سفارشات. بعد، شما یک را ایجاد خواهید کرد api-gateway و Flagsmith SDK را با آن یکپارچه کنید، عملکرد monolith را به میکروسرویس ها جدا کنید، و در نهایت کل برنامه را برای اجرا و آزمایش آن داکر کنید.

برای پیگیری، به درک موارد زیر نیاز دارید:

  • Node.js و سرور Express
  • جاوا اسکریپت
  • Docker و Docker Compose
  • REST APIها

ابتدا باید یک پروژه در Flagsmith ایجاد کنیم. یک حساب کاربری (رایگان) ایجاد کنید و در اینجا وارد Flagsmith شوید که فقط چند دقیقه طول می کشد. پس از ورود به سیستم، یک پروژه جدید مانند شکل زیر ایجاد کنید: ایجاد یک پروژه پرچمدار جدید من نام آن را “مونو به میکرو” گذاشته ام، اما شما می توانید از هر نامی که دوست دارید استفاده کنید.

در مرحله بعد، دو پرچم ویژگی برای میکروسرویس های خود به شرح زیر ایجاد کنید: ایجاد دو پرچم ویژگی برای میکروسرویس های شما واکشی کلید محیطی برای ادغام SDK از بخش کلیدهای SDK در نوار منو سمت چپ. شما باید یک کلید محیط سمت سرور ایجاد کنید و آن را ایمن نگه دارید:

ایجاد یک کلید محیطی سمت سرور در Flagsmith

اکنون همه چیزهایی را که برای شروع کار نیاز داریم در اختیار داریم…

کدگذاری پروژه

یک پوشه ایجاد کنید و نام آن را بگذارید monolith با دستور زیر:

mkdir monolith
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

├── docker-compose.yml
├── microservices/
│   ├── api-gateway/
│   ├── order-service/
│   └── user-service/
└── monolith/
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

NB، هنگام راه اندازی پروژه های زیر، به یاد داشته باشید که وارد کنید app.js در قسمت نقطه ورودی برای لغو نام پیش فرض index.js، زیرا ما استفاده می کنیم app.js در این راهنما

سپس یک پروژه Node ایجاد کنید و دستور زیر را اجرا کنید:

yarn init
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در package.json فایل، اضافه کردن a scripts موضوع به شرح زیر است:

"scripts": {
   "start": "node app.js",
   "test": "nodemon app.js"
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ایجاد کنید app.js در ریشه دایرکتوری قرار دهید و کد زیر را اضافه کنید:

// app.js
const express = require("express");
const app = express();
const port = 3000;

// Hardcoded data
const users = [
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" },
  { id: 3, name: "Charlie" },
];

const orders = [
  { id: 1, item: "Laptop", quantity: 1, userId: 1 },
  { id: 2, item: "Phone", quantity: 2, userId: 2 },
  { id: 3, item: "Book", quantity: 3, userId: 3 },
];

// Routes
app.get("/users", (req, res) => {
  console.log("User list from monolith app", users);
  res.json(users);
});

app.get("/orders", (req, res) => {
  console.log("Order list from monolith app", orders);
  res.json(orders);
});

app.listen(port, () => {
  console.log(`Monolith listening at http://localhost:${port}`);
});
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

سپس دستور زیر را برای نصب چند وابستگی ضروری اجرا کنید:

yarn add express nodemon
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در همان دایرکتوری یک Dockerfile ایجاد کنید و کد زیر را اضافه کنید:

FROM node:18-alpine
RUN apk --no-cache add \
    bash \
    g++ \
    python3
WORKDIR /usr/app
COPY package.json .
RUN yarn install
COPY . .
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اکنون که نمونه برنامه یکپارچه شما با برخی از نقاط پایانی و داده های رمزگذاری شده ساخته شده است، می توانید نقطه پایانی برنامه را با اجرای دستور زیر آزمایش کنید:

yarn test
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این خروجی مورد انتظار است:

تست نقطه پایانی برنامه

برای آزمایش نقاط پایانی، Postman را باز کنید و نقاط پایانی زیر را بزنید: orders-endpoint: http://localhost:3000/orders users-endpoint: http://localhost:3000/users این خروجی مورد انتظار برای است user-service: خروجی سرویس کاربران و این نتیجه مورد انتظار برای order-service:

سفارشات-خروجی خدمات

ما برنامه monolith را با موفقیت آزمایش کردیم، بنابراین اکنون زمان تبدیل آن به میکروسرویس است. ما برنامه را بر اساس عملکردها جدا خواهیم کرد. در حال حاضر، اپلیکیشن monolith را می توان به دو قابلیت متمایز تقسیم کرد: اول، سرویس سفارش، که سفارشات را مدیریت می کند و داده های رمزگذاری شده را برای سفارش ها ارائه می دهد، و دوم، سرویس کاربر، که داده های کاربر کد سخت را ارائه می دهد.

همانطور که می بینید، میکروسرویس هایی که ما در حال ساختن آن ها هستیم، هر کدام مسئولیت یک کار واحد را بر عهده خواهند داشت (این یکی از اصول اصلی جداسازی یک برنامه یکپارچه است).

بیایید به کدنویسی ادامه دهیم…

ایجاد سرویس سفارشات

در کنار دایرکتوری monolith، یک دایرکتوری جدید به نام ایجاد کنید microservices و داخل آن یک Node.js ایجاد کنید order-service پروژه را با اجرای دستورات زیر انجام دهید:

mkdir order-service
cd order-service
yarn init
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

برای نصب چند وابستگی ضروری دستور زیر را اجرا کنید:

yarn add express nodemon
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در package.json file، a اضافه کنید scripts موضوع به شرح زیر است:

"scripts": {
   "start": "node app.js",
   "test": "nodemon app.js"
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ایجاد کنید app.js در ریشه دایرکتوری قرار دهید و کد زیر را اضافه کنید:

// app.js
const express = require("express");
const app = express();
const port = 3002;

const orders = [
  { id: 1, item: "Laptop", quantity: 1, userId: 1 },
  { id: 2, item: "Phone", quantity: 2, userId: 2 },
  { id: 3, item: "Book", quantity: 3, userId: 3 },
];

app.get("/orders", (req, res) => {
  console.log("Order list from microservice app", orders);
  res.json(orders);
});

app.listen(port, () => {
  console.log(`Order Microservice listening at http://localhost:${port}`);
});
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در همان دایرکتوری یک Dockerfile ایجاد کنید و کد زیر را اضافه کنید:

FROM node:18-alpine
RUN apk --no-cache add \
    bash \
    g++ \
    python3
WORKDIR /usr/app
COPY package.json .
RUN yarn install
COPY . .
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ایجاد سرویس کاربران

حالا بیایید ایجاد کنیم user-service. در همان دایرکتوری ایجاد خواهد شد order-service، تقریباً همه چیز به جز نقاط پایانی یکسان است. بنابراین، مراحل قبلی مورد استفاده برای ایجاد را تکرار کنید order-service و جایگزین کنید app.js فایل با کد زیر:

// app.js
const express = require("express");
const app = express();
const port = 3001;

// Hardcoded data
const users = [
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" },
  { id: 3, name: "Charlie" },
];

// Routes
app.get("/users", (req, res) => {
  console.log("User list from microservice app", users);
  res.json(users);
});

app.listen(port, () => {
  console.log(`User microservice listening at http://localhost:${port}`);
});
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ایجاد api-gateway سرویس

در این آخرین مرحله، ما api-gateway به عنوان یک رابط برای تعامل با میکروسرویس های ما عمل می کند و با Flagsmith SDK ادغام می شود.

از آنجایی که این یک برنامه Node.js خواهد بود، مراحل قبلی را برای ایجاد میکروسرویس ها تکرار کنید و فایل نقطه ورودی را جایگزین کنید (app.js) با کد زیر. به یاد داشته باشید که آن را Dockerize کنید زیرا ما تمام خدمات خود را از docker-compose اجرا خواهیم کرد:

// app.js
const express = require("express");
const axios = require("axios");
const Flagsmith = require("flagsmith-nodejs");
const app = express();
const port = 8080;

const flagsmith = new Flagsmith({
  environmentKey: "",
});

// Users route
app.get("/users", async (req, res) => {

  const flags = await flagsmith.getEnvironmentFlags();
  var isEnabled = flags.isFeatureEnabled("use_user_microservice");

  if (isEnabled) {
    const response = await axios.get("http://user-service:3001/users");
    console.log("Response from user microservice", response.data);
    res.status(200).json(response.data);

} 
else {
    const response = await axios.get("http://monolith-service:3000/users");
    console.log("Response from monolith service", response.data);
    res.status(200).json(response.data);
  }
});

// Orders route
app.get("/orders", async (req, res) => {

  const flags = await flagsmith.getEnvironmentFlags();
  var isEnabled = flags.isFeatureEnabled("use_order_microservice");

  if (isEnabled) {
    const response = await axios.get("http://order-service:3002/orders");
    console.log("Response from order microservice", response.data);
    res.status(200).json(response.data);

  } else {
    const response = await axios.get("http://monolith-service:3000/orders");
    console.log("Response from monolith service", response.data);
    res.status(200).json(response.data);
  }
});

app.listen(port, () => {
  console.log(`API Gateway listening at http://localhost:${port}`);
});
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

توضیح مختصری از api-gateway

کد بالا دو تابع GET دارد: یکی داده های کاربر و دیگری داده های سفارش را واکشی می کند. تصمیمات مسیریابی بر اساس مقدار پرچم دریافت شده از Flagsmith است. اگر پرچم true باشد، ترافیک به سمت میکروسرویس ها هدایت می شود. در غیر این صورت، به برنامه monolith ادامه خواهد داد.

پرچم هایی که در حساب کاربری خود برای هر دو سرویس ایجاد کردم به شرح زیر بود:
1. use_user_microservices
2. use_order_microservices
برای اینکه Flagsmith SDK کار کند، باید کلید SDK ایجاد شده از حساب خود را اضافه کنید و از آن در کد استفاده کنید.

ایجاد فایل docker-compose

برای اجرای موازی مونولیت و میکروسرویس ها، باید یک فایل docker-compose بنویسیم تا دید و کنترل بهتری داشته باشیم. ما هر چهار سرویس را به‌عنوان کانتینرهای Docker اجرا می‌کنیم و سپس درخواست‌های API خود را با استفاده از Flagsmith SDK که در مرحله قبل ادغام کردیم، تغییر می‌دهیم.

یک فایل docker-compose که در آن دایرکتوری ها، monolith و microservice ها قرار دارند ایجاد کنید و کد زیر را کپی کنید:

version: "3"

services:
  api-gateway:
    build: ./microservices/api-gateway
    container_name: api-gateway
    command: yarn start
    hostname: api-gateway
    restart: always
    ports:
      - 8080:8080

  monolith-service:
    build: ./monolith
    container_name: monolith-service
    command: yarn start
    hostname: monolith-service
    restart: always

  user-service:
    build: ./microservices/user-service/
    container_name: user-service
    command: yarn start
    hostname: user-service
    restart: always

  order-service:
    build: ./microservices/order-service/
    container_name: order-service
    command: yarn start
    hostname: order-service
    restart: always
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اکنون دستور زیر را اجرا کنید و تمام کانتینرها شروع به کار خواهند کرد:

docker compose up -d –build
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

این خروجی مورد انتظار است:

خروجی کانتینرهای داکر

همه سرورها در حال اجرا هستند و اکنون می‌توانیم پرچم‌گذاری ویژگی Flagsmith را در عمل مشاهده کنیم.

در حال حاضر، هر دو پرچم ما خاموش هستند، بنابراین اگر یک API را بزنید، دروازه درخواست را به برنامه monolith ارسال می کند. برای تست سریع آن، دستور curl را روی آن اجرا کنید api-gateway نقطه پایانی مانند این:

curl http://localhost:8080/users
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

همانطور که در خروجی زیر مشاهده می شود، درخواست به کانتینر یکپارچه هدایت می شود:

مسیریابی درخواست به کانتینر یکپارچه

آن را تأیید کنید، سیاهههای مربوط به کانتینر را باز کنید api-gateway، و پاسخی مشابه با آنچه در بالا نشان داده شده است خواهید دید.

حالا بیایید به Flagsmith برویم و پرچم ویژگی را روشن کنیم user-service:

روشن کردن پرچم ویژگی برای سرویس کاربر در Flagsmith

ما دوباره همان نقطه پایانی را آزمایش می کنیم، اما این بار اگر آن را باز کنید api-gateway گزارش های کانتینر، یک اعلان متفاوت خواهید دید که نشان می دهد درخواست به جای برنامه monolith به میکروسرویس ارسال شده است:

این درخواست به جای برنامه Monolith به Microservice ارسال شده است

همانطور که می بینید، علامت گذاری ویژگی در عمل است. ما فقط یک لحظه ترافیک نقطه پایانی را از یکپارچه به میکروسرویس هدایت کردیم.

در حال حاضر، پرچم برای order-service خاموش است، به این معنی که اگر ما به نقطه پایانی دستورات از خود ضربه بزنیم api-gateway، به جای میکروسرویس باید از اپلیکیشن monolith پاسخ بگیریم. سعی کنید نقطه پایانی زیر را زده و خروجی را در قسمت مشاهده کنید api-gateway سیاههها:

curl http://localhost:8080/orders
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در اینجا خروجی مورد انتظار است:

مشاهده گزارش‌های API-Gateway

همانطور که می بینید، ما با موفقیت از قابلیت پرچم گذاری ویژگی Flagsmith برای انتقال درخواست API از monolith به میکروسرویس ها استفاده کرده ایم. اگرچه این یک نمایش در مقیاس کوچک است، این مفهوم را می توان تکرار کرد و در محیط های تولیدی مانند Kubernetes برای نمایش نقاط پایانی و خدماتی که اخیراً به میکروسرویس ها تغییر یافته اند، در معرض دید کاربر قرار می گیرد.

پرچم‌گذاری ویژگی Flagsmith می‌تواند در کاهش زمان از کار افتادگی در طول مهاجرت، انجام تست A/B و تسهیل استقرار قناری بسیار مفید باشد.

نتیجه

در این مقاله، تاریخچه مختصری از معماری های کاربردی را پوشش دادیم و ظهور معماری میکروسرویس را بررسی کردیم. ما همچنین یک برنامه وب کتابفروشی ایجاد کردیم تا کاربرد عملی این مفاهیم را نشان دهیم.

در طول نمایش، موضوع تغییر مسیر ترافیک و اینکه Flagsmith چگونه می تواند به حل این مشکل کمک کند را پوشش دادیم. در نهایت، ما یک برنامه آزمایشی را پیاده‌سازی کردیم که در آن دیدیم که چگونه پرچم‌گذاری ویژگی Flagsmith می‌تواند برای تغییر مسیر ترافیک از یک monolith به microservices در یک محیط محلی مفید باشد، که می‌تواند به عنوان مرجعی برای پیاده‌سازی‌های مشابه در یک محیط تولید عمل کند.

برای مطالعه بیشتر در مورد Flagsmith، برای شروع به مستندات رسمی مراجعه کنید.


فقط در دهه 200✓ نظارت بر درخواست های شبکه ناموفق و کند در حال تولید است

استقرار یک برنامه وب یا وب سایت مبتنی بر Node بخش آسانی است. اطمینان از اینکه نمونه Node شما همچنان به ارائه منابع به برنامه شما ادامه می دهد، جایی است که همه چیز سخت تر می شود. اگر می‌خواهید مطمئن شوید درخواست‌ها به پشتیبان یا خدمات شخص ثالث موفقیت‌آمیز هستند، LogRocket را امتحان کنید.

ثبت نام LogRocket

LogRocket مانند یک DVR برای برنامه های وب و تلفن همراه است که به معنای واقعی کلمه هر اتفاقی را که هنگام تعامل کاربر با برنامه شما اتفاق می افتد ضبط می کند. به جای حدس زدن چرایی مشکلات، می‌توانید درخواست‌های شبکه مشکل‌ساز را جمع‌آوری کرده و گزارش دهید تا به سرعت علت اصلی را درک کنید.

LogRocket برنامه شما را برای ضبط زمان‌بندی عملکرد پایه مانند زمان بارگذاری صفحه، زمان تا اولین بایت، درخواست‌های شبکه کند و همچنین گزارش‌های Redux، NgRx، و اقدامات/وضعیت Vuex را ابزار می‌کند. نظارت را به صورت رایگان شروع کنید.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا