Skip to content

فصل ۷ — دانه‌بندی سرویس‌ها

خلاصهٔ تحلیلی — این متن چکیده‌ای تحلیلی و بازنویسی‌شده از فصل است، نه ترجمهٔ مستقیم.

مسئله و زمینه

پس از تقسیم یک سیستم به سرویس، دشوارترین سؤال معمولاً این نیست که «آیا ماژولار هست؟» بلکه این است که «هر مرز چقدر ریز باشد؟». modularity به وجود بخش‌های جدا اشاره می‌کند؛ granularity اندازهٔ همان بخش‌هاست. تعداد کلاس یا خط کد پاسخ مسئله نیست؛ موضوع، دامنهٔ رفتاری سرویس و اثر آن بر تغییر، مقیاس و عملیات است.

فصل با این هشدار شروع می‌کند که «micro» مترادف «تا حد ممکن کوچک» نیست. ریزکردن بر پایهٔ سلیقه یا تفسیر شخصی از single responsibility، شبکه‌ای از تماس‌ها، شکست‌ها و تراکنش‌های توزیع‌شده می‌سازد. مرز مناسب از تعادل نیروهای شکافنده و چسباننده به دست می‌آید.

مفاهیم و الگوهای محوری

شاخص‌های سنجش

اندازه را با آنچه سرویس انجام می‌دهد بسنجید: تعداد statementها و شمار operationهای عمومی، از LOC یا تعداد کلاس قابل‌اتکاترند. این معیارها حکم نهایی نمی‌دهند، اما گفت‌وگو را از شهود صرف به شواهد نزدیک می‌کنند.

شش دلیل برای شکستن سرویس

  • دامنه و cohesion: سرویسی که کارهای کم‌ارتباط را زیر نامی فراخ جمع کرده، نامزد تفکیک است. اما چند کانالِ یک مفهوم، مثل اعلان به مشتری، لزوماً چند مسئولیت مستقل نیستند.
  • نوسان کد: بخشی که مدام تغییر می‌کند، با جداسازی، محدودهٔ آزمون و ریسک deployment را از بخش‌های پایدار دور می‌کند.
  • مقیاس‌پذیری و throughput: اگر یک مسیر صدها یا هزاران برابر مسیر دیگر فراخوانی می‌شود، scale مشترک اتلاف منابع و کاهش elasticity است.
  • تاب‌آوری: crash مکرر یک قابلیت نباید قابلیت‌های مستقل را هم از کار بیندازد؛ با این حال، بازماندهٔ سرویس باید cohesion قابل دفاع داشته باشد.
  • امنیت: داده و عملیات حساس، مانند اطلاعات پرداخت، ممکن است مرز سرویس ویژه‌ای برای کنترل access بخواهد؛ فقط جداکردن storage کافی نیست.
  • قابلیت توسعه: وقتی رشد یک خانوادهٔ قابلیت واقعاً قابل پیش‌بینی است، تفکیک محل اضافه‌کردن نوع جدید را محدود می‌کند. این دلیل نباید بر حدس مبهم از آینده تکیه کند.

چهار دلیل برای یکپارچه‌سازی

  • تراکنش database: اگر ارزش کسب‌وکار «همه یا هیچ» است، تقسیم مسیر نوشتن به سرویس‌ها ACID محلی را به consistency نهایی و جبران پیچیده تبدیل می‌کند.
  • workflow و choreography: تماس همگام زیاد، latency را جمع می‌کند، availability را به ضعیف‌ترین سرویس وابسته می‌کند و handling خطا را پخش می‌سازد.
  • کد دامنهٔ مشترک: کتابخانهٔ مشترکی که بخش بزرگی از منطق business یا تغییرات مکرر را حمل می‌کند، عملاً deployهای مستقل را دوباره هماهنگ می‌کند. این منطق با logging و authentication مشترک تفاوت دارد.
  • رابطهٔ داده: اگر دو سرویس دائماً دادهٔ هم را نیاز دارند و ownership جدول‌ها به ارتباط رفت‌وبرگشتی می‌انجامد، تفکیک ممکن است فقط یک join محلی را به dependency شبکه‌ای تبدیل کرده باشد.

موازنه‌ها

نمونهٔ مرکزی فصل نشان می‌دهد انزوای الگوریتمی که مرتب تغییر می‌کند، ممکن است در برابر workflow همگام و جدانشدنی آن با routing شکست بخورد. در این حالت سرویس واحد، با componentهای داخلی جدا، تغییرپذیری کد را حفظ می‌کند بدون اینکه latency و failure mode توزیع‌شده بسازد.

نمونهٔ دیگر، ثبت‌نام مشتری است: جداسازی profile، password و card access را محدودتر می‌کند؛ ولی اگر ثبت‌نام و لغو باید قطعاً اتمیک باشند، سرویس واحد ACID را آسان‌تر حفظ می‌کند. امنیت را گاهی می‌توان با طراحی لایهٔ API و service mesh جبران کرد؛ اما ACID از روی شبکه به‌سادگی بازنمی‌گردد. انتخاب به اولویت کسب‌وکار بستگی دارد، نه به یک قاعدهٔ زیبایی‌شناسانه.

راهنمای عملی

  1. برای هر پیشنهاد split، دلیل را با داده بیان کنید: تاریخچهٔ commit، نرخ درخواست، MTTS، خطاهای بحرانی، sensitivity داده و نقشهٔ دسترسی.
  2. هم‌زمان سمت مخالف را نیز بنویسید: چه تراکنش، workflow، shared domain code یا رابطهٔ داده‌ای با split آسیب می‌بیند؟
  3. درصد درخواست‌های چندسرویسی و criticality آن‌ها را بسنجید؛ یک مسیر حساس با latency سخت‌گیرانه می‌تواند از میانگین‌ها مهم‌تر باشد.
  4. نام سرویس حاصل را امتحان کنید. نامی مانند «سایر اعلان‌ها» اغلب نشانهٔ cohesion ضعیفِ باقی‌مانده است.
  5. تصمیم را با ذی‌نفع کسب‌وکار به trade-off statement تبدیل و در ADR ثبت کنید: چه چیزی را برای چه ارزشی قربانی می‌کنیم و چگونه اثر منفی را کاهش می‌دهیم؟

نکات کلیدی فصل

  • granularity یک طیف است، نه برچسب microservice یا monolith.
  • استقلال deployment وقتی ارزش دارد که وابستگی‌های data، workflow و shared code آن را خنثی نکنند.
  • security، scale و volatility دلایل جداسازی‌اند؛ transactionality، ارتباط پرتکرار و رابطهٔ داده دلایل جدی برای کنار هم ماندن‌اند.
  • یک سرویس coarse-grained با ماژول‌های داخلی تمیز، در برخی workflowهای هم‌بسته انتخاب سالم‌تری از چند سرویس ریز است.

یادداشت‌های مترجم

  • granularity به «دانه‌بندی» و disintegrator/integrator به «نیروی شکافنده/یکپارچه‌ساز» برگردانده شده است.
  • workflow، choreography، ACID و service mesh به‌سبب کاربرد رایج فنی، لاتین حفظ شده‌اند.