Разликата между Microservice Architecture и SOA рамката

Микросервизна архитектура и SOA разлики

Микро услугите сега са горещи, популярният контраст на индустрията е така нареченото монолитно еднократно приложение и голям брой системи са разпространени преди повече от десетилетие, а след това микро услугите като нова концепция и оригинални Каква е разликата между разпределена система или SOA (Service-ориентирана архитектура)?

Нека първо да разгледаме същата точка:

  • Изисква Регистърът да внедри динамичен механизъм за откриване на регистрация на услуга;
  • Необходимо е да се вземе предвид съгласуваността на транзакциите по разпределения, принцип на ОСП, двуетапният ангажимент не може да гарантира изпълнение, трябва да се вземе предвид механизмът за компенсация на транзакциите;
  • Синхронни или асинхронни съобщения, как да се гарантира надеждността на съобщението? SOA е интегриран от ESB във всички съобщения;
  • Необходим е унифициран шлюз за агрегиране и подреждане на интерфейси, внедряване на унифициран механизъм за удостоверяване и осигуряване на RESTful интерфейс за външно използване на APP.
  • Същото трябва да обърне внимание на това как да преместите проблема със системата за позициониране, как да направите проследяване на регистрационния файл, точно както телекомуникационното поле е извършило повече от десет години функция за проследяване на сигнализация;

И така, къде е разликата?

  • Продължава ли интеграцията и непрекъснатото внедряване? За CI, CD (непрекъсната интеграция, непрекъснато разгръщане) това е преплетено с agile и DevOps. Мисля, че това е по-склонно към областта на софтуерното инженерство, отколкото към самата технология на микросервизите;
  • Различно ли е да се използват различни комуникационни протоколи? Протоколът за сравнителен анализ на микро услуги е RESTful, докато традиционният SOA обикновено е SOAP, но в момента има много леки рамки RubC, Thrift, gRPC и рамката Feign в Spring Cloud превръща стандартния RESTful в код. Подобно на API поведение на RPC, тези комуникационни протоколи не трябва да са основната разлика между архитектурата на микрослужбата и SOA;
  • Популярен ли е въз основа на контейнерна рамка или виртуална машина? Докерските и виртуалните машини все още са начин за внедряване на архитектури, а не основни различия;

Същността на микросервизната архитектура е разцепването

  • Има голяма разлика в сегментацията на услугите. SOA първоначално е разработен като „интегрирана“ технология. Много технически решения капсулират оригиналните вътрешни услуги на предприятието в отделен процес, така че новите услуги да могат да използват повторно тези услуги. Тези услуги вероятно са много големи частици като веригата за доставки и CRM. Микро услугите от този вид микро услуги показват, че той има особен акцент върху изключването и не прави компромиси. Многобройни случаи са доказали, че ако вашата сегментация е грешна, тогава няма да получите предимствата на „ниското свързване, ъпгрейдът не влияе, високата надеждност“, което обещава микрослужбата, и ще бъде по-трудно, отколкото използването на Monolithic. ,
  • Микросервизите, които не разделят съхранението, са псевдо услуги: На практика често виждаме архитектура, в която резервното съхранение е всичко и в една база данни, само бизнес-логиката отпред е разделена на различни сервизни процеси, същността Подобно на Monolithic, просто промяната на разговора в процеса между модулите към междупроцесови повиквания, това разделяне не е желателно, нарушавайки разпределения първи принцип, свързването на модулите не се решава и производителността се влияе.

Първият принцип на разпределения дизайн - „Не разпространявайте вашите обекти“

  • Думата „Микро“ за микросервизите не е толкова малка, колкото е възможно, а по-грубо зърнеста услуга като SOA. Нуждаем се от по-малка и по-подходяща подробност. Този Micro не е неограничен.

Ако комбинираме двупосочна (синхронна) комуникация с малки / микро услуги и следваме принципа „1 клас = 1 услуга“, тогава всъщност се връщаме към 20-ти век, използвайки Corba, J2EE и разпределени обекти. Възраст. За съжаление новото поколение разработчици няма опит с разпределени обекти, така че те не осъзнават колко лоша е идеята. Те се опитваха да повторят историята, но този път използваха нови технологии, като замяна на RMI или IIOP с HTTP. ,

Дизайн на микросервизи и домейн

