Здравейте, колеги.
Днес ви представяме превод на статията на Тугберк Угурлу, който се опитва в сравнително малък обем да изложи принципите на проектиране на съвременни софтуерни системи. Ето какво авторът съобщава за себе си в сух остатък:

Понеже е абсолютно невъзможно да обхванем в хабростатията такава колосална тема, като архитектурни патерни + патерни на проектиране към 2019 година, препоръчваме не само текста на господин Угурлу, но и многобройните линкове, които той е любезно поставил в него. Ако ви хареса — ще публикуваме и по-тесен тематичен текст за проектиране на разпределени системи.

Снимка от сайта Unsplash
Ако никога не сте се сблъсквали с предизвикателства като проектирането на софтуерна система от нулата, то при започването на такава работа понякога дори не е ясно откъде да започнете. Аз смятам, че първо е необходимо да очертаете границите, за да имате по-горе-долу уверена представа какво точно възнамерявате да проектирате, а след това – да засучете ръкави и да работите, без да излизате извън тези граници. Като отправна точка можете да вземете някакъв продукт или услуга (в идеалния случай – такава, която ви харесва много) и да се запознаете с нейното реализиране. Може би ще се учудите колко просто изглежда този продукт и каква огромна сложност наистина се крие зад него. Не забравяйте: , и това е нормално.
Смятам, че най-добрият съвет, който мога да дам на онези, които започват проектирането на система, е следният: не допускайте никакви допускания! От самото начало е необходимо да конкретизирате фактите, познати за тази система, и свързаните с нея очаквания. Ето няколко добри въпроса, на които отговорите ще ви помогнат да започнете проектирането:
- Какъв е проблемът, който се опитваме да решим?
- Какво е максималното количество потребители, които ще взаимодействат с нашата система?
- Какви патерни на запис и прочит на данни ще използваме?
- Какви са очакваните случаи на откази, как ще се справим с тях?
- Какви очаквания има относно консистентността и достъпността на системата?
- Трябва ли да вземем предвид при работата някакви изисквания, свързани с външна проверка и регламентация?
- Какви видове конфиденциални данни смятаме да съхраняваме?
Това е само няколко въпроса, които ми помогнаха както в работата, така и на екипите, с които имах възможност да работя през годините на професионалната си кариера. Ако знаете отговорите на тези въпроси (и на всякакви други, които са релевантни в контекста, в който работите), можете постепенно да навлезете в техническите детайли на задачата.
Задаваме начално ниво
Какво разбирам тук под "начално ниво" (baseline)? Всъщност, в наши дни повечето проблеми в софтуерната индустрия могат да бъдат решени с помощта на вече съществуващи методи и технологии. Следователно, ориентирайки се в този ландшафт, получавате определено предимство, срещайки задачи, които вече са били решавани от други преди вас. Не забравяйте, че програмите се пишат, за да решават проблеми на бизнеса и потребителите, затова се стремим да решим задачата по най-простия и директен (от потребителска перспектива) начин. Защо е важно да помните това? Може би в системата ви харесва да търсите уникални решения за всяка задача, защото смятате, че „какъв програматор съм аз, ако навсякъде следвам шаблони“? Всъщност, изкуството тук е в вземането на решения за това къде и какво да правите. Разбира се, на всеки от нас понякога се налага да се справя с уникални проблеми, всеки от които е истинско предизвикателство. Въпреки това, ако нашето начално ниво е ясно очертано, знаем на какво да отделим усилията си: на търсене на готови решения за поставената задача или на по-подробно проучване и по-дълбоко разбиране.
Мисля, че успях да ви убедя, че ако специалист уверено разбира каква е архитектурната съставка на някои велики софтуерни системи, тези знания ще бъдат незаменими за овладяване на изкуството на архитектурата и изграждане на солидна основа в тази област.
Добре, от къде да започнем? У има репозиторий в GitHub, наречен , с материала, от който можете да научите как да проектирате мащабни системи, както и да се подготовите за интервюта по тази тема. В репозитория има раздел с примери , където, в частност, е разгледано как компаниите подхождат към дизайна на своите системи , например, Twitter, Uber и др.
Въпреки това, преди да пристъпим към този материал, нека по-подробно разгледаме най-важните архитектурни предизвикателства, с които практическите специалисти се срещат. Това е важно, тъй като трябва да конкретизираме МНОЖЕСТВО аспекти на трудната и многопластова проблематика и след това да я решим в контекста на регулацията, която действа в съответната система. , бивш служител на Facebook, е записал , където споделя личния си опит от прегледа на стотици кандидати. Въпреки че видеото изразително се отнася до проектирането на големи системи и критериите за успех, важни при търсенето на кандидат за такава позиция, то все пак ще служи като изчерпателен ресурс относно това, какви неща са най-важни при проектирането на системи. Също така предлагам на това видео.
Наблюдавайте знанията за съхранение и извличане на данни
Обикновено, вашето решение за това как ще съхранявате и раздавате данните си в дългосрочен план оказва критично влияние върху производителността на системата. Следователно, трябва първо да разберете очакваните характеристики на записване и четене на данни в системата ви. След това трябва да умеете да оценявате тези показатели и да взимате решения въз основа на направените оценки. Въпреки това, ще можете ефективно да се справяте с тази задача само ако разберете съществуващите модели на съхранение на данни. Основно, това предполага уверени познания, свързани с .
Базите данни могат да се считат за структури от данни, които притежават изключителна мащабируемост и дълговечност. Затова познанията за структури от данни трябва да ви бъдат много полезни и при избора на съответна база данни. Например, – това е сървър за структурирани данни, който поддържа различни видове стойности. Той позволява работа с такива структури от данни като списъци и множества, както и четене на данни чрез известни алгоритми, например, , организирайки тази работа по дълготраен и достъпен стил.

