Mehrdad Esmaeilpour
Mehrdad Esmaeilpour
خواندن ۸ دقیقه·۲ سال پیش

انتشار نسخه؛ این قناری خاموش

تصویر از nordapis.com
تصویر از nordapis.com

ای قناری!

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



قناری قهرمان!

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

حالا شیوه انتشار قناری چیه؟ تو این شیوه تغییرات به شکل جزیی و تو یه بازه زمانی مشخص برای تعداد کمی از کاربران منتشر می‌شه. این شیوه بهمون کمک می‌کنه برای انتشار کامل نسخه تصمیم بگیریم -درست مثل قناری‌های در حال مرگ تو معدن- اون بخش از سرویس که تغییرات رو تو خودش داره رو «قناری» صدا می‌کنیم و بقیه بخش‌ها رو «کنترل». منطق پشت این روش هم اینه که قناری همیشه بخش کوچیک‌تری از درخواست‌ها یا کاربران رو نسبت به کنترل شامل می‌شه. شیوه قناری یه فرایند تست A/B موثره.

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

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

مهندسی انتشار با قناری

وقتی نسخه جدیدی از سیستم یا یه بخش اصلیش (مثل تنظیمات یا دیتا) رو منتشر می‌کنیم، با تغییراتی سر و کار داریم که در معرض ورودی‌های دنیای واقعی نبودن. تغییرات واسه‌مون امکانات و توانایی‌های جدید به وجود میارن اما همیشه همراه خودشون ریسکی دارن که در زمان انتشار، مشخص می‌شه. هدف ما کنترل کردن این ریسکه. این کار رو از طریق تست کردن تغییرات روی بخش کوچیکی از ترافیک انجام ‌می‌دیم. اینجوری می‌تونیم مطمئن بشیم اثر مخربی وجود نداره.

فرایند قناری بهمون کمک می‌کنه تغییرات‌مون رو با اعتماد به نفس در معرض دیتا و ورودی بزرگ و بزرگ‌تر قرار بدیم. استفاده از قناری همچنین کمک‌مون می‌کنه نقاط کوری که با فریم‌ورک‌های تست مثل یونیت تست یا تست بار قابل شناسایی نیستن رو پیدا کنیم.

چی چیزایی لازمه؟

برای پیاده‌سازی قناری رو یه سرویس به این موارد نیاز داریم

  • روشی که باهاش بتونیم تغییرات رو برای بخش کوچکی از سرویس در دسترس قرار بدیم
  • یه فرایند ارزیابی که باهاش بتونیم مشخص کنیم تغییرات روی قناری «خوب» یا «بد» هستن
  • همگام‌سازی ارزیابی‌های قناری با فرایند‌های انتشار

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

چقدر زمان لازمه؟

وقتی می‌خوایم زمان مناسب برای قناری رو انتخاب کنیم باید به سرعت انتشار نسخه‌هامون دقت کنیم. اگه هر روز نسخه می‌دیم، نمی‌تونیم قناری رو یه هفته طول بدیم. اگه هر هفته نسخه منتشر می‌کنیم، قناری‌هامون باید طولانی‌تر عمر کنن. اگه هر روز نزدیک بیست نسخه منتشر می‌کنیم، اونوقت عمر قناری‌ها باید خیلی کوتاه‌تر باشه.

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

انتخاب و ارزیابی متریک‌ها

از چه معیارهایی می‌تونیم برای ارزیابی این‌که یه قناری منجر به نسخه خوب یا بد شده استفاده کنیم؟

متریک‌ها باید نشان دهنده مشکل باشن

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

قبل از هر چیز، متریک انتخابی باید بتونه مشکل رو در سرویس مشخص کنه. این بخش کمی سخته چرا که تعریف مشخصی از مشکلی که هنوز به وجود نیومده، وجود نداره. شاید بتونیم یه درخواست کاربر که با خطا رو به رو شده رو یه مشکل فرض کنیم اما اگه درخواست کاربر ده درصد بیشتر زمان ببره یا ده درصد بیشتر مموری نیاز داشته باشه چی؟ معمولا استفاده از SLI ها نقطه شروع خوبی برای انتخاب متریک‌ها هستن. SLI های خوب به میزان قابل توجهی سلامت سیستم رو مشخص می‌کنن. به عنوان مثال برای یه سرویس که API ارائه می‌ده، کد وضعیت HTTP (۲۰۰ و ۳۰۰ و ...)، مدت زمان پاسخ‌دهی، میزان درستی و ... می‌تونن متریک‌های خوبی باشن.

