X. برابری توسعه/عملیات
توسعه، آزمون و عملیات را تا حد امکان، همانند نگه دارید
از لحاظ تاریخی، شکافهای قابل توجهی بین توسعه (توسعهدهندهای که تغییرات مداوم در استقرار محیط توسعهی برنامه انجام می دهد) و عملیات (استقرار در حال اجرای برنامه که توسط کاربران نهایی در دسترس است) وجود داشته است. این شکافها در سه حوزه ظاهر می شوند:
- شکاف زمانی: یک توسعهدهنده ممکن است روی کدی کار کند که عملیاتیسازی آن روزها، هفتهها یا حتی ماهها طول میکشد.
- شکاف پرسنل: توسعهدهندگان کد می نویسند، مهندسان عملیات آن را مستقر میکنند.
- شکاف ابزار: توسعهدهندگان ممکن است از پشته ای مانند Nginx، SQLite و OS X استفاده کنند، در حالی که در محیط عملیات از Apache، MySQL و Linux استفاده میشود.
برنامه دوازده-سازه برای استقرار مستمر طراحی شده است و فاصله بین توسعه و عملیات را کم نگه می دارد. با نگاهی به سه شکاف توضیح داده شده در بالا:
- فاصله زمانی را کم کنید: طوریکه یک برنامهنویس ممکن است کد بنویسد و چند ساعت یا حتی چند دقیقه بعد آن را مستقر کند.
- شکاف پرسنل را کم کنید: طوریکه توسعهدهندگانی که کد را نوشتهاند، از نزدیک در استقرار آن و مشاهده رفتار آن در عملیات نقش دارند.
- شکاف ابزارها را کم کنید: طوریکه محیط توسعه و عملیات را تا حد امکان هماهند هم هستند.
چکیدهی موارد فوق را در جدول زیر ببینید:
برنامهی سنتی | برنامهی دوازده-سازه | |
---|---|---|
زمان بین استقرارها | هفتهها | ساعتها |
نویسندگان کد در مقابل استقراردهندگان کد | افراد مختلف | افراد یکسان |
محیط توسعه در مقابل محیط عملیات | تا حد زیاد متفاوت | تا حد امکان همانند |
سرویسهای پشتیبان، مانند پایگاهدادهی برنامه، سیستم صف یا حافظهی نهان یکی از حوزههایی است که در آن برابری توسعه/عملیات مهم است. بسیاری از زبانهای برنامهنویسی، کتابخانههایی را ارائه میکنند که دسترسی به سرویسهای پشتیبان را ساده میکنند. از این دسته میتوان به رابطهای برنامهنویسی برای انواع مختلف سرویسهای پشتیبان اشاره کرد. چند نمونه در جدول زیر آمده است.
نوع | زبان | کتابخانه | تطبیقدهنده |
---|---|---|---|
پایگاه داده | روبی/ریل | ActiveRecord | MySQL، PostgreSQL، SQLite |
صف | Python/Django | Celery | RabbitMQ، Beanstalkd، Redis |
حافظه پنهان | روبی/ریل | ActiveSupport::Cache | حافظه، سیستم فایل، Memcached |
توسعهدهندگان گاهی اوقات علاقهی زیادی در استفاده از یک سرویس پشتیبان کوچک در محیط های توسعهی خود پیدا میکنند، در حالی که یک سرویس پشتیبان جدیتر و قویتر در محیط عملیات استفاده میشود. به عنوان مثال، استفاده از SQLite در محیط توسعه و PostgreSQL در محیط عملیات. یا حافظهی سیستم برای ذخیره سازی در توسعه و Memcached در عملیات.
توسعهدهندهی برنامهی کاربردی دوازده-سازه در برابر اصرار برای استفاده از خدمات پشتیبان مختلف بین توسعه و عملیات مقاومت میکند، حتی زمانی که رابطهای برنامهنویسی از نظر تئوری هرگونه اختلاف در سرویس پشتیبان را از بین میبرند. تفاوت بین سرویسهای پشتیبان به این معنی است که ناسازگاریهای کوچک ظاهر میشوند و باعث میشوند کدهایی که کار میکردند و آزمایشهایشان را در مرحله توسعه یا آزمون پشت سر گذاشتهاند، در عملیات شکست بخورند. این نوع خطاها باعث ایجاد اصطکاک می شود که استقرار مداوم را از بین میبرد. هزینه این اصطکاک و عدمسرویسدهی متعاقب آن در استقرار مستمر، در طی طول عمر یک برنامهی کاربردی بسیار زیاد است.
ابزارهای کوچک محیط توسعه، همانند گذشته برای برنامهنویسان قانعکننده نیستند. نصب و اجرای سرویسهای پشتیبان مدرن مانند Memcached، PostgreSQL و RabbitMQ به لطف سیستمهای بستهبندی تازهوارد مانند Homebrew و apt-get همانند گذشته سخت و طاقتفرسا نیست. از طرف دیگر، ابزارهای ارائه اعلامی مانند Chef و Puppet همراه با محیطهای مجازی کمهزینه مانند Docker و Vagrant به توسعهدهندگان اجازه میدهند محیطهای توسعهای را پیکربندی کنند که تقریباً همانند محیطهای عملیات هستند. هزینهی نصب و استفاده از این سیستمها در مقایسه با مزیت برابری توسعه/عملیات و استقرار مستقمر بسیار پایین است.
رابطهای برنامهنویسی سرویسهای پشتیبان مختلف هنوز مفید هستند، زیرا انتقال به سرویسهای پشتیبان جدید را نسبتاً بدون دردسر میسازند. اما همه راهاندازیهای برنامه (محیطهای توسعهدهنده، آزمون و عملیات) باید از یک نوع و نسخهی همانند از هر یک از خدمات پشتیبان استفاده کنند.