Една проста система за управление на книги определено не изисква архитектура на микросервизи. Тъй като архитектурата на микро услугите е приета, проблемното пространство, което е изправено, трябва да бъде сравнително голямо, като цялата електронна търговия и CRM.

Как да разглобявате услугата?

Какъв метод се използва за разглобяване на услугата? Индустрията е популярна с 1 клас = 1 услуга, 1 метод = 1 услуга, 2 екипа за пица, 2 седмици могат да бъдат пренаписани и т.н., но тези липсват основа за внедряване. Трябва да търсим някои методи за проектиране на софтуер. Проблемното пространство за обектно-ориентираните и дизайнерски модели е модул, а концепцията за функционално програмиране е по-скоро на микро ниво на нивото на кода.

Книгата за дизайн на домейн на Ерик Еванс е чудесна справка за архитектурата на микросервизите. Тази книга предлага техника, която разгражда голямо проблемно пространство на взаимоотношения и поведение между домейни и образувания. В момента това е най-разумното решение на проблема с разделението. Чрез концепцията за ограничен контекст (наричана по-долу BC) можем да капсулираме подробностите за изпълнението и да дадем възможност на BC да внедрява SRP (една отговорност). )по принцип. Всяка микро-услуга е физическото картографиране на BC в реалния свят, а микро-услугите, които съответстват на идеята за BC, са независими и свободно свързани помежду си.

Микросервизната архитектура е добро нещо, което принуждава всички да обърнат внимание на рационалността на софтуерния дизайн. Ако анализът на домейните и обектно-ориентираният дизайн в Monolithic не са добри, микро-услугата ще удвои проблема.

Например, в двете области на поръчки и стоки в електронната търговия, според демонтажа на DDD, те трябва да са два независими гранични контекста, но поръчката трябва да съдържа стоки. Ако тя е разделена на две BC, връзката запитване и обаждане ще бъде свързана заедно, дори и при проблема с проблемните разпределени транзакции, как се разглобява тази асоциация? Теорията на пр. Н. Е. Смята, че в различни BC, дори термин, фокусът му не е един и същ. В стоката BC, акцентът е върху атрибутите, спецификациите, детайлите и т.н. (Всъщност стоката BC има цени, инвентар, промоции в тази област. Чакай, не е разумно да се отнасяме към него като към един BC. За да може опростете примера, всички първо смятат, че стоката BC е основната информация за стоката) и в реда BC, обърнете повече внимание на инвентара и цената на стоката. Следователно, в действителния дизайн на кодиране, услугата за поръчка има тенденция да осребри името на продукта, цената и други атрибути, които представляват интерес към поръчката. Този дизайн освобождава силната връзка със стоката пр. Н. Е. Двата BC могат да предоставят независими услуги, независимо съхранение на данни.

резюме

Първото нещо, на което трябва да се обърне внимание на архитектурата на микросервизите, не са концепциите за RPC / ServiceDiscovery / Circuit Breaker, нито техническата рамка на Eureka / Docker / SpringCloud / Zipkin. Това е границата на обслужването и разделението на задълженията. Ако разделите грешката, ще попаднете на голям брой услуги. В случай на извиквания и разпределени транзакции, микросервизите в този случай не са удобни, но обезпокоителни.

DDD ни донесе разумно разделение, но концепцията за DDD е многобройна, трудно е да разберем, как да схванем ключовите моменти и рационално да приложим към архитектурата на микро услугите?

Мисля, че следните архитектурни идеи са най-важни

  • Конгестивен модел
  • Събитие задвижвано

По-горе говорихме за връзката между DDD за микросервиз, много хора все още се чувстват много илюзорно, DDD е толкова сложна теория, обобщени корени, стойностни обекти, проследяване на събитията, как да започнем?

Всъщност DDD е неразривно свързана с обектно-ориентиран дизайн, модели на проектиране и т.н. Ако не сте запознати с OOA, OOD, DDD също не се използва добре. Въпреки това, когато изучават тези теории за OO, хората често се чувстват безполезни, тъй като по-голямата част от кариерата за развитие на Java програмист започва с изучаването на класическата теория за слоеве J2EE (Action, Service, Dao) в тази теория за слоеве. В този случай ние по принцип нямаме шанс да използваме така наречения „поведенчески” модел на дизайн. Основната причина тук е, че класическият слоест метод за развитие J2EE е „модел на анемия“.

