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

Тъй като е абсолютно невъзможно да се обхване в хабр статия така колосална тема, като архитектурни шаблони + шаблони за проектиране към 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