Снимка от сайта Unsplash
Когато достатъчно добре се запознаете с различните модели на съхранение на данни, преминете към изучаване на консистентността и достъпността на данните. Първо, ще трябва да усвоите поне в общи линии, а след това да усъвършенствате тези знания, като разгледате по-подробно утвърдените модели и . По този начин ще разширите хоризонтите си в тази област и ще разберете, че четенето и писането на данни всъщност са два много различни проблема, всеки от които носи своите специфични предизвикателства. Със специфични модели на осигуряване на консистентност и достъпност, ще можете значително да увеличите производителността на системата, докато гарантирате непрекъсната подача на данни в приложенията си.
Накрая, завършвайки разговора за проблемите на съхранението на данни, трябва да спомена и кеширането. Трябва ли то да се извършва едновременно на клиента и на сървъра? Какви данни ще имате в кеша си? И защо? Как ще организирате анулирането на кеша? Ще се извършва ли периодично, на определени интервали? Ако да – колко често? Препоръчвам да започнете разглеждането на тези теми с от споменатия буквар по проектиране на системи.
Комуникационни модели
Системите се състоят от различни компоненти; те могат да бъдат както различни процеси, работещи вътре в един и същ физически възел, така и различни машини, действащи в различни части на мрежата ви. Някои от тези ресурси във вашата мрежа може да са частни, но други трябва да бъдат публични и отворени за външните потребители, които имат достъп до тях.
Необходимо е да се осигури комуникация между тези ресурси, както и обмен на информация между цялата система и външния свят. В контекста на проектирането на системи отново се сблъскваме с набор от нови уникални предизвикателства. Разглеждаме как могат да бъдат полезни , и какви разнообразни модели на комуникация съществуват.