В своята книга „Шаблони за архитектура на корпоративни приложения“ Мартин Фаулър предлага два метода за разработка: „скрипт на транзакции“ и „модел на домейна“, които съответстват на „модела на анемия“ и „модела на задръстване“.

Модел за развитие на домейн модел

  • Моделът на домейн капсулира данните и поведението и ги пренасочва към бизнес обекти в реалния свят. Всеки тип има ясно разделение на отговорностите, което позволява разпределението на логиката в правилните обекти. Такъв обект е „модел на задръстване“.
  • В конкретната практика трябва да изясним концепцията, че моделът на домейна е състоятелен и представлява реално нещо. Все още следвайки горния пример, ние проектираме Фонда за представяне на действителния опис на дадена стока и добавяме бизнес логика към обекта.

Когато правите бизнес логиката на инвентаризацията с единично заключване, всеки път първо трябва да възстановите обекта Inventory от хранилището според натоварването на първичния ключ и след това да изпълните съответния метод за заключване (num), за да промените състоянието на обекта Inventory (атрибутът е също вид състояние) и след това използвайте метода за запис на хранилището, за да запазите обекта в магазина.

Горепосочените серии операции са завършени, Application, Application осигурява външен интерфейс за тази интегрирана операция.

Най-важният аспект на метода за разработване на домейн модел е да се включат детайлите на промяната на състоянието, причинена от приспадането, в изпълнението на обекта Inventory, което е капсулирането на бизнес логиката.

Методът на заключване на обекта Application може да се сравни с заключването на StockService на метода скрипт за транзакции. StockService е напълно наясно с всички подробности. След като има промяна (например, инвентарят може да бъде изваден от 0), методът на услугата ще се промени; Не е необходимо да променяте начина, стига да се изчисли вътре в инвентарния обект. Кодът е на точното място, изчислението е на правилното ниво и всичко е разумно. Този дизайн може да използва пълноценно различните OOD, OOP теория за постигане на много красива бизнес логика.

  • Недостатъци на модела на задръстванията

От горния пример, в зареждането на хранилището за изпълнение на бизнес метода и след това запазване обратно, отнема известно време, но ако няколко нишки поискат блокирането в инвентаризационния списък едновременно, това ще доведе до непостоянно състояние , Проблемът е, че паралелността на инвентара е не само трудна за обработка, но и много често срещана.

Моделът на анемия разчита изцяло на подкрепата на базата данни за едновременност. Изпълнението може да бъде опростено много, но моделът на задръстванията трябва да се приложи сам. Независимо дали става въпрос за заключващия обект в паметта или чрез механизма за дистанционно заключване, използващ Redis, той е по-сложен от модела на анемия и надеждността е влошена. Това е предизвикателството на модела на задръстванията. По-добър подход е да се отмени паралелността чрез архитектура, базирана на събития.

Връзка между модела на домейна и микросервизите

Горното говори за реализацията на модела на домейна, но каква е връзката между него и микросервизите? На практика този инвентар е обобщен корен на ограничен контекст. Можем да мислим за агрегиран корен като за микросервиз.

Проблемът обаче идва отново. Описът на инвентара трябва да е свързан с информацията за продукта. Не е достатъчно да разчитате на излишния идентификационен номер на продукта в инвентара. Състоянието на продукта се изисква от бизнес логиката, която също не е въведена тежък предмет, като продукта Sku в тази микросервиза? Два тежки предмета в една услуга? Такава микро-услуга не може да бъде отворена или трябва да разчита на стоковата библиотека? !

В горното ние възприехме метод за разработка, управляван от домейн, използвахме модел на задръствания и се радвахме на неговите предимства, но също така трябваше да се справим с недостатъците. Този недостатък се увеличава при разпределената архитектура на микросервизите.

Консистенция на транзакциите

Въпросът за транзакционната консистенция не е голям проблем при Monolithic, но той е много мъртъв при микросервизите. Нека разгледаме така наречения ACID принцип.

  • Атомност - атомно, променящо се състояние на данни се извършва или заедно, или се проваля заедно
  • Последователност - последователност, състоянието на данните е пълно и последователно
  • Изолация - изолационните линии, дори ако има едновременни транзакции, не се засягат взаимно
  • Трайност - постоянство, след като сделката е извършена, неотменима

