اصول توسعه برنامه های مدرن از NGINX. قسمت 1

سلام دوستان. در انتظار راه اندازی دوره توسعه دهنده باطن PHP، به طور سنتی ترجمه مطالب مفید را با شما به اشتراک می گذارد.

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

اصول توسعه برنامه های مدرن از NGINX. قسمت 1

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

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

اصول توسعه برنامه های مدرن از NGINX. قسمت 1

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

امیدواریم این مقاله شما را به استفاده از اصول پیشنهادی برای ساخت برنامه های مدرن ترغیب کند که رویکردی واحد برای طراحی در زمینه یک پشته فناوری در حال رشد ارائه می دهد.

با به کارگیری این اصول، متوجه خواهید شد که از آخرین روند توسعه نرم افزار، از جمله، بهره می برید DevOps برای توسعه و تحویل برنامه های کاربردی، استفاده از کانتینرها (به عنوان مثال، کارگر بارانداز) و چارچوب های ارکستراسیون کانتینر (به عنوان مثال، کوبرنیتس، استفاده از میکروسرویس ها (از جمله معماری میکروسرویس). NGINX и معماری ارتباطات شبکه برای کاربردهای میکروسرویس

اپلیکیشن مدرن چیست؟

برنامه های مدرن؟ پشته مدرن؟ «مدرن» دقیقاً به چه معناست؟

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

یک برنامه مدرن از چندین کلاینت پشتیبانی می کند، خواه یک رابط کاربری کتابخانه React JavaScript، یک برنامه تلفن همراه Android یا iOS، یا برنامه ای که به API دیگری متصل می شود. یک برنامه کاربردی مدرن شامل تعداد نامحدودی از مشتریان است که برای آنها داده یا خدمات ارائه می دهد.

یک برنامه مدرن یک API برای دسترسی به داده ها و خدمات درخواستی ارائه می دهد. API باید تغییر ناپذیر و ثابت باشد و به طور خاص برای یک درخواست خاص از یک مشتری خاص نوشته نشود. API از طریق HTTP(S) در دسترس است و دسترسی به تمام عملکردهای موجود در GUI یا CLI را فراهم می کند.

داده ها باید در قالبی قابل قبول و قابل همکاری مانند JSON در دسترس باشند. یک API اشیا و سرویس‌ها را به روشی تمیز و سازمان‌دهی شده در معرض نمایش می‌گذارد، مانند RESTful API یا GraphQL یک رابط مناسب ارائه می‌کند.

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

نسخه های محبوب این نوع پشته بر اساس جاوه, پــایتــون, گره, یاقوت, پی اچ پی и Go. معماری میکروسرویس NGINX نمونه ای از پشته مدرن پیاده سازی شده در هر یک از زبان های ذکر شده را نشان می دهد.

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

اصول

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

یکی از اصول به نظر می رسد "برنامه های کوچک بسازید"، بگذارید فقط آن را صدا کنیم اصل کوچکی. برنامه های فوق العاده پیچیده ای وجود دارد که از قطعات متحرک بسیاری تشکیل شده است. به نوبه خود، ساختن یک برنامه از اجزای کوچک و مجزا، طراحی، نگهداری و کار با آن را به عنوان یک کل آسان تر می کند. (توجه داشته باشید که گفتیم «ساده می کند» نه «ساده می کند»).

اصل دوم این است که می‌توانیم بهره‌وری توسعه‌دهندگان را با کمک به تمرکز بر ویژگی‌هایی که در حال توسعه هستند افزایش دهیم، در حالی که آنها را از نگرانی‌های زیرساختی و CI/CD در حین پیاده‌سازی رها کنیم. بنابراین، به طور خلاصه، رویکرد ما متمرکز بر توسعه دهندگان.

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

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

بیایید این سه اصل را با جزئیات بیشتری بررسی کنیم.

اصل کوچکی

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

اصول توسعه برنامه های مدرن از NGINX. قسمت 1

برنامه ها به دلایل زیر تجزیه می شوند:

  • کاهش بار شناختی در توسعه دهندگان؛
  • تسریع و ساده سازی تست؛
  • تحویل سریع تغییرات در برنامه.


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

بنابراین در اینجا سه ​​راه برای کاهش بار شناختی وجود دارد:

  1. بازه زمانی را که باید در هنگام توسعه یک ویژگی جدید در نظر بگیرند، کاهش دهید - هرچه بازه زمانی کوتاه‌تر باشد، بار شناختی کمتری دارد.
  2. مقدار کدی را که یک بار کار روی آن انجام می شود کاهش دهید - کد کمتر - بار کمتر.
  3. فرآیند ایجاد تغییرات تدریجی در برنامه را ساده کنید.

کاهش بازه زمانی توسعه

برگردیم به روزهایی که روش شناسی waterfall استاندارد فرآیند توسعه بود و بازه‌های زمانی شش ماه تا دو سال برای توسعه یا به‌روزرسانی یک برنامه کاربردی معمول بود. به طور معمول، مهندسان ابتدا اسناد مربوطه مانند الزامات محصول (PRD)، سند مرجع سیستم (SRD)، طرح اولیه معماری را می‌خوانند و شروع به ترکیب همه این موارد در یک مدل شناختی می‌کنند که بر اساس آن کدگذاری می‌کنند. با تغییر الزامات و در نتیجه تغییر معماری، باید تلاش جدی برای اطلاع رسانی به کل تیم در مورد به روز رسانی های مدل شناختی صورت می گرفت. چنین رویکردی در بدترین حالت می‌تواند به سادگی کار را فلج کند.

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

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

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

پایگاه های کد کوچک

گام بعدی در کاهش بار شناختی، کاهش پایه کد است. به عنوان یک قاعده، برنامه های کاربردی مدرن عظیم هستند - یک برنامه قوی و سازمانی می تواند از هزاران فایل و صدها هزار خط کد تشکیل شده باشد. بسته به نحوه سازماندهی فایل‌ها، پیوندها و وابستگی‌های بین کد و فایل‌ها ممکن است آشکار باشد یا برعکس. حتی اجرای کد اشکال زدایی به خودی خود می تواند مشکل ساز باشد، بسته به کتابخانه های مورد استفاده و اینکه چگونه ابزارهای اشکال زدایی بین کتابخانه ها/ بسته ها/ ماژول ها و کد سفارشی تمایز قائل می شوند.

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

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

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

تغییرات تدریجی کوچک

آخرین عنصر اصل کوچکی مدیریت تغییر است. این یک وسوسه خاص برای توسعه دهندگان است که به پایه کد (حتی شاید کدهای قدیمی تر خود) نگاه کنند و بگویند: "این تلخ است، ما باید همه آن را بازنویسی کنیم." گاهی این تصمیم درست است و گاهی نه. بار تغییر مدل جهانی را بر دوش تیم توسعه می گذارد که به نوبه خود منجر به بار شناختی عظیم می شود. بهتر است مهندسان بر روی تغییراتی که می توانند در طول اسپرینت ایجاد کنند تمرکز کنند تا بتوانند عملکردهای لازم را به موقع و البته به تدریج اجرا کنند. محصول نهایی باید شبیه محصول از پیش برنامه ریزی شده باشد، اما با برخی تغییرات و آزمایشات متناسب با نیاز مشتری.

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

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

  1. از روش شناسی استفاده کنید agileبرای محدود کردن بازه زمانی که در آن تیم باید روی ویژگی های کلیدی تمرکز کند.
  2. برنامه خود را به عنوان چندین میکروسرویس پیاده سازی کنید. این تعداد ویژگی هایی را که می توان پیاده سازی کرد محدود می کند و مرزهایی را که بار شناختی را در کار نگه می دارند، تقویت می کند.
  3. تغییرات افزایشی را به بزرگ و سخت ترجیح دهید، کدهای کوچک را تغییر دهید. از پنهان کردن ویژگی برای اجرای تغییرات استفاده کنید حتی اگر بلافاصله پس از اضافه شدن قابل مشاهده نباشند.

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

پایان قسمت اول.

به زودی قسمت دوم ترجمه را منتشر خواهیم کرد و اکنون منتظر نظرات شما و دعوت شما هستیم روز بازکه امروز ساعت 20.00:XNUMX برگزار می شود.

منبع: www.habr.com

اضافه کردن نظر