Снимка от сайта Unsplash
, за което също трябва да се подходи с голяма сериозност и активно да се работи. Разпределение на връзките
Разпределение на връзките
Не съм сигурен, че извеждането на тази тема в самостоятелен раздел ще се стори оправдано на всички. Въпреки това, ще изложа подробно тази концепция тук, като считам, че материалът на този раздел се описва най-точно с термина „разпределение на връзките“ (connection distribution).
Системите се формират чрез правилно свързване на множество компоненти, а комуникацията помежду им често се организира на базата на утвърдени протоколи, като например TCP и UDP. Въпреки това, тези протоколи често не са достатъчни, за да задоволят всички нужди на съвременните системи, които често работят при високи натоварвания и силно зависят от потребностите на потребителите. Често е необходимо да се търсят начини за разпределение на връзките, за да се справят с такива високи натоварвания в системата.
В основата на такова разпределение стои добре известната (DNS). Тази система позволява преобразуването на домейн име, например, на базата на алгоритми с тегло (weighted round robin) и методи, основани на закъснения, които помагат за разпределяне на натоварването.
е принципиално важна, като практически всяка голяма система в интернет, с която се сблъскваме днес, се намира зад един или повече балансировачи на натоварването. Балансировачите на натоварване помагат да се разпределят клиентските заявки между множество налични инстанции. Те могат да бъдат както хардуерни, така и софтуерни, но на практика по-често се срещат софтуерни, например с и . концептуално също са много подобни на балансировачите на натоварване, въпреки че между тях съществуват редица . Тези различия задължително трябва да се вземат предвид при проектиране на система, съобразена с вашите нужди.
Също така е важно да се знае за (CDN). CDN е глобална разпределена мрежа от прокси сървъри, която доставя информация от възли, които географски са разположени по-близо до конкретния потребител. CDN мрежите са за предпочитане, когато работите със статични файлове, написани на JavaScript, CSS и HTML. Освен това, днес са разпространени облачни услуги, които предлагат трафик мениджъри, например, , осигуряващи ви глобално разпространение и намалени закъснения при работа с динамично съдържание. Въпреки това, тези услуги обикновено са полезни в случаите, когато трябва да работите с уеб услуги, които не съхраняват състояние.
Нека поговорим за бизнес логика. Структуриране на бизнес логиката, потоците от задачи и компонентите
И така, успяхме да обсъдим различни инфраструктурни аспекти на системата. Скорее всего, потребителят дори не се замисля за всички тези елементи на вашата система и, честно казано, не се тревожи за тях. Потребителя интересува какво е взаимодействието с вашата система, какво може да постигне, като направи това, както и как системата изпълнява командите на потребителя, какво прави и как обработва данните на потребителя.
Както е ясно от заглавието на тази статия, планирах да говоря за софтуерната архитектура и проектирането на системи. Съответно, не планирах да обсъждам шаблоните за проектиране на софтуер, които описват как се създават софтуерни компоненти. Въпреки това, колкото повече разсъждавам по този въпрос, толкова повече ми се струва, че границата между шаблоните за проектиране на софтуер и архитектурните шаблони е много размита, а тези две концепции са тясно свързани. Нека вземем, например, (event sourcing). Щом започнете да прилагате този архитектурен шаблон, той ще повлияе практически на всички аспекти на вашата система: дългосрочното съхранение на данни, нивото на консистентност, прието в системата, очертанията на компонентите в нея и т.н. и т.н. Затова реших да спомена някои архитектурни шаблони, касаещи директно бизнес логиката. Дори и в тази статия да трябва да се огранича до прост списък, ви препоръчвам да се запознаете с него и да обмислите идеите, свързани с тези шаблони. Ето, моля:
- Концепции , в частност, ,
Колаборативни подходи
Изключително малко вероятно е да бъдете човекът, който поема единствено отговорността за проектирането на системата в проекта. Напротив, вероятно ще ви се наложи да взаимодействате с колеги, които работят както в рамките на вашата задача, така и извън нея. В този случай може да се наложи да оцените избраните технологични решения заедно с колегите, да определите бизнес нуждите и да разберете как най-добре да паралелизиране задачите.

Снимка от сайта Unsplash
На първо място, ще трябва да разработите точно и общоприето разбиране за бизнес целта, която се опитвате да постигнете, и с какви подвижни елементи ще трябва да се справяте. Методите за групово моделиране, по-специално, (event storming) значително ускоряват този процес и увеличават шансовете ви за успех. Тази работа може да започне преди или след като определите , а след това да я задълбочите с развитието на продукта. Откривайки нивото на съгласие, което ще бъде постигнато тук, можете също така да формулирате за ограничения контекст, в който работите. Когато се нуждаете да говорите за архитектурата на вашата система, може да се нуждаете от , предложен от , особено когато е необходимо да разберете до колко дълбоко трябва да навлезете в детайлите на проблема, визуализирайки нещата, които искате да предадете.
Вероятно в тази тема ще намерите и друга зряла технология, не по-малко полезна от предметно ориентираното проектиране. Въпреки това, по един или друг начин, се връщаме към разбирането на предметната област, така че знанията и опитът в сферата на би трябвало да ви бъдат полезни.
Източник: habr.com