В случай на база данни с една услуга и релационни данни е лесно да се приложи ACID чрез характеристиките на базата данни. Но след като разделите съвкупната архитектура на root-microservice според DDD, техните бази данни се разделят и трябва да се справите с разпределените транзакции независимо и трябва да удовлетворите ACID в собствения си код.

За разпределените транзакции хората обикновено мислят за предишния стандарт JTA, 2PC ангажимент от две части. Спомням си, че през тази година в групата на Dubbo хората бяха питани за Dubbo да поддържат разпределени транзакции. Всъщност, съгласно принципа на ОСП в разпределените системи, когато P (толеранс на дяловете) се осъществява, стремежът към C (консистенция) насила води до (A) наличност и деградация на пропускателната способност. Понастоящем обикновено използваме окончателната консистенция, за да ни гарантираме. Възможности за системна AP. Разбира се, не е да се откаже от C, но като цяло, ОСП може да гарантира, че в случай на разделяне можем да гарантираме съгласуваност на данните чрез окончателна съгласуваност.

Пример:

Поръчката е замразена в бизнеса с електронна търговия. Необходимо е да се определи дали поръчката е попълнена според ситуацията с инвентара.

Да предположим, че сте приели разпределена система, където модулът за поръчка и модулът за инвентаризация са две услуги, всяка със собствено съхранение (релационна база данни).

В база данни транзакция може да фиксира две таблици, но в микросервизите няма начин да направите това.

В концепцията DDD транзакцията може да промени само състоянието вътре в агрегацията. Ако много агрегации трябва да имат едно и също състояние, тогава се предава крайната консистенция. Поръчките и материалните запаси са ясно обобщени, които принадлежат към два различни ограничаващи контекста. За постигане на максимална последователност е необходима архитектура, ориентирана към събития.

Събитие, задвижвано за максимална последователност

Управляваната от събития архитектура синхронизира състояние между обекти на домейна чрез асинхронни съобщения. Някои съобщения могат да бъдат публикувани едновременно на множество услуги. След като съобщението предизвика синхронизиране на услуга, това може да доведе до друго съобщение и събитието ще се разпространи. Строго погледнато драйверите за събития не се извикват синхронно.

Пример:

След като услугата за поръчка добави поръчка, състоянието на поръчката е „включено“ и след това събитие, създадено с поръчка, се публикува в опашката за съобщения.

След получаване на събитието "Създадена поръчка", службата за инвентаризация изважда продаваемия инвентар от определен скул в таблицата с инвентара, увеличава инвентара за запълване на поръчките и след това изпраща събитие със заключена инвентаризация на опашката за съобщения.

Услугата за поръчки получи събитието „Заключено с инвентара“ и промени състоянието на поръчката на „потвърдено“

Някой попита, ами ако инвентаризацията не е успешна и заключването не е успешно? Просто, услугата за инвентаризация изпраща събитие Loil Fail и след като услугата за поръчка я получи, поръчката е настроена на „анулирана“.

Добра новина, не можем да заключим!

Задвижваните от събития имат голямо предимство в анулирането на паралелността, всички заявки са поставени на опашка, което е много полезно за прилагането на модела на задръствания, не е необходимо сами да управляваме ключалките в паметта. Отменете заключването, ефективността на обработката на опашката е много висока и драйверът за събития може да бъде използван при сценарии с висока съвместимост, като щракане.

Да, потребителското изживяване се е променило,

С това събитие задвижване, опитът на потребителя може да се промени. Например, когато оригиналната структура за синхронизация не е на склад, тя веднага ще ви каже, че условието не е изпълнено и поръчката не може да бъде направена и поръчката няма да бъде генерирана. Механизмът на събитията обаче се променя и поръчката се генерира незабавно. Много вероятно е след известно време системата да ви уведоми, че поръчката е анулирана. Точно като „телефона за просо“ стотици хиляди хора чакат на опашка, които ви казват, че дълго време е на склад, върнете се утре. Ако искате потребителят да получи резултата веднага, можете да го помислите в предния край. В BFF (Backend For Frontend) използвайте ключалката на CountDownLatch, за да преобразувате задния асинхрон в синхронизацията на фронта. Разбира се, консумацията на BFF е сравнително голяма.

В никакъв случай продуктовият мениджър не приема,

Продуктовият мениджър каза, че опитът на потребителя трябва да е, че няма инвентар и няма да се генерира поръчка. Тази програма непрекъснато ще генерира анулирани поръчки. Той не може да го приеме. Какво трябва да направя? След това, когато поръчвате списъка, пропуснете тези поръчки в състояние за отмяна, може би ви е необходим допълнителен изглед, за да го направите. Не съм идеалист. Решаването на настоящия проблем е първото нещо, което трябва да разгледам. Целта на проектирането на микросервизи е решаването на бизнес паралелността. Сега проблемът е в потребителското изживяване, така че архитектурният дизайн също трябва да бъде компрометиран: (Но поне след анализа знам къде съм направил компромиси, защо компромис и възможността за промяна в бъдеще.

Multi-table Присъединете се към заявка в множество полета

  • Аз лично смятам, че моделът на агрегирания корен е особено подходящ за промяна на състоянието, но е неудобен за данните от търсенето, като филтриране на партида от отговарящи на изискванията поръчки, самият агрегиран корен обект не може да поеме задачата за групово запитване, т.е. защото това не е негово задължение. След това трябва да разчитате на услугата „Обслужване на домейни“.

Когато методът е неудобен за поставяне върху обект или обект на стойност, използването на услугата на домейна е най-доброто решение. Уверете се, че услугата на домейна е без гражданство.

  • Задачите ни за заявки често са сложни, като заявка на списък с елементи, изискващи сортиране по продажби от миналия месец; сортиране по възвръщаемост на артикула и т.н. Но след микросервизи и DDD, моделът ни за съхранение е премахнат. Горните заявки са свързани с данни в множество полета на поръчки, потребители и стоки. Как да се ангажирам? В този момент ще въведем концепцията за възглед. Например, по-долу, запитване на операцията на потребителското име, за да поръчате, директно се обадете на двете услуги в ефективността на присъединяване към паметта несъмнено е много ниска, плюс някои условия на филтър, пейджинг, не може да направи. Така че ние излъчваме събитието, отделна услуга за преглед, за да получаваме тези събития, и формираме материализиран изглед, данните са съединени, обработени, поставени в отделна библиотека с заявки, в очакване на заявката, това е типичен начин за справяне с пространство за време.

След анализ, в допълнение към простия списък, базиран на първичния ключ Намиране или не твърде свързана заявка, повечето от нашите задачи за заявки могат да бъдат поставени в отделна библиотека с заявки, тази библиотека с заявки може да бъде библиотеката ReadOnly на релационната база данни или базата данни NoSQL Всъщност използвахме ElasticSearch като специализиран изглед на заявки в проекта, който работи много добре.

Ограничен контекст и свързване на данни

В допълнение към проблема с присъединяването към много домейни, често срещаме някои сцени в бизнеса. Например информацията за продукта в електронната търговия е основната информация, която принадлежи на отделния BC и други BC, независимо дали е маркетингова услуга, ценова услуга, услуга за пазаруване на колички. Всички услуги за поръчка са задължени да цитират информация за този продукт. Необходимата информация за продукта обаче е само малка част от нея. Маркетинговата услуга изисква идентификатора и името на продукта и състоянието на рафтовете; услугата за поръчка изисква идентификатор на продукта, име, директория, цена и т.н. Това е малко подмножество от дефиницията на даден продукт (идентификатор на елемент, име, спецификация, стойност на спецификация, подробности и т.н.) в сравнение с продуктовия център. Това илюстрира една и съща терминология за различни ограничаващи контексти, но посочените понятия са различни. Този вид проблем е картографиран към нашата реализация. Определено е неподходящо директно да запитвате стоковия модул в модула за поръчка и маркетинг.

  • Търговските центрове трябва да адаптират данните, необходими за всяка услуга, осигурявайки различни интерфейси
  • Паралелността трябва да е голяма
  • Свързването между услугите е сериозно и след като престоя и надстройките са засегнати, обхватът е голям.

По-специално, последният силно ограничава предимството ни от предоставянето на микросервизи. „Слабо свързана, всяка услуга може да бъде надграждана често, без да се засяга други модули.“ Това изисква да използваме подход, управляван от събития, за да съкратим правилно някои данни към различни БК, за да разглобим тази връзка. Този вид свързване понякога е вграден в субекта чрез стойностния обект, който е излишен при генерирането на субекта. Например, поръчката е излишна, когато продуктът се генерира; понякога е чрез допълнителен списък на обекти на стойност. Маркетинговият център излишно съхранява част от свързаните данни от списъка с продукти и обръща внимание на състоянието на подчинените на наблюдаваните продукти по всяко време и синхронно заменя списъка с продукти в контекста на ограничението.

Следващата фигура показва анализ на сценария на поръчката. В системата за електронна търговия можем да мислим, че членовете и стоките са основните данни на всички бизнеси и техните промени трябва да бъдат излъчвани в различни области, като всяко поле запазва информацията, от която се нуждае.

Гарантирайте максимална консистенция

Крайната консистенция зависи от много условия

  • В зависимост от надеждността на доставката на съобщение, A системата може да промени състоянието и съобщението се губи, когато се изпрати до системата B, което води до несъответствие на състоянието на AB.
  • В зависимост от надеждността на услугата, ако системата A промени собственото си състояние, но не е имала време да изпрати съобщение, тя виси. Ще доведе и до непостоянно състояние

Спомням си, че JMS в спецификацията на JavaEE има изисквания за обработка на тези два проблема. Единият е, че JMS гарантира надеждността на доставката на съобщения чрез различни съобщения за потвърждение (потвърждение на клиента и др.), А операцията за предаване на JMS съобщения може да бъде добавена към базата данни. При транзакцията - тоест не се изпраща съобщение, това ще доведе до преобръщане на базата данни (не се откриват данни, не е много точно описание, моля, поправете ме). Понастоящем обаче има малко MQ, които отговарят на спецификацията на JMS, особено за да се осигури последователност и да се намали производителността. Сега високопроизводителната MQ хвърля проблема към собственото ни приложение. Ето няколко общи начина за подобряване на крайната консистенция.

Използвайте местни транзакции

Все още вземаме примера за приспадане на кредит от горния ред

  • Услугата за поръчки започва локална транзакция, като първо се добавя поръчка;
  • След това поставете събитието "Създадена поръчка" в специална таблица на събитията, транзакцията се изпраща;
  • Има отделна времева нишка за задачи, която периодично сканира таблицата на събитията, размита я и я изпраща в MQ и задава събитието на „изпратено“.

Предимството на решението е, че се използва транзакцията на локалната база данни. Ако събитието не бъде поставено успешно, поръчката няма да бъде създадена. След като нишката сканира, събитието се изпраща за изпращане и съобщението не е изтекло. Нашата цел е да бъдем по-добри. Повторно изпратете, не го пропускайте, защото обработката на събитията ще бъде проектирана така, че да е безсилна).

