حسین ثمررخی
حسین ثمررخی
خواندن ۴ دقیقه·۶ سال پیش

در باب Availability! یا چگونه همیشه در دسترس باشیم؟

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

در دسترس بودن یعنی چی؟ یعنی اینکه بعد از کلی تبلیغات برای فروش ویژه یکی از فروشگاه های اینترنتی خوش نام، وقتی می ری تو سایتشون چشمت به لودینگ صفحه خشک نشه. یا اینکه وقتی یه صبح کاری شلوغ اپ تاکسی اینترنتی محبوبت رو باز می کنی اون دکمه «تلاش مجدد» لعنتی رو اون پایین نبینی.

بعد از اینکه این شانس رو داشتم که با بزرگترین و پر ترافیک ترین تک استارتاپ های ایران همکاری کنم، حالا می خوام یه کم براتون از تجربه هام در این زمینه بگم.


نپیچونش: اور انجینیرینگ (over engineering) ممنوع!

اگه نمی دونی آورو (Avro) به چه دردی می خوره بجای جیسان (Json) استفادش نکن. قرار نیست همه سیستم داینامیک طراحی بشه. اگه شی گرا (OOP) کد می زنی قرار نیست هر 23 تا پترن «گنگ آو فور» رو تا دسته توی کد پیاده کنی.

همه اینا نمونه هایی از اور انجینیرینگ هستن. هر چقدر کد بیس (code base) پر باشه از نمونه های مشابه نه تنها به صورت مستقیم هزینه نگهداری سیستم رو افزایش میده بلکه روی در دسترس بودن (Availability) سیستم هم تاثیر می ذاره.

انتخاب ساده ترین و سریع ترین نوع سریالایزر (serializer) متناسب با نوع و حجم داده ارسالی، اجتناب از انجام پردازشهای اضافی و پیاده سازی های ساده، یعنی شما CPU رو برای پردازش های بیشتر آزاد می ذارید.

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


کش (Cache): یه دوست صمیمی که شوخی نداره

توی سه چهار سال اخیر بیشتر وقتم رو با سر و کله زدن با مدل های مختلف کشینگ گذروندم. در کل چندتا قانون برای خودم تعریف کردم:

  • اگه درخواست متعدد میاد کش کن
  • اگه کوئری (Query) سنگین روی دیتابیس می زنه کش کن
  • اگه درخواست تکراریه و زیاد تغییر نمی کنه کش کن
  • اگه آبجکت ارزشمند بود کش کن

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

در نهایت هم یادتون باشه همیشه به فکر وارم آپ (warm up) شدن کش سرورها باشید، تخمین سایز مورد نیازشون رو جدی بگیرید. و از روز اول طراحی سیستم به لایه ها و پالیسی های کشینگ فکر کنید.

[یه روز در باره پالیسی های مختلف کش کردن و باید ها و نبایدهاش می نویسم.]


معماری: مایکروسرویس و CQRS

چند سالی هم هست که تب مایکروسرویس خیلی داغ شده. اما آیا این معماری می تونه به در دسترس بودن سیستم های با ترافیک بالا کمک کنه؟ جواب: اگه درست پیاده بشه بلی.

با توجه به اینکه مقیاس پذیری (Scalaility) یکی از اصلی ترین ویژگی های معماری های مایکروسرویس هست پس می تونه تاثیر مستقیم روی افزایش ظرفیت ترافیک سیستم داشته باشه.

یک سیستم تاکسی اینترنتی با معماری مایکروسرویس رو تصور کن، توی زمان پیک درخواستها تعداد اینستنس (Instances) های سرویس پرایسینگ رو به صورت خودکار افزایش بده. شما دیگه پیغام «خطا در قیمت دهی» رو نمی بینید.

در واقع مایکروسرویس ها این امکان رو به شما می دن که در صورت نیاز بخشی از سیستم (یه سرویس مشخص) رو به تعداد نیاز اسکیل کنید و از منابع سرورهاتون بهینه استفاده کنید.

طرح اولیه معماری مایکروسرویس - بامیلو
طرح اولیه معماری مایکروسرویس - بامیلو

حالا CQRS این وسط چی میگه؟ تعریف خیلی سادش اینه که مدل خوندن (read) از نوشتن (write) متفاوت باشه [البته یخورده پیچیده تره]. با توجه به اینکه هر مایکروسرویس در واقع یه سیستم مونولتیک (Monolithic) کوچیکه که خودش معماری خودش رو داره پس پیشنهاد می کنم برای سرویس های پر ترافیکتون از این معماری استفاده کنید. پیاده سازی های مختلفی هم داره که بعضیاشون خیلی پیچیدست. شما با ساده ترینش شروع کنید. اما حواستون حسابی به یکپارچگی داده (data consistency) باشه.


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

حتمن لازم نیست صبر کنی که کارت تا آخر تموم بشه و بعد بیای سروقت لود تست. حتمن هم نباید یه سناریو خیلی بزرگ و جامع Jmeter داشته باشی. خیلی وقتا یه لود ساده با Vegeta گذاشتن کمکت می کنه. اما هیچوقت، تَکرار می کنم، هیچوقت بدون لود تست سرویسی رو پروداکشن نفرستید.

چندتا نکته در باب لود تست بگم:

  • تست بلاک هاتون رو بشناسید. [سرورهایی که لود می فرستن هم جز تست بلاک ها حساب می شن.]
  • نقطه شکست سرویس ها رو در بیارید. [تهش چند RPS جواب می ده]
  • تخمین بزنید اسکیل آپ کردن (Scale-up) چه تاثیری روی پرفورمنس داره. [ریسورس بهینه هر اینستنس رو پیدا کنید]
  • تخمین بزنید اسکیل اوت (Scale-out) کردن چه تاثیری روی پرفورمنس داره.
  • تست بلاک هارو دقیق مانیتور کنید. یادتون باشه باتل نک (bottleneck) از بین نمیره، فقط از بلاکی به بلاک دیگه جابجا می شه.
  • نرخ خطاهای سرویس رو کنترل کنید.

حواستون هم باشه اشتباه تست نکنید، مثلن اگر توکنِ آتنتیکیشن (Authentication Token) رو نمی فرستی و همه یوزرهات گست حساب میشن داری اشتباه می زنی و احتمالن تخمینت بیشتر از ظرفیت سیستم زیر ترافیک واقعی هستش. پس ساده تست کن ولی اشتباه نه!

[یه روز یه ویرگول در باره لود تست و استرس تست و ابزارهاش می نویسم]


در آخر...

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

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