متریک‌ها باید نمایشگر و قابل انتساب باشن

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

مدیریت قناری‌ها در واقع ایجاد تعادل بین نیروهای مختلفه. زیاد کردن جمعیت قناری‌ها یک راه کم کردن تاثیر این مشکله. زمانی که به جمعیت مورد قبول قناری برای سیستم خودمون رسیدیم باید مطمئن بشیم که تمام متریک‌هایی که انتخاب کردیم می‌تونن مغایرت‌های شدید رو نمایش بدن.

استراتژی‌های انتخاب کاربران

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

  • تصادفی: تو این روش همونطور که از اسمش پیداست درصد مورد نظر از کاربران رو به شکل تصادفی به قناری می‌فرستیم.
  • منطقه جغرافیایی: کاربران با توجه به منطقه جغرافیایی‌شون انتخاب می‌شن. به عنوان مثال می‌شه نسخه جدید رو برای هر منطقه تو زمان ترافیک کم منتشر کرد.
  • استفاده‌کننده‌های اولیه: با استفاده از این روش کاربرانی که دوست دارن تو مرحله قناری از محصول استفاده کنن درخواست می‌دن و از نسخه‌های قناری استفاده می‌کنن. یکی از مزیت‌های این روش اینه که این مدل کاربران معمولا تمایل دارن نظرات سازنده‌شون رو به اشتراک بذارن.
  • مدل Dogfooding: این اصطلاح به عبارت «غذای سگ خودت رو بخور» اشاره داره و به معنی اینه که نسخه‌های قناری برای کاربران داخلی و کارمندان منتشر می‌شن.

گاهی بهترین انتخاب، تنها یک گزینه نیست و میشه هر کدوم از روش‌های گفته شده رو در ترکیب با همدیگه استفاده کرد.

نقاط تاریک استفاده از قناری‌ها

هیچ روشی کامل نیست و قناری‌ها هم بهترین پرنده‌ها نیستن. ببینیم با استفاده از قناری‌ها چه چیزهایی ممکنه اشتباه پیش برن.

  • کلافگی: کاربرانی که از نسخه‌های قناری استفاده می‌کنن می‌تونن با بدترین باگ‌ها روبه‌رو بشن. بعضی کاربران ممکنه با فهمیدن این‌که از نسخه‌های قناری استفاده می‌کنن حس موش آزمایشگاهی بگیرن. اگه این موضوع باعث نگرانی‌تون می‌شه از برنامه‌های داوطلبانه واسه قناری استفاده کنین.
  • هزینه: استفاده از قناری به زیرساخت بیشتر نیاز داره. زیرساخت بیشتر یعنی هزینه بیشتر.
  • پیچیدگی: استفاده از چندین ماشین مختلف برای پروداکشن، مهاجرت کاربران به قناری و کنترل، مانیتور کردن تغییرات، همه و همه کارهای پیچیده‌ای هستن. برای کنترل کردن این پیچیدگی میزان انجام‌شون به شکل دستی رو به حداقل برسونین.
  • زمان: ایجاد و مدیریت یک پایپ‌لاین خوب قناری زمان و تلاش زیادی می‌بره اما اگه به درستی انجام بشه باعث نسخه‌دهی امن‌تر می‌شه.
  • پایگاه‌داده‌ها: کتاب‌های زیادی درباره این‌که چطور اسکیما پایگاه‌داده‌ها رو تغییر بدیم نوشته شده. در زمان استفاده از روش قناری یک مشکل بزرگ وجود داره. اسکیما باید با هر دو نسخه کار کنه. بنابراین باید نسخه‌هامون همیشه backward-compatible باشن و این یعنی اضافه کردن یک لایه دیگه از پیچیدگی.

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

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

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

منابع

[1] Domestic canary

[2] Google site reliability engineering By Alec Warner and Štěpán Davidovič

[3] What is Canary Deployment By Tomas Fernandez

قناری
مهندس نرم افزار، نویسنده، شاعر و خیال پرداز
شاید از این پست‌ها خوشتان بیاید