قناریها، تو معادن ذغالسنگ، به عنوان سیستم طبیعی هشدار استفاده میشدن. سیستمی که عاقبت خوشی واسشون نداشت. گازهای سمی مثل دیاکسید کربن، مونواکسید کربن یا متان خیلی زودتر از آدما، جون قناریها رو میگیرن. وقتی قناریها تو معدن بیتابی میکردن، معدنچیها میفهمیدن اوضاع خوب نیست و باید بزنن بیرون. البته این شیوه دیگه از سال ۱۹۸۷ مورد استفاده قرار نمیگیره و حالا ما از قناریهای کوچیک تو نسخهدهیها استفاده میکنیم تا قبل از انفجار بزنیم بیرون.
مهندسی انتشار، واژهایه که برای توصیف فرایندها و کارهای مربوط به انتقال کد از یه ریپازیتوری به یه سیستم در حال اجرای پروداکشن گفته میشه. خودکارسازی انتشار نسخهها میتونه از خیلی از مشکلات سنتی که با انتشار یه نسخه عجین شدهان، جلوگیری کنه. مشکلاتی مثل: نیاز به انجام کارهای پشتسر هم و تکراری به شکل دستی، ناپایدار بودن یه فرایند غیرخودکار، ندونستن اینکه وضعیت فعلی چیه و در آخر سخت بودن برگشتن به نسخه قبلی.
حالا شیوه انتشار قناری چیه؟ تو این شیوه تغییرات به شکل جزیی و تو یه بازه زمانی مشخص برای تعداد کمی از کاربران منتشر میشه. این شیوه بهمون کمک میکنه برای انتشار کامل نسخه تصمیم بگیریم -درست مثل قناریهای در حال مرگ تو معدن- اون بخش از سرویس که تغییرات رو تو خودش داره رو «قناری» صدا میکنیم و بقیه بخشها رو «کنترل». منطق پشت این روش هم اینه که قناری همیشه بخش کوچیکتری از درخواستها یا کاربران رو نسبت به کنترل شامل میشه. شیوه قناری یه فرایند تست A/B موثره.
حتی اگه پایپلاین انتشار نسخهتون کاملا خودکار باشه باز هم امکان اینکه به شکل کامل همه مشکلاتی که ممکنه تو محیط پروداکشن اتفاق بیفته رو پیدا کنین، خیلی بالا نیست. زمانی که تصمیم به انتشار یه نسخه روی پروداکشن میگیرین، استراتژی تستتون باید به شکلی باشه که به مقدار قابل توجهی به تغییرات اطمینان داشته باشین و بدونین که نسخه جدید همونطور که انتظار دارین کار میکنه. با این وجود محیط تست نمیتونه صد درصد مثل پروداکشن باشه و تستهای ما هم احتمالا همه سناریوها رو پوشش نمیدن. بنابراین بعضی از باگها راهشون رو به محیط پروداکشن باز میکنن. حالا اگه یه نسخه رو همزمان همهجا منتشر کنیم، باگهاش هم دنبالش همهجا خواهند رفت.
این سناریو زمانی که امکان کشف و حل اشکالات به شکل خیلی سریع وجود داره شاید قابل قبول باشه اما یه راه خیلی بهتر هست. اونم اینه که بخش کوچیکی از ترافیک پروداکشن رو با استفاده از قناری به سمت تغییرات جدید هدایت کنین. استفاده از قناری کمک میکنه که اشکالات خیلی سریع و با تاثیر خیلی کم حل بشن.
وقتی نسخه جدیدی از سیستم یا یه بخش اصلیش (مثل تنظیمات یا دیتا) رو منتشر میکنیم، با تغییراتی سر و کار داریم که در معرض ورودیهای دنیای واقعی نبودن. تغییرات واسهمون امکانات و تواناییهای جدید به وجود میارن اما همیشه همراه خودشون ریسکی دارن که در زمان انتشار، مشخص میشه. هدف ما کنترل کردن این ریسکه. این کار رو از طریق تست کردن تغییرات روی بخش کوچیکی از ترافیک انجام میدیم. اینجوری میتونیم مطمئن بشیم اثر مخربی وجود نداره.
فرایند قناری بهمون کمک میکنه تغییراتمون رو با اعتماد به نفس در معرض دیتا و ورودی بزرگ و بزرگتر قرار بدیم. استفاده از قناری همچنین کمکمون میکنه نقاط کوری که با فریمورکهای تست مثل یونیت تست یا تست بار قابل شناسایی نیستن رو پیدا کنیم.
برای پیادهسازی قناری رو یه سرویس به این موارد نیاز داریم
در نهایت یه فرایند خوب قناری قراره نسخههای بد رو به شکل قطعی و نسخههای خوب رو بدون درستنماها مشخص کنه.
وقتی میخوایم زمان مناسب برای قناری رو انتخاب کنیم باید به سرعت انتشار نسخههامون دقت کنیم. اگه هر روز نسخه میدیم، نمیتونیم قناری رو یه هفته طول بدیم. اگه هر هفته نسخه منتشر میکنیم، قناریهامون باید طولانیتر عمر کنن. اگه هر روز نزدیک بیست نسخه منتشر میکنیم، اونوقت عمر قناریها باید خیلی کوتاهتر باشه.
در نظر داشته باشید که امکان اینکه همزمان چند نسخه قناری داشته باشیم وجود داره اما اینکار انرژی ذهنی زیادی از ما برای دنبال کردن وضعیت سیستم میگیره. مثلا وقتی تحلیل وضعیت فعلی سیستم تو بازه خیلی کوتاه مورد نیازه وجود چندین وضعیت همزمان کار رو پیچیده میکنه. پیشنهاد معمولا اینه که در یک زمان تنها یک نسخه قناری وجود داشته باشه.
از چه معیارهایی میتونیم برای ارزیابی اینکه یه قناری منجر به نسخه خوب یا بد شده استفاده کنیم؟
متریکها باید نشان دهنده مشکل باشن
هر متریکی اگه به شکل افراطی انتخاب بشه، میتونه مشکلساز باشه، در عین حال اضافه کردن متریکهای جدید هم هزینهبره. باید بتونیم با دقت رفتار درست و قابل قبول یک متریک رو در فرایند قناری کردن، تعریف کنیم. اگه این تعریف خیلی سفت و سخت باشه، تعداد درستنماها خیلی زیاد میشن و ممکنه به اشتباه فکر کنیم تغییرات قناری درست نیستن، در حالی که واقعا اینطور نیست. از طرفی اگه تعریفمون از رفتار درست خیلی ساده باشه، امکان اینکه تغییرات نادرست باشن و متوجهشون نشیم وجود داره. انتخاب اینکه رفتار درست چیه فرایند هزینهبری هست که زمانبره و نیاز به آنالیز داره. با این حال اگه اینکار به درستی انجام نشه، نتایج کار گمراهکننده خواهند بود. همچنین با بزرگتر شدن و تغییر تو کل سیستم این تعاریف باید بازنگری یا بازتعریف بشن و همیشه در کنار کل مجموعه رشد کنن.
قبل از هر چیز، متریک انتخابی باید بتونه مشکل رو در سرویس مشخص کنه. این بخش کمی سخته چرا که تعریف مشخصی از مشکلی که هنوز به وجود نیومده، وجود نداره. شاید بتونیم یه درخواست کاربر که با خطا رو به رو شده رو یه مشکل فرض کنیم اما اگه درخواست کاربر ده درصد بیشتر زمان ببره یا ده درصد بیشتر مموری نیاز داشته باشه چی؟ معمولا استفاده از SLI ها نقطه شروع خوبی برای انتخاب متریکها هستن. SLI های خوب به میزان قابل توجهی سلامت سیستم رو مشخص میکنن. به عنوان مثال برای یه سرویس که API ارائه میده، کد وضعیت HTTP (۲۰۰ و ۳۰۰ و ...)، مدت زمان پاسخدهی، میزان درستی و ... میتونن متریکهای خوبی باشن.
متریکها باید نمایشگر و قابل انتساب باشن
منبع تغییرات تو متریکها باید به طور واضح قابل انتساب به تغییراتی که قناری کردیم، باشن و فاکتورهای بیرونی نباید روی این متریکها اثر بذارن. تو سرویسهای بزرگ (به عنوان مثال تعداد زیاد سرورها و کانتینرها) معمولا عوامل جانبی مثل ماشینهایی که کرنل متفاوت دارن یا مشخصات سختافزاریشون فرق میکنه یا تو قسمت پر بار شبکه قرار گرفتن وجود داره. تغییراتی که بین قناری و کنترل وجود داره باید توزیع متناسبی بین این مدل تفاوتها داشته باشه.
مدیریت قناریها در واقع ایجاد تعادل بین نیروهای مختلفه. زیاد کردن جمعیت قناریها یک راه کم کردن تاثیر این مشکله. زمانی که به جمعیت مورد قبول قناری برای سیستم خودمون رسیدیم باید مطمئن بشیم که تمام متریکهایی که انتخاب کردیم میتونن مغایرتهای شدید رو نمایش بدن.
زمانی که متریکها و درصد قناریها مشخص شدن باید روشی رو برای انتخاب کاربرانی که به نسخه قناری هدایت میشن یا ازش استفاده میکنن داشته باشیم. چهار روش مختلف برای این کار وجود داره.
گاهی بهترین انتخاب، تنها یک گزینه نیست و میشه هر کدوم از روشهای گفته شده رو در ترکیب با همدیگه استفاده کرد.
هیچ روشی کامل نیست و قناریها هم بهترین پرندهها نیستن. ببینیم با استفاده از قناریها چه چیزهایی ممکنه اشتباه پیش برن.
استفاده از قناریها برای همه شیوههای توسعه نرمافزار مناسب نیست. قناریها با نرمافزارهایی که درون حلقه توسعه مداوم هستن سازگارترن. این مدل نرمافزارها بهتره از قناری استفاده نکنن:
[1] Domestic canary
[2] Google site reliability engineering By Alec Warner and Štěpán Davidovič
[3] What is Canary Deployment By Tomas Fernandez