اسپاتیفای (Spotify) و ساندکلاد (SoundCloud) دو پلتفرم پیشرو در عرصۀ استریم محتوای صوتی هستند که هر کدام میلیونها کاربر در سراسر جهان دارند. موفقیت این سرویسها تنها با رابط کاربری جذاب و محتوای غنی محقق نشده، بلکه پشتوانۀ آنها معماری نرمافزاری پیچیده و مقیاسپذیری است که امکان ارائه خدمات پایدار و باکیفیت را فراهم کرده است. در این گزارش، معماری نرمافزاری اسپاتیفای و ساندکلاد را از منظر ویژگیهای کیفی معماری مقایسه میکنیم. این ویژگیها شامل عملکرد، مقیاسپذیری، امنیت، قابلیت نگهداری، انعطافپذیری، قابلیت تست، در دسترس بودن، تحمل خطا، قابلیت استقرار و قابلیت استفادهٔ مجدد هستند. ابتدا به صورت مختصر معماری هر پلتفرم را معرفی میکنیم و سپس برای هر یک از این ویژگیهای کیفی، رویکردهای دو پلتفرم را مورد بررسی و مقایسه قرار میدهیم. هدف، ارائهٔ تحلیلی جامع و مستند است که نشان دهد هر کدام از این دو سرویس چگونه معماری خود را برای برآورده کردن نیازهای فنی و کسبوکاری بهینه کردهاند.
معماری اسپاتیفای بر پایهٔ میکروسرویسها بنا شده است. در این رویکرد، به جای یک سیستم یکپارچهٔ بزرگ (monolith)، مجموعهای از سرویسهای کوچک و مستقل مسئول بخشهای مختلف عملکرد سیستم هستند. هر سرویس وظیفهٔ مشخصی بر عهده دارد (مثلاً سرویس احراز هویت، سرویس جستجوی موسیقی، سرویس پخش آهنگ و غیره) و میتواند بدون اثرگذاری مستقیم بر سایر بخشها توسعه، استقرار یا مقیاسبندی شود. این معماری به اسپاتیفای امکان میدهد که تیمهای مهندسی کوچک و مستقلی (که در فرهنگ سازمانی اسپاتیفای اسکوادنام دارند) مالکیت کامل هر سرویس را بر عهده گیرند و به صورت خودمختار روی آن توسعه دهند. یکی از نتایج این استقلال، کاهش وابستگی بین اجزای سیستم است که نوآوری و تغییرات سریع را ممکن میسازد.
از منظر فناوری، اسپاتیفای عمدتاً از زبانهای جاوا (برای بخش اعظم سرویسهای بکاند) و پایتون (به ویژه در حوزهٔ تحلیل داده و یادگیری ماشین) استفاده میکند. در سالهای اولیه از پایگاهدادهٔ PostgreSQL استفاده میشد، اما با رشد دادهها و کاربران، اسپاتیفای به یک راهکار توزیعشدهتر مانند Apache Cassandra مهاجرت کرد. کاساندرا یک پایگاهداده NoSQL با قابلیت دسترسپذیری بالا و توزیعشدگی است که برای ذخیرهٔ دادههای عظیم (پروفایلهای کاربری، لیستهای پخش، سوابق فعالیت کاربران و غیره) استفاده میشود. اسپاتیفای همچنین برای ذخیرهٔ فایلهای حجیم (نظیر خود محتوای صوتی و کاور آلبومها) از فضای ابری بهره میگیرد (برای نمونه، استفاده از ذخیرهسازی ابری مانند Amazon S3 گزارش شده است). ارتباطات بین میکروسرویسها در اسپاتیفای از طریق APIهای سبک عمدتاً REST یا gRPC انجام میشود و جالب اینکه این شرکت حتی یک پروتکل اختصاصی به نام Hermes ( مبتنی بر ZeroMQ و Protobuf) توسعه داده است تا ارتباط بین سرویسها کارآمدتر و استاندارد باشد. با گذر زمان، زیرساخت اسپاتیفای از سرورهای فیزیکی به سرویسهای ابری منتقل شد و اکنون بخش عمدهٔ بار پردازشی آن روی پلتفرم ابری گوگل (Google Cloud Platform) اجرا میشود. این مهاجرت به اسپاتیفای امکان داده از خدمات تحلیلی و پردازش دادهٔ قدرتمند گوگل بهرهمند شود و مقیاسپذیری خود را بهبود بخشد. در لایهٔ مدیریت و استقرار سرویسها، اسپاتیفای به صورت گسترده از کانتینرسازی با Docker و ارکستریشن با Kubernetes استفاده میکند. این امر فرآیند استقرار (Deploy) سرویسهای متعدد را خودکار و پایدار کرده و مقیاسبندی پویا را تسهیل میکند. همچنین، معماری میکروسرویس چالش مشاهدهپذیری (Observability) را به همراه دارد؛ اسپاتیفای برای نظارت بر هزاران سرویس خود، یک کاتالوگ خدمات مرکزی توسعه داده که از طریق پلتفرم متنباز Backstage (محصولی که خود اسپاتیفای ایجاد کرده است) در دسترس است. این کاتالوگ به مهندسان امکان میدهد وابستگیها و سلامت سرویسها را بهروز رصد کنند و به شکل خودکار نمودارهای معماری با استفاده از مدل C4 تولید نمایند. در مجموع، معماری اسپاتیفای ترکیبی از خدمات کوچک اما متعدد است که بهدقت سازماندهی شدهاند تا ضمن ارائهٔ قابلیتهای متنوع، سیستم را مقیاسپذیر، قابل توسعه و تابآور نگه دارند.
ساندکلاد نیز طی سالهای فعالیت خود، مسیر تکاملی قابل توجهی در معماری نرمافزار پیموده است. در ابتدا، ساندکلاد بر پایهٔ یک نرمافزار یکپارچه پیادهسازی شده بود که تمام وظایف (از مدیریت کاربران تا پخش صوت) را در یک کدبیس بزرگ انجام میداد. با رشد سریع تعداد کاربران و ویژگیها، این رویکرد با مشکلاتی مواجه شد؛ از جمله کندی توسعه(عدم توانایی اطمینان از تغییرات در یک بخش بدون اثر مخرب بر بخشهای دیگر) و مقیاسناپذیری پایگاهدادهٔ مرکزی. مهندسان ساندکلاد برای حل این مشکلات تصمیم به مهاجرت تدریجی به سوی معماری میکروسرویسها گرفتند. راهبرد آنها این بود که: ابزارها و کتابخانههای داخلی بسازند تا ایجاد سرویسهای کوچک آسان شود، ویژگیهای جدید را خارج از مونو olith و با استفاده از API داخلی یاeventهای ارسالی از سیستم قدیمی توسعه دهند، و بخشهای موجود را به مرور از مونو olith استخراج کرده و به سرویسهای جداگانه تبدیل کنند. هر سرویس جدید به صورت مستقل توسعه، ساخته و استقرار مییابد و ارتباطش با دیگر سرویسها از طریق درخواستهای HTTP ) به شکل همزمان) یا تبادل رویداد (غیرهمزمان) برقرار میشود. طی چند سال، ساندکلاد توانست دهها سرویس مجزا و دیکوپلشده ایجاد کند که هر کدام مالک بخش تعریفشدهای از دامنهٔ محصول هستند. این گذار به میکروسرویسها باعث شد تیمهای مهندسی خودمختارتر شوند و هر تیم بتواند بخش مربوط به خود را سریعتر و با وابستگی کمتر به دیگران توسعه دهد. با این حال، همزیستی طولانیمدت مونو olith و میکروسرویسها چالشهایی نیز به همراه داشت، از جمله دشواری استخراج کامل برخی قابلیتها از کد قدیمی و وقوع مواردی که سرویسهای جدید گاهی برای دستیابی سریعتر به اهدافشان بهصورت ناهمخوان مستقیماً به پایگاهدادهٔ مونو olith متصل میشدند. مهندسان ساندکلاد با شناسایی این چالشها، به تدوین راهبردهای جدیدتری دست زدند تا فرآیند تجزیهٔ مونو olith را تسریع کنند و یک معماری مدرن، پایدار و قابل نگهداری شکل دهند.
یکی از الگوهای معماری جالبی که ساندکلاد در مسیر گذار به کار گرفت، الگوی Backends for Frontends (BFF) بود. ساندکلاد از پیشگامان این الگو در حدود سال ۲۰۱۳ بود. در معماری BFF بهجای یک API واحد برای همهٔ مشتریان (کلاینتها)، چندین درگاه API تخصصی برای هر نوع مشتری (وب، موبایل، شرکا و غیره) ایجاد میشود تا نیازهای خاص هر مشتری بهینهسازی گردد. با حرکت به سمت میکروسرویسها و ایجاد یک API خصوصی داخلی برای مونوolithکه عملاً خود مونوolith را هم به شکل یک سرویس در کنار بقیه قرار داد)، راه برای ایجاد BFFهای جداگانه باز شد. نتیجه این شد که مثلاً یک API اختصاصی موبایل، یک API اختصاصی وب و APIهای عمومی/همکاران شکل گرفتند که هر کدام توسط یک سرویس BFF مربوط به خود مدیریت میشود. هر BFF نقش یک گیتوی ورودی را ایفا میکند که مسئولیتهایی نظیر احراز هویت و مجوز، نرخدهی درخواستها (Rate Limiting)، پاکسازی هدرها و کنترل کش را بر عهده دارد. تمامی ترافیک ورودی از بیرون ابتدا به یکی از این BFFها وارد میشود و سپس به سرویسهای داخلی هدایت میگردد. از مزایای BFF برای ساندکلاد، یکی خودمختاری بیشتر تیمها بود (چرا که هر تیم فرانتاند میتوانست بدون نیاز به هماهنگیهای پیچیده با سایر تیمها، شکلAPI دلخواه خود را داشته باشد) و دیگری تابآوری بالاتر سیستم؛ بهطوریکه اگر یک BFF(مثلاً BFF وب) بر اثر استقرار بد یا باگ دچار مشکل میشد، فقط همان بخش از پلتفرم تحت تأثیر قرار میگرفت و کل سرویس ساندکلاد از کار نمیافتاد. لازم به ذکر است که BFFها با سرعت توسعهٔ بسیار بالا نیز همراه بودند به طوری که برخی از آنها روزانه چندین بار دیپلوی میشدند و تغییرات مستمری از سراسر سازمان مهندسی در آنها اعمال میگردید.
به مرور زمان، ساندکلاد متوجه شد که استفاده از BFFهای متعدد بدون لایههای میانی میتواند منجر به تکرار منطق بیزینسی در هر کدام از BFFها شود (مشکلی که سایر مدلها نظیر API Gateway متمرکز نیز ممکن است داشته باشند). برای نمونه، منطق بررسی مجوز دسترسی (Authorization) برای موجودیتهای اصلی نظیر «آهنگ» یا «پلیلیست» که دادههایشان در میکروسرویسهای مختلف پخش شده بود، ناچار شده بود به لایهٔ BFF منتقل شود و چون چندین BFF وجود داشت، این منطق امنیتی در هر کدام به شکل جداگانه پیادهسازی و تکرار میشد. توسعهٔ ویژگیهای جدید نیز گاهی باعث میشد یک BFF حجم زیادی از کد تجمیع داده و منطق را در خود جای دهد که از نظر نگهداری ایدهآل نبود. برای حل این معضل، معماری ساندکلاد یک گام فراتر رفت و لایهای جدید تحت عنوان سرویسهای ارزشافزوده (Value-Added Services or VAS) معرفی کرد. VAS ها سرویسهایی هستند که بین BFFها و میکروسرویسهای بنیادین قرار میگیرند و وظیفهٔ تجمیع و پردازش دادهها از چند سرویس پایه را بر عهده دارند. به بیان دیگر، به جای آنکه هر BFF مستقیماً با چندین میکروسرویس زیربنایی صحبت کند و نتایج را ترکیب نماید (که منجر به منطق تکراری در هر BFF میشد)، یک سرویس ارزشافزودهٔ میانی مثلاً برای «آهنگ» یا «پلیلیست» ایجاد شد که تمام دادهها و منطق مرتبط با آن موجودیت را از سرویسهای زیرین جمعآوری کرده و به صورت یکپارچه در اختیار BFFها قرار میدهد. این تغییر باعث حذف تکرار کد در BFFهای مختلف شد و نگهداری منطق مرکزی (مثلاً قوانین دسترسی به آهنگها در مناطق جغرافیایی مختلف) را بسیار سادهتر کرد. البته اضافه شدن لایهٔ VAS چالشهایی همچون افزایش احتمال Fan-out(افزایش تعداد فراخوانیهای همزمان به سرویسهای متعدد در دل یک درخواست) را نیز در پی داشت که نیازمند مدیریت و بهینهسازی بود. در سالهای اخیر، ساندکلاد همچنین مفهوم درگاههای دامنه (Domain Gateways) را مطرح کرده است. به این معنا که بر اساس حوزههای مختلف کسبوکاری (برای ساندکلاد دامنۀ «مصرفکنندگان محتوا» و دامنۀ «سازندگان محتوا/هنرمندان» دو حوزهٔ متمایز هستند)، سرویسهای ارزشافزودهٔ جداگانهای ایجاد شوند تا هر کدام نیازهای یک دامنه را پوشش دهند و وابستگیهای متقابل کاهش یابد. این رویکرد اگرچه مقداری تکرار را بین دامنهها افزایش میدهد، اما خودمختاری و سرعت توسعه را در هر حوزه بالا میبرد و پیچیدگی کمتری نسبت به داشتن یک سرویس واحد بزرگ برای همهٔ موارد به همراه دارد.
به طور خلاصه، معماری کنونی ساندکلاد را میتوان یک معماری سه-لایه دانست که در لایۀ بیرونی سرویسهای Edge یاBFF قرار دارند، در لایۀ میانی سرویسهای ارزشافزوده (VAS) برای تجمیع منطقهای پراکنده، و در لایۀ زیربنایی میکروسرویسهای پایه که هر کدام مسئول CRUD و عملیات اساسی یک بخش از دامنه هستند. شکل زیر طرح کلی این معماری را نمایش میدهد که چگونه مشتریان مختلف (وب، موبایل و...) از طریق BFFهای مجزا به لایهٔ ارزشافزوده و سرویسهای بنیادی متصل میشوند.
ساندکلاد نیز همانند اسپاتیفای از فناوریهای مدرنی نظیر Docker و Kubernetes برای استقرار و مدیریت سرویسهای خود بهره میگیرد. همچنین، نظارت بر سرویسها از طریق ابزارهایی چون Prometheus و ثبت لاگ متمرکز انجام میشود که برای پوششدهی سیستم توزیعشده ضروری است. بخش زیادی از سرویسهای ساندکلاد با زبان اسکالا (Scala) و بر بستر کتابخانهٔFinagle (از توییتر) نوشته شدهاند که برای ساخت سرویسهای مقیاسپذیر و تحملپذیر طراحی شده است. ساندکلاد نیزAPIهای عمومی خود را بر اساس OAuth2 امن کرده و اخیراً آن را به استاندارد OAuth 2.1 بهروز کرده است. در ادامه، با جزئیات بیشتری به هر یک از ویژگیهای کیفی معماری در این دو پلتفرم میپردازیم و راهکارهای هر کدام را مقایسه میکنیم.
یکی از مهمترین معیارهای کیفیتی برای سرویسهای استریم، عملکرد و کارایی سیستم در تحویل محتوا با کمترین تأخیر و تجربهٔ روانبرای کاربر است. اسپاتیفای و ساندکلاد برای دستیابی به عملکرد بالا، از ترکیبی از تکنیکهای زیرساختی و بهینهسازی نرمافزاری استفاده میکنند.
اسپاتیفای: برای تضمین بارگذاری سریع و پخش بدون وقفهٔ موسیقی، اسپاتیفای از چندین راهبرد بهره میبرد. نخست، استفادهٔ گسترده از شبکههای تحویل محتوا (CDN) است. اسپاتیفای با بهرهگیری از CDNهای توزیعشده، فایلهای صوتی و سایر محتواهای استاتیک را بر روی سرورهای لبه در سراسر جهان کش میکند تا کاربران دادهها را از نزدیکترین موقعیت جغرافیایی دریافت کنند. این کار فاصلهٔ فیزیکی و تأخیر شبکه را به حداقل رسانده و تأثیر چشمگیری در کاهش زمان بارگذاری دارد. دوم، اسپاتیفای از پخش تطبیقی بر اساس کیفیت شبکه بهره میگیرد. این سرویس به صورت آنی سرعت اتصال کاربر را رصد کرده و نرخ بیت (bitrate) استریم صوت را متناسب با آن تنظیم میکند تا حتی در شرایط شبکهٔ ضعیف، پخش موسیقی بدون قطع و وصلی باقی بماند (معمولاً با انتخاب خودکار نسخههای فشردهتر آهنگ در پهنای باندهای محدود). سوم، کشینگ چندلایه در معماری اسپاتیفای نقش کلیدی دارد. در سمت کاربر، اپلیکیشن اسپاتیفای قطعاتی از آهنگهای بعدی یا آهنگهای اخیراً پخششده را پیشکش میکند تا در صورت انتخاب آنها، فوری و بدون تأخیر شروع به پخش شوند. در سمت سرور، اسپاتیفای از کشهای درونحافظهای مانند Redis برای ذخیرهٔ دادههای پرکاربرد (مانند لیستهای پخش محبوب، اطلاعات پروفایل کاربر و غیره) استفاده میکند تا از تماس مکرر به دیتابیس جلوگیری شود. همچنین، CDNها در سطح Edge کاور آلبومها وpreviewهای آهنگ را کش میکنند. چهارم، بهینهسازی در سطح کد و کلاینت انجام شده است؛ اسپاتیفای در سمت وب از تکنیکهایی مانند بارگذاری ماژولار، WebAssembly و بهینهسازی استفاده از DOM بهره برده تا اپلیکیشن وب خود را سبک و سریع کند. در سمت اپلیکیشنهای موبایل و دسکتاپ نیز استفاده مؤثر از منابع سختافزاری هر دستگاه CPU، حافظه و هماهنگسازی مناسب عملیات شبکه، به بهبود عملکرد کمک کرده است. پنجم، اسپاتیفای به پیشبینی و پیشبارگذاری متکی است؛ رفتار کاربر تا حدی پیشبینی میشود (برای مثال اگر کاربر در حال گوشدادن یک آلبوم است، ترک بعدی پیشاپیش دانلود میشود) تا یک بافر محتوا همیشه جلوتر از شنونده آماده باشد. این پیشخوانی تضمین میکند حتی اگر لحظهای شبکه افت کند، کاربر قطعی در پخش حس نکند. نهایتاً، اسپاتیفای یک فرهنگ «پایش و بهبود مستمر» در تیمهای خود دارد؛ مقدار عظیمی داده جمعآوری میشود تا عملکرد سمت کلاینت و سرور بهدقت سنجیده شود و هر جا گلوگاهی مشاهده شد، تیمها برای رفع آن وارد عمل شوند. به عنوان نمونه، ذکر شده که اسپاتیفای «مقدار مضحکی داده» از رفتار کلاینتها جمعآوری و تحلیل میکند تا مشکلات پرفورمنس را شناسایی کرده و تجربهٔ کاربر را بهتر کند.
ساندکلاد: در مورد عملکرد، ساندکلاد نیز نیازمند تحویل سریع فایلهای صوتی آپلودشده توسط میلیونها خالق محتوا به شنوندگان جهانی است. رویکردهای ساندکلاد در بسیاری موارد مشابه اسپاتیفای است، هرچند در منابع فنی، جزئیات کمتری به صراحت بیان شده است. ساندکلاد از شبکههای توزیع محتوا برای توزیع فایلهای صوتی و تصاویر کاورها استفاده میکند تا کاربران بر اساس محل جغرافیایی، محتوا را از نزدیکترین سرور دریافت کنند (این امر در صنعت استریم صوت رایج است و تأخیر پخش را کاهش میدهد). همچنین، ساختار سرویسهای BFF در ساندکلاد، به بهبود عملکرد تجربهٔ کاربری کمک کرده است. بدین صورت که BFFها برای هر پلتفرم (وب یا موبایل) پاسخهای API را بهینهسازیشده برای همان پلتفرم ارائه میکنند؛ مثلاً BFF موبایل ممکن است چندین قطعه دادهٔ مرتبط را یکجا برگرداند تا تعداد درخواستهای جداگانه کاهش یابد و تأخیر مجموع کمتر شود. این کاهش رفتوبرگشتهای شبکه برای موبایل که معمولاً اتصالات کندتری دارند، به معنای عملکرد بهتر است. علاوه بر این، با اضافه شدن لایهٔ سرویسهای ارزشافزوده (VAS)، BFFهای ساندکلاد دیگر مجبور نیستند برای جمعآوری یک پاسخ، به دهها سرویس مجزا درخواست بفرستند؛ بلکه یک تماس به VAS مربوطه کافیست. این کاهش Fan-out در لایهٔ BFF، باعث کاهش چشمگیر زمان پاسخدهی به درخواستهای پیچیده شد و بار پردازشی سمت کلاینت (که قبلاً باید چندین درخواست سریالی یا موازی میفرستاد) را کم کرد. به بیان دیگر، VASها با تجمیع دادهها، زمان ترکیب را به سمت سرور منتقل کردند که معمولاً کارآمدتر و نزدیک به منابع داده است. طبق گزارشها، ترکیب این معماری با بهینهسازیهای زیرساختی سبب شده که مجموعهٔ BFFهای ساندکلاد بتوانند صدها میلیون درخواست در ساعت را پردازش کنند که نشان از ظرفیت عملکردی بالای سیستم دارد. از نظر کشینگ، ساندکلاد برای برخی APIها مکانیزم کش داخلی دارد تا پاسخ درخواستهای پرتکرار (مثل پروفایل یک کاربر محبوب یا لیست آهنگهای چارت) برای مدت کوتاهی ذخیره و سریعاً تحویل داده شود. همچنین، ساندکلاد از یک سامانهٔ پخش استریم تدریجی بهره میبرد که فایلهای صوتی بلند را تکهتکه (چانکشده) ارسال میکند تا پخش سریع آغاز شود و ادامهٔ داده در پسزمینه بارگیری گردد. در سمت کاربر نیز احتمالاً اپلیکیشن ساندکلاد آهنگ بعدی در صف پخش را کمی زودتر شروع به بافر میکند (هر چند تصریحی در منابع بر این مورد نیست، اما این تکنیکی رایج است). به علاوه، تیمهای مهندسی ساندکلاد به طور مستمر کارایی سیستم را زیر نظر دارند؛ لاگهای مرتبط با زمان پاسخ سرویسها و مدت زمان پخش بدون بافر ثبت و تحلیل میشود تا هرگونه افت عملکرد سریعا شناسایی و برطرف گردد.
از منظر مقایسه، هر دو سرویس در بطن خود برای عملکرد بهتر از CDN، کش و تجمیع درخواستها بهره میگیرند. اسپاتیفای شاید با داشتن کنترل بیشتر روی فرمت محتوا (مثلاً چند کیفیت مختلف از هر آهنگ) توانسته باشد قابلیت پخش با نرخ تطبیقی را پیادهسازی کند، در حالی که ساندکلاد که محتوایش توسط کاربران آپلود میشود ممکن است بیشتر روی یک کیفیت استاندارد متکی باشد. با این حال، رویکرد کلی یکسان است: رساندن سریع محتوا به کاربر با حداقل رفتوبرگشت و فاصلهٔ شبکه. هر دو سیستم معماری خود را طوری تنظیم کردهاند که تا حد امکان کار ترکیب و آمادهسازی داده در سمت سرور انجام شود و کلاینتها پاسخهای از پیش آماده و بهینه دریافت کنند – اسپاتیفای از طریق سرویسهای تجمیعکنندهٔ داده (view aggregation service) برای هر صفحه/نمایش در اپ خود و ساندکلاد از طریق لایهٔ VAS. این اشتراک رویکرد نشان میدهد که برای عملکرد بالا در مقیاس میلیونها کاربر، تفکیک وظایف به سرویسهای خاص و نزدیک کردن دادههای مرتبط به هم، امری ضروری است.
مقیاسپذیری توانایی سیستم در سازگاری با افزایش بار (کاربران بیشتر، دادهٔ بیشتر، درخواستهای بیشتر) بدون افت کیفیت سرویس است. هر دو پلتفرم اسپاتیفای و ساندکلاد، به عنوان سرویسهای اینترنتی بسیار محبوب، از ابتدا چالش مقیاسپذیری را در مرکز توجه معماری خود داشتهاند.
اسپاتیفای: همانطور که اشاره شد، انتخاب معماری میکروسرویس توسط اسپاتیفای دقیقاً با هدف مقیاسپذیری بهتر صورت گرفته است. در معماری میکروسرویس، هر سرویس را میتوان بهطور مستقل افقی مقیاس کرد؛ به این معنا که اگر مثلاً سرویس «پخش آهنگ» تحت فشار بار بیشتری قرار گیرد، تنها همان سرویس را میتوان با افزودن سرور/کانتینر جدید گسترش داد، بدون اینکه نیاز باشد کل سیستم را بزرگ کنیم. اسپاتیفای با داشتن صدها سرویس مختلف، این امکان را دارد که هر بخش متناسب با تقاضا رشد کند. در واقع، نایبرئیس مهندسی اسپاتیفای در سال ۲۰۱۵ اشاره کرده بود که «شما باید سیستمتان را طوری بسازید که بتوانید هر بخش را مستقل مقیاس کنید». برای نمونه، سرویسهای مرتبط با پروفایل کاربر ممکن است نیاز به مقیاس در حد میلیونها درخواست خواندن داشته باشند، در حالی که سرویسهای مربوط به آپلود محتوا چنین باری ندارند. اسپاتیفای همچنین از خدمات ابری بهره میبرد که مقیاسپذیری زیرساخت را بسیار سادهتر کرده است. مهاجرت اسپاتیفای به پلتفرم ابری گوگل (GCP) به آنها اجازه داد تا از ظرفیت تقریباً بیکران محاسبات ابری در مناطق جغرافیایی مختلف استفاده کنند و به سرعت در پاسخ به افزایش ترافیک، منابع بیشتری تخصیص دهند. علاوه بر این، استفاده از Kubernetes به اسپاتیفای امکان autoscaling سرویسها را میدهد؛ یعنی براساس متریکهایی مانند CPU یا نرخ درخواست، خودکار تعداد پادهای سرویسها بالا یا پایین میرود. نمونهای از مقیاسپذیری موفق اسپاتیفای، رویداد سالانهٔ Spotify Wrapped است که طی آن ترافیک به شکل انفجاری افزایش مییابد اما زیرساخت قادر به پاسخگویی است. در سطح پایگاهداده، مهاجرت به Cassandra نیز به دلیل مقیاسپذیری خطی آن بود – اضافه کردن گرههای بیشتر به کلاستر Cassandra به اسپاتیفای امکان داد تا از پس رشد نمایی کاربران برآید بدون آنکه به یک سرور پایگاهدادهٔ واحد فشار بیش از حد وارد شود. همچنین اسپاتیفای برای مدیریت حجم انبوه دادههای جریانیstreaming data به سراغ Apache Kafka رفت که یک پلتفرم مقیاسپذیر برای استریم رویدادها است. Kafka میتواند میلیونها رویداد (نظیر پخش یا اسکیپ شدن آهنگ توسط کاربران) را در ثانیه پردازش و صفبندی کند و مقیاس آن با اضافه کردن بروکرهای بیشتر افزایش مییابد. تمام این تمهیدات باعث شدهاند که اسپاتیفای بتواند به طور همزمان میلیونها کاربر را سرویسدهی کند و با رشد سالانهٔ کاربران خود (که اکنون بیش از نیم میلیارد کاربر فعال ماهانه گزارش شده است) سازگار شود. نقطهٔ قوت دیگر، عدم وجود نقاط گلوگاه مشترک است؛ به عبارت دیگر، با حذف معماری یکپارچه، دیگر یک جزء خاص (مثلاً پایگاهدادهٔ مرکزی یا وبسرور منفرد) وجود ندارد که افزایش بار کل سیستم را فلج کند. هر سرویس و هر داده بین چندین نمونه و چندین مرکز داده توزیع شده است. اسپاتیفای همچنین از تعادل بار (Load Balancing) در تمامی لایهها استفاده میکند تا بار ترافیک به طور متوازن پخش شود و از تمرکز بار روی یک نود جلوگیری گردد. مجموعهٔ این اقدامات، فلسفهٔ «مقیاسپذیری بیانتها» در اسپاتیفای را عملی کرده است.
ساندکلاد: مقیاسپذیری در ساندکلاد بیشتر به شکل مقیاسپذیری سازمانی و فنی خود را نشان داد. از منظر سازمانی، حرکت به سوی معماری میکروسرویس دقیقاً به دلیل ناتوانی سیستم قبلی در همراهی با رشد پلتفرم بود. با پیادهسازی میکروسرویسها، ساندکلاد توانست تیمهای بیشتری را به صورت موازی روی بخشهای مختلف محصول فعال کند بدون اینکه اضافه شدن توسعهدهندگان باعث افت سرعت توسعه یا کیفیت شود – مشکلی که در مونو olith قبلی به وجود آمده بود. حال از منظر فنی، ساندکلاد سرویسهای خود را به گونهای طراحی کرد که مقیاس افقی داشته باشند. به عنوان مثال، سرویس «پخش صوت» در چندین منطقهٔ جغرافیایی مستقر شده و اگر تعداد شنوندگان بالا برود، نمونههای بیشتری از آن سرویس در همان لحظه بالا میآیند. استفاده از Docker و Kubernetes در ساندکلاد دقیقاً با همین هدف بوده که فرایند افزودن ظرفیت برای سرویسها مکانیزه و سریع باشد. افزون بر این، BFF های ساندکلاد این امکان را فراهم کردند که مقیاسپذیری بر اساس نوع مشتری اتفاق بیفتد. به طور مشخص، اگر تعداد کاربران موبایل رشد ویژهای داشت، سرویسهای مرتبط با موبایل (یعنی BFF موبایل و سرویسهای زیرمجموعهٔ آن) را میشد مستقل از سایر بخشها ارتقا داد یا بهینه کرد. همینطور اگر یکی از APIهای شرکای تجاری ترافیک سنگینی میگرفت، فقط همانسرویس را میشد گسترش داد بیآنکه به پلتفرم اصلی فشار آید. چنین جداسازیهایی در معماری به ساندکلاد کمک کرد تا ترافیکهای مختلف را ایزوله کرده و مقیاس هر کدام را جداگانه مدیریت کند.
از لحاظ ذخیرهسازی داده، ساندکلاد پایگاهدادهٔ اصلی (مونوولیت) را که به سرعت در حال رشد بود به چندین دیتابیس تقسیم کرد. هر سرویس جدید معمولاً دیتابیس خودش (مسئول دادههای مربوط به دامنهٔ همان سرویس) را دارد و بدین ترتیب فشار توزیع میشود. برای محتوای صوتی (فایلهای آهنگ و صوت)، ساندکلاد از ذخیرهسازی ابری توزیعشده (احتمالاً AWS S3 یا مشابه) استفاده میکند که از لحاظ مقیاس تقریباً نامحدود است و با افزایش تعداد آهنگهای آپلودشده، میتواند فضا و پهنای باند بیشتری تخصیص دهد. همچنین، در بخش پردازش آمار و رویدادها، ساندکلاد حجم بالایی از رخدادها(play، pause، لایک و غیره) را جمعآوری میکند و برای این منظور از یک زیرساخت استریمینگ داده بهره میبرد (در برخی منابع اشاره شده که ازKafka برای مدیریت ایونتها استفاده شده است). این زیرساخت به شکل توزیعشده طراحی شده تا با اضافه کردن نودهای بیشتر (سرورهای پردازش رویداد)، توان بلادرنگ سیستم افزایش یابد و عقب نیفتد.
نکتهٔ جالب دیگر در مقیاسپذیری ساندکلاد، توجه به مقیاسپذیری کد و منطق بود. برای مثال، مشکل تکرار منطق Authorization در چند BFF که پیشتر ذکر شد، در واقع یک مسئلهٔ مقیاسپذیری در ابعاد کدبود: با بزرگتر شدن سیستم، تکثیر کدهای مشابه باعث عدم مقیاسپذیری در نگهداری میشود. راهحل ساندکلاد معرفی VAS را میتوان تمهیدی جهت مقیاسپذیر نگهداشتن منطق کسبوکاردانست، بهطوری که با اضافه شدن ویژگیهای جدید، نیاز نباشد تغییرات هماهنگ در دهها نقطه اعمال شود. این جنبهای است که گاه نادیده گرفته میشود: مقیاسپذیری تنها مربوط به سختافزار و ترافیک نیست، بلکه مربوط به توان مهندسان در مدیریت سیستم نیز هست. ساندکلاد با طراحی سازمان مهندسی خود به تیمهای کوچک دامنهمحور (موسوم به دومینتیم) عملاً مسیر رشد محصول را هموار کرد.
مقایسه: اسپاتیفای و ساندکلاد هر دو با چالش مقیاسپذیری با اتخاذ معماری میکروسرویس و توزیع بار بین سرویسها مواجه شدند. اسپاتیفای از همان ابتدا سرویس خود را توزیعشده ساخت و سپس با مهاجرت به کلاود مقیاس را چندبرابر کرد. ساندکلاد کمی دیرتر اما مصمم، از مدل قدیمی فاصله گرفت و اکنون معماری کاملاً توزیعشدهای دارد. هر دو برای مدیریت پیک ترافیک، ازCDN و کش و autoscaling استفاده میکنند. تفاوت در این است که اسپاتیفای از چندین مرکز دادهٔ بینالمللی (ابتدا با مراکز دادهٔ خود و سپس روی GCP) استفاده کرده و حتی رویدادهایی مانند قطعی کابل زیردریایی بین دو دیتاسنتر را تجربه و با موفقیت پشت سر گذاشته است (ماجرای حملهٔ احتمالی کوسه به کابل که مهاجرت به Cassandra را تسریع کرد). این نشان میدهد اسپاتیفای به مقیاسپذیری جغرافیایی و تحمل خرابی منطقهای نیز توجه داشته است. ساندکلاد با تکیه بیشتر بر AWS (و احتمالاً CloudFront و سایر سرویسهای ابری) مقیاسپذیری جغرافیایی را از طریق ارائهدهندگان ابری به دست آورده است. خلاصه آنکه، معماری هر دو سرویس برای رشد افقی طراحی شده و تجربه نشان داده که آنها توانستهاند با افزایش عظیم کاربران خود، مقیاس را بدون افت کیفیت همراه کنند.
امنیت در خدماتی مانند اسپاتیفای و ساندکلاد ابعاد مختلفی دارد: حفاظت از دادههای حساس کاربران (اطلاعات شخصی، رمزهای عبور)، جلوگیری از دسترسی غیرمجاز به محتوای دارای حق نشر (آهنگها و فایلهای صوتی)، و مقاومبودن در برابر حملات مخرب (مانند DDOS، تلاش برای نفوذ به سرورها و غیره). طراحی معماری نرمافزار باید به نحوی باشد که این جنبههای امنیتی تأمین شود. در ادامه، راهکارهای امنیتی هر دو پلتفرم را بررسی میکنیم.
اسپاتیفای: اسپاتیفای مجموعهای از اقدامات چندلایه برای امنیت پیاده کرده است. در لایهٔ کاربری و API، اسپاتیفای از استاندارد OAuth2 برای احراز هویت و مجوز استفاده میکند. به این ترتیب، کاربران هنگام ورود یا اتصال حسابشان به اپلیکیشنهای ثالث، از رویهٔ امنی عبور میکنند که شامل توکنهای دسترسی زماندار است. همچنین APIهای اسپاتیفای توکنهای JWT یا مشابه آن را میپذیرند که در سمت سرور اعتبارسنجی میشوند و دسترسی به منابع (مثل لیستهای پخش یا کتابخانهٔ موسیقی کاربر) را کنترل میکنند. تمام ترافیک بین مشتریان و سرورها از TLS/SSL استفاده میکند تا دادهها در حین انتقال رمزنگاری شده باشند و قابل شنود نباشند. دادههای حساس در سمت سرور نیز با الگوریتمهای استاندارد نظیر AES رمزنگاریشده در حالت Rest نگهداری میشوند. گذشته از مباحث احراز هویت، اسپاتیفای تدابیر امنیتی داخلی متعددی دارد که برخی توسط بلاگ مهندسی آن ذکر شدهاند: این شرکت بهروزرسانی و پچکردن منظم سیستمها را یک اولویت میداند تا از سوءاستفاده از آسیبپذیریهای شناختهشده جلوگیری شود. علاوه بر آن، اسپاتیفای از اصل دفاع در عمق پیروی میکند؛ یعنی به یک مکانیسم دفاعی اکتفا نکرده و ترکیبی از دیوارههای آتش، سامانههای تشخیص نفوذ و ضدبدافزارها را در زیرساخت خود به کار گرفته است. برای نمونه، ارتباطات بین میکروسرویسهای داخلی ممکن است از طریق یک شبکهٔ مجزا یا با احراز هویت داخلی (مثل متادیتای سرویس Mesh) محافظت شود تا حتی در صورت نفوذ به یکی از سرویسها، مهاجم نتواند آزادانه به سایر بخشها دسترسی پیدا کند. اسپاتیفای همچنین سطوح دسترسی محدود برای دادههای حساس دارد؛ یعنی تنها سرویسها و افرادی که نیاز دارند به دادههایی مثلاً جداول کاربران یا گزارشهای مالی دسترسی دارند و این دسترسی نیز با احراز هویت قوی (مثلMFA) محافظت میشود. یکی دیگر از جنبههای امنیتی مهم، محافظت از محتوای دارای حق نشر (آهنگها) در برابر دانلود یا استفادهٔ غیرمجاز است. اسپاتیفای برای این منظور پروتکل اختصاصی رمزگذاری جریان صوتی خود را دارد؛ هرچند جزئیات دقیق آن عمومی نیست، اما مشخص است که فایلهای موسیقی به صورت رمزنگاریشده به کلاینتها ارسال میشوند و فقط توسط کلاینت رسمی و با کلیدهای موقتی قابل پخش هستند. همچنین، از آنجاکه اسپاتیفای زمانی از شبکهٔ همتابههمتا (P2P) نیز برای توزیع محتوا استفاده میکرد، روشهای جلوگیری از استخراج فایل از کش P2P را نیز به کار بسته بود (اسپاتیفای البته بعدترP2P را کنار گذاشت و کاملاً به CDN مهاجرت کرد). نرخدهی و محدودسازی درخواستهانیز یک تمهید امنیتی دیگر است؛ API اسپاتیفای دارای Rate Limit برای هر کلاینت و توکن است تا از سوءاستفادهٔ API و حملات اتوماتیک ممانعت شود. مجموعه این اقدامات، به اسپاتیفای کمک کرده تا تاکنون از افشای بزرگ داده یا حملات جدی در امان بماند.
اسپاتیفای همچنین از منظر فرهنگ سازمانی به امنیت اهمیت میدهد: آزمونهای نفوذ دورهای، مسابقات پیدا کردن باگ (Bug Bounty)، و آموزش منظم توسعهدهندگان دربارهٔ بهترین رویههای امنیتی، بخشی از برنامههای امنیتی اسپاتیفای است. این شرکت یک سیاست امنیتی جامع تدوین کرده که تمام جنبهها از توسعه تا عملیات را پوشش میدهد و اطمینان حاصل میکند که همهٔ تیمها اصول پایه را رعایت کنند.
ساندکلاد: برای ساندکلاد نیز امنیت از ابتدا حیاتی بوده است. در سطح API، ساندکلاد همانند اسپاتیفای از OAuth2 برای اعطای دسترسی به اپلیکیشنهای ثالث استفاده میکند (تا حدی که اخیراً به OAuth 2.1 مهاجرت کرده است). هر کاربری که میخواهد حساب ساندکلاد خود را به برنامهای متصل کند یا یک اپ از API ساندکلاد استفاده کند، باید از طریق OAuth توکن دریافت نماید. ارتباطات سرویسگیرنده-سرویسدهنده همه با HTTPS/TLS ایمن شدهاند. اما جذابتر، معماری BFF ساندکلاد است که نقش پررنگی در امنیت ایفا میکند. همانطور که گفته شد، BFFها جلوی همهٔ درخواستهای ورودی قرار دارند و مکان مناسبی برای پیادهسازی سیاستهای امنیتی یکپارچه هستند. برای مثال، BFF موبایل و وب میتوانند توکنهای احراز هویت کاربر را اعتبارسنجی کنند و فقط در صورت صحت، درخواست را به سرویسهای داخلی پاس بدهند. همچنین BFFها مسئول نرخدهی هستند تا اگر یک مشتری بیش از حد درخواست فرستاد (احتمالاً حملهٔ DDOS یا باگ کلاینت)، بهموقع جلوی آن گرفته شود. BFFها همچنین با پاکسازی و اعتبارسنجی هدرها و ورودیها، لایهای از امنیت افزوده ایجاد میکنند؛ بدین معنی که اجازه نمیدهند ورودیهای مخرب یا هدرهای دستکاریشده به سرویسهای داخلی راه یابد. این رویکرد Edge Security تضمین میکند که هریک از دهها میکروسرویس داخلی نیاز نباشد جداگانه همهٔ چکهای امنیتی اولیه را انجام دهند بلکه این کار متمرکز در لبه انجام میشود.
در بخش حفاظت از دادهها، ساندکلاد سیاستهای مشابهی با اسپاتیفای دارد: رمزنگاری رمزهای عبور (به صورت هش)، رمزنگاری ارتباطات و محدود کردن دسترسی مستقیم به پایگاهدادهها تنها از طریق سرویسهای مجاز. یک چالش امنیتی ویژه در ساندکلاد، جلوگیری از دانلود غیرمجاز آهنگها بوده است؛ چون ساندکلاد پلتفرمی است که به هنرمندان مستقل امکان انتشار میدهد، اما محتوای آنان به راحتی قابل rip کردن بود. برای حل این مشکل، ساندکلاد نیز استریم صوتی خود را با کلیدهای موقت و درخواستهای امضاشده ایمن کرد. هر درخواست پخش، یک URL موقت از CDN دریافت میکند که فقط برای مدت کوتاهی معتبر است و فقط برای همان کاربر تولید شده. بدین ترتیب، حتی اگر کسی لینک دانلود را کپی کند، پس از چند دقیقه منقضی میشود.
شاید مهمترین اقدام امنیتی معمارانه ساندکلاد در سالهای اخیر، همانی باشد که در قسمت معماری بحث شد: یکپارچهسازی منطق احراز و مجوز در سرویسهای مرکزی (VAS) به جای چندگانگی در BFFها. وقتی منطق حساس امنیتی – مثلاً بررسی اینکه آیا کاربر X اجازه دارد آهنگ Y را گوش کند یا خیر – در چند نقطهٔ مختلف پیاده شود، ریسک ناسازگاری و خطا بالا میرود. ساندکلاد دریافت که این عدم هماهنگی میتواند به شکاف امنیتی منجر شود (برای نمونه، یک BFF ممکن بود فراموش کند شرطی را چک کند). لذا، آوردن این منطق به یک سرویس ارزشافزودهٔ واحد (مثلاً سرویس Track VAS) سبب شد نقاط تصمیمگیری امنیتی متمرکز شوند و امکان اشتباه یا فراموشی کاهش یابد. در واقع، آنها با این کار به اصل Single Source of Truth در امنیت رسیدند: هر قانون دسترسی فقط یک بار و در یک مکان اعمال میشود و همهٔ خروجیها از همان تبعیت میکنند. این موضوع توسط منابع به عنوان یک بهبود حیاتی برای تضمین یکپارچگی امنیتی سیستم ساندکلاد ذکر شده است.
در حوزهٔ مقاومت در برابر حملات بیرونی، ساندکلاد از خدمات ابری برای جذب حملات DDOS بهره میگیرد. احتمالاً با تنظیماتAWS Shield یا Cloudflare ترافیک غیرعادی را قبل از رسیدن به سرورهای اصلی فیلتر میکند. همچنین گزارش شده که ساندکلاد برای جلوگیری از رباتها و ترافیک جعلی، با ابزارهای تشخیص بات (مثل DataDome) و سرویسهای ابری همکاری داشته است. این نشانه میدهد که آنها به تهدیدات مدرن (اکانتهای جعلی، اسپم کامنتها و ...) نیز واقفند و راهحلهای بهروز را بکار میبرند.
مقایسه: در مجموع، اسپاتیفای و ساندکلاد هر دو یک نگرش چندلایه و جامع به امنیت دارند. هر دو از OAuth2 برای محافظت ازAPI و احراز هویت کاربران استفاده میکنند، هر دو ترافیک را رمزنگاریشده منتقل میکنند و دادههای حساس را رمزگذاری میکنند. اسپاتیفای بیشتر بر روی استانداردهای صنعتی و بهترین رویهها تأکید کرده و با پشتوانهٔ مالی و تیم بزرگ امنیتی، احتمالاً پروتکلهای خود را نیز توسعه داده است (مثل پروتکل Hermes یا شیوههای رمزنگاری محتوای موسیقی). ساندکلاد با بهرهگیری هوشمندانه از معماری BFF/VAS موفق شده امنیت را در معماری خود نهادینه کند – به این شکل که لایهٔ Edge را به عنوان دیوار نخست دفاع قرار داده و منطقهای حساس را به صورت متمرکز در آورده است. ممکن است گفته شود اسپاتیفای به دلیل شهرت جهانی و داشتن محتوای تحت لیسانس شرکتهای بزرگ موسیقی، هدف حملات پیچیدهتری باشد و بنابراین سرمایهگذاری بیشتری در امنیت سایبری کرده باشد (بهعنوان مثال سیستمهای خودکار کشف تقلب در استریمها، یا حفاظت از حریم خصوصی کاربران در برابر نشت داده). از سوی دیگر، ساندکلاد با جامعهٔ هنرمندان و مدل کسبوکار متفاوت، بیشتر تمرکز خود را بر امنیت دسترسی و جلوگیری از سو استفاده از پلتفرم توسط اسپمرها قرار داده است. با این همه، هیچ گزارش مهمی از نقض امنیت جدی در هر دو پلتفرم منتشر نشده که نشان میدهد معماری و سیاستهای امنیتی آنها تاکنون موفق عمل کرده است.
قابلیت نگهداری به معنای سهولت اصلاح، بهروزرسانی و رفع عیب سیستم در طول عمر آن است. یک معماری قابل نگهداری باید طوری باشد که تیمهای توسعه بتوانند با صرف تلاش معقول، سیستم را ارتقا دهند، بخشهای معیوب را شناسایی و تعمیر کنند و از پیچیدگی افسارگسیخته جلوگیری کنند. معماری اسپاتیفای و ساندکلاد هر دو برای دستیابی به نگهداریپذیری بالا طراحی و تکامل یافتهاند، اما رویکردهای عملی آنها قابل مقایسه است.
اسپاتیفای: معماری میکروسرویس اسپاتیفای ذاتاً نگهداریپذیری را بهبود داده است. تقسیم سیستم به سرویسهای کوچکتر با مسئولیت مشخص باعث شده هر بخش درکپذیرتر و تستپذیرتر باشد و توسعهدهندگان بتوانند سریعتر روی آن مسلط شوند. همانطور که کوین گلدسمیت اشاره کرده، میکروسرویسها رفع باگ و دیباگ کردن را سادهتر میکنند، چرا که حوزهٔ اثر هر تغییر کوچک و محدود است. علاوه بر این، اسپاتیفای یک فرهنگ مهندسی قوی حول مستندسازی و اشتراک دانش ساخته است. به عنوان نمونه، ابزار Service Discovery و Documentation داخلی اسپاتیفای – که بعدها در قالب Backstage منتشر شد – به هر مهندس امکان میدهد از وجود سرویسهای مختلف و وظیفهٔ آنها آگاه شود و مستندات مرتبط (شامل APIها، نمودار وابستگیها و ...) را بهروز ببیند. این شفافیت جلوی اختراع مجدد چرخ را میگیرد و کمک میکند اگر تیمی نیازمند قابلیت یک سرویس دیگر بود، بهجای دوبارهنویسی، از همان سرویس استفاده کند یا با تیم مالک همکاری نماید. همچنین اسپاتیفای با باز نگه داشتن کدها درون سازمان (مدل inner source) محیطی فراهم کرده که همه به کد هم دسترسی دارند و میتوانند مشارکت کنند. گزارش شده که تمام تیمهای اسپاتیفای روی یک انبار Git بزرگ)monorepo یا چیزی نزدیک به آن) کار میکنند و کد یکدیگر را میتوانند مشاهده کنند. این امر حس مالکیت جمعی و استانداردسازی رویهها را تقویت میکند؛ در نتیجه، نگهداری سیستم به تلاش هماهنگ کل سازمان بدل شده نه اینکه هر تیم در سیلوی خود عمل کند.
اسپاتیفای همچنین از مدل سازمانی اسکواد/ترایب بهره میبرد که در آن Chapters (فChapter( گروههای مهندسان همتخصص در سراسر سازمان) وجود دارند. این Chapters به حفظ یکنواختی تکنیکی و بهترین شیوهها بین تیمهای مختلف کمک میکنند. مثلاً یک Chapter از مهندسان بکاند اطمینان حاصل میکند که همهٔ سرویسها به روشی استاندارد لاگ میگیرند یا خطاها را مدیریت میکنند. این نوع حاکمیت سبک سبب میشود با گذشت زمان، کدبیسهای سرویسها از هم بیگانه نشوند و افزودن افراد جدید یا انتقال افراد بین تیمها آسانتر گردد، چون الگوهای آشنا را خواهند دید.
برای رفع عیب و مانیتورینگ، اسپاتیفای حجم گستردهای از لاگها و متریکها را در یک سیستم متمرکز (مثل ELK Stack، Grafana/Prometheus) جمعآوری میکند. این بدان معناست که اگر مشکلی گزارش شد (مثلاً کندی در پخش آهنگ برای کاربران یک منطقه)، مهندسان به سرعت میتوانند از طریق داشبوردهای مانیتورینگ سرویس مشکلدار را شناسایی کنند. کوچک بودن دامنهٔ هر سرویس کمک میکند محدودهٔ جستجو برای علتیابی خطا کوچک باشد و در نتیجه MTTR )میانگین زمان ترمیم) پایین بیاید. همچنین، امکان چرخش نسخهها در میکروسرویسها نگهداری را ساده کرده است: اسپاتیفای میتواند نسخههای قدیمیتر یک سرویس را تا مدتی در کنار نسخههای جدید نگه دارد تا در صورت بروز مشکل در نسخهٔ جدید، سریعاً سرویس به نسخهٔ قبلی برگردانده شود. این استراتژی در اسپاتیفای بارها استفاده شده و باعث میشود انتشار کد جدید ریسک کمتری داشته باشد و نگهداری سیستم پایدارتر انجام شود.
ساندکلاد: قابلیت نگهداری دغدغهٔ اصلی ساندکلاد در تصمیم به مهاجرت به میکروسرویس بود. زمانی که ساندکلاد یک مونوolith بزرگ داشت، توسعهدهندگان احساس میکردند نمیتوانند با اطمینان در آن تغییر ایجاد کنند و بخشهایی از کد تبدیل به ناحیهٔ ترس شده بود (کسی جرأت تغییرش را نداشت). شکستن سیستم به میکروسرویسها عملاً این مشکل را نشانه گرفت تا هر تیم محدودهٔ کاری خود را داشته باشد و کد آن بخش را کاملاً بفهمد. ساندکلاد اذعان کرده که این کار اعتمادبهنفس تیمها را در اعمال تغییر بالا برد و توسعهٔ فیچرهای جدید را تسریع کرد. علاوه بر این، ساندکلاد از همان ابتدا روی ابزارها و کتابخانههای داخلی سرمایهگذاری کرد تا توسعه و نگهداری سرویسهای کوچک آسان شود. به عنوان مثال، آنها کتابخانههای مشترکی برای لاگگیری، پیکربندی، تلهمتری و مدیریت نشست ساختند و در اختیار همهٔ تیمها گذاشتند. نتیجه این شد که هر سرویس جدید به جای اختراع مجدد این چرخها، از آن کتابخانههای امتحانپسداده استفاده میکرد و در صورت بهبود هر یک از آنها، تمام سرویسها منتفع میشدند. این استفادهٔ مجدد از مؤلفهها عملاً توان مهندسی سازمان را بهتر بهکار گرفت و از تکثیر راهحلهای موازی جلوگیری کرد – امری که مستقیماً بر نگهداریپذیری اثر مثبت دارد (چون کد مشترک کمتر یعنی نقاط اصلاح کمتر و یکپارچگی بیشتر). خود مهندسان ساندکلاد گفتهاند که هر بهبودی در این زیرساخت مشترک، اثری معادل اضافه شدن یک مهندس جدید از نظر بهرهوری داشته است.
ساندکلاد با گذار به BFF/VAS نیز نگهداری را بهبود داد، چرا که اکنون تفکیک مسئولیت شفافتری دارند. قبلاً شاید یک تغییر کوچک (مثلاً تغییر ساختار دادهٔ Track( مستلزم تغییر در مونوolith و چندین جای دیگر بود، اما حالا مثلاً اگر قرار باشد فیلد جدیدی به اطلاعات Track اضافه شود، مشخص است که باید در سرویس Track VAS و سرویس Track پایه اعمال شود وBFFها خودبهخود دادهٔ جدید را دریافت خواهند کرد. تمرکز منطق مرتبط با هر دامنه در سرویسهای مشخص، فهم سیستم را سادهتر کرده است. البته نباید از مشکلات نگهداری نیز غافل شد: ساندکلاد تجربه کرد که در ابتدا به دلیل کندی در حذف کامل مونوolith، نوعی دوگانگی ایجاد شده بود و برخی تیمهای جدید اصلاً با کد قدیمی آشنا نبودند و لذا در یک برهه نگهداری آن قسمت قدیمی دشوار شده بود. این یک درس مهم بود: نگهداریپذیری یک سیستم در حال گذار نیازمند آن است که دانش سیستم قدیمی مستند شود و میان اعضای جدید هم توزیع شود. ساندکلاد با بهکارگیری مهندسان باتجربهٔ مونوolith در پروژههای استخراج (Extraction projects) و تدوین مستندات و راهنماهای مشخص توانست این شکاف را پر کند. آنها حتی نظارت کردند که آیا تیمها برای استفاده از سرویسهای جدید کدهای مونوolith را دور میزنند یا خیر و شیوههای غلط (مانند اتصال مستقیم سرویس جدید به دیتابیس مونوolith( را از طریق آموزش و نظارت تصحیح کردند.
ساندکلاد نیز مانند اسپاتیفای به ابزارهای مانیتورینگ و logging مدرن (نظیر Prometheus/Grafana و ELK مجهز است. بنابراین مهندسان دید لحظهای روی وضعیت سرویسها دارند و در صورت بروز ایراد، آن را تا سطح سرور و حتی درخواست مشکلدار پیگیری میکنند. کوچک بودن اندازهٔ هر سرویس و محدود بودن مسئولیتش، خطایابی (Debugging) را سریعتر کرده است. برای مثال، اگر گزارشی برسد که «صفحهٔ پروفایل کاربر در اپ موبایل لود نمیشود»، مهندسان ساندکلاد میدانند باید وضعیت BFF موبایل و سرویسهای کاربر و آهنگ را بررسی کنند – نیازی به شانه زدن کل کدبیس نیست.
مقایسه: هر دو پلتفرم از رهگذر معماری سرویسگرا به نگهداریپذیری بالاتری رسیدهاند، اما اسپاتیفای با راهاندازی یک پلتفرم درونی (Backstage) برای مستندسازی و اشتراک دانش یک گام جلوتر حرکت کرده است. در مقابل، ساندکلاد با اندرسون(InnerSource) کردن کتابخانهها و کدهایش و مدل مشارکتی، به جنبهٔ دیگری از نگهداری پرداخته است. اسپاتیفای با داشتن هزاران سرویس، روی مدلسازی و مصورسازی معماری سرمایهگذاری کرده و استاندارد C4 را با Spotify Software Model تطبیق داده تا درک سیستم برای همگان آسان باشد. این نشان از این دارد که وقتی شمار اجزای یک سیستم بسیار زیاد میشود، صرف سرویسگرا بودن کافی نیست و باید زبانی مشترک و دیدی انتزاعی برای صحبت دربارهٔ کل سیستم ایجاد کرد – کاری که اسپاتیفای انجام داده و در وبلاگش منتشر کرده است. ساندکلاد با تعداد سرویس کمتر (هرچند باز هم قابل توجه) شاید هنوز بدون چنین ابزاری کار را پیش میبرد یا از ابزارهای اپنسورس عمومی بهره گرفته است. به طور کلی، هر دو بر خودمختاری تیمها تأکید دارند اما اسپاتیفای در عین حال با ساختار Chapters/Guilds از اشتراک بهترین عملیها اطمینان حاصل میکند، ساندکلاد هم با ایجاد کلکتیوها و جلسات منظم بین تیمها(مثلاً در مورد BFFها یک جمع مشترک دارند) تجربیات را منتقل میکند. بنابراین، نگهداریپذیری در هر دو معماری به واسطهٔ کوچکسازی اجزا، اشتراک دانش و استفاده از ابزارهای مناسب تضمین شده و این امکان را داده که با وجود توسعهٔ مداوم ویژگیهای جدید، سیستم پایدار و قابل پیشبینی باقی بماند.
انعطافپذیری معماری بیانگر سهولت و سرعتی است که با آن سیستم میتواند با تغییرات سازگار شود – چه تغییر نیازمندیهای کسبوکار (افزودن قابلیتهای جدید) و چه تغییر فناوریهای زیربنایی. معماریهای خوب باید تغییرپذیر باشند تا عمر طولانی داشته باشند. در مقایسهٔ اسپاتیفای و ساندکلاد، هردو با بهرهگیری از میکروسرویسها، انعطافپذیری را به میزان زیادی افزایش دادهاند، اما مصادیق آن در هر کدام جالب توجه است.
اسپاتیفای: شعار نانوشتهٔ اسپاتیفای در معماری این بوده که «هر قسمت مستقل باشد تا سریع تغییر کند». با مستقل کردن سرویسها، اسپاتیفای میتواند ویژگیهای جدید را با افزودن سرویسهای جدید یا اصلاح سرویسهای موجود پیادهکند بدون آنکه نگران اثرات جانبی گسترده باشد. برای نمونه، وقتی اسپاتیفای تصمیم گرفت پادکست را به پلتفرم خود اضافه کند، این قابلیت عمدتاً از طریق مجموعهای سرویس جدید (برای مدیریت پادکست، جستجوی پادکست، توصیهٔ پادکست و غیره) عملی شد، بیآنکه نیاز باشد ساختار سرویسهای موسیقی دچار تغییرات بنیادی شود. این جدا بودن دامنهها، امکان توسعهٔ موازی ویژگیهای متعدد را به اسپاتیفای داده و در نتیجه این شرکت هر هفته دهها ویژگی کوچک و بزرگ را به کاربران ارائه میکند. گزارش شده که اسپاتیفای توان انجام صدها استقرار در هفته را دارد، که خود گواه انعطاف سیستم در پذیرش تغییرات پیوسته است. از منظر بهروزرسانی فناوری، معماری اسپاتیفای انعطاف لازم برای مهاجرتهای بزرگ زیرساختی را نیز داشته است. برای مثال، انتقال ازPostgreSQL به Cassandra یا انتقال از سرورهای دیتاسنتر خود به Google Cloud بدون توقف چشمگیر سرویس انجام شد. این موفقیت به لطف طراحی آزادانهٔ سرویسها و استفاده از الگوهایی مثل Dark Launching و Backwards Compatibility بوده است. اسپاتیفای هنگام مهاجرت دیتابیس، سیستم را طوری طراحی کرد که مدتی به هر دو دیتابیس قدیم و جدید به موازات بنویسد (طرح “dark loading” که در متن به آن اشاره شده) تا از صحت عملکرد Cassandra اطمینان حاصل کند، سپس به مرور خواندنها را نیز به آن منتقل کرد – این تغییر تدریجی تنها در معماریهای انعطافپذیر ممکن است که بتوانند دو سیستم را همزمان نگه دارند. به طور مشابه، اسپاتیفای توانست فرآیند بیلد و CI اپلیکیشن iOS خود را در سال ۲۰۲۳ به طور کامل عوض کند استفاده از Bazel با دخیل کردن ۱۲۰ تیم؛ چنین تغییری عظیم در ابزارهای توسعه اگر معماری نرمافزار و سازمان مهندسی منعطف نبود، میتوانست ماهها سرویس را مختل کند. اما اسپاتیفای با طراحی ماژولار (چه در کد کلاینت و چه سرویسها) این ریسکها را مدیریت کرد. فرهنگ «تجربه و تغییر» نیز در اسپاتیفای مشهود است – آنها مدل «Spotify Squad» خود را همواره بازنگری و اصلاح میکنند تا موانع انعطاف سازمانی را رفع کنند.
ساندکلاد: ساندکلاد پس از معماری مجدد، جهش بزرگی در انعطافپذیری به دست آورد. در معماری قدیمی، افزودن حتی یک فیچر ساده (مثلاً افزودن قابلیت Repost کردن آهنگ توسط کاربر) ممکن بود مستلزم کار روی همان کدبیس بزرگ و هماهنگی بین دهها توسعهدهنده باشد. اکنون اما هر ویژگی جدید میتواند به عنوان یک سرویس جدید یا یک افزونه در یک سرویس موجود توسط یک تیم کوچک توسعه یابد و به راحتی در سیستم پلاگ شود. به عنوان مثال، اضافه کردن استوری (Story) یا پلیلیستهای چندنفره در ساندکلاد، دیگر مستلزم تغییر ساختار کلی پلتفرم نبود، بلکه احتمالاً با ایجاد سرویسهای جدید در کنار سایر سرویسها انجام شد. حتی برخی قابلیتهای جدید میتوانستند کاملاً خارج از مونو olith پیاده و آزمایش شوند و تنها از طریقAPI با سیستم قدیم تعامل کنند، که این نشان از انعطافپذیری بالای مرحلهٔ گذار داشت.
معماری ساندکلاد با معرفی BFF، امکان انعطاف در پاسخگویی به نیازهای متفاوت کلاینتها را فراهم کرد. برای نمونه، اگر تیم موبایل تصمیم میگرفت صفحهٔ خانگی اپلیکیشن محتوای متفاوتی نسبت به وب نمایش دهد، BFF موبایل میتوانست بدون دخالت در سرویسهای زیربنایی، این منطق را پیاده کند. یا اگر نیاز بود برای یک شریک تجاری API ویژهای ارائه شود (مثلاً API سادهتری برای embedded widgetها)، به راحتی یک BFF جدید یا یک مسیر جدید در BFF موجود ایجاد میشد بیآنکه کل معماری را تحت تأثیر قرار دهد. این سطح از انعطاف که فرمتهای مختلف ارائهٔ سرویس را پشتیبانی کند، نتیجهٔ مستقیم جداسازی لایهٔ ارائه (Presentation Layer) در قالب BFF بوده است.
از زاویهٔ تغییر فناوری، ساندکلاد در خلال مهاجرت به میکروسرویس چندین تکنولوژی جدید را وارد کرد: مثلا زبان Scala و کتابخانهٔ Finagleرا برگزید و بسیاری از سرویسهای جدید را با آن ساخت. این تصمیم جسورانه (حرکت از دنیای دینامیکRuby/PHP به دنیای استاتیک JVM) به خوبی جواب داد چون معماری جدید اجازه میداد بخشبهبخش فناوری عوض شود؛ نیازی نبود کل سیستم به یکباره بازنویسی شود. بنابراین سرویسهای جدیدتر با اسکالا نوشته شدند در حالی که مونوolith قدیمی احتمالاً با Ruby on Rails باقی ماند تا زمانی که حذف شود. این همزیستی فناوریها از انعطاف فناوری معماری حکایت دارد. در سمت زیرساخت هم، ساندکلاد انعطاف خوبی نشان داده است: مثلاً به کارگیری Kubernetes به نسبت زمان خود یک تصمیم پیشرو بود و ساندکلاد بدون نیاز به توقف سرویسها، معماری استقرارش را از روشهای سنتی به container orchestration مدرن تغییر داد.
از جهت تفکیک دامنههای کسبوکار هم انعطاف معماری ساندکلاد قابل ستایش است. با معرفی Domain Gatewayها، تیمهای جداگانه برای دامنهٔ «هنرمندان (Creators)» و «شنوندگان (Consumers)» شکل گرفتند. این یعنی اگر در آینده ساندکلاد تصمیم بگیرد سرویس خاصی فقط برای سازندگان ارائه کند (مثلاً یک داشبورد آنالیتیکس پیشرفته)، میتواند آن را درDomain Gateway مربوطه توسعه دهد بدون نگرانی از تداخل با تجربهٔ شنوندگان. یا برعکس، فیچرهای مربوط به شنوندگان (مثل الگوریتمهای پیشنهاد آهنگ) میتواند مستقل از ابزارهای آپلود و مدیریت هنرمندان تکامل یابد. این انعطاف در برابر نیازمندیهای کسبوکار مختلف در یک پلتفرم واحد، برای سرویسهایی که دوسوی مارکتپلیس را دارند بسیار مهم است و ساندکلاد با معماری خود به آن دست یافته است.
مقایسه: اسپاتیفای و ساندکلاد از نظر انعطافپذیری، هر دو سرآمد هستند و شاید معماریشان را بتوان الگوی سایر شرکتها قرار داد. اسپاتیفای بیشتر به انعطاف در مقیاس کلان شهرت دارد – اینکه میتواند به سرعت خود را با تکنولوژیهای روز (ابری، بیگ دیتا، ماشین لرنینگ و ...) وفق دهد و امکانات جدیدی مثل پادکست و کتاب صوتی را در پلتفرمش ادغام کند بیآنکه کاربران دچار تجربهٔ بد شوند. ساندکلاد نیز انعطاف در طراحی محصول را به نمایش گذاشت – به نحوی که توانست حالتهای استفادهٔ متنوع (پلتفرم شنیدن موسیقی، شبکهٔ اجتماعی هنرمندان، فضای همکاری در تولید پادکست و...) را روی یک بستر فراهم کند. یک فرق ممکن در فلسفه: اسپاتیفای از اول سرویس خود را ماژولار ساخت، بنابراین کمتر دچار بازطراحیهای عمده شد (اگرچه مهاجرت دیتابیس و مهاجرت ابری رخ داد اما سرویسها از ابتدا جدا بودند)؛ ساندکلاد اما یک بازطراحی اساسی را تجربه کرد و به نوعی معماری فعلیاش زاییدهٔ درسهایی است که از انعطافناپذیری سیستم قدیمی آموخت. شاید بتوان گفت ساندکلاد اکنون انعطافپذیرتر از همیشه است اما در این مسیر هزینه و زمان بیشتری صرف شد. در هر حال، هر دو اکنون به مرحلهای رسیدهاند که تغییر در آنها سریع، کمهزینه و با ریسک پایین است – شاخصههایی که هر مهندس نرمافزار آرزو دارد در سیستمش ببیند.
قابلیت تست یعنی اینکه بتوان اجزای سیستم را به آسانی و به طور مؤثر آزمود و از صحت عملکرد آنها اطمینان حاصل کرد. معماری نرمافزار نقش مهمی در تستپذیری ایفا میکند؛ جداسازی مناسب اجزا، در دسترس بودن نقاط ورودی برای آزمون، و امکان شبیهسازی سناریوها همگی متاثر از طراحی معماری است. در مقایسهٔ اسپاتیفای و ساندکلاد از نظر تستپذیری، شباهتهای زیادی به چشم میخورد چرا که هر دو با اتخاذ معماری میکروسرویس این بُعد را نیز بهبود دادهاند.
اسپاتیفای: میکروسرویسهای اسپاتیفای به صورت مستقل قابل اجرا و تست هستند. هر سرویس یک مجموعه API مثلاً REST endpoints یا فراخوانیهای gRPC مشخص دارد که به راحتی میتوان برای آنها تستهای واحد (Unit Test) و تستهای یکپارچگی محدود نوشت. تیمهای اسپاتیفای از این بابت آزادی عمل دارند که مثلاً برای سرویس توصیههای موسیقی، شبیهسازی رفتار سرویس کاربر و سرویس آهنگ را انجام داده و منطق توصیه را در شرایط مختلف بیازمایند، بدون اینکه نیاز باشد کل سیستم را بوت کنند. کوین گلدسمیت صراحتاً اشاره کرده که «میکروسرویسها تست کردن را آسانتر میکنند». یکی از دلایل این است که هر سرویس نسبتاً کوچک و تخصصی است و حالات ورودی/خروجی کمتری دارد که باید پوشش داده شود. به علاوه، چون وابستگی بین سرویسها کمینه شده، در تست یک سرویس میتوان وابستگیها را به سادگی با موک (mock) یا استاب(stub) جایگزین کرد. در اسپاتیفای، تستهای خودکار بخش جداییناپذیر فرآیند توسعه هستند؛ آنها دارای خطوط CI/CD پیشرفتهای هستند که با هر تغییر کد، صدها یا هزاران تست را اجرا میکند. معماری آنها اجازه داده که بسیاری از این تستها در سطح واحد یا سرویس ایزوله باشند و بنابراین سریع و قابل اطمینان اجرا شوند. حتی برای تستهای end-to-end، اسپاتیفای سرویسهای غیرواقعی یا محیط staging کاملی دارد که شبیهسازی سناریوهای کاربر نهایی در آن ممکن است. همچنین، وجود سرویسهای توافقپذیر (Contract Service) باعث میشود اگر تغییری در قرارداد یک API سرویس به سرویس دیگر ناسازگاری ایجاد کند، تستهای آن به سرعت شکسته و مشکل گزارش شود.
با استفاده از Docker، اسپاتیفای حتی امکان اجرای سرویسها در محیط ایزوله برای تست را ساده کرده است؛ توسعهدهندگان میتوانند نسخهٔ Docker image یک سرویس را چرخانده و تستهای تعامل آن با سرویس دیگر را به صورت محلی یا درpipeline CI انجام دهند.
ساندکلاد: برای ساندکلاد نیز میکروسرویسها موهبتی در تستپذیری بودند. در بلاگ مهندسی ساندکلاد اشاره شده که آنها کار زیادی برای تست تعاملات سرویسها انجام دادهاند و این به دادن اطمینان خاطر در دیپلویمنتها کمک کرده است. یکی از اقدامات ساندکلاد پیادهسازی تستهای integration میان سرویسها بوده تا اطمینان حاصل شود وقتی یک سرویس بهروزرسانی میشود، هنوز هم با سرویسهای مرتبط سازگار است. همچنین، استقرار مبتنی بر Docker/K8s این امکان را فراهم کرده که محیطهای staging یا review به سرعت بالا بیایند – یعنی مثلاً برای یک شاخهٔ git جدید یک دستۀ سرویس Docker با آن تغییر بالا بیاید و QA بتواند کل سیستم را با آن تغییر تست کند.
ساندکلاد در دوران مونوolith، تست کردن تغییرات بزرگ بسیار دشوار بود چون کل سیستم باید در کنار هم کار میکرد تا نتیجه دیده شود. اکنون با سرویسهای مجزا، هر تکه را میشود مستقل آزمود. به عنوان نمونه، تیمی که روی سرویس آمار پخش کار میکند، میتواند آن را با مجموعهای از eventهای ساختگی بیازماید و خروجی را تأیید کند، بدون نیاز به اجرای فرانتاند یا سایر قسمتها. از سوی دیگر، BFFها که ورودی مستقیم از دنیای خارج میگیرند، بهترین جا برای نوشتن تستهای end-to-end سبک هستند؛ زیرا یک BFF عملاً نمایندهٔ یک کلاینت است. بنابراین ساندکلاد میتواند مثلاً مجموعهای از تستهای خودکارAPI برای BFF موبایل داشته باشد که رایجترین سناریوهای کاربردی اپ موبایل (مثل لاگین، مرور فید، پخش آهنگ) را با call زدن به API موبایل شبیهسازی و صحت پاسخها را بررسی کند. این تستها کل مسیر را از BFF تا سرویسهای زیرین و برعکس طی میکنند و از سالم بودن اکوسیستم اطمینان میدهند. کوچک بودن هر ماژول و مستقل بودن تیمها باعث شده مسئولیت تستنویسی بر عهدهٔ همان تیمی باشد که کد را میزند – این حس مالکیت کیفیت را بالا برده است. تیمهای ساندکلاد برایAPIهای خود احتمالاً قرارداد تست (Contract Test) نیز تعریف کردهاند تا اگر BFF یا سرویس downstream تغییری کرد که با انتظارات آنها مغایرت داشت، فوراً آشکار شود.
در ساندکلاد، تستهای خودکار انتشار نیز اهمیت دارد. وقتی سیستمی روزانه چندین بار دیپلوی میشود، حتماً زنجیرهٔ CI حاوی تستهای جامعی است که هر بار باید پاس شوند. به علاوه، با توجه به اینکه ساندکلاد هنوز به طور کامل مونوolith را حذف نکرده بود (حداقل تا چند سال پیش)، آنها باید اطمینان مییافتند که سرویسهای جدید و سیستم قدیم دادههای همسان تولید میکنند. به همین منظور، برای مهاجرت Playlist VAS ذکر شده که تستهای خودکاری نوشته شد که خروجی BFFهای قدیمی و سرویس جدید را مقایسه میکرد تا مطمئن شوند تفاوتی نکند. این نمونهای عالی از تست در خدمت مهاجرت معماری است؛ عملاً تست به بخشی از استراتژی انتقال تبدیل شد.
مقایسه: معماری میکروسرویس محور هر دو پلتفرم، تستپذیری را بسیار بالا برده است. تیمهای مستقل، اجزای مستقل و رفتارهای قابل جداسازی یعنی امکان تست در مقیاسهای مختلف (واحد، یکپارچگی، end-to-end) و در محیطهای مختلف (محلی، staging، تولید با فلگهای خاموش) میسر است. اسپاتیفای احتمالاً با اتکا به فرهنگ DevOps قوی و ابزارهایش، تست را تا حد ممکن خودکار کرده و حتی ممکن است از روشهای نوینی مانند Testing in Production ( تست در محیط واقعی با دریافت بازخورد از رفتار سیستم) استفاده کند – مثلاً با دیپلوی تدریجی یک تغییر به درصدی از کاربرها و پایش. ساندکلاد نیز با طراحی تمیز سرویسها، کاری کرده که هر تغییر کوچکی تنها تعداد محدودی کامپوننت را تحت تاثیر قرار دهد، پس نوشتن تست و اجرای آن آسان است. شواهد نشان میدهد هر دو شرکت با جدیت روی پوشش تست کار کردهاند تا سرعت بالای انتشار را فدا نکنند. برای نمونه، اسپاتیفای تأکید دارد که میکروسرویسها تنها وقتی ارزش دارند که همراهشان ابزار تست و مانیتورینگ خوب باشد؛ و ساندکلاد هم تجربه کرد که بدون تست کافی تعاملات، مهاجرت سرویسها کند و پرخطر خواهد بود. در مجموع میتوان گفت معماری این دو سرویس Test-Driven بوده است به این معنا که امکان آزمایش و تضمین کیفیت از اجزای کوچک تا کل سیستم در تار و پود طراحیشان لحاظ شده است.
در دسترس بودن به میزان توانایی سیستم در ارائهٔ مداوم سرویس و پرهیز از downtime )زمان ازکارافتادگی) اشاره دارد. سرویسهای استریم موسیقی باید نزدیک به ۱۰۰٪ اوقات در دسترس باشند، چرا که کاربران جهانی در هر لحظه انتظار دارند به موسیقی دلخواهشان گوش دهند. معماری و زیرساخت اسپاتیفای و ساندکلاد هر دو برای بالابردن availability طراحی شدهاند، اما راهکارهای خاصی نیز اتخاذ کردهاند که شایان ذکر است.
اسپاتیفای: اسپاتیفای از چند جهت در دسترس بودن را تضمین میکند. اول، توزیع جغرافیایی سرویسها و دادهها است. اسپاتیفای دادههای خود (چه آهنگها، چه متادیتا و پروفایل کاربران) را در دیتاسنترهای متعددی در نقاط مختلف دنیا و نیز در نقاط لبه (Edge) از طریق CDNها تکثیر کرده است. این بدان معناست که اگر یک دیتاسنتر کامل دچار مشکل شود (مثلاً قطعی شبکه یا قطعی برق)، ترافیک به سرعت به نزدیکترین مرکز دیگر هدایت میشود و کاربران ممکن است افت سرویس ناچیزی حس کنند. نمونهای که قبلاً اشاره شد – قطع شدن کابل اقیانوس اطلس – آزمون بزرگی برای اسپاتیفای بود که توانست آن را پشت سر بگذارد و همین موضوع باعث شد مهندسان به فکر افزونگی بیشتر بیفتند. دوم، اسپاتیفای معماری میکروسرویس را طوری پیاده کرده که ایزولیشن خرابی داشته باشد؛ یعنی خرابی یک جزء لزوماً به خرابی اجزای دیگر منجر نشود. برای مثال اگر سرویس توصیهگر موسیقی از کار بیفتد، کاربران همچنان میتوانند به پخش مستقیم آهنگهایشان ادامه دهند و فقط بخش پیشنهادات ممکن است موقتاً کار نکند. یا اگر بخشی از سرویس پرداخت دچار مشکل شود، این نباید خللی در گوش کردن موسیقی رایگان ایجاد کند. این ایزولهسازی با جداسازی وظایف و اغلب با معماری Async (غیرهمزمان) و صفها تقویت شده است؛ یعنی سرویسها به جای قفل کردن یکدیگر منتظر پاسخ، درخواستها را صف میکنند و اگر سرویسی موقتاً در دسترس نبود، بعداً اقدام میکنند. سوم، چندین نسخه فعال از هر سرویس همیشه در حال اجراست (حداقل دو یا بیشتر). اسپاتیفای از Kubernetes استفاده میکند که خود ترمیمی (Self-healing) را فراهم کرده – اگر یک کانتینر سرویس کرش کند، به سرعت کانتینر جدیدی جایگزین میشود. مکانیزمهای Load Balancing نیز همواره سالم بودن نمونهها را پایش میکنند و ترافیک را فقط به نمونههای سالم میفرستند. چهارم، اسپاتیفای از پایگاهدادههای توزیعشده مانند Cassandra بهره میبرد که به طور داخلی افزونگی داده دارند (Replication) و تحمل خرابی چند گره را دارند بدون از دست دادن داده یا قطع سرویس. Cassandra طوری پیکربندی شده که حتی اگر یک یا دو گره از کلاستر موجود نباشند، سایر گرهها پاسخگویی میکنند و کاربر متوجه خطا نمیشود. همین امر برای سیستم پیامرسانی Kafka نیز صادق است؛ Kafka دادهها (eventها) را در پارتیشنهای متعدد تکثیر میکند تا در صورت سقوط یک Broker، brokers دیگر داده را تحویل دهند.
علاوه بر اینها، اسپاتیفای تیمهای ویژهای برای قابلیتاطمینان سایت (Site Reliability) دارد که به طور فعال وضعیت سرویسها را رصد میکنند و runbookهای دقیق برای سناریوهای خرابی آماده کردهاند. مانیتورینگ لحظهای همراه با آلارمهای خودکار، مهندسان را در هر ساعتی از شبانهروز از بروز اختلال مطلع میکند تا سریعاً مداخله کنند. اما مهمتر اینکه، معماری چنان طراحی شده که پیش از نیاز به مداخلهٔ انسانی، خود سیستم لایههایی از دفاع داشته باشد. مثلاً Circuit Breakerها در لایهٔ سرویسها وجود دارند که اگر سرویس وابسته پاسخگو نبود، به سرعت شکست را تشخیص داده و شاید یک پاسخ degradeشده به کاربر بدهند (برای نمونه، اگر سرویس اشعار آهنگ در دسترس نبود، اپ اسپاتیفای بخش نمایش شعر را خالی میگذارد ولی بقیهٔ قسمتها کار میکند). این الگوهای تحملپذیری خطا (Fault Tolerance) در اسپاتیفای گسترده به کار رفته تا High Availability حفظ شود. خود اسپاتیفای هدف سطحخدمت (SLA) بسیار بالایی دارد و برخی گزارشها از ۷۹۹/۹۹٪ آپتایم سخن گفتهاند، که نشاندهندهٔ نهایت تلاش برای تقریباً بدونdowntime بودن سرویس است.
ساندکلاد: ساندکلاد نیز با بهرهگیری از معماری توزیعشده به دسترسپذیری بالایی رسیده است. در روزگار مونوolith، یک باگ بد یا افزایش ناگهانی ترافیک ممکن بود کل سایت ساندکلاد را از دسترس خارج کند. اکنون به لطف میکروسرویسها و BFFها، احتمال چنین رخدادی کمتر شده است. Resilience یکی از مزایای اعلامشدهٔ BFF در ساندکلاد بود: حتی اگر یک BFF به خاطر استقرار بد از کار بیفتد، اثرش محدود به همان بخش است و کل پلتفرم پایین نمیآید. به عنوان نمونه، فرض کنیم BFF وب دچار مشکل شده؛ در این حالت کاربران وب با اختلال مواجه میشوند اما API عمومی و اپهای موبایل همچنان از طریقBFFهای خودشان کار میکنند. این جداسازی جلوی وقوع شکست سرتاسری را میگیرد.
در لایهٔ سرویسهای داخلی، ساندکلاد نیز همه چیز را چندمجموعهای (redundant) نگه میدارد. حداقل دو نمونه از هر سرویس در هر زمان در حال اجراست تا اگر یکی رفت، دیگری پاسخگو باشد. استفاده از Kubernetes، اینجا هم مزیت خود-ترمیمی را به همراه دارد – CrashLoopBackoffهای K8s از نو تلاش میکنند سرویسها را بالا بیاورند. دیتابیسهای مورد استفاده ساندکلاد (چه SQLهای sharded شده، چه NoSQLهایی مثل Cassandra یا Elastic برای جستجو) همه replication دارند تا فقدان یک نود باعث از دسترس خارج شدن داده نشود.
ساندکلاد همچنین برای افزایش availability، سیستمها را در حالت active-active )فعال در چند دیتاسنتر) دارد. حداقل در چند سال پیش، ساندکلاد مراکز دادهٔ اصلی در آمریکا و اروپا داشت و ترافیک کاربران هر منطقه را به نزدیکترین نقطه هدایت میکرد. در صورت بروز اشکال، امکان failover به دیگری مهیا بود. اگرچه جزئیات سطحخدمت اعلامشدهٔ عمومی برای ساندکلاد در دسترس نیست، اما به طور کیفی مشخص است که این سرویس نیز همیشه آنلاین بوده و موارد قطعی سراسری نادر و کوتاه بودهاند.
معماری ساندکلاد با Domain Gatewayها حتی تابآوری در برابر باگهای منطقی را نیز بالا برد. مثلاً اگر یک تغییر خاص مربوط به دامنهٔ creators دارای باگ باشد، تاثیری بر دامنهٔ مصرفکنندگان نخواهد داشت چون Gateway آنها جداست. این یعنی مشکلات دامنهای حداکثر نصف پلتفرم را تحت تأثیر میگذارد نه همه را. به بیان دیگر، Domain Gateway یک نوعbulkhead isolation (سوراخشدگی کنترلشده) ایجاد کرده است.
مقایسه: اسپاتیفای و ساندکلاد هر دو به طراحی برای عدم تکنقطه-خرابیNo Single Point of Failure پایبند بودهاند. هر جزء مهم یا توزیع شده (multi-node) است یا راهی برای degrade کردن در صورت نبود آن در نظر گرفته شده است. اسپاتیفای ممکن است با داشتن منابع و مهندسان بیشتر، سناریوهای پیشرفتهتری را پوشش داده باشد – مثل تحمل خرابی ناحیهای کامل در سطح قاره، یا حتی آزمایشهایی شبیه Chaos Engineering (مهندسینی که عمداً بخشی از سیستم را خراب میکنند تا مطمئن شوند سیستم کلی تاب میآورد). ساندکلاد نیز از الگوهای رایج تحمل خطا مانند timeoutهای معقول، circuit breaker، fallbacks استفاده میکند تا کاربران به ندرت با صفحهٔ خطا مواجه شوند.
یک تفاوت جزئی: اسپاتیفای در مقطعی برای بهبود latency به سمت معماری Cell/Region رفت (هر مجموعه کاربر را به یک سلول خدمتدهندهٔ خاص اختصاص میدهند تا خرابی یک سلول کل کاربران را متاثر نکند). ساندکلاد این تقسیمبندی را به آن شکل گزارش نکرده، اما BFFهای جداگانهشان کار مشابهی انجام دادهاند (بخشها را از هم جدا کردهاند).
در نهایت، هر دو سرویس با ترکیب نرمافزار مقاوم (میکروسرویسهای مستقل)، زیرساخت افزونه (سرورهای متعدد، دیتابیسهای توزیعشده) و پایش فعال (مانیتورینگ ۲۴/۷)، توانستهاند به سطوح بسیار بالای High Availability دست یابند که برای کاربرانشان امری بدیهی جلوه میکند (اما دستیابی به آن حاصل سالها طراحی و پیادهسازی دقیق بوده است).
تحملپذیری خطا با Availability ارتباط نزدیک دارد ولی تمرکز آن بر نحوهٔ رفتار سیستم هنگام وقوع خطاها و شکستها است. یک سیستم Fault-Tolerant به شکلی طراحی میشود که اگر جزئی از آن خراب شد یا رفتارش غیرطبیعی بود، سیستم کلی همچنان به درستی کار کند یا حداقل به شکل کنترلشده تنزل یابد. بررسی تحملپذیری خطا در معماری اسپاتیفای و ساندکلاد جالب است، زیرا نشان میدهد چگونه اصول طراحی توزیعشده به آنها قدرت تابآوری داده است.
اسپاتیفای: در اسپاتیفای اصل اساسی این است که خرابی اجتنابناپذیر است، پس باید آن را مدیریت کرد. به همین دلیل، هرجا ممکن بوده، مهندسان این شرکت فرض گرفتهاند که هر سرویس یا هر ماشین ممکن است در هر زمانی از کار بیفتد – بنابراین وابستگیهای شدید را حذف کرده و برای حالات خرابی رویه تعریف کردهاند. یکی از مکانیزمهای مهم اسپاتیفای، استفادهٔ گسترده از Circuit Breaker در فراخوانیهای بینسرویسها است. Circuit Breaker الگوهایی هستند که اگر مشاهده کردند فراخوانی به یک سرویس بیش از حد خطا میدهد یا کند شده، آن را به طور موقت قطع میکنند تا هم سرویس معیوب فرصت بازیابی بیابد و هم صفی از درخواستهای معیوب ایجاد نشود. این باعث میشود یک سرویس خراب نتواند خرابیاش را به کل سیستم سرایت دهد. در کلاینتها نیز، اسپاتیفای مکانیزم fallback دارد: اگر مثلاً دانلود از یکی از سرورهای CDN ممکن نبود، خود اپ به سراغ سرور بعدی در لیست میرود تا آهنگ پخش شود (مستخدم از دید کاربر).
معماری میکروسرویس اسپاتیفای ایزولهسازی خطا را تسهیل کرده است. همانطور که گفته شد، کوچک بودن هر سرویس به این معنی است که خرابی آن محدودهٔ کوچکی از قابلیتها را تحت تأثیر قرار میدهد. اسپاتیفای این را با یک مثال توضیح داده: «هر سرویس کار محدودی انجام میدهد، پس اگر در دسترس نباشد، تأثیرش بر کاربر حداقلی است». برای نمونه، اگر سرویس پیشنهاد آهنگهای مشابه از دسترس خارج شود، کاربر فقط آن بخش را نخواهد دید اما همچنان میتواند جستجو کند و آهنگ اصلی را گوش دهد. به این شکل، اسپاتیفای تجربهٔ کاربر را حتی در شرایط خطا تا حد ممکن بدون اختلال نگه میدارد.
از منظر ذخیرهسازی داده، اسپاتیفای با استفاده از Cassandra تحمل خطا را ارتقا داد چون Cassandra طوری طراحی شده که تحمل خرابی گرهها را دارد – اگر یک گره دچار مشکل شد، تا زمان تعمیر یا جایگزینی، سایر گرهها درخواستها را هندل میکنند و دادهها را بین خود تکثیر میکنند. در Kafka نیز اسپاتیفای replication factorهای مناسب تعریف کرده که خطای یک ماشین در کلاستر eventها را از بین نبرد. همچنین، سیستمهای کش مانند Redis اگر Fail شوند، اسپاتیفای طوری برنامهریزی کرده که بهصورت graceful degrade به پایگاهداده اصلی رجوع شود (cache miss) تا عملکرد کاهش یابد ولی سرویس قطع نشود.
ساندکلاد: ساندکلاد نیز از اصول مشابهی تبعیت میکند. یکی از کلیدیترین موارد، همان BFF و VAS است که اجازه میدهند در صورت خرابی یک سرویس پایه، حداقل پاسخ ناقصی اما قابل ارائه به کاربر برگردانده شود. برای مثال اگر سرویس کامنتها در ساندکلاد از کار بیفتد، VAS یا BFF میتواند صرفاً بخش نظرات را خالی بگذارد ولی همچنان خود آهنگ و جزئیاتش را نمایش دهد – بنابراین کاربر متوجه نبودن نظرات میشود اما اصل کار یعنی پخش موسیقی انجام میشود. این نوع طراحیهای تحمل خطا (عرضهٔ حداقلی خدمات به جای خطای کامل) به شکل Graceful Degradation در ساندکلاد به کار گرفته شده است. نمونهٔ آن در بلاگشان ذکر شده: اگر برای سرعت، BFF سعی کند مجموعهای بزرگ از آیتمها را یکجا بفرستد)pagination سرور-ساید)، ممکن است خطر fan-out و timeout داشته باشد که میتواند یک مسیر را کلاً مختل کند. ساندکلاد تشخیص داده که این موارد باید مدیریت شوند تا سیستم از دسترس خارج نشود؛ لذا مثلاً مکانیزم partial responseو Field Masking را اضافه کردهاند که BFF بتواند فقط بخشی از دادهٔ aggregate را درخواست کند تا مشکل حجم بیش از حد حل شود. این نشان میدهد حتی برای سناریوهای غیرخرابی سختافزاری، بلکه برای خطاهای منطقی یا باری هم پیشبینیهایی کردهاند.
در سطح زیرساخت، ساندکلاد مانند اسپاتیفای همه چیز را چندتایی دارد: چندین نمونه از هر سرویس، چندین گره از هر دیتابیس. پس خرابی سختافزاری تک ماشینها مشکلی ایجاد نمیکند. همچنین، استفاده از پلتفرم ابری AWS به آنها امکان داده از خدماتی مثل Multi-AZ بهره ببرند. برای مثال، دیتابیسهای رابطهای اگر استفاده شده باشند، احتمالاً با Multi-AZ deployment اجرا شدهاند که اگر یک Availability Zone مشکل داشت، یک کپی در Zone دیگر آماده است.
علاوه بر این، ساندکلاد کشف کرد که خطای انسانی هم باید تحمل شود – وقتی که گفتند برخی مهندسان جدید مونوolith را نمیشناختند و حتی اشتباهاً سرویس جدید را مستقیم به دیتابیس مونوolith وصل کردند. برای چنین مواردی، آنها فرآیندهایی گذاشتند (guideline و نظارت) تا این اشتباهات به حداقل برسد و اگر هم رخ داد سریعا تصحیح شود. این بیشتر جنبهٔ فرآیندی دارد تا معماری، اما بر قابلیت تحمل خطاهای فرآیندی دلالت دارد.
مقایسه: اسپاتیفای و ساندکلاد هر دو مصداق سیستمهای توزیعشدهٔ خطاپذیر هستند. استراتژیهای مشترکشان شامل: افزونگی در همه لایهها، ایزولهسازی سرویسها، Timeout و Circuit Breaker، degrade کردن خروجی به جای Fail کامل، و پایش پیوسته. اسپاتیفای با گسترهٔ جهانی و کاربران بسیار احتمالاً حتی سناریوهای نادر را هم در نظر گرفته – مثلاً قطع زیرساختهای شهری، فجایع طبیعی – و برای آنها آماده است (از طریق multi-region deployment). ساندکلاد چون مقیاس کوچکتری نسبت به اسپاتیفای دارد شاید از نظر گسترهٔ جغرافیایی به اندازهٔ اسپاتیفای پراکنده نباشد، ولی با تکیه بر AWS به اهداف مشابه رسیده است.
نکتهٔ آخر اینکه، تحملپذیری خطا فقط مربوط به تحمل خرابی نیست، بلکه برگشت سریع از خرابی را هم شامل میشود. هر دو شرکت با مانیتورینگ و DevOps قوی، MTTR را بسیار پایین نگه داشتهاند – یعنی اگر خطایی هم رخ داد، در کوتاهترین زمان تشخیص و رفع میشود. پس میتوان گفت معماری این دو سرویس نه تنها از خطا پیشگیری میکند و اثرش را محدود میکند، بلکه زمینهٔ واکنش سریع را هم فراهم کرده است.
قابلیت استقرار یعنی سهولت و سرعتی که با آن میتوان نسخههای جدید نرمافزار را در محیط تولید مستقر کرد. این ویژگی در عصر توسعهٔ چابک و انتشار مستمر بسیار مهم است. اسپاتیفای و ساندکلاد به عنوان شرکتهای نرمافزاری مدرن، فرآیند دیپلوی را تا حد امکان خودکار و روان کردهاند و معماری نرمافزارشان هم این امر را پشتیبانی میکند.
اسپاتیفای: با معماری میکروسرویس، اسپاتیفای میتواند بهروزرسانیهای نرمافزار را به صورت مستقل برای هر سرویس منتشر کند. این یعنی نیازی نیست صبر کنند تا کل سیستم آمادهٔ انتشار باشد؛ هر تیم هر زمان کارش آماده شد، میتواند سرویس خود را دیپلوی کند. نتیجه این شده که اسپاتیفای نرخ دیپلوی بسیار بالایی دارد (طبق برخی منابع صدها بار در روز در کل سازمان). اما چگونه این ممکن شده است؟ اول، اسپاتیفای یک خط لولهٔ CI/CD قوی پیاده کرده است. تمام کد تغییرات پس از merge شدن، به صورت خودکار build میشود، تستهای خودکار اجرا میشوند و در صورت پاس شدن، image جدید Docker ساخته و به مخزن imageها push میشود. سپس با استفاده از ابزاری که اسپاتیفای ساخته احتمالاً مشابه Spinnaker یا Jenkins Pipelines ، این image روی محیط staging و بعد تولید منتشر میشود. استفاده از Kubernetes دیپلوی را بسیار انعطافپذیر کرده – تعریف manifestهای هر سرویس به اسپاتیفای امکان میدهد rollout نسخهٔ جدید را کنترلشده انجام دهد (مثلاً اول درصدی از پادها نسخهٔ جدید شوند و اگر OK بود باقی نیز). همچنین، Canary Release )انتشار کاناری) وFeature Flagها در اسپاتیفای رواج دارد تا ریسک انتشارها کم شود.
ثانیاً، استقلال تیمها برای دیپلوی به این معناست که هر تیم مالکیت کامل Pipeline سرویس خود را دارد. مهندسان بکاند اسپاتیفای مسئول اجرای عملیاتی سرویس خود نیز هستند
مدل DevOps “You build it, you run it.” این فرهنگ باعث شده تیمها در خودکارسازی و سادهسازی فرآیند استقرار سرویسشان فعال باشند.
از نظر ابزار، اسپاتیفای ابزار داخلی برای مدیریت دیپلوی داشت مثلاً قدیماً سیستم Helios را داشتند قبل از Kubernetes. اما اکنون عمدتاً از ابزارهای استاندارد Kubernetes و سرویسهای GCP (مثل GKE و Cloud Build استفاده میکنند که خودشکار را آسان کرده است. Backstage هم یک plugin برای مدیریت انتشار سرویسها دارد که دید به مهندسان میدهد چه چیزی کجا دیپلوی شده و چه ورژنی در Prod است.
در کل، اسپاتیفای توانسته زمان بین کد زدن و رسیدن آن به کاربر را بسیار کوتاه کند – چیزی که به عنوان lead time درDevOps اندازهگیری میشود و اسپاتیفای احتمالاً در زمرهٔ شرکتهای high performer قرار میگیرد.
ساندکلاد: ساندکلاد نیز با مهاجرت به معماری جدید، فرآیند استقرار را خیلی بهبود بخشید. در دوران مونوolith، هر تغییر باید با دهها تغییر دیگر بنایی بسته میشد و در یک انتشار بزرگ به پروداکشن میرفت (که احتمالاً بهندرت – شاید هفتهای یا ماهی یکبار – رخ میداد). اکنون اما هر سرویس را میتوان مستقل منتشر کرد. ساندکلاد هم از Docker و Kubernetes بهره میگیرد که یعنی یک سرویس جدید یا یک ورژن جدید را کافی است به صورت image عرضه کنند و K8s آن را در کلاستر مستقر و ترافیک را به سمت آن هدایت کند. وبلاگ ساندکلاد اشاره میکند که BFFهای آنها چندین بار در روز دیپلوی میشوند. این رقم چشمگیری است که نشان میدهد فرایند انتشار به حدی کمهزینه است که یک تیم شاید هر تغییری را سریعاً پس از آماده شدن منتشر کند. برای نیل به این هدف، ساندکلاد خطوط CI خود را مجهز کرده که احتمالاً شامل ابزارهایی مثل Jenkins یا GitLab CI و غیره است که پس از merge، همه چیز را خودکار انجام میدهد (بیلد، تست، Dockerize، دیپلوی روی staging، دیپلوی روی prod).
ساندکلاد در دورهٔ گذار، ترکیبی از سرویسهای جدید و کد قدیمی داشت که چالش دیپلوی را کمی پیچیده میکرد (چون مونوolith را هم باید گهگاه دیپلوی میکردند). اما راهکار آنها این بود که قابلیتهای جدید را خارج از مونوolith بسازند تا نیاز دیپلوی مونوolith کم و کمتر شود. هرجا هم مجبور بودند، extraction project انجام داده و بعد از تکمیل آن ماژول، عملاً مونوolith را آپدیت نمیکردند بلکه سرویس جدید را جایگزین میکردند. این استراتژی باعث شد تعداد دیپلویهای مونوolith کاهش یابد و به جای آن سرویسهای کوچک سریع سریع منتشر شوند.
با سازماندهی مهندسی مبتنی بر تیمهای کوچک صاحب سرویس، مسئولیت دیپلوی نیز به همان تیمها سپرده شد. تصور کنید تیم جستجوی ساندکلاد، pipeline خاص خود را دارد و میتواند هر زمان خواست نسخهٔ جدید سرویس جستجو را ارائه کند. هماهنگی بین تیمها هم به حد نیاز انجام میشود (مثلاً اگر API بین دو سرویس تغییر کند، از قبل با هم توافق میکنند و نسخههای جدید را منظماً ترتیب انتشار میدهند).
ساندکلاد برای جلوگیری از بروز مشکل در حین انتشارهای مکرر، روی آزمایش خودکار و مانیتورینگ پس از دیپلوی تکیه میکند. بعد از هر دیپلوی، احتمالاً یک سری health-check پیشرفته و alarm وجود دارد که اگر شاخصهای خطا بالا رفت یا latency اوج گرفت، به سرعت مهندسان را باخبر کند یا حتی یک auto-rollback انجام دهد. معماری آنها rollback را هم آسان کرده است: وقتی هر سرویس جداگانه مستقر میشود، برگرداندن یک نسخه (اگر باگی دیده شد) به معنای صرفاً replace کردن کانتینر با image قبلی است. چون وابستگی تناتنگ با بقیه وجود ندارد، این کار اغلب بدون عوارض جانبی میسر است.
مقایسه: هر دو پلتفرم در حوزهٔ استقرار Continuous Delivery یا حتی Continuous Deployment را پیاده کردهاند؛ یعنی کد به محض آماده شدن (و گذراندن تستها) به شکل مداوم در حال راهیافتن به محیط عملیاتی است. اسپاتیفای از این نظر مشهورتر است و حتی به خاطر فرهنگ DevOps عالیاش Squad model + CI/CD شناخته میشود. ساندکلاد هم پس از تغییر معماری به همان مسیر رفته و موفق شده دیپلوی را از یک کار پراسترس و نادر به یک کار روزمره و عادی بدل کند.
یکی از تفاوتهای قابل ذکر، استفادهٔ اسپاتیفای از ابزارهای خودکارسازی ریپوها است. مقالهای بود که اسپاتیفای راهکاری به نامFleet Management یا Fleet Shuffle دارد که به طور خودکار ریپوهای متعدد سرویسها را بهروز میکند (مثلاً کتابخانهٔ مشترکی آپدیت میشود، ابزار خودکار به همه ریپوها PR میدهد). چنین چیزی نشان میدهد اسپاتیفای با مقیاس بسیار بزرگ سرویسها، نیاز به اتوماسیونهای پیشرفتهتری برای مدیریت دیپلوی همه سرویسها دارد. شاید ساندکلاد در مقیاس خود هنوز نیازی به این حد اتوماسیون نداشته باشد و بیشتر کارها در حد pipelineهای معمول انجام شود.
به هر روی، DevOps در هر دو سازمان نهادینه شده و فرکانس بالای استقرار + پایداری در استقرار (بدون خرابی) در آنها مشاهده میشود که مطابق گزارش State of DevOps، نشانهٔ بلوغ فنی بالا است. معماری میکروسرویس شرط لازم بود و با فرهنگ و ابزار مناسب ترکیب شده تا این دستاورد حاصل شود.
قابلیت استفادهٔ مجدد مربوط به میزان امکان بهرهگیری مجدد از اجزای نرمافزار (کد، کامپوننت، سرویس) در بخشهای دیگر سیستم یا حتی سیستمهای دیگر است. معماریهای مدولار معمولاً هدفشان افزایش استفادهٔ مجدد است تا از اختراع دوبارهٔ چرخ جلوگیری شود و توسعه کاراتر گردد. در زمینهٔ اسپاتیفای و ساندکلاد، میتوان استفادهٔ مجدد را در دو سطح بررسی کرد: استفادهٔ مجدد کد/کامپوننت درون سازمان، و ارائهٔ اجزایی برای استفادهٔ بیرونی (مثلاً APIها یا کتابخانههای اپنسورس). این دومی البته بیشتر محصول جانبی است، پس تمرکز ما بر اولی است.
اسپاتیفای: اسپاتیفای با معماری مبتنی بر سرویس، عملاً هر قابلیت عمده را به شکل سرویسی درآورده که میتواند توسط بخشهای مختلف استفاده شود. مثلاً سرویس «کاربر» (User Service) احتمالاً هم توسط سرویسهای توصیهگر، هم سرویسهای پلیلیست و هم سرویسهای دنبالکردن (Follow) مورد استفاده قرار میگیرد. به جای اینکه هرکدام از این نیازها جداگانه اطلاعات کاربر را مدیریت کنند، یک بار این سرویس ساخته شده و بارها استفاده میشود. این یک نوع استفادهٔ مجدد در سطح سرویس است که معماری سرویسگرا به خوبی محقق میکند. نکته در اسپاتیفای این است که به گفتهٔ مهندسانش، آنها تلاش میکنند ماموریت سرویسها تکراری نباشد تا دو تیم کار یکسان نکنند. با تعیین محدودهٔ مسئولیت روشن برای هر سرویس و شفافسازی مالکیت، اگر تیمی نیاز به قابلیتی داشت که سرویس دیگری ارایه میدهد، به سراغ همان سرویس میرود تا از آن مصرف کند نه اینکه خودش مجدداً بسازد. ساختار سازمانی Chapter/Guild نیز به این هدف کمک میکند چون دید جامعی از اینکه چه کارهایی کجا انجام میشود به افراد میدهد. همچنین Spotify Backstage با فهرست کردن همهٔ سرویسها و کتابخانههای داخلی، یافتن و استفاده از آنها را ساده کرده است. مثلاً اگر تیمی نیاز به سرویس recommendation دارد، کافیست در کاتالوگ جستجو کند، API آن را بیابد و استفاده کند، به جای نوشتن سیستم توصیهگر جدید.
در سطح کد، اسپاتیفای بسیاری از ابزارها و زیرساختهایش را اشتراکی کرده است. مثلاً یک فریمورک داخلی برای logging یا برای instrumentation نوشته و همهٔ سرویسها از آن استفاده میکنند به جای اینکه هر تیم سلیقهٔ خود را داشته باشد (مشابه این در ساندکلاد هم بود که آنها هم کتابخانههای مشترک داشتند). اسپاتیفای حتی برخی از این ابزارهای داخلی را اپنسورس کرده (Backstage یک نمونهٔ بارز است) تا جامعه هم بهره ببرد.
در فرانتاند، اسپاتیفای با پروژههایی مثل Spotify Web API و کیتهای SDK تلاش کرده قسمتهایی از پلتفرمش را نیز به صورت قابل استفاده مجدد به بیرون عرضه کند. این البته از بحث معماری داخلی جداست، اما نشان میدهد طراحی سیستم به نحوی بوده که APIهای تمیز داشته باشند تا بتوان به بیرون هم ارائه کرد.
ساندکلاد: استفادهٔ مجدد یک انگیزهٔ اصلی حرکت ساندکلاد به سرویسها بود. در سیستم قدیمی، هر قسمتی tightly-coupled بود و مثلاً اگر دو بخش نیاز مشابهی داشتند، یا باید یکجورهایی در همان کد monolith اشتراک میکردند یا کلاً دوباره مینوشتند که هر دو بد بود. در معماری جدید، آنها سرویسهای بنیادی را طوری ساختند که به عنوان building blockهای قابل استفاده در چند جای مختلف عمل کنند. برای مثال، سرویس «Tracks» که جزئیات آهنگ و آپلود و ... را مدیریت میکند، هم توسط BFF وب برای صفحهٔ آهنگ استفاده میشود، هم توسط BFF موبایل برای پخش آهنگ، هم شاید توسط سرویس آمار برای بازیابی اطلاعات آهنگ. این به معنی یکبار ساخت – چندبار استفاده است. یا سرویس «اعلانها» (Notifications) احتمالاً یک سرویس مشترک است که هر رویدادی (کامنت جدید، لایک جدید، فالو جدید) از طریق آن به کاربر اعلان میشود، فارغ از اینکه رویداد از کدام بخش آمده. این سرویس واحد اعلان، جایگزین چندین پیادهسازی پراکنده میشود.
ساندکلاد همچنین کتابخانههای داخلی مشترک زیادی ایجاد کرد. در بخش معماری گفته شد که آنها کتابخانههای مشترکی برای حل مسائل تکراری ساختند و به همه تیمها عرضه کردند. این یعنی استفادهٔ مجدد در سطح کد به حداکثر رسیده logging،config، auth middleware، error handling، messaging client و... همگی یکبار توسط گروه متخصص نوشته شده و در اختیار همه قرار گرفته است. نتیجه این شد که نه تنها دوبارهکاری کم شد، بلکه کیفیت این بخشهای مشترک هم بالا رفت چون تمرکز تخصصی رویشان بود.
اقدام دیگر ساندکلاد، استفاده از مدل inner source برای BFFها بود. BFFهای آنها هرچند هر کدام متولی مشخصی داشت، اما تغییرات توسط تیمهای مختلف پیشنهاد میشد و یک تیم هسته نظارت میکرد. این فرآیند موجب میشد اگر یک قابلیت در BFF موبایل به کار رفت و مشابهش برای BFF وب هم نیاز بود، عملاً همان کد یا منطق با مشارکت دو تیم به هر دو BFF راه یابد، به جای اینکه هر تیم جداگانه و شاید با تفاوت پیادهسازی کند. کنترل یکسان از طریق Core Team و Collective روی BFF ها نیز تضمین کرد که بهترین راهحلها بین همه BFFها تکرار شوند و کدهای آنها واگرا نشود. هرچند دیدیم در عمل مقداری واگرایی پیش آمد (مثلاً منطق authorization تکراری شد)، اما نهایتاً با VAS حل شد که خود آن گام، نوعی متمرکزسازی برای استفادهٔ مجدد بود. یعنی به جای N بار پیادهسازی آن منطق، یک بار در VAS نوشته شد و همه استفاده کردند.
ساندکلاد نیز مثل اسپاتیفای، برخی قابلیتهایش را به صورت API عمومی عرضه میکند (مثلاً API پخش یا آپلود)، اما آنچه مهمتر است اینکه توانسته کامپوننتهای دامنهای خود را تفکیک و قابل ترکیب مجدد کند. Domain Gatewayها این را نشان میدهند: برای مثال Domain Gateway شنوندگان و Domain Gateway هنرمندان هر دو به سرویسهای پایه Track وPlaylist متصلاند و از خروجی آنها استفاده میکنند، ولی هر کدام دید خود را ارائه میدهند. سرویسهای پایه را میتوان مثل لگو در کاربردهای جدید هم به کار گرفت، بدون نیاز به تغییر درونشان.
مقایسه: در هر دو معماری، Reusable Components یک مزیت کلیدی است. اسپاتیفای در مقیاس بزرگتر خود با موفقیت این را مدیریت کرده، به طوری که خودشان میگویند تلاش میکنند کار تکراری در تیمها پیش نیاید و سرویسها حداقل همپوشانی را داشته باشند. آنها همچنین دانش را هم به شکل قابل استفادهٔ مجدد درآوردهاند (از طریق Backstage و guildها )، به عبارتی reuse فقط کد نیست بلکه الگوها و تجربیات نیز هست. ساندکلاد در مقیاس خودش با رویکرد inner-source و تمرکز بر کتابخانههای core نشان داده که reuse برایش مهم بوده و توانسته بخشهای مشترک زیرساختی را یکجا نگه دارد.
البته در عمل، هیچ سیستمی ۱۰۰٪ بدون کار تکراری نیست. اسپاتیفای هم ممکن است در تاریخش دو سرویس مشابه ساخته که بعدها یکی شدهاند یا یکی کنار رفته. ساندکلاد هم نمونهٔ واضح تکرار را در BFFها داشت که البته آن را رفع کرد. مهم این است که هر دو با رصد دائم این موارد، تلاش در کاهششان داشتهاند.
از جنبهٔ بیرونی، اسپاتیفای با انتشار ابزارهای اپنسورس (Backstage، Ruler، Klio و غیره) حتی استفادهٔ مجدد را به جامعهٔ بزرگتر توسعهدهندگان تسری داده است. ساندکلاد به آن اندازه فعال در اپنسورس نبوده، هرچند پروژههایی مثل roshi سیستم ذخیرهسازی netty-zmtp و غیره را منتشر کرده بود. اما اپنسورس خارج از محدودهٔ این بحث است.
در مجموع، معماری سرویسگرای هر دو پلتفرم reuse را هم در سطح ماژولار و هم در سطح سازمانی ارتقا داده است. این امر به صرفهجویی در زمان توسعه، کاهش باگ (چون کدهای مشترک بهتر تست و امتحان میشوند) و همگرایی تکنولوژی در پلتفرم منجر شده که خود از علائم بلوغ معماری است.
در این گزارش معماری نرمافزاری دو پلتفرم محبوب استریم صوت یعنی اسپاتیفای و ساندکلاد را از منظر مجموعهای جامع از ویژگیهای کیفی مورد بررسی و مقایسه قرار دادیم. هر دو سرویس مسیر تکاملی خاص خود را طی کردهاند اما امروز هر دو بر معماری میکروسرویس توزیعشده استوارند که ستون فقرات توانمندیهایشان در مقیاس وب جهانی است. اسپاتیفای به عنوان رهبر بازار استریم موسیقی، از آغاز بر طراحی سیستمهای مقیاسپذیر و قابل انعطاف تأکید داشت و توانست با اتخاذMicroservices، فرهنگ مهندسی مدرن (اسکواد مدل)، بهرهگیری از فناوریهای ابری (Google Cloud, Kubernetes) و سرمایهگذاری در زیرساختهای داده (Cassandra, Kafka)، پلتفرمی بسازد که عملاً بدون وقفه و با کارایی بالا به صدها میلیون کاربر سرویس میدهد. در سوی دیگر، ساندکلاد که به عنوان فضایی برای اشتراکگذاری مستقل موسیقی و صدا شروع به کار کرد، در میانهٔ راه دریافت معماری یکپارچهٔ اولیه پاسخگوی رشد و نوآوری سریع نیست؛ لذا با یک بازطراحی جسورانه به سمت میکروسرویسها رفت و الگوهای مبتکرانهای مانند Backends for Frontends و Value-Added Services را ابداع یا بهکار گرفت تا چالشهای خاص خود (تفاوت نیاز کلاینتها، تکرار منطق در سرویسها) را حل کند. نتیجهٔ این تحول، افزایش چشمگیر قابلیت نگهداری، انعطاف و پایداری در ساندکلاد بود به طوری که اکنون این پلتفرم نیز قادر است به طور مستمر ویژگیهای جدید عرضه کند و تجربهٔ کاربران را بهبود دهد بیآنکه دچار بیثباتی شود.
در مقایسهٔ جزئیتر بر اساس کیفیتها، مشاهده کردیم:
· عملکرد: اسپاتیفای با شبکه توزیع محتوا، کشهای چندلایه و بهینهسازیهایی نظیر پخش تطبیقی، تجربهٔ استریم بیوقفه در هر شرایط شبکه را فراهم کرده است. ساندکلاد نیز با استفاده از CDN، نزدیک کردن منطق تجمیع داده به سرور (VAS) و کاهش درخواستهای رفتوبرگشتی، توانسته عملکرد قابل قبولی ارائه دهد که مقیاس میلیونها کاربر را پشتیبانی میکند.
· مقیاسپذیری: هر دو سیستم بر مبنای مقیاسپذیری افقی طراحی شدهاند. اسپاتیفای با بهرهگیری از میکروسرویسهای مستقل که هر یک را میتوان جداگانه بزرگ کرد، و نیز مهاجرت به زیرساخت ابری قدرتمند، از عهدهٔ رشد عظیم کاربران خود برآمده است. ساندکلاد نیز با شکستن مونوolith، توانست ظرفیت توسعه و عملیات را متناسب با نیاز افزایش دهد و سرویسهای خود را در چندین ناحیهٔ ابری تکثیر کند. تفکیک BFFها و دامنهها در ساندکلاد به معنای امکان مقیاس مستقل هر بخش (موبایل، وب، هنرمندان، شنوندگان) بود که یک مزیت سازمانی در مقیاسپذیری است.
· امنیت: اسپاتیفای و ساندکلاد هر دو لایههای امنیتی متعددی پیاده کردهاند از جمله احراز هویت OAuth2، رمزنگاری جامع داده در حین انتقال و در حالت ذخیره، کنترل دسترسی دقیق و بهروز نگه داشتن مداوم سیستمها. اسپاتیفای شاید روی برخی جزئیات مانند DRM محتوا و تحلیل تهدیدات سرمایهگذاری بیشتری کرده باشد، ولی ساندکلاد نیز با معماری جدیدش امنیت را در طراحی لحاظ کرد (مثل متمرکزسازی منطق مجوز در VASها و قرار دادن BFFهای محافظ در لبه). نتیجه آن است که هر دو تاکنون سابقهٔ خوبی در محافظت از دادههای کاربران و داراییهای دیجیتال داشتهاند.
· قابلیت نگهداری: در این بُعد، معماری ماژولار هر دو سرویس باعث کاهش پیچیدگی هر بخش و بهبود عیبیابی شده است. اسپاتیفای با ابزارهای مستندسازی (Backstage) و فرهنگ شفافیت کد، نگهداری را تسهیل کرده، و ساندکلاد با اشتراک کتابخانههای داخلی و درسآموزی از تجارب استخراج مونوolith، توانست تیمها را در مدیریت سرویسهای خود توانمند کند. هر دو از مانیتورینگ و لاگ متمرکز بهره میبرند که برای نگهداری و رفع خطا ضروری است.
· انعطافپذیری: اسپاتیفای تغییرات کسبوکاری (مثلاً افزودن پادکست) یا فنی (مهاجرت دیتابیس، مهاجرت ابری) را به خوبی مدیریت کرده بدون آنکه نیاز به بازنویسی کل سیستم باشد. ساندکلاد نیز اکنون به حدی منعطف است که میتواند تجربههای جدید (مثلاً ویژگیهای اجتماعی تازه) را با افزودن سرویسهای نو پیاده کند بیآنکه به هستهٔ سیستم آسیبی برسد. تفکیک دامنهای در ساندکلاد نیز انعطاف سازمان را بالا برده که همگام با تغییر نیازهای دو سمت پلتفرم حرکت کند.
· قابلیت تست: هر دو شرکت از Continuous Testing بهره میبرند و معماریشان این امر را ممکن کرده است؛ میکروسرویسهای کوچک تست واحد آسانی دارند و روابط سرویسها هم با تستهای یکپارچهسازی منظم چک میشود. اسپاتیفای تصریح کرده که تستپذیری یکی از دلایل انتخاب میکروسرویس بود، و ساندکلاد نیز با بهبود تست تعاملات سرویسها، اعتمادبهنفس در استقرارهای مکرر را به دست آورده است.
· در دسترس بودن: هر دو پلتفرم به سطوح بالایی از آپتایم دست یافتهاند. اسپاتیفای با پخش جهانی خود، از افزونگی چند-منطقهای و سرویسهای بدون نقطه شکست استفاده میکند، و ساندکلاد نیز با ایزولهسازی بخشها (مثلاً BFFها) و افزونگی در زیرساخت ابری، حتی با وجود مشکلات موضعی، کل سرویس را آنلاین نگه میدارد. معماری میکروسرویس، اثر خرابی را محصور میکند (degrade به جای outage کامل) و این در هر دو سیستم صادق است.
· تحمل خطا: اسپاتیفای و ساندکلاد هر دو الگوهای تحمل خطا مانند Circuit Breaker، Failover، Replication وSelf-healing را در معماری خود به کار گرفتهاند. اسپاتیفای به طور خاص ذکر کرده که هر سرویس کوچک نگه داشته شده تا خرابیاش کمترین اثر را داشته باشد. ساندکلاد هم با رویکرد degrade تدریجی (عدم نمایش یک بخش به جای کل صفحه) در مقابل خطاها مقاوم است. تحمل خرابی سختافزار (با چندین نسخه از هر مولفه) و تحمل خطای نرمافزار (با fallbackهای منطقی) در هر دو رعایت شده است.
· قابلیت استقرار: هر دو شرکت به Continuous Deployment نزدیک شدهاند. اسپاتیفای با خطوط CI/CD خودکار، Kubernetes و فرهنگ "هر تیم، هر زمان دیپلوی" توانسته فرکانس انتشار را بسیار بالا ببرد. ساندکلاد نیز پس از معماری جدید گزارش میدهد برخی اجزایش چندبار در روز منتشر میشوند. استقلال سرویسها به این معنی است که استقرار یک بخش نیازی به هماهنگی عظیم ندارد و با ابزارهای مدرن در حداقل زمان انجام میشود. این چابکی در ارائهٔ ویژگیهای جدید، یک مزیت رقابتی مهم برای هر دو بوده است.
· قابلیت استفادهٔ مجدد: اسپاتیفای با ماژولارسازی سرویسها و اشتراک کتابخانههای داخلی، از تکرار تلاشها جلوگیری کرده و اجازه داده یک سرویس توسط چندین بخش مصرف شود. همچنین با کاتالوگ Backstage، کشف و استفاده ازAPIهای داخلی ساده شده است. ساندکلاد نیز به وضوح با ایجاد سرویسهای مستقل دامنهای و متمرکزسازی منطقهای تکراری (مثل VAS)، استفادهٔ مجدد را افزایش داده است. تیمهای آنها هم با inner source کردن کدها، بهترین راهکارها را بین بخشها به اشتراک گذاشتهاند. بنابراین هر دو معماری بهرهوری توسعه را با reuse بالا بردهاند.
با وجود این شباهتها در اصول کلی، تفاوتهای ظریفی در مسیر و رویکرد مشاهده شد. اسپاتیفای از موضع قدرت و آیندهنگری، زودتر بر میکروسرویس سوار شد و همواره یکی از مثالهای موفق آن باقی مانده است، در حالی که ساندکلاد پس از مواجهه با مشکلات عملی مجبور به تغییر قطبنما شد و البته با ابتکار و تلاش، چالش را به فرصت تبدیل کرد. اسپاتیفای بر مبنای تجربهٔ سالها عملیات در مقیاس بزرگ، ابزارها و فرایندهای پیچیدهتری (نظیر سیستم مدل معماری خودکار، migration methodology پیشرفته و غیره) توسعه داده که متناسب با اندازهٔ سازمانش است. ساندکلاد سازمان کوچکتری است و راهحلهایش متمرکز بر حل مشکلات خاص خودش (مثلاً تکثیر منطق در BFFها) بوده ولی همین راهحلها BFF، VAS اکنون به الگوهای مورد توجه صنعت تبدیل شدهاند.
در جمعبندی، میتوان گفت هر دو پلتفرم اکنون نمونههای بلوغیافتهای از معماری سرویسگرای ابری در مقیاس وب هستند که توانستهاند طیفی از الزامات کیفی را به تعادل برسانند. اسپاتیفای بیشتر به عنوان معیار طلا در مقیاسپذیری، کارایی و سرعت ارائهٔ ویژگی جدید شناخته میشود، و ساندکلاد به عنوان مثالی از تطبیق معماری با نیاز کسبوکار و حرکت از میراث قدیمی به ساختار مدرن مورد توجه است. مقایسهٔ این دو نشان میدهد که اصول معماری خوب – نظیر جداسازی مسئولیت، خودمختاری سرویسها، افزونگی، خودکارسازی و تمرکز بر تجربهٔ توسعهدهنده – چگونه در عمل منجر به سامانههایی میشوند که نه تنها امروز عملکرد عالی دارند، بلکه فردا نیز آمادهٔ تغییر و رشد هستند. هر سازمان نرمافزاری دیگری بسته به شرایط خود میتواند از راه طیشده توسط این دو الهام بگیرد: از طراحی برای چابکی و تغییر مداوم اسپاتیفای گرفته، تا شجاعت در بازنگری پلتفرم و بهبود مستمر ساندکلاد. در نهایت، معماری موفق معماریای است که اهداف کسبوکار را محقق کند و در عین حال کیفیتهای بنیادی نظیر کارایی، مقیاسپذیری، امنیت و غیره را به همراه داشته باشد – و اسپاتیفای و ساندکلاد به خوبی نمایانگر این توازن ظریفاند.