<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Architecture Archives &#8226; König Labs</title>
	<atom:link href="https://koniglabs.ru/category/architecture/feed/" rel="self" type="application/rss+xml" />
	<link>https://koniglabs.ru/category/architecture/</link>
	<description></description>
	<lastBuildDate>Wed, 21 May 2025 12:56:24 +0000</lastBuildDate>
	<language>ru-RU</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://koniglabs.ru/wp-content/uploads/2019/06/cropped-favicon-32x32.png</url>
	<title>Architecture Archives &#8226; König Labs</title>
	<link>https://koniglabs.ru/category/architecture/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Serverless vs монолит: что выбрать в среде AWS?</title>
		<link>https://koniglabs.ru/serverless-vs-monolit/</link>
					<comments>https://koniglabs.ru/serverless-vs-monolit/#respond</comments>
		
		<dc:creator><![CDATA[Alexey Palatkin]]></dc:creator>
		<pubDate>Mon, 30 Aug 2021 16:21:54 +0000</pubDate>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[serverless]]></category>
		<category><![CDATA[архитектура]]></category>
		<category><![CDATA[монолит]]></category>
		<guid isPermaLink="false">https://koniglabs.com/?p=6240</guid>

					<description><![CDATA[<p>The post <a href="https://koniglabs.ru/serverless-vs-monolit/">Serverless vs монолит: что выбрать в среде AWS?</a> appeared first on <a href="https://koniglabs.ru">König Labs</a>.</p>
]]></description>
										<content:encoded><![CDATA[<div id="tm-row-69dc3b982595f" class="vc_row vc_row-outer vc_row-fluid"><div id="tm-column-69dc3b9827f26" class="wpb_column vc_column_container vc_col-sm-12"><div class="vc_column-inner "><div class="wpb_wrapper">
	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<p><span style="font-weight: 400;">Скажу сразу &#8211; оба архитектурных подхода имеют место быть. И монолит и Serverless, конечно, имеют свои плюсы и минусы. Но как подобрать лучший подход для конкретного ИТ-продукта? Я изучил этот вопрос и решил поделиться своими мыслями. Может быть, получится сэкономить кому-то время в поисках лучшего решения. </span></p>
<p>&nbsp;</p>
<p><span style="font-weight: 400;">Меня зовут Василий Широченко, я backend-разработчик в Konig Labs. Когда я в очередной раз столкнулся с темой выбора архитектурного подхода для приложения в среде Amazon Web Services (про это тоже поговорим), я работал над мобильным приложением для обучения игре на фортепиано. Так что, все выводы в статье будут основаны на реальной практике. Поехали!</span></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b982888c"></div>
</div></div></div></div><div id="tm-row-69dc3b9828ad0" class="vc_row vc_row-outer vc_row-fluid"><div id="tm-column-69dc3b9829019" class="wpb_column vc_column_container vc_col-sm-12"><div class="vc_column-inner "><div class="wpb_wrapper">
	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<h2><span style="font-weight: 400;">Начинаем с требований</span></h2>
<p>&nbsp;</p>
<p><span style="font-weight: 400;">Для начала, давайте разберемся, почему вопрос архитектуры так важен. </span><span style="font-weight: 400;">Планирование архитектуры ИТ-продукта всегда проводится перед стартом разработки. Это критически важно, т.к. как и архитектура здания, архитектура ИТ-продукта не должна “посыпаться” при малейших изменениях, и в перспективе должна выдержать масштабирование, увеличение нагрузки и возрастающую сложность. Стоимость внесения изменений при этом должна оставаться адекватной. </span></p>
<p>&nbsp;</p>
<p><span style="font-weight: 400;">Также, верно подобранная архитектура &#8211; гарантия того, что реализация продукта будет учитывать нюансы всех требований (бизнесовых, нефункциональных, процессных и т.д.). </span></p>
<p>&nbsp;</p>
<p><span style="font-weight: 400;">Теперь немного контекста о проекте, на примере которого будем рассуждать об архитектуре, и его предметной области. Заказчик поставил задачу разработать мобильное приложение, которым люди, интересующиеся игрой на фортепиано, могут пользоваться на платформах iOS и Android. Приложение должно уметь сканировать с листа произведения, записанные в классической музыкальной нотации, и далее распознавать нотный стан, сами ноты, знаки альтерации и т.д. (рис. 1, рис. 2).</span></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b9829619"></div>
</div></div></div></div><div id="tm-row-69dc3b98298ce" class="vc_row vc_row-outer vc_row-fluid same-height vc_row-o-content-bottom vc_row-flex"><div id="tm-column-69dc3b9829f1d" class="wpb_column vc_column_container vc_col-sm-6"><div class="vc_column-inner "><div class="wpb_wrapper"><div class="tm-box-image style-02 tm-animation move-up" id="tm-box-image-69dc3b982a7b7">
	
	
	<div class="content-wrap">
		
<div class="content">

	<div class="images">
					<div class="image">
				<img decoding="async" src="https://koniglabs.ru/wp-content/uploads/2021/08/scanning-50x108.png" data-src="https://koniglabs.ru/wp-content/uploads/2021/08/scanning-80x174.png" class="ll-image unload" alt="scan" width="80" height="174" />			</div>
		
			</div>

	
			<div class="text">Рис. 1. Сканирование с листа</div>	
	</div>
	</div>

	
</div>
</div></div></div><div id="tm-column-69dc3b982e689" class="wpb_column vc_column_container vc_col-sm-6"><div class="vc_column-inner "><div class="wpb_wrapper"><div class="tm-box-image style-02 tm-animation move-up has-image-hover" id="tm-box-image-69dc3b982ed82">
	
	
	<div class="content-wrap">
		
<div class="content">

	<div class="images">
					<div class="image">
				<img fetchpriority="high" decoding="async" src="https://koniglabs.ru/wp-content/uploads/2021/08/recognition-50x28.jpg" data-src="https://koniglabs.ru/wp-content/uploads/2021/08/recognition.jpg" class="ll-image unload" alt="recognition" width="512" height="288" />			</div>
		
					<div class="image-hover">
				<img fetchpriority="high" decoding="async" src="https://koniglabs.ru/wp-content/uploads/2021/08/recognition-50x28.jpg" data-src="https://koniglabs.ru/wp-content/uploads/2021/08/recognition.jpg" class="ll-image unload" alt="recognition" width="512" height="288" />			</div>
			</div>

	
			<div class="text">Рис. 2. Распознавание нот</div>	
	</div>
	</div>

	
</div>
</div></div></div></div><div id="tm-row-69dc3b983c643" class="vc_row vc_row-outer vc_row-fluid"><div id="tm-column-69dc3b983cc2c" class="wpb_column vc_column_container vc_col-sm-12"><div class="vc_column-inner "><div class="wpb_wrapper"><div class="tm-spacer" id="tm-spacer-69dc3b983d087"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<p><span style="font-weight: 400;">Затем, на основании т.н. эталонной записи, пользователь исполняет свой вариант музыкального произведения на фортепиано. После игры система производит поиск ошибок и неточностей в игре учащегося (пользователя). Для каждого пользователя хранится история его попыток, показывается процент точности </span><i><span style="font-weight: 400;">попадания</span></i><span style="font-weight: 400;">. Также есть экран статистики в разрезе дня/недели/месяца/года. В принципе, получается </span><i><span style="font-weight: 400;">несложная </span></i><span style="font-weight: 400;">предметная область. </span></p>
<p>&nbsp;</p>
<p><span style="font-weight: 400;">Конечно, мы понимаем, что приложение само по себе не будет работать, потому как где-то необходимо сохранять прогресс их игры, статистику и другие важные данные. По этим причинам необходимо разработать backend-часть для приложения. </span></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b983d353"></div>
</div></div></div></div><div id="tm-row-69dc3b983d766" class="vc_row vc_row-outer vc_row-fluid"><div id="tm-column-69dc3b983dd0f" class="wpb_column vc_column_container vc_col-sm-12"><div class="vc_column-inner "><div class="wpb_wrapper">
	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<h2><span style="font-weight: 400;">Про выбор архитектуры</span></h2>
<p>&nbsp;</p>
<p><span style="font-weight: 400;">Как я уже говорил, мы будем сравнивать монолитный и Serverless подходы. На самом деле, еще затронем микросервисный, но вскользь. Далее поймете, почему.</span></p>
<p>&nbsp;</p>
<p><span style="font-weight: 400;">Сперва предлагаю кратко пройтись по всем трем подходам, посмотреть на “профпригодность” каждого из них и уже более детально рассмотреть то, что мы выбрали.</span></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b983e3e6"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<h4><span style="font-weight: 400;">Монолитное решение</span></h4>
<p>&nbsp;</p>
<p><span style="font-weight: 400;">Кратко напомним, что подразумевается под монолитным решением. Прежде всего, все </span><i><span style="font-weight: 400;">слои </span></i><span style="font-weight: 400;">приложения находятся в рамках единой кодовой базы, и, как следствие, публикация такого решения производится не частично (например, поменяли только визуальную составляющую), а целиком на все приложение.</span></p>
<p>&nbsp;</p>
<p><span style="font-weight: 400;">Так исторически сложилось, и более того, подтверждено различными опросами среди разработчиков, что монолитная архитектура &#8211; самый распространенный способ построения программного обеспечения. Почему так? Все благодаря своей простоте в разработке и поддержке по сравнению с более сложными подходами (если рассматривать те же микросервисы). Простота заключается в едином развертывании, когда у нас бизнес-логика всего приложения, UI (то, что видит конечный пользователь), хранение данных (база данных) и возможно другие дополнительные компоненты находятся в общем репозитории, разрабатываются совместно и публикуются на сервер в рамках одного процесса. </span></p>
<p>&nbsp;</p>
<p><span style="font-weight: 400;">Конечно, у любого решения есть и минусы. Эволюция любого приложения &#8211; довольно непредсказуемый процесс, потому как появляются новые требования от заказчика. Эти требования необходимо стараться как-то “вписать” в существующее рабочее решение. В случае с монолитом, у разработчиков очень часто появляется соблазн нарушить определенные рамки и конвенции, разработанные на этапе проектирования, вследствие чего система начинает сильно </span><i><span style="font-weight: 400;">вязнуть</span></i><span style="font-weight: 400;">, и вносить все новые и новые изменения становится труднее.</span></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b983e6fb"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<h4><span style="font-weight: 400;">Микросервисы</span></h4>
<p>&nbsp;</p>
<p><span style="font-weight: 400;">Архитектура, построенная на основе микросервисов &#8211; подход, набравший огромную популярность последние лет десять. Весьма распространен в больших проектах с долгим жизненным циклом, когда разработкой занимается несколько команд, каждая из которых отвечает за свои несколько микросервисов. В нашем блоге уже была статья про микросервисы, если интересно вникнуть в детали, читайте здесь: <a href="https://koniglabs.ru/cqrs-microservices/" target="_blank" rel="noopener noreferrer">Микросервисы и CQRS: оптимизируем затраты на продукт</a>.</span></p>
<p>&nbsp;</p>
<p><span style="font-weight: 400;">Среди явных плюсов: система разбита на модули, каждый из которых поддерживается определенной командой разработки, независимые публикации отдельно взятых микросервисов (допустим, в системе развернуто два микросервиса A и B, мы можем обновить микросервис B, не затронув при этом микросервис A). В то же время, приходится мириться с определенными ограничениями и иметь в виду, например, что для качественной разработки требуется высокая квалификация специалистов. Плюс ко всему, не стоит забывать и о том, что, несмотря на кажущуюся гибкость в разделении бизнес-процессов на так называемые</span><i><span style="font-weight: 400;"> ограниченные контексты</span></i><span style="font-weight: 400;">, стоит обязательно позаботиться о системе логирования и мониторинга (о записи действий приложения в специальный файл и о сборе, хранении метрик по инфраструктуре приложения). Более того, микросервисы должны уметь </span><i><span style="font-weight: 400;">общаться </span></i><span style="font-weight: 400;">друг с другом &#8211; реализуется это посредством различных протоколов, таких как </span><i><span style="font-weight: 400;">http</span></i><span style="font-weight: 400;">, </span><i><span style="font-weight: 400;">amqp </span></i><span style="font-weight: 400;">и других. Т.е., в отличие от монолита, здесь дополнительно нужно продумать и реализовать API.</span></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b983e9db"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<h4><span style="font-weight: 400;">Serverless</span></h4>
<p>&nbsp;</p>
<p><span style="font-weight: 400;">Serverless &#8211; данный подход стал применяться сравнительно недавно (последние несколько лет). Его суть в том, что облачный провайдер (по примеру AWS, Azure и др.) предлагает воспользоваться т. н. бессерверными вычислениями &#8211; пользователям теперь не надо заботиться о конфигурировании и поддержке сервера &#8211; за вас все делает провайдер (сколько ресурсов потребуется &#8211; столько провайдер и предоставит). </span></p>
<p>&nbsp;</p>
<p><span style="font-weight: 400;">Этот подход достаточно новый. С одной стороны, простота &#8211; главное его преимущество перед остальными подходами. Здесь мы имеем в виду удобство работы с инфраструктурой (сервисы, службы, логирование, мониторинг, вертикальное и горизонтальное масштабирование).</span></p>
<p>&nbsp;</p>
<p><span style="font-weight: 400;">С другой стороны, есть палка о двух концах &#8211; это управление бюджетом. Провайдер предлагает определенные расценки за использование ресурсов, которые можно посчитать в </span><i><span style="font-weight: 400;">калькуляторе </span></i><span style="font-weight: 400;">на сайте. Вот только есть нюанс динамически выделяемых ресурсов &#8211; к этому вопросу стоит относиться крайне внимательно &#8211; об этом будет рассказано более подробно ниже. Так что советуем не закрывать статью, вдруг дальше будет написано, где находится Янтарная комната… 🙂</span></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b983ecf8"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<h4><span style="font-weight: 400;">Наши мысли</span></h4>
<p>&nbsp;</p>
<p><span style="font-weight: 400;">Итак, что мы имеем? Монолит как самый популярный вариант, микросервисы, как пример слабо связанной архитектуры и serverless &#8211; эдакий многообещающий вариант построения приложений. Ах, да, чуть не забыли &#8211; команду backend-разработчиков из двух человек 🙂</span></p>
<p><span style="font-weight: 400;"><br />
</span> <span style="font-weight: 400;">Посовещавшись, пришли к выводу, что микросервисы мы отметаем по причине того, что бизнес-модель не является </span><i><span style="font-weight: 400;">сложной </span></i><span style="font-weight: 400;">(даже если забегать вперед с </span><i><span style="font-weight: 400;">возможными </span></i><span style="font-weight: 400;">дополнениями) в связи с четко поставленными требованиями к конечному продукту для пользователей. Да, зарекаться не стоит, но взвесив все “за” и “против” решили оставить для более детального рассмотрения два варианта: монолитное решение и serverless.</span></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b983ef82"></div>
</div></div></div></div><div id="tm-row-69dc3b983f229" class="vc_row vc_row-outer vc_row-fluid"><div id="tm-column-69dc3b983f8d8" class="wpb_column vc_column_container vc_col-sm-12"><div class="vc_column-inner "><div class="wpb_wrapper">
	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<h2><span style="font-weight: 400;">Использование монолита и serverless: детально</span></h2>
<p><span style="font-weight: 400;">Прежде всего, для наглядности приведем сводную таблицу со списком основных сервисов, которые предоставляет AWS. Каждый из этих сервисов может быть использован в любом из предложенных архитектурных решений. Почему AWS &#8211; спросите вы? Все дело в том, что во-первых, заказчик был заинтересован в использовании инфраструктуры AWS, во-вторых, действительно AWS является лидером среди облачных провайдеров во всем мире.</span></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b983ff58"></div>
<div class="tm-image tm-animation move-up" id="tm-image-69dc3b98400eb">
			<div class="image"><img decoding="async" src="https://koniglabs.ru/wp-content/uploads/2021/08/servisy-aws-50x28.png" data-src="https://koniglabs.ru/wp-content/uploads/2021/08/servisy-aws.png" class="ll-image unload" alt="AWS services" width="1202" height="694" /></div>	</div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<p><em><span style="font-weight: 400;">Рис. 3. Сервисы AWS, необходимые в backend-части</span></em></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b9846a5a"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<p><span style="font-weight: 400;">Позже мы более детально посмотрим на их использование и какое место каждый из этих элементов занимает в построении архитектуры приложения.</span></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b9846ca5"></div>
</div></div></div></div><div id="tm-row-69dc3b9846ef7" class="vc_row vc_row-outer vc_row-fluid"><div id="tm-column-69dc3b98475d4" class="wpb_column vc_column_container vc_col-sm-12"><div class="vc_column-inner "><div class="wpb_wrapper">
	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<h3><span style="font-weight: 400;">Монолитное решение</span></h3>
<h4><span style="font-weight: 400;">Инфраструктурный вопрос</span></h4>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b9847cc8"></div>
<div class="tm-image tm-animation move-up" id="tm-image-69dc3b9847e57">
			<div class="image"><img decoding="async" src="https://koniglabs.ru/wp-content/uploads/2021/08/example-of-backend-architecture-50x45.png" data-src="https://koniglabs.ru/wp-content/uploads/2021/08/example-of-backend-architecture.png" class="ll-image unload" alt="backend-architecture" width="512" height="466" /></div>	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b984f78b"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<p><em><span style="font-weight: 400;">Рис. 4. Предложенный вариант архитектуры backend’а, построенной на базе монолита</span></em></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b984fa46"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<p><span style="font-weight: 400;">Из схемы на рис. 4 видно, что в системе есть мобильный клиент. Далее из мобильного приложения отправляется запрос в облачную инфраструктуру AWS, а конкретно,в виртуальную машину Ec2 instance. Запрос первым делом попадает на сервер nginx, который отвечает за перенаправление запроса в наше приложение. Что собой представляет приложение? </span></p>
<p>&nbsp;</p>
<p><span style="font-weight: 400;">Это приложение, написанное на Python, со всеми необходимыми нам endpoint’ами, бизнес-логикой и т.д., запущенное и работающее в Docker-контейнере. Все остальные необходимые сервисы &#8211; это просто компоненты, созданные однажды. Хранилище файлов можно удобным образом выделить в S3. В качестве сервера БД выступает RDS (Relational Database Service). Так как в системе предусмотрена отправка email-уведомлений, то можно использовать либо Sendgrid, как на схеме, либо AWS SES (Simple Email Service). </span><span style="font-weight: 400;"><br />
</span></p>
<p>&nbsp;</p>
<p><i><span style="font-weight: 400;">P.S. Забегая вперед, хочется отметить, что на схеме не учтен момент с алгоритмом нахождения ошибок в игре пользователя (SMR). Предполагалось, что этот блок будет являться частью API, но после замеров нагрузки стало ясно, что такие тяжелые вычисления необходимо выносить в специальный сервис. Поэтому дальше в оценке можно будет увидеть этот дополнительный пункт.</span></i></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b984fccb"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<h4><span style="font-weight: 400;">Оценка трудозатрат на разработку (с учетом на одного разработчика)</span></h4>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b985000d"></div>
<div class="tm-image tm-animation move-up" id="tm-image-69dc3b9850163">
			<div class="image"><img decoding="async" src="https://koniglabs.ru/wp-content/uploads/2021/08/trudozatraty-1-50x10.png" data-src="https://koniglabs.ru/wp-content/uploads/2021/08/trudozatraty-1.png" class="ll-image unload" alt="Трудозатраты монолит" width="1058" height="232" /></div>	</div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<p><em><span style="font-weight: 400;">Рис. 5. Трудозатраты на разработку монолитного решения</span></em></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b9858ce0"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<p><span style="font-weight: 400;">Пока что эти цифры нам ни о чем не говорят, чуть позже сравним их со значениями для serverless-решения.</span></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b98590dc"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<h4><span style="font-weight: 400;">Затраты на хостинг</span></h4>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b98594ee"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<p><span style="font-weight: 400;">* Исходим из расчета на 1000 активных пользователей системы</span></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b98598cd"></div>
<div class="tm-image tm-animation move-up" id="tm-image-69dc3b9859b46">
			<div class="image"><img decoding="async" src="https://koniglabs.ru/wp-content/uploads/2021/08/zatraty-na-hosting-50x22.png" data-src="https://koniglabs.ru/wp-content/uploads/2021/08/zatraty-na-hosting.png" class="ll-image unload" alt="Затраты на хостинг" width="1169" height="530" /></div>	</div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<p><em><span style="font-weight: 400;">Рис. 6. Затраты на хостинг</span></em></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b98620ca"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<p><b>Итого: ~ 265$ / месяц</b></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b98624ac"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<h5><span style="font-weight: 400;">Плюсы</span></h5>
<ol>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Традиционная кодовая база. Можем сменить хоста в любой момент и практически ничего менять не придется</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Упрощенная схема инфраструктуры (общий сервер почти для всего, если не используем выделенные сегменты инфраструктуры)</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Ec2 запущен в режиме 24/7, поэтому нет проблемы «холодного старта»</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Довольно предсказуемая ценовая политика, что весьма важно!</span></li>
</ol>
<p>&nbsp;</p>
<h5><span style="font-weight: 400;">Минусы</span></h5>
<ol>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Повышенная ответственность со стороны разработки: настройка веб-сервера nginx, настройка логирования, настройка мониторинга сервисов приложения. Плюс необходима соответствующая квалификация разработчиков.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Масштабирование. Нет гарантии, что однажды не упремся в пороговое значение.  Для горизонтального масштабирования необходима настройка, что само по себе непросто (стоимость будет увеличиваться в разы).</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Если захотелось бесплатно поднять БД, то придется настроить бэкапы и мониторинг самостоятельно. Это сложнее, чем просто «выставить галочку» в RDS «мне нужны бэкапы каждый день в 24:00», а значит и стоимость работы все равно будет недешевой. </span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">При изменении чего-либо в конфигурации сервера не всегда получается понять, что пошло не так</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Авторизацию в серверной части, например, придется реализовывать самостоятельно</span></li>
</ol>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b98629f3"></div>
</div></div></div></div><div id="tm-row-69dc3b9862f29" class="vc_row vc_row-outer vc_row-fluid"><div id="tm-column-69dc3b9863a53" class="wpb_column vc_column_container vc_col-sm-12"><div class="vc_column-inner "><div class="wpb_wrapper">
	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<h3><span style="font-weight: 400;">Serverless</span></h3>
<h4><span style="font-weight: 400;">Инфраструктурный вопрос</span></h4>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b9864500"></div>
<div class="tm-image tm-animation move-up" id="tm-image-69dc3b9864803">
			<div class="image"><img decoding="async" src="https://koniglabs.ru/wp-content/uploads/2021/08/example-of-serverless-architecture-50x49.png" data-src="https://koniglabs.ru/wp-content/uploads/2021/08/example-of-serverless-architecture.png" class="ll-image unload" alt="Example of serverless-architecture" width="512" height="509" /></div>	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b986da1b"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<p><em><span style="font-weight: 400;">Рис. 7. Архитектура serverless backend’а приложения</span></em></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b986dd4c"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<p><span style="font-weight: 400;">В данном случае система выглядит немного интересней 🙂 </span></p>
<p><span style="font-weight: 400;">Нет привычных nginx’а, Docker’а, вместо них появились какие-то Lambda с нумерацией от 1 до N, Step Function, Cognito… На самом деле все не очень сложно. Если вспомнить, что serverless тесно связано с понятием FaaS, то можно увидеть, что вместо единого API у нас получились разрозненные lambda-функции, каждая из которых отвечает за свой endpoint. Например, чтобы создать пользователя в системе (выполнить POST-запрос /users) мы вызываем определенную lambda-функцию, задача которой создавать пользователей &#8211; ничего более!</span></p>
<p><span style="font-weight: 400;">Тот блок, который помечен как Step Function &#8211; </span><i><span style="font-weight: 400;">долгая </span></i><span style="font-weight: 400;">задача, выполняющаяся асинхронно (</span><i><span style="font-weight: 400;">дело в том, что мы не можем блокировать выполнение http-запроса до момента получения результата, потому как алгоритм нахождения ошибок может выполняться десятки секунд, а пользователь не очень хочет видеть заблокированный экран приложения</span></i><span style="font-weight: 400;">).</span></p>
<p><span style="font-weight: 400;">Cognito &#8211; мощный сервис авторизации пользователей в системе.</span></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b986dfd6"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<h4><span style="font-weight: 400;">Оценка трудозатрат на разработку (с учетом одного разработчика)</span></h4>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b986e1f9"></div>
<div class="tm-image tm-animation move-up" id="tm-image-69dc3b986e3a9">
			<div class="image"><img decoding="async" src="https://koniglabs.ru/wp-content/uploads/2021/08/trudozatraty-serverless-50x11.png" data-src="https://koniglabs.ru/wp-content/uploads/2021/08/trudozatraty-serverless.png" class="ll-image unload" alt="Трудозатраты serverless" width="1057" height="235" /></div>	</div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<p><em><span style="font-weight: 400;">Рис. 8. Трудозатраты на разработку</span></em></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b9876319"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<p><span style="font-weight: 400;">Чуть позже сравним 🙂</span></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b987654b"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<h4><span style="font-weight: 400;">Затраты на хостинг</span></h4>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b9876793"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<p><span style="font-weight: 400;">* Исходим из расчета на 1000 активных пользователей системы</span></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b9876a1d"></div>
<div class="tm-image tm-animation move-up" id="tm-image-69dc3b9876b4c">
			<div class="image"><img decoding="async" src="https://koniglabs.ru/wp-content/uploads/2021/08/zatraty-na-hosting-serverless-50x20.png" data-src="https://koniglabs.ru/wp-content/uploads/2021/08/zatraty-na-hosting-serverless.png" class="ll-image unload" alt="Затраты на хостинг serverless" width="1202" height="502" /></div>	</div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<p><em><span style="font-weight: 400;">Рис. 9. Затраты на хостинг &#8211; serverless</span></em></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b987e811"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<p><b>Итого: ~ 250$ / месяц</b></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b987eb1c"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<h5><span style="font-weight: 400;">Плюсы</span></h5>
<ol>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Подход развертывания конфигурации через</span><i><span style="font-weight: 400;"> template.yaml</span></i><span style="font-weight: 400;">, который, имеет очевидные достоинства в виде четко структурированного файла с описанием AWS инфраструктуры + любые изменения отслеживаются Git’ом (можно выявить проблемы, связанные с изменением конфигурации) + хорошо документировано на официальном сайте.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Lambda-функции являются изолированными, удобно тестируются, для каждой из них создана своя группа для мониторинга.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Cloud Watch – очень удобный инструмент для сбора логов и мониторинга сервисов AWS. Для Python есть мощная библиотека boto3, которая позволяет выполнять любые операции с сервисами AWS.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Удобный CI/CD (с использованием environment-переменных): dev-stack/prod-stack/etc.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Мы не заботимся об обслуживании lambda-функций, мы лишь пишем код и точка. Хотя нет, не точка – еще платим деньги, сколько – не известно – вот такая простая математика, все зависит от ситуации. Тогда почему этот пункт в плюсах?..</span></li>
</ol>
<h5></h5>
<h5><span style="font-weight: 400;">Минусы</span></h5>
<ol>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Высокий порог вхождения при отсутствии опыта. </span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">«Холодный старт» у lambda-функций – специфическое ограничение, для нашего проекта некритично.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Грамотная настройка IAM-политик и их полное соблюдение требуют соответствующей квалификации специалистов, что есть не всегда.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Кодовая база достаточно плотно завязана на AWS-провайдере.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Зачастую, невозможно предсказать нагрузку и предотвратить автомасштабирование (пример – черная пятница), что ведет к непредсказуемым затратам.</span></li>
</ol>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b987f512"></div>
</div></div></div></div><div id="tm-row-69dc3b987f9d0" class="vc_row vc_row-outer vc_row-fluid"><div id="tm-column-69dc3b98804d0" class="wpb_column vc_column_container vc_col-sm-12"><div class="vc_column-inner "><div class="wpb_wrapper">
	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<h2><span style="font-weight: 400;">Подведение итогов</span></h2>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b9880cac"></div>
<div class="tm-image tm-animation move-up" id="tm-image-69dc3b9880de2">
			<div class="image"><img decoding="async" src="https://koniglabs.ru/wp-content/uploads/2021/08/sravnenie-stoimostej-50x19.png" data-src="https://koniglabs.ru/wp-content/uploads/2021/08/sravnenie-stoimostej.png" class="ll-image unload" alt="Сравнение стоимостей" width="1042" height="402" /></div>	</div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<p><em><span style="font-weight: 400;">Рис. 10. Сравнение стоимостей</span></em></p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b988912a"></div>

	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<p><span style="font-weight: 400;">Итак, как можно видеть из таблицы (рис. 10), стоимость инфраструктуры не сильно разнится, если смотреть со стороны стоимости разработки. Зато стоимость работ оценена практически в два раза больше. Это весомый аргумент в пользу монолитного решения. Плюс ко всему, как говорилось ранее, это и простота, и меньший порог вхождения и т.д. Тем не менее, есть несколько пунктов, которые перевесили наше решение в сторону выбора serverless: </span></p>
<p>&nbsp;</p>
<ul>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Заказчик имеет положительный опыт разработки с использованием инфраструктуры AWS  и настаивает на serverless;</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">решение выглядит масштабируемым, т. е. со стороны разработки «практически» не потребуется ничего предпринимать с ростом нагрузки. Те затраты, которые понес заказчик в начале, с лихвой окупятся при масштабировании. А это значительный плюс по сравнению с монолитным решением;</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">SAM &#8211; об этом будет рассказано более подробно в следующей в статье;</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Со стороны команды разработки, действительно хотелось опробовать современный подход в разработке, поэтому остановились на serverless 🙂</span></li>
</ul>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b9889512"></div>
</div></div></div></div><div id="tm-row-69dc3b9889789" class="vc_row vc_row-outer vc_row-fluid"><div id="tm-column-69dc3b988a01c" class="wpb_column vc_column_container vc_col-sm-12"><div class="vc_column-inner "><div class="wpb_wrapper"><div class="tm-button-wrapper tm-animation move-up" id="tm-button-69dc3b988ab88">
		<a class="tm-button style-flat tm-button-nm tm-button-" href="https://b24-9tnih8.bitrix24.site/crm_form4/"
		target=" _blank"	>

		
						<span class="button-text" data-text="Консультация по архитектуре ПО">
				Консультация по архитектуре ПО			</span>
			
		

	</a>
</div>
<div class="tm-spacer" id="tm-spacer-69dc3b988acc9"></div>
</div></div></div></div><div id="tm-row-69dc3b988af08" class="vc_row vc_row-outer vc_row-fluid"><div id="tm-column-69dc3b988b4fc" class="wpb_column vc_column_container vc_col-sm-12"><div class="vc_column-inner "><div class="wpb_wrapper">
	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			
		</div>
	</div>
</div></div></div></div>
<p>The post <a href="https://koniglabs.ru/serverless-vs-monolit/">Serverless vs монолит: что выбрать в среде AWS?</a> appeared first on <a href="https://koniglabs.ru">König Labs</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://koniglabs.ru/serverless-vs-monolit/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Если вам нужен архитектор, то у меня для вас плохие новости</title>
		<link>https://koniglabs.ru/nuzhen-arhitektor/</link>
					<comments>https://koniglabs.ru/nuzhen-arhitektor/#comments</comments>
		
		<dc:creator><![CDATA[Alexey Palatkin]]></dc:creator>
		<pubDate>Fri, 04 Jun 2021 15:08:49 +0000</pubDate>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[архитектура]]></category>
		<guid isPermaLink="false">https://koniglabs.com/?p=5925</guid>

					<description><![CDATA[<p>The post <a href="https://koniglabs.ru/nuzhen-arhitektor/">Если вам нужен архитектор, то у меня для вас плохие новости</a> appeared first on <a href="https://koniglabs.ru">König Labs</a>.</p>
]]></description>
										<content:encoded><![CDATA[<div id="tm-row-69dc3b9890fc9" class="vc_row vc_row-outer vc_row-fluid"><div id="tm-column-69dc3b989156e" class="wpb_column vc_column_container vc_col-sm-12"><div class="vc_column-inner "><div class="wpb_wrapper">
	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<h3><span style="font-weight: 300;">Начнем с начала</span></h3>
<p>&nbsp;</p>
<p>Для начала давайте, как всегда, определимся с понятиями. Кто такой вообще Архитектор?<br />
Если на пальцах — то это роль, отвечающая за построение правильной архитектуры программной системы. Что такое «правильная архитектура» — повод для нескончаемых холиваров. Что такое «программная система» — тоже не вполне определено, т.к. надо учитывать размер системы, уровень абстракции и ширину рассмотрения. В общем, на пальцах понятно только, что это роль, и что это про архитектуру.</p>
<p>&nbsp;</p>
<p>На практике, кстати, уровень понимания этой роли обычно именно такой. Чёрт его знает, кто это должен быть и чем заниматься. Никто ведь не лезет в описания System Architect / Solution Architect по тому же SAFe. Просто нанимают какого-то башковитого мужика и говорят: вот, будешь у нас Архитектором.</p>
<p>&nbsp;</p>
<p>Ну, а чем обычно занимается этот Архитектор? Понятное дело, что если это какая-то громадная система уровня информационной системы министерства, или что-то с кучей интеграций — скажем, крупный проект SAP — то там бывает, что и несколько Архитекторов трудятся… в основном над документацией. И следят, чтобы все договоренности, описанные в этой документации, соблюдались. И бьют по кривым рукам коллег из параллельных структур за то, что те не соблюдают оговоренные программные интерфейсы. И пишут, пишут, пишут документацию.</p>
<p>&nbsp;</p>
<p>Ну, а в обычной продуктовой или заказной разработке? Как роль — безусловно, Архитектор нужен вообще в любом проекте. В начале. Ну, и немного — иногда исчезающе немного — по ходу работы над проектом. Чтобы следить, не нарушаем ли принятых архитектурных решений, и иногда эти решения обновлять под давлением обстоятельств.</p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b9891c28"></div>
</div></div></div></div><div id="tm-row-69dc3b9891e64" class="vc_row vc_row-outer vc_row-fluid"><div id="tm-column-69dc3b9892498" class="wpb_column vc_column_container vc_col-sm-12"><div class="vc_column-inner "><div class="wpb_wrapper">
	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<h3><span style="font-weight: 300;">Плохая новость №1</span></h3>
<p>&nbsp;</p>
<p>Но ведь бывает, что на роли Архитектора сидит действительно башковитый, опытный товарищ, и фуллтайм что-то делает сразу во всех проектах компании. И без него — никуда.</p>
<p>&nbsp;</p>
<p>Вот это как раз и есть первая плохая новость. Если разработчики проектов настолько некомпетентны, что не умеют / не могут выстроить архитектуру своего проекта — настолько некомпетентны, что за них это делать приходится отдельному башковитому мужичку — то какой же код они потом будут писать? Архитектор ведь не будет следить за каждой реализацией класса или интерфейса… или будет? 🙂</p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b9892a45"></div>
</div></div></div></div><div id="tm-row-69dc3b9892d96" class="vc_row vc_row-outer vc_row-fluid"><div id="tm-column-69dc3b9893233" class="wpb_column vc_column_container vc_col-sm-12"><div class="vc_column-inner "><div class="wpb_wrapper">
	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<h3><span style="font-weight: 300;">Плохая новость №2</span></h3>
<p>&nbsp;</p>
<p>Есть такой забавный подход к разработке ПО — условно можно назвать «подход Звезда» — когда на работу берут мощного опытного парня, ставят его в центр, а вокруг образуется звезда из кодеров. Уже не разработчиков — а именно кодеров. Тимлид / Архитектор генерит UML диаграммы с детализацией вплоть до конкретных классов и интерфейсов — а кодеры бездумно реализуют его концепцию. Кодеру вообще не надо думать — за него думает Архитектор. Более того — кодер НИКОГДА и не научится думать с таким подходом. А если даже и умел когда-то думать — то со временем разучится.</p>
<p>&nbsp;</p>
<p>И это — вторая плохая новость. Если вы централизуете принятие архитектурных решений — вам не только придётся всё глубже и глубже погружать Архитектора в каждый проект. Вы ещё и своих разработчиков разучите принимать самостоятельные решения, да и вообще думать головой.</p>
<p>&nbsp;</p>
<p>Правда, нынче придумали микросервисы. И я тихо подозреваю, что популярность микросервисов связана именно с проблемами индустрии, а не с тем, что это такой уж офигенный подход в принципе. Если вкратце — то микросервисный подход позволяет посадить в центре Архитектора, но ему надо будет детализировать уже не на уровне классов, а на уровне модулей и интерфейсов между ними. Это супер удобно, учитывая, что все разрабы — удаленщики, друг с другом общаются мало или вообще никак, да и живут / работают в абсолютно разных часовых поясах. Ну и ещё, положа руку на сердце, — потому что хорошего разработчика найти тяжело, воспитать еще тяжелее, а микросервис реализовать можно и незнакомому индусу поручить.</p>
<p>&nbsp;</p>
<p>В итоге все проблемы разработки убираются с уровня модулей — микросервисов — и перекладываются на уровень выше. На уровень согласования работы модулей, data flow, взаимного оповещения и так далее. То есть на традиционно гораздо более проблемный уровень. На котором, к тому же, приходится работать куда более квалифицированным и дорогостоящим специалистам. А уж при развертывании всего этого колхоза у DevOps проблем столько, что из отложенных кирпичей можно каждый день строить новый дом. Зато есть куда приложить нашего Архитектора. Конечно, при этом разработчики снова будут превращаться в бездумных кодеров — ну, да это их проблемы, верно?</p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b9893903"></div>
</div></div></div></div><div id="tm-row-69dc3b9893b58" class="vc_row vc_row-outer vc_row-fluid"><div id="tm-column-69dc3b98940ef" class="wpb_column vc_column_container vc_col-sm-12"><div class="vc_column-inner "><div class="wpb_wrapper">
	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<h3><span style="font-weight: 300;">Плохая новость №3</span></h3>
<p>&nbsp;</p>
<p>Есть ещё так называемые Архитекторы-Астронавты. Любители накручивать абстракции на абстракции, намазывать сложность поверх сложности, и так далее. Очень хорошо их описал Джоэль Спольски ещё в 2001-м году. Ну, действительно, вы же взяли очень умного парня на фуллтайм. Надо же ему чем-то заняться… не код же писать, в самом деле. Вот он и ходит туда-сюда, задумчивый. Продумывает очередную гениальную идею реализации стандартной, в общем-то, функциональности новым, революционным методом. Очень сложным, разумеется. Он же не дурак, чтобы делать просто. И это — третья плохая новость. Такой человек не просто будет бесполезно жрать огромную зарплату — он ещё и вреда нанесет столько, что потом с двумя бригадами ассенизаторов не разгребешь.</p>
<p>&nbsp;</p>
<p>В общем, в таких надо стреля… эмм, увольнять их надо без предупреждения.</p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b9894662"></div>
</div></div></div></div><div id="tm-row-69dc3b989487f" class="vc_row vc_row-outer vc_row-fluid"><div id="tm-column-69dc3b9894e71" class="wpb_column vc_column_container vc_col-sm-12"><div class="vc_column-inner "><div class="wpb_wrapper">
	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<h3><span style="font-weight: 300;">Ищем решение</span></h3>
<p>&nbsp;</p>
<p>А что же делать? — спросит удивлённый читатель.</p>
<p>&nbsp;</p>
<p>На это есть два ответа: простой и сложный. Простой — брать на вооружение подход «Звезда», но делать это осознанно. Понимая, что микросервисы могут принести в дальней перспективе множество проблем. Понимая, что вы делаете своего Архитектора узким местом, бутылочным горлышком, повышая Bus Factor. Понимая, что вы низводите своих разработчиков до уровня кодеров, и им это не очень-то понравится. Понимая, что проблема воспитания кадров встанет ещё сильнее, и подходить к её решению придётся очень серьёзно.</p>
<p>&nbsp;</p>
<p>Просто, не правда ли? 🙂</p>
<p>&nbsp;</p>
<p>Ну, а сложный ответ: это учиться строить полноценные команды с Тим/Тех-лидами во главе, где каждый человек носит гордое звание разработчика и учится принимать ответственные решения на своём уровне понимания. И делать это в условиях удаленной работы, осложненной коронаситуацией. Что, собственно, и делает этот ответ сложным.</p>

		</div>
	</div>
<div class="tm-spacer" id="tm-spacer-69dc3b98954f8"></div>
</div></div></div></div><div id="tm-row-69dc3b9895725" class="vc_row vc_row-outer vc_row-fluid"><div id="tm-column-69dc3b9895baa" class="wpb_column vc_column_container vc_col-sm-12"><div class="vc_column-inner "><div class="wpb_wrapper"><div class="tm-button-wrapper tm-animation move-up" id="tm-button-69dc3b989616e">
		<a class="tm-button style-flat tm-button-nm tm-button-" href="https://b24-9tnih8.bitrix24.site/crm_form4/"
		target=" _blank"	>

		
						<span class="button-text" data-text="Нужен архитектор!">
				Нужен архитектор!			</span>
			
		

	</a>
</div>
<div class="tm-spacer" id="tm-spacer-69dc3b9896293"></div>
</div></div></div></div>
<p>The post <a href="https://koniglabs.ru/nuzhen-arhitektor/">Если вам нужен архитектор, то у меня для вас плохие новости</a> appeared first on <a href="https://koniglabs.ru">König Labs</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://koniglabs.ru/nuzhen-arhitektor/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Микросервисы и CQRS: оптимизируем затраты на продукт</title>
		<link>https://koniglabs.ru/cqrs-microservices/</link>
					<comments>https://koniglabs.ru/cqrs-microservices/#comments</comments>
		
		<dc:creator><![CDATA[Alexey Palatkin]]></dc:creator>
		<pubDate>Tue, 07 Apr 2020 14:50:23 +0000</pubDate>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[cqrs]]></category>
		<category><![CDATA[микросервисы]]></category>
		<category><![CDATA[разработка микросервисов]]></category>
		<guid isPermaLink="false">https://koniglabs.com/?p=3962</guid>

					<description><![CDATA[<p>The post <a href="https://koniglabs.ru/cqrs-microservices/">Микросервисы и CQRS: оптимизируем затраты на продукт</a> appeared first on <a href="https://koniglabs.ru">König Labs</a>.</p>
]]></description>
										<content:encoded><![CDATA[<div id="tm-row-69dc3b989fac9" class="vc_row vc_row-outer vc_row-fluid"><div id="tm-column-69dc3b98a059b" class="wpb_column vc_column_container vc_col-sm-12"><div class="vc_column-inner "><div class="wpb_wrapper">
	<div class="wpb_text_column wpb_content_element  tm-animation move-up" >
		<div class="wpb_wrapper">
			<p><em>Эта статья для представителей бизнеса с запросом на разработку ИТ-решения, чьи технические знания не актуальны или недостаточны для принятия обоснованных решений. То есть для тех, кто отошел от “дел технических” и работает на стороне стратегии, маркетинга или клиентского сервиса. Мы подскажем, как запустить продукт и избежать неоправданных затрат, связанных с архитектурой. А также посмотрим, как использование CQRS поможет при реализации функционала в разных клиентах приложения, и являются ли микросервисы той самой панацеей.</em></p>
<p> </p>
<h2 class="wp-block-heading">Почему архитектура важна для бизнеса</h2>
<p>Ни один программный продукт невозможно рассматривать в отрыве от конкретных бизнес-процессов. Софт существует не сам по себе, а для того чтобы автоматизировать процессы, улучшить пользовательский опыт, помочь бизнесу добиться определенных показателей. Архитектура ИТ-решения строится с учетом бизнес-архитектуры. Таким образом, она является воплощением общего видения бизнеса и закладывает предпосылки для развития, масштабирования и оптимизации продукта.</p>
<p>&nbsp;</p>
<p>Итак, какие преимущества дает грамотная и своевременная проработка архитектуры ИТ-решения?</p>
<p> </p>
<h3 class="wp-block-heading">Снижение стоимости разработки</h3>
<p>Архитектура снижает стоимость разработки не только за счет переиспользования элементов, но и за счет повышения эффективности коммуникаций и работы команды. Это можно делать в рамках одного модуля или проекта и таким образом снижать стоимость всей системы. Если не позаботиться о том, чтобы заложить архитектуру, то на более поздних этапах внесение изменений может быть дорогостоящим.</p>
<p> </p>
<h3 class="wp-block-heading">Амортизация рисков</h3>
<p>То, как система будет выглядеть, из каких частей состоять, с какими бизнес-процессами пересекаться и взаимодействовать, определяется архитектурой. Экономия средств происходит за счет того, что архитектурное проектирование указывает на риски и помогает избежать таковых на ранних стадиях. Это намного дешевле последующего устранения последствий.</p>
<p> </p>
<h3 class="wp-block-heading">Ускорение выхода на рынок</h3>
<p>Возможность сокращать время выхода на рынок особенно важна в условиях повышенной конкуренции. Бизнес, который способен удовлетворять потребности рынка быстрее и лучше других, получает конкурентное преимущество</p>
<p> </p>
<h3 class="wp-block-heading">Готовность бизнеса к изменениям</h3>
<p>Сегодня бизнес оперирует в условиях быстро меняющихся рынков. Способность адаптировать бизнес-модель и быстро вносить изменения в продукт завязано на архитектуру. Если карта развития архитектуры не будет выстроена в соответствии с картой развития ИТ-продукта и бизнеса, то эта способность будет утрачена.</p>
<p> </p>
<h3 class="wp-block-heading">Выбор оптимальных технических решений</h3>
<p>Архитектура продукта диктует ряд технических решений. Выбор языка программирования, платформы, фреймворка, инструментов разработки и т.д. определяет уровень текущих и будущих затрат. Технические средства исполнения определяют скорость изменений в продукте. Это весьма критично, в таких ситуациях, когда MVP не справляется с наплывом клиентов, выдавая отказы.</p>
<p> </p>
<h2 class="wp-block-heading">Две крайности при разработке</h2>
<p>При создании программных продуктов возникают вопросы:</p>
<p> </p>
<ul class="wp-block-list">
<li>Когда именно стоит приступать к архитектурному проектированию?</li>
<li>Какой стиль и шаблоны использовать?</li>
<li>Насколько тщательно следует прорабатывать архитектурные решения?</li>
</ul>
<p>&nbsp;</p>
<p>Мы сталкивались с разными подходами и мнениями. На одном конце спектра  &#8211; “в MVP архитектура не нужна”, на другом &#8211;  “с самого начала нужно проработать микросервисы, чтобы обеспечить гибкость и масштабируемость продукта”. Это две крайности, которые могут стоить бизнесу больших денег. Ниже рассмотрим, как выбрать золотую середину.</p>
<p> </p>
<h3 class="wp-block-heading">Типичная ситуация: “большой комок грязи”</h3>
<p>К “большому комку грязи” &#8211;  программной системе с нераспознаваемой архитектурой &#8211; приходят постепенно. А начинается все с запроса от бизнеса, который звучит примерно так: “Нам бы побыстрее выйти в релиз и получить первых клиентов. А потом уже давайте думать, что делать с клиентами и как улучшать продукт”.</p>
<p>&nbsp;</p>
<p>Для этого очень часто используется эволюционный подход. Он заключается в том, что сначала разрабатывается MVP (минимальный жизнеспособный продукт) без анализа нефункциональных требований и проработки архитектуры. Затем начинается долгий этап доработок. В результате система плохо функционирует и развивать ее все сложнее.</p>
<p> </p>
<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img decoding="async" class="wp-image-3990 aligncenter" src="https://koniglabs.com/wp-content/uploads/2020/04/big-ball-of-mud-3000x1477.png" alt="большой комок грязи" width="568" height="276" /></figure>
</div>
<p>Мы видели много случаев отсутствия регулярной практики по архитектурному проектированию. И каждый раз это неизбежно приводило к плачевным результатам. Например, наплыв первых клиентов приводит к сбоям в работе системы, т. к. она не выдерживает высокой нагрузки. Система “валится”. Команда “тушит пожары”. Клиенты недовольны и уходят. В результате бизнес рушится, не сумев масштабироваться.</p>
<p>&nbsp;</p>
<p>В другом случае возникает необходимость переписывания системы целиком. На это тратится больше сил и средств, чем на всю предыдущую разработку. В таких случаях приходится переучивать всех пользователей для работы с новой системой. Это в свою очередь негативно отражается на лояльности пользователей и потенциале последующих продаж.</p>
<p> </p>
<h3 class="wp-block-heading">Микросервисы не спасут</h3>
<p> </p>
<h4 class="wp-block-heading">Что такое микросервисы</h4>
<p>Существуют разные типы, способы и паттерны моделирования архитектуры. Микросервисы &#8211; один из возможных стилей архитектуры, главной особенностью которого является модульность. Такая архитектура противопоставляется монолитной, в которой разные компоненты объединены в одно целое.</p>
<p>&nbsp;</p>
<p>В микросервисной архитектуре создаются небольшие, независимые модульные сервисы. Каждый сервис решает определенную задачу. Сервисы взаимодействуют через API (application program interface) &#8211; это посредник, который связывает все элементы воедино. Каждый API запрограммирован на выполнение определенной бизнес-цели. Использование отдельных сервисов позволяет использовать наиболее подходящий технический стек для каждой конкретной задачи.</p>
<p> </p>
<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img decoding="async" class="wp-image-3992 aligncenter" src="https://koniglabs.com/wp-content/uploads/2020/04/Microservice_Architecture.png" alt="микросервисы" width="412" height="281" /><figcaption></figcaption></figure>
</div>
<p> </p>
<h4 class="wp-block-heading">О чем помнить при подготовке микросервисов</h4>
<p>Микросервисы очень популярны. При этом некоторые заказчики на волне хайпа требуют, чтобы все было реализовано с использованием микросервисной архитектуры, не зная реальную стоимость ее применения. Кроме того, чтобы получить пользу, надо уметь правильно микросервисы готовить. Недостаточно просто сделать несколько независимых проектов.</p>
<p>&nbsp;</p>
<p>При разделении программного продукта на микросервисы возникает много вопросов по <strong>взаимодействию сервисов</strong>. Например, как отследить цепочку вызовов различных сервисов, которая привела к конкретной ошибке? Или как понять, какой сервис сейчас является узким местом в работе системы? Эти вопросы с разной степенью успешности решаются либо готовыми инфраструктурными решениями (например, Elastic для логирования), либо под них надо разрабатывать какие-то свои инфраструктурные сервисы.</p>
<p>&nbsp;</p>
<p>Еще один момент о котором необходимо помнить &#8211; <strong>целостность данных</strong>. Поэтому заранее необходимо заложить механизмы обеспечения целостности данных. К сожалению, про это часто забывают. При эксплуатации это приводит к потери или рассинхронизации данных.</p>
<p>&nbsp;</p>
<p>Кроме того, грамотно <strong>разделить систему на независимые микросервисы </strong>на начальном этапе, как правило, не получается. Еще не известен ни точный функционал проектируемой системы, ни структура предметной области. Следовательно, неправильно выбранное разделение по сервисам приводит к сложностям и дополнительным расходам при реализации необходимых сценариев работы системы. В некоторых случаях &#8211; к полной невозможности корректного функционирования.</p>
<p> </p>
<h4 class="wp-block-heading">Микросервисы могут стоить дорого</h4>
<p>В зависимости от проекта, стоимость развертывания всей инфраструктуры для нескольких сервисов в нескольких конфигурациях, проверка работоспособности, масштабируемости и т.д. варьируется от 100 тысяч до 1 миллиона рублей.</p>
<p>&nbsp;</p>
<p>В большинстве случаев, крупные вложения в разработку инфраструктуры, особенно на начальном этапе, не оправданы. Неизвестно, будет ли система работать сколько-нибудь продолжительное время, сколько пользователей к нам придет или проект будет закрыт из-за несостоятельности бизнес-идеи.</p>
<p> </p>
<h2 class="wp-block-heading">Продуманная архитектура &#8211; залог успеха</h2>
<p>Останется ли заказчик или пользователь доволен работой системы зависит от того, насколько грамотно она спроектирована. Описание и разделение предметной области является ключевым моментом в планировании архитектуры. Даже при разработке традиционных монолитных систем это крайне важно. При построении микросервисов неправильное разделение на слабо связанные контексты приведет к нежелательным последствиям: очень сложному внесению изменений, невозможности отследить и проверить все сценарии поведения. Ошибки будут возникать и нарастать как снежный ком в самых неожиданных местах. Чтобы этого избежать, необходимо понять работу будущеей системы на всех уровнях, кто и как будет ей пользоваться. Поэтому крайне важно задуматься об архитектурном проектировании как можно раньше.</p>
<p> </p>
<h3 class="wp-block-heading">Пример</h3>
<p>Скажем, мы делаем интернет-магазин. Для того, чтобы спроектировать положительный пользовательский опыт, необходимо позаботиться о комплектации заказа, удобной оплате и оформлении доставки. Для этого разрабатывается удобный интерфейс комплектовщика, производится интеграция с платежной системой и системой складской логистики. Крайне важно понимать хотя бы основные бизнес-процессы, в которых будет принимать участие наш программный продукт, т.е. бизнес-архитектуру. В противном случае мы можем упустить очень большую часть потребностей. В свою очередь это приведет к ситуации, когда все вроде сделали правильно, но пользоваться продуктом нельзя. И, как следствие, нужны доработки. А это расходы, которые можно было избежать.</p>
<p>&nbsp;</p>
<p>Не редкость в таких ситуациях отсутствие средств: они тратятся на функции не столь критичные на данном этапе. Не проработав до конца все взаимодействия и интеграции, мы можем начать делать дорогие и бессмысленные вещи. Например, CRM-систему в то время как у заказчика нет особенных требований, и можно использовать готовое решение “из коробки”. И только проработав и поняв окружение, можно обоснованно принимать решение о выборе программной архитектуры, разделения системы на слабосвязанные контексты и т.д.</p>
<p> </p>
<h3 class="wp-block-heading">Так с чего начать?</h3>
<p>На практике, для выработки таких архитектурных решений хорошо помогает одно- или двухдневный воркшоп, на котором прорабатывается в том числе и низкодетализированный дизайн, и основные сценарии использования. В случае со стартапами, чрезвычайно важным шагом является проработка <a href="https://jo.my/business-model" target="_blank" rel="noreferrer noopener"><strong>Business Canvas</strong></a> вместе с подрядчиком для того, чтобы все стороны оценили жизнеспособность идеи. Одним из результатов воркшопа будет являться документ, описывающий нефункциональные требования к разрабатываемой системе.</p>
<p> </p>
<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img decoding="async" class="wp-image-3996 aligncenter" src="https://koniglabs.ru/wp-content/uploads/2020/04/Biznes-model%60.png" alt="Бизнес модель" width="622" height="320" /><figcaption>Business Model Canvas или шаблон бизнес-модели</figcaption></figure>
</div>
<p>Не исключено, что результатом может быть и закрытие проекта сразу после воркшопа. Он поможет стейкхолдерам увидеть несостоятельность бизнес-замысла, сэкономив время и деньги на технической реализации. Как бы странно ни звучало, даже в таких ситуация очень сильно возрастает доверие между участниками проекта.</p>
<p>&nbsp;</p>
<p>Резонный вопрос, надо ли это делать и дорого ли это? Отвечаем: стоимость воркшопа примерно равна стоимости двухдневной работы организованной команды. Исправление ошибок и доработки однозначно обойдутся заказчику намного дороже, чем такой воркшоп.</p>
<p>&nbsp;</p>
<p>Стоит помнить о том, что с течением времени бизнес-идея может измениться из-за внешних обстоятельств. К примеру, сейчас происходят очень большие изменения в работе практически любого бизнеса. Мы точно знаем, что мир уже не будет таким, как раньше (привет, COVID-19!). Нужно быть готовым к переменам и адаптировать свою бизнес-модель и продукт под новые реалии рынка.</p>
<p>&nbsp;</p>
<p>Как мы упоминало выше, такая гибкость закладывается адекватной архитектурой и использованием проверенных практик. Например, применение шаблона CQRS на логическом уровне архитектуры приложения (о том, что это такое, расскажем чуть ниже) в начале разработки позволит впоследствии выделять физические сервисы при развитии бизнеса и продукта.</p>
<p>&nbsp;</p>
<p>Переиспользование написанной функциональности станет возможным за счет разделения на независимые компоненты. При этом, если не пытаться сразу разделить сервисы физически, то команда сэкономит деньги на мониторинге, реализации распределенной транзакционной работы и на других зависимостях, которые пока еще не нужны для текущего уровня развития продукта.</p>
<p> </p>
<h2 class="wp-block-heading">CQRS на уровне логической архитектуры</h2>
<p> </p>
<h3 class="wp-block-heading">Коротко о CQRS</h3>
<p>CQRS (Command-Query Responsibility Segregation — разделение команд и запросов) — популярный и широко применяемый шаблон проектирования архитектуры программ. Его суть заключается в том, что все методы (т. е. определенные наборы действий) в программе могут быть двух типов. Это либо запросы, после выполнения которых состояние программы не изменяется, либо команды, которые состояние изменяют. Другими словами, запросы могут выполнять лишь чтение данных, в то время как команды обязательно включают в себя запись.</p>
<p> </p>
<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img decoding="async" class="wp-image-3988 aligncenter" src="https://koniglabs.com/wp-content/uploads/2020/04/command-and-query-responsibility-segregation.png" alt="CQRS" width="398" height="284" srcset="https://koniglabs.ru/wp-content/uploads/2020/04/command-and-query-responsibility-segregation.png 444w, https://koniglabs.ru/wp-content/uploads/2020/04/command-and-query-responsibility-segregation-300x214.png 300w" sizes="(max-width: 398px) 100vw, 398px" /></figure>
</div>
<p> </p>
<h3 class="wp-block-heading">Что сделали мы</h3>
<p>В этом <a href="https://koniglabs.ru/case_study/maintenance/" target="_blank" rel="noreferrer noopener" aria-label="проекте (opens in a new tab)"><strong>проекте</strong> </a>мы разработали ПО для управления и автоматизации бизнес-процессов судоходной компании. Чтобы сократить стоимость и выпустить первую версию ПО в кратчайшие сроки, мы выбрали подход внедрения CQRS на уровне логической архитектуры. Само приложение имело следующую схему:</p>
<p> </p>
<figure class="wp-block-image size-large"><img decoding="async" class="wp-image-4070" src="https://koniglabs.ru/wp-content/uploads/2020/04/CQRS_shema-arhitektury-IO.png" alt="cqrs архитектура " /></figure>
<p>Если соблюдать базовые принципы SOLID, а именно Dependency Inversion и Dependency Injection, то при хорошей настройке контейнеров инверсии управления все команды и запросы становятся небольшими кусочками, которые можно переиспользовать в разных частях вашей системы. Так и было в этом случае, что однозначно дало положительный результат.</p>
<p>&nbsp;</p>
<p>На схеме видно 3 части системы, которые вполне могут иметь схожую работу с моделью:</p>
<p> </p>
<ol class="wp-block-list">
<li>Взаимодействие офисного приложения с моделью (Admin office Desktop App)</li>
<li>Взаимодействие приложения механика с моделью (Ship Desktop Mechanic app)</li>
<li>Взаимодействие сервиса синхронизации с моделью (SyncService)</li>
</ol>
<p>Мы заметили, что люди, которые используют приложение в офисе, намного чаще читают данные с кораблей, нежели заполняют. При этом пользователи на кораблях в Offline-зоне наоборот чаще вводят данные в приложение, чем читают. Что это дает? Ценность заключается в том, что это отличная база для масштабирования системы. Если возникнет необходимость, то выделить окружающие контексты из кусочков запросов в одни физические сервисы с оптимизированной под чтение базой данных, а контексты из команд  &#8211; в другие сервисы будет намного легче. Всё это уже будет зависеть от бизнес-задач и от направлений развития архитектуры.</p>
<p> </p>
<h3 class="wp-block-heading">Примеры того, как внедрить такое разделение у себя в проекте</h3>
<p>Ниже я привожу пару основных классов на языке C#, которые можно просто переиспользовать в своих решениях.</p>
<p> </p>
<pre class="wp-block-verse">     /// &lt;summary&gt;
    ///     Универсальная фабрика для создания запросов.
    ///     Должна быть реализована в Composition Root(web api проект, главный проект сайта и т.д.)
    /// &lt;/summary&gt;
    public interface IHandlersFactory
    {
        IQueryHandler&lt;TQuery, TResult&gt; CreateQueryHandler&lt;TQuery, TResult&gt;();
 
        IAsyncQueryHandler&lt;TQuery, TResult&gt; CreateAsyncQueryHandler&lt;TQuery, TResult&gt;();
 
        ICommandHandler&lt;TCommand&gt; CreateCommandHandler&lt;TCommand&gt;();
 
        IAsyncCommandHandler&lt;TCommand&gt; CreateAsyncCommandHandler&lt;TCommand&gt;();
    }
/// &lt;summary&gt;
///   Базовый интерфейс для выполнения команды
/// &lt;/summary&gt;
 public interface ICommandHandler&lt;TCommand&gt;
    {
        void Execute(TCommand command);
    }
/// &lt;summary&gt;
///   Базовый интерфейс для выполнения запроса
/// &lt;/summary&gt;
 
public interface IQueryHandler&lt;TQuery, TResult&gt;
    {
        TResult Execute(TQuery query);
    }
 
/// &lt;summary&gt;
///   Фабрика для Ninject, создающая типизированные команды и запросы
/// &lt;/summary&gt;
public class NinjectFactory : IHandlersFactory
    {
        private readonly IResolutionRoot _resolutionRoot;
 
        public NinjectFactory(IResolutionRoot resolutionRoot)
        {
            _resolutionRoot = resolutionRoot;
        }
 
        public IAsyncCommandHandler&lt;TCommand&gt; CreateAsyncCommandHandler&lt;TCommand&gt;()
        {
            return _resolutionRoot.Get&lt;IAsyncCommandHandler&lt;TCommand&gt;&gt;();
        }
 
        public IAsyncQueryHandler&lt;TQuery, TResult&gt; CreateAsyncQueryHandler&lt;TQuery, TResult&gt;()
        {
            return _resolutionRoot.Get&lt;IAsyncQueryHandler&lt;TQuery, TResult&gt;&gt;();
        }

        public ICommandHandler&lt;TCommand&gt; CreateCommandHandler&lt;TCommand&gt;()
        {
            return _resolutionRoot.Get&lt;ICommandHandler&lt;TCommand&gt;&gt;();
        }
 
        public IQueryHandler&lt;TQuery, TResult&gt; CreateQueryHandler&lt;TQuery, TResult&gt;()
        {
            return _resolutionRoot.Get&lt;IQueryHandler&lt;TQuery, TResult&gt;&gt;();
        }
    }</pre>
<p><strong> Пример Биндинга запросов через Ninject</strong></p>
<p> </p>
<pre class="wp-block-verse">  public override void Load()
        {
            // queries
            Bind&lt;IQueryHandler&lt;GetCertificateByIdQuery, Certificate&gt;&gt;().To&lt;GetCertificateByIdQueryHandler&gt;();
            Bind&lt;IQueryHandler&lt;GetCertificatesQuery, List&lt;Certificate&gt;&gt;&gt;().To&lt;GetCertificatesQueryHandler&gt;();
            Bind&lt;IQueryHandler&lt;GetCertificateByShipQuery, List&lt;Certificate&gt;&gt;&gt;().To&lt;GetCertificateByShipQueryHandler&gt;();
………….
}</pre>
<p>После инъекции IHandlerFactory в ваш класс вы получаете возможность использовать свои команды и запросы следующим образом:</p>
<p> </p>
<pre class="wp-block-verse"> <strong>Пример выполнения запроса:</strong>
Ship ship = mHandlersFactory.CreateQueryHandler&lt;GetShipByIdQuery, Ship&gt;().Execute(new GetShipByIdQuery(id));

<strong>Пример выполнения команды:</strong>
mHandlersFactory.CreateCommandHandler&lt;DeleteReportCommand&gt;()
                    .Execute(new DeleteReportCommand(report));</pre>
<p>Но, конечно, всё надо применять ситуативно и с умом. Для этого и нужно разработать архитектуру. Другой момент, что не надо её продумывать на 300 шагов вперёд. Она должна ситуативно развиваться вместе с продуктом и давать ответы минимум на 3 вопроса:</p>
<p> </p>
<ol class="wp-block-list">
<li>Почему структура моего ИТ-продукта именно такая? Почему в этом месте надо реализовывать именно так?</li>
<li>Если я придумаю крутую реализацию, то как она ляжет на общую картину системы?</li>
<li>Каким образом будут соблюдаться нефункциональные требования системы в целом?</li>
</ol>
<p>Также очень важным этапом является момент выделения Bounded Context в системе. Данная практика хорошо помогает изобразить структуру бизнеса заказчика, найти с ним общий язык и управлять регрессией в продукте. Но об этом уже следующая статья.</p>
<p> </p>
<h4 class="wp-block-heading">Преимущества CQRS на уровне логической архитектуры</h4>
<p>Базовая архитектура рассмотренного приложения была выстроена с соблюдением разных принципов и шаблонов проектирования: MVVM, SOLID, CQRS и т.д. Это позволило переиспользовать функциональность фич для разных клиентов приложения. При этом, внедрение не занимало много времени и было достаточно недорогим.</p>
<p>&nbsp;</p>
<p>Реализация данного подхода не потребовала дополнительных затрат, так как при старте разработки у команды были уже наработанные классы и один уровень понимания архитектуры приложения. В последующих доработках этот подход полностью себя оправдал: порядка 40% функциональности можно было гибко переиспользовать. При таком подходе заказчик существенно сократил затраты на реализацию функций, определённые части которых дублируются для разных клиентов приложения. Мы оценили экономию средств в 30-40%.</p>
<p> </p>
<h2 class="wp-block-heading">Напоследок</h2>
<p>Agile-подход к разработке ошибочно трактуется как “не надо ничего проектировать заранее, надо ввязаться в бой, а там война &#8211; план покажет”. А если нам будет не хватать скорости работы или скорости изменения программы,  мы зарядим  серебряную пулю &#8211; микросервисы. Ведь на всех конференциях рассказывают, что микросервисы &#8211; это просто, и они решают сразу все проблемы. Такой оптимизм, как правило, ведет к потере денег и неработающему продукту. С другой стороны, проектировать все заранее в нашем быстро меняющемся мире практически невозможно. Как всегда надо находить баланс.</p>
<p>&nbsp;</p>
<p>Во-первых, проработка архитектуры позволяет осознанно выбрать подходящее решение на текущем этапе и в итоге сэкономить денег на разработку.</p>
<p>&nbsp;</p>
<p>Во-вторых, документирование архитектурных решений позволит в дальнейшем понять, почему именно такие решения были приняты. Более того, такой документ экономит время команды, исключая лишние обсуждения.</p>
<p>&nbsp;</p>
<p>В-третьих, периодическая валидация изменившихся условий позволяет снизить риски отказов в работе продукта или системы и принять взвешенное решение о необходимости доработки или изменения.</p>
<p>&nbsp;</p>
<p>Таким образом, следование грамотным практикам непосредственно при написании кода позволяет получить хороший фундамент, на основании которого можно будет масштабировать решение в дальнейшем.</p>
<p> </p>
<div class="wp-block-spacer" style="height: 30px;" aria-hidden="true"> </div>
<p>&nbsp;</p>

		</div>
	</div>
<div class="tm-button-wrapper  similar-post-btn tm-animation move-up" id="tm-button-69dc3b98a1a28">
		<a class="tm-button style-text tm-button-nm tm-button-custom tm-button-icon-move has-icon icon-right" href="https://koniglabs.ru/it-solutions/"
			>

		
						<span class="button-text" data-text="Смотреть решения по отраслям">
				Смотреть решения по отраслям			</span>
							<span class="button-icon">
				<i class="linea-arrows-slim-right"></i>
			</span>
			
		

	</a>
</div>
</div></div></div></div><p>The post <a href="https://koniglabs.ru/cqrs-microservices/">Микросервисы и CQRS: оптимизируем затраты на продукт</a> appeared first on <a href="https://koniglabs.ru">König Labs</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://koniglabs.ru/cqrs-microservices/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>