Недостатъкът е, че обработката на събитията трябва да се обработва отделно по бизнес логиката, което е тромаво и лесно се забравя; изпращането на събитието се забавя донякъде; ефективността на сканиране с времево сканиране е скъпа, а високото ниво на водата скрива опасност от базата данни;

Направихме леко подобрение, като използвахме специфичното за базата данни проследяване на MySQL Binlog (канал на Али) или технологията GoldenGate на Oracle, за да получим известие за промяна на таблицата на събитията в базата данни, така че можете да избегнете сканиране чрез задачата за определяне на времето.

Въпреки това, инструментите, които използват тези регистрационни файлове, ще бъдат обвързани с конкретни реализации на базата данни (дори конкретни версии), така че бъдете внимателни, когато вземате решения.

Проследяване със събитието Sourcing на събитието

Проследяването на събитията е специална идея за нас. Вместо да се поддържа обектът Entity, той записва само първоначалното състояние и събитието на всяка промяна и възстановява най-новото състояние на обекта Entity според събитието в паметта. Много подобен на Redolog реализацията на базата данни, но той вкара този механизъм в приложния слой.

Въпреки че проследимостта на събитието има много предимства, въвеждането на тази технология изисква специални грижи. На първо място, той не е непременно подходящ за повечето бизнес сценарии. След като се направят много промени, ефективността наистина е голям проблем; други въпроси също са проблемни.

Ние използваме само изтъркващи събития и AxonFramework проучвателно в отделни бизнеси. Поради сложността на прилагането, конкретната ситуация трябва да изчака до известно време на практика. Може би е необходима допълнителна статия, за да се опише подробно.