<?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>
    <language>ru</language>
    <title>Микросервисы</title>
    <description/>
    <link>https://tproger.ru/tag/microservices</link>
    <atom:link href="https://tproger.ru/tag/microservices/feed" rel="self" type="application/rss+xml"/>
    <lastBuildDate>Fri, 23 Oct 2026 16:07:21 GMT</lastBuildDate>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>12</sy:updateFrequency>
    <image>
      <title>Микросервисы</title>
      <link>https://tproger.ru</link>
      <url>https://tproger.ru/apple-touch-icon.png</url>
    </image>
    <item>
      <title>Монолит, модульный монолит или микросервисы: как выбрать архитектуру</title>
      <link>https://tproger.ru/articles/monolit-modulnyj-monolit-ili-mikroservisy-kak-vybrat-arhitek</link>
      <comments>https://tproger.ru/articles/monolit-modulnyj-monolit-ili-mikroservisy-kak-vybrat-arhitek?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Дима Дмитриев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/monolit-modulnyj-monolit-ili-mikroservisy-kak-vybrat-arhitek</guid>
      <description><![CDATA[<p>Модульный монолит развёртывается целиком, а сервисы можно обновлять отдельно. Как выбрать архитектуру с учётом нагрузки, транзакций и ресурсов команды?</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/monolit-modulnyj-monolit-ili-mikroservisy-kak-vybrat-arhitek">Монолит, модульный монолит или микросервисы: как выбрать архитектуру</a>»</p>]]></description>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Архитектура ПО]]></category>
      <category><![CDATA[Архитектура приложений]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 28 Sep 2026 11:44:11 GMT</pubDate>
      <content:encoded><![CDATA[<p>Когда пользователей становится больше, приложение может начать тормозить, а с добавлением новых функций код усложняется: перед каждым обновлением приходится проверять, как изменения повлияют на связанные части. В зависимости от причины можно добавить серверные мощности, разделить код на модули с понятными задачами или выделить самостоятельные сервисы, которые можно обновлять отдельно.</p><h2>Чем отличаются монолит, модульный монолит и микросервисы</h2><p>Представим приложение магазина. В нём есть заказы, каталог товаров и биллинг, который рассчитывает скидки и выставляет счета. Эти части связаны бизнес-логикой: для персональной скидки нужна сумма прошлых заказов, а при покупке нужно знать, есть ли товар на складе.</p><p>В <b>монолите</b> эта функциональность входит в одно приложение. Его части могут вызывать функции друг друга внутри процесса и обращаться к общей базе данных. Новую версию собирают и развёртывают целиком, даже если изменения касаются только расчёта скидки.</p><p>Такое устройство удобно на старте. Команда работает с общим приложением, и для проверки взаимодействия заказов с биллингом достаточно запустить его вместе с необходимой инфраструктурой. Обновление связанных частей можно включить в один релиз. Разработчикам проще проследить выполнение операции, когда её логика находится рядом.</p><p>По мере роста проекта становится важнее то, как устроен код внутри приложения. Если расчёт скидок, обработка заказов и работа с товарами связаны, изменение одной функции может затронуть соседние. Разработчику приходится учитывать всё больше связей, а проверка последствий занимает больше времени.</p><p><b>Модульный монолит</b> сохраняет общее развёртывание, но внутри разделён на модули с обязанностями и границами. Модуль заказов отвечает за заказы, биллинг содержит правила расчётов. Взаимодействие между ними организуют через определённые интерфейсы: по ним должно быть понятно, какие данные запрашивает соседняя часть и какой результат получает. Поэтому, когда меняются правила расчёта скидок, разработчик знает, где искать соответствующий код и какие части приложения используют результат. При этом вызов между модулями может оставаться обычным вызовом функции в памяти.</p><p><b>Модульный монолит</b> относится к монолитной архитектуре, из его названия вы можете понять организацию внутренних границ. Она требует работы с зависимостями в коде: раскладывание файлов по папкам само по себе ещё ничего не говорит о том, насколько самостоятельно устроены модули.</p><p>В <b>микросервисной архитектуре</b> части системы работают как самостоятельные сервисы. Заказы и биллинг можно развёртывать отдельно, выделять им разные ресурсы и разрабатывать силами разных команд. Для получения суммы заказов биллинг обращается к сервису заказов через API, получает ответ и использует его в расчёте.</p><p>Здесь появляется возможность выпускать изменения одного сервиса независимо от остальных, пока сохраняется совместимость взаимодействия. Вместе с ней возникает ответственность за контракт: сервис заказов должен возвращать данные в том виде, который понимает биллинг. Если изменение затрагивает обе стороны, командам нужно согласовать обновление.</p><h2>Что меняется, когда вызов функции становится сетевым запросом</h2><p>Вернёмся к персональной скидке. Биллинг должен узнать, на какую сумму пользователь сделал заказы за год. Пока логика находится в одном приложении, он может получить результат через внутренний вызов. В варианте с общей БД нужные данные доступны через запрос к ней.</p><p>После выделения заказов в сервис путь становится длиннее. Биллинг отправляет запрос к его API. Сервис заказов обращается к своей базе, формирует ответ и передаёт его обратно. Затем биллинг разбирает полученные данные и рассчитывает скидку.</p><p>На каждом таком переходе появляется дополнительная работа. Данные нужно подготовить к передаче и восстановить на другой стороне, дождаться ответа по сети, обработать результат. Эти расходы могут быть приемлемыми для одной операции. Если пользовательский запрос запускает длинную цепочку обращений, время ожидания начинает зависеть от всех её участников.</p><p>Например, страница профиля может собирать данные из нескольких сервисов. Тогда разработчику приходится выяснять, на каком участке задерживается ответ. Медленная работа одного сервиса способна задержать весь сценарий, который от него зависит. Физическое разделение компонентов сохраняет логические связи между ними.</p><p>Контракт API тоже становится частью работы. Если сервис меняет формат ответа, нужно учесть потребителей этих данных. Изменение, которое внутри монолита могло попасть в один релиз, в распределённой системе может потребовать обновления нескольких сервисов в согласованном порядке. При частых совместных изменениях ожидаемая независимость релизов сокращается.</p><p>Кроме кода прикладных задач, команда поддерживает инфраструктуру каждого сервиса. Нужно организовать сборку и развёртывание, наблюдать за работой компонентов, собирать их логи. При отладке приходится восстанавливать ход операции по нескольким частям системы. Для локальной разработки также нужно продумать, какие сервисы и базы потребуются, чтобы проверить изменение.</p><p>Стоимость взаимодействия покажем на примере системы мониторинга качества видео Amazon Prime Video. Сначала она работала как распределённое решение на AWS Lambda и Step Functions. При увеличении нагрузки обмен данными и управление выполнением компонентов потребовали слишком больших расходов. Команда объединила систему в монолитное приложение, после чего расходы на неё снизились примерно на 90%.</p><p>Результат относится к конкретной системе мониторинга с её характером вычислений и обмена данными. Для выбора архитектуры здесь полезно проверить, какую долю работы составляют полезные вычисления, а какую занимает координация компонентов. Чем чаще элементы приложения обращаются друг к другу, тем внимательнее нужно оценивать стоимость их разделения.</p><h2>Как масштабировать монолит и микросервисы</h2><p>Монолитное приложение можно запускать в нескольких экземплярах. Перед ними размещают балансировщик, который распределяет входящие запросы. Каждый экземпляр выполняет код того же приложения, поэтому монолитная архитектура совместима с горизонтальным масштабированием: нагрузку распределяют между дополнительными экземплярами.</p><p>С микросервисами применяется похожий подход. Если сервис заказов получает больше запросов, запускают дополнительные экземпляры именно этого сервиса. Биллинг при этом может продолжать работать с прежними ресурсами. Такая избирательность полезна, когда нагрузка на части системы заметно различается.</p><p>Однако увеличение числа обработчиков помогает в пределах возможностей остальных компонентов. Если все экземпляры сервиса заказов обращаются к одной перегруженной БД, она продолжит ограничивать обработку запросов. Поэтому перед изменением архитектуры нужно разобраться, где именно приложение упирается в доступные ресурсы.</p><h3>Воркеры и очереди задач</h3><p>Часть работы можно выполнять в фоне. Пользователь получает данные, необходимые для текущего действия, а отложенные вычисления выполняются отдельно. Для этого используют воркеры: процессы, которые забирают задачи из очереди и обрабатывают их.</p><p>В нашем магазине таким вычислением может быть расчёт персональной скидки по прошлым заказам. Воркер получает задачу, считает результат и сохраняет его в БД. Приложение затем использует подготовленное значение. Возможность вынести конкретный расчёт в фон зависит от того, в какой момент его результат нужен пользователю.</p><p>У монолита воркеры могут использовать ту же кодовую базу, что и веб-приложение, но выполнять разные группы задач. Один занимается расчётами биллинга, другой обрабатывает задачи, связанные с товарами. Для каждого направления можно организовать свою очередь и подобрать число исполнителей.</p><p>Допустим, в очереди четыре задачи, а свободных воркеров три. Каждый возьмёт по одной задаче, оставшаяся дождётся первого освободившегося исполнителя. Если очередь регулярно растёт и вычисления позволяют распределить работу, можно увеличить число воркеров. Для этого достаточно масштабировать обработку фоновых задач в существующей архитектуре.</p><p>Ресурсы воркеров тоже могут различаться. Расчётам, которым нужно держать в памяти большой объём данных, выделяют больше памяти. Более лёгким задачам достаточно меньших ресурсов. Такой подбор применим и к монолиту, и к отдельным сервисам.</p><h3>Чтение и запись в базе данных</h3><p>Для распределения нагрузки на чтение можно использовать реплики БД. Основная база принимает изменения, а её копии получают эти изменения через механизм репликации. Часть запросов на чтение направляют к копиям, разгружая основную базу.</p><p>В этой схеме запись по-прежнему сосредоточена в основной БД. Если ограничение связано именно с ней, увеличение числа реплик для чтения решает другую задачу. Потребуется отдельно рассматривать, как устроены данные и операции записи.</p><p>Разделение по сервисам позволяет распределить запись между разными базами, когда данные принадлежат разным частям системы. При этом сильно нагруженная база конкретного сервиса всё равно может потребовать масштабирования. Оценивать нужно каждый участок, на котором сосредоточена работа.</p><p>Возможен и шардинг: распределение данных между несколькими базами, например по пользователям или клиентам. Такой подход можно применять в разных архитектурах. Он требует продумать, как приложение найдёт нужные данные и как будет работать с информацией, относящейся сразу к нескольким группам.</p><h2>Что усложняется при разделении данных между сервисами</h2><p>Заказы связаны с товарами независимо от того, где выполняется код. Если обе сущности хранятся в общей реляционной БД, данные о них можно соединить запросом с JOIN. База выполняет связанную операцию, а приложение получает результат.</p><p>Когда каждая часть системы управляет своими данными и предоставляет их через API, получение общей информации требует обращений к соответствующим сервисам. Результаты нужно собрать и обработать. В системе появляется код, который организует эти обращения и учитывает доступность участников.</p><p>Поэтому перед выделением компонента полезно проследить, какие сведения нужны ему для обычной работы. Если почти каждый расчёт биллинга требует обращения к заказам, а затем к товарам, эти зависимости войдут в стоимость нового сервиса. Само разделение сохранит потребность в данных соседних частей.</p><p>Более сложный вопрос возникает, когда операция меняет данные сразу в нескольких местах. Допустим, покупатель оформляет заказ, а система должна зарезервировать товар на складе. Запись о заказе и доступный остаток должны соответствовать друг другу. Если товар уже закончился, приложение должно корректно обработать эту ситуацию.</p><p>При выполнении связанных изменений внутри одной БД можно использовать общую транзакцию. Она позволяет применить предусмотренные изменения вместе или отменить их при неудаче. Разработчик описывает операцию с учётом возможностей и правил работы выбранной базы.</p><p>После разделения данных между сервисами согласование становится отдельной задачей. Один участник может успеть выполнить свою часть, пока другой столкнулся с ошибкой. Команде нужно определить, что произойдёт с уже внесёнными изменениями и какой итог получит пользователь.</p><p>Один из подходов к такому согласованию называется Saga. Общую операцию описывают как последовательность шагов с действиями на случай неудачи. Для заказа и резервирования потребуется продумать, как система поступит, если выполнить весь сценарий не удалось. Эти правила становятся частью прикладной логики и требуют отдельной проверки.</p><p>Здесь возрастает объём работы по обеспечению согласованного результата. Чем больше участников и связей между ними, тем больше сценариев должна учитывать команда. Поэтому частые операции, которые тесно связывают данные разных частей приложения, влияют на выбор границ сервисов.</p><h2>По каким признакам выбирать архитектуру для проекта</h2><p>Начать стоит с устройства разработки. Небольшой команде, которая проверяет продуктовую идею и часто меняет связанную функциональность, удобно работать с общим приложением. Один релиз позволяет одновременно обновить нужные части, а разработчики тратят меньше времени на инфраструктуру взаимодействия.</p><p>Для такой ситуации монолит даёт простой старт. По мере того как проясняются обязанности частей приложения, их можно оформлять в модули. Это помогает ограничивать зависимости в коде и сохранять понятную структуру, пока общее развёртывание подходит команде.</p><p>Модульный монолит особенно полезен, когда функциональность уже выросла, а многие изменения по-прежнему удобно выпускать вместе. У разработчиков есть границы, по которым можно разделять работу внутри приложения. При этом сохраняется возможность выполнять внутренние вызовы и работать с тесно связанными данными в общей системе.</p><p>В большой организации ситуация может быть другой. Несколько команд развивают самостоятельные направления и хотят выпускать обновления в собственном темпе. Если границы этих направлений совпадают с границами функциональности, отдельные сервисы позволяют согласовать устройство системы с организацией разработки.</p><p>Следующий критерий связан с нагрузкой. Например, обработка изображений может требовать заметно больше ресурсов, чем остальная часть приложения. Выделение такой функциональности позволяет масштабировать её отдельно. Перед этим стоит сравнить пользу самостоятельного сервиса с возможностями фоновых воркеров в текущем приложении.</p><p>Также нужно учитывать бюджет эксплуатации. Каждый дополнительный сервис требует внимания к развёртыванию и наблюдению за его работой. Если поддержкой всей инфраструктуры занимается та же небольшая команда, время на неё придётся учитывать в сроках разработки функций продукта.</p><p>Потребность в разных технологиях может стать ещё одним аргументом за разделение. Для отдельной задачи бывает удобнее другой язык или стек. Тогда сервис даёт возможность использовать его локально. Вместе с этим потребуется поддерживать соответствующие знания в команде и учитывать особенности новой технологии при эксплуатации.</p><p>Наконец, проверьте требования к данным и времени ответа. Если пользовательский сценарий требует частых синхронных обращений между частями системы, сетевое взаимодействие войдёт в его стоимость. Если операция меняет тесно связанные данные, нужно заранее оценить сложность согласования этих изменений после разделения.</p><p>Чтобы обсудить решение на конкретных примерах, команда может ответить на несколько вопросов:</p><ul><li>Какие части приложения обычно меняются вместе и почему им нужен общий релиз?</li><li>Какая функциональность требует самостоятельного масштабирования и где именно возникает нагрузка?</li><li>Какие данные потребуются выделенному сервису для выполнения обычной операции?</li><li>Кто будет отвечать за его развёртывание и разбирать проблемы в эксплуатации?</li><li>Можно ли разрабатывать и проверять этот сервис, запуская только необходимые ему компоненты?</li></ul><p>Ответы позволяют увидеть цену самостоятельности. Если выделение сервиса освобождает команду от общего графика релизов и даёт полезное управление ресурсами, эти преимущества можно сопоставить с расходами на поддержку. Если же каждое изменение продолжает затрагивать несколько сервисов, сначала стоит пересмотреть их границы и зависимости.</p><h2>Как понять, что компонент готов стать отдельным сервисом</h2><p>Архитектуру можно менять постепенно. Можно начать с монолита, оформить внутри него модули, а затем при необходимости выделить часть функциональности в сервис. К этому моменту команда будет знать, какую нагрузку получает компонент и с какими частями приложения он связан.</p><p>Для выделения нужен компонент с понятной самостоятельной обязанностью. Его должно быть возможно описать через выполняемую работу и необходимые данные. Полезно заранее проследить основные сценарии: какие запросы приходят на вход, откуда берётся информация для их обработки и кому потребуется результат.</p><p>Возьмём биллинг. Если он при каждом действии запрашивает множество сведений о заказах и товарах, после выделения эти обращения придётся поддерживать через интерфейсы сервисов. Стоит оценить их частоту и понять, насколько биллинг сможет развиваться самостоятельно. Если изменение расчёта каждый раз требует одновременно переделывать соседние части, независимый релиз останется ограничен их зависимостями.</p><p>Следующая проверка касается локальной разработки. Сервис проще сопровождать, когда разработчик может запустить его, выполнить нужную проверку и разобраться в результате без развёртывания всего проекта. Чем больше других сервисов и баз приходится поднимать ради небольшой доработки, тем внимательнее стоит рассмотреть выбранные границы.</p><p>Затем нужно сопоставить ожидаемую пользу с работой по переносу. У компонента появится собственное развёртывание, его взаимодействие с остальным приложением потребуется организовать и проверить. Если выделяются данные, отдельно планируют согласование операций, которые раньше выполнялись внутри одной БД.</p><p>Для существующего проекта такие изменения входят в более широкую работу по модернизации ПО. Centicore Group занимается обновлением легаси-кода, баз данных и инфраструктуры; в услугу входят рефакторинг и обновление технологического стека. Если команда планирует переработку работающей системы, можно<a href="https://centicore.ru/services/legacy-modernization/"> обсудить её модернизацию с Centicore Group</a>.</p><p>После выделения компонента у команды должна появиться конкретная возможность: выпускать его изменения в собственном темпе или подбирать ему ресурсы отдельно от остального приложения. Эту возможность полезно сформулировать ещё до переноса, тогда результат можно оценивать по исходной задаче, а дальнейшие изменения архитектуры планировать по мере появления новых потребностей.</p><h2>Итого</h2><p>Монолит упрощает совместную разработку и выпуск связанных изменений. Модульная организация помогает сохранять понятные границы внутри такого приложения. Микросервисы дают больше самостоятельности отдельным частям и командам, одновременно увеличивая работу по их взаимодействию.</p><p>Перед выделением сервиса сформулируйте, какая конкретная задача требует самостоятельного развёртывания или отдельного управления ресурсами. Затем проследите его зависимости и операции с данными. Если команда понимает, какую пользу получит и как будет поддерживать новые связи, у неё есть основание для разделения. При проблемах с нагрузкой на конкретный участок сначала оцените доступные способы масштабирования этого участка в текущей архитектуре.</p>]]></content:encoded>
    </item>
    <item>
      <title>Наблюдаемость: где на самом деле теряются миллисекунды</title>
      <link>https://tproger.ru/articles/nablyudaemost-gde-na-samom-dele-teryayutsya-millisekundy</link>
      <comments>https://tproger.ru/articles/nablyudaemost-gde-na-samom-dele-teryayutsya-millisekundy?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Tproger]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/nablyudaemost-gde-na-samom-dele-teryayutsya-millisekundy</guid>
      <description><![CDATA[<p>Как собрать трассы без правки кода через eBPF, превратить их в метрики по медленным запросам и не принять смену методики за регрессию. Разбираем три слоя с цифрами.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/nablyudaemost-gde-na-samom-dele-teryayutsya-millisekundy">Наблюдаемость: где на самом деле теряются миллисекунды</a>»</p>]]></description>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Golang]]></category>
      <category><![CDATA[OpenTelemetry]]></category>
      <category><![CDATA[Grafana]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 09 Sep 2026 13:00:26 GMT</pubDate>
      <content:encoded><![CDATA[<p>Дашборд краснеет, а причина не находится. У наблюдаемости, которая так себя ведёт, обычно три независимые беды: телеметрия собрана не везде, собранное не переведено в решения, а полученные числа прочитаны неверно.</p><p>Разбираем все три слоя: как получить трассировку, не переписывая сервисы, как превратить трассы в метрики, по которым можно действовать, и как не принять смену методики измерения за изменение продукта.</p><p>Трассировка через eBPF снимает налог на ручное инструментирование, но требует ядра не ниже 5.8, несрезанной таблицы символов и знания устройства планировщика Go.</p><p>При 50 000 запросах в секунду и четырёх точках съёма на запрос получается 200 000 входов в ядро ежесекундно и потолок расхода в 200–600 мс процессорного времени на ядро.</p><p>Медленный запрос это не одна проблема, а пять разных: лишняя работа, борьба за ресурсы, давление среды, деградация плана и патологические шаблоны вроде N+1.</p><p>Инструменты базы говорят, что дорого внутри неё, но не говорят, какой сервис это вызвал и был ли запрос пользовательским. Этот контекст приносят трассы.</p><p>Версия браузера, тип навигации, библиотека сбора данных и версия инструментирования входят в определение метрики: смешав их в одном графике, вы увидите изменение измерения вместо изменения продукта.</p><h2>Слой первый наблюдаемости: собрать данные, не трогая код</h2><p>Ручное инструментирование обходится дороже, чем кажется на старте. Каждая точка вызова библиотеки, каждая ветка передачи контекста и каждое извлечение сопутствующих данных — это код, который расходится с реальностью, забывается в горячем пути и стоит процессорного времени на высокой частоте запросов.</p><p>Альтернатива, ставшая эксплуатационно пригодной за последние пару лет, — <a href="https://dev.to/neeraj_singhi_golang/ebpf-powered-request-tracing-in-go-microservices-without-instrumentation-tax-34kf">подключение зондов eBPF напрямую к символам рантайма</a> и точкам входа библиотек HTTP и gRPC. Трассы восстанавливаются из событий ядра и пользовательского пространства, а файл бинарника на диске не меняется вовсе: правки идут только в памяти работающего процесса, точечно и обратимо.</p><h3>Почему с Go это сложнее, чем с C</h3><p>Зонд работает так: в заданное смещение работающего бинарника ставится инструкция прерывания, при попадании в неё ядро останавливает поток, выполняет свою программу и возобновляет исполнение. Для C и Rust это ложится на прологи функций почти без остатка. Go добавляет три осложнения.</p><p><b>Планирование горутин.</b> Планировщик Go раскладывает множество горутин на меньшее число системных потоков. Один HTTP-запрос может обрабатываться горутиной на одном потоке в момент срабатывания зонда и переехать на другой поток до записи ответа. Наивный зонд, читающий идентификатор потока или процесса, теряет непрерывность на этом переезде. Правильный якорь — идентификатор горутины, а достать его можно либо через карту, построенную по отладочной информации, либо вычислением фиксированного смещения от указателя, лежащего в регистре локального хранилища потока.</p><p><b>Соглашение о вызовах.</b> В Go 1.17 аргументы функций переехали со стека в регистры, причём сначала только на amd64; на arm64 и ppc64 это произошло версией позже. Программа зонда, написанная под прежнее соглашение и читающая контекст со смещения от указателя стека, на новых бинарниках прочитает мусор. Значит, трассировщику нужна либо логика зондов под каждую минорную версию языка, либо вычисление места по отладочной информации самого бинарника.</p><p><b>Встраивание функций.</b> Компилятор Go агрессивно встраивает мелкие функции, и нужный символ может просто отсутствовать по ожидаемому адресу. Зонд, поставленный не туда, даёт пропущенные отрезки трассы или испорченные аргументы, причём молча.</p><p><b>Отдельная ловушка при разборе событий:</b><br />Структура на стороне потребителя должна побайтово совпадать со структурой в программе зонда, включая выравнивание. Расхождение в один байт приводит к тому, что все поля после первого декодируются неправильно, а внешне это выглядит как случайный мусор в трассах.</p><h3>Главная нерешённая проблема: передача контекста между сервисами</h3><p>Если нельзя вписать заголовок в коде приложения, как передать идентификатор трассы дальше по цепочке вызовов? Есть три подхода, и практически применим один.</p><ul><li>Писать заголовок прямо в пакет на уровне сетевого интерфейса. Требует расширенных привилегий и работает только для нешифрованного HTTP/1.1: шифрование выполняется выше уровня сокета, и программа видит уже зашифрованные байты.</li><li>Пропускать исходящие вызовы через локальный вспомогательный прокси, который держит соответствие идентификатора горутины и контекста трассы и вставляет заголовки перед пересылкой. Добавляется сетевой переход, зато шифрование не ломается.</li><li>Править карту заголовков прямо в памяти процесса. Соответствующая функция ядра помечена как опасная и действительно способна повредить память: каждая её загрузка пишет предупреждение в журнал ядра, работа требует широкой привилегии CAP_SYS_ADMIN, а в режиме блокировки ядра она запрещена совсем.</li></ul><p>Единственный вариант, который одновременно совместим с шифрованием, безопасен и разворачивается где угодно, — второй. Его цена в задержке составляет обычно меньше 100 мкс на переход через локальную петлю, что приемлемо, когда сами измеряемые операции занимают миллисекунды.</p><h3>Что ломается в продакшене</h3><ul><li>Идентификаторы горутин переиспользуются. При высокой конкурентности номер может уйти на новую горутину раньше, чем потребитель разобрал события старой.</li><li>Обновление бинарника сдвигает смещения символов. Зонды старого отображения ядро снимает само, и новый бинарник какое-то время работает без трассировки. Слежение за изменением файла сокращает разрыв до секунд, но не убирает его.</li><li>Требования к ядру. Кольцевые буферы нужны ядру от 5.8, а переносимая компиляция зондов требует 5.4 с включённой отладочной информацией о типах. Матрицу ядер стоит проверить до внедрения, а не после.</li><li>Срезанные бинарники. Сборка без таблицы символов и отладочной информации лишает трассировщик возможности сопоставить имена функций со смещениями. Компромисс: оставить хотя бы таблицу символов, заплатив примерно 10–15% размера бинарника.</li></ul><h3>Сколько это стоит в процессорном времени</h3><p>Зонды не бесплатны: каждое срабатывание это программное прерывание с входом в ядро. При 50 000 запросах в секунду и четырёх точках съёма на запрос получается 200 000 входов ежесекундно. Опубликованные замеры дают порядка 1–3 мкс на срабатывание на современном оборудовании, то есть верхняя оценка расхода составляет 200–600 мс процессорного времени в секунду на одно ядро.</p><p>Цифра ощутимая, но сравнивать её стоит с альтернативой, а не с нулём. Автор разбора оценивает эту альтернативу в десятую часть рабочего времени разработчиков, уходящую на сопровождение кода инструментирования. Потребителя событий при этом лучше держать на отдельной горутине, привязанной к ядру, которое не обслуживает запросы, чтобы выделение памяти под отрезки трасс не мешало обработке.</p><p>Правильный вывод не «заменить инструментирование зондами», а «использовать оба». Зонды дают сплошное покрытие и базовое распределение задержек без усилий разработчиков, включая сторонние бинарники, которые вы не можете изменить. Ручное инструментирование даёт смысловое наполнение: идентификатор пользователя, арендатора, флаг функциональности — то, чего из сырых байтов HTTP не синтезировать. Наиболее точные схемы наблюдаемости держат оба слоя, причём слой зондов работает проверкой на непротиворечивость для отрезков, которые приложение теряет под нагрузкой.</p><h2>Слой второй: превратить трассы в решения</h2><p>Собранная телеметрия сама по себе ничего не улучшает. Больше телеметрии означает больше объектов для разглядывания, а не больше понимания. Полезной она становится, когда из неё извлечены закономерности, на которые можно действовать.</p><h3>«Медленный запрос» это пять разных диагнозов</h3><p>Прежде чем что-то чинить, стоит понять, чем именно болен запрос. <a href="https://www.cncf.io/blog/2026/08/21/how-to-turn-slow-queries-into-actionable-reliability-metrics-with-opentelemetry/">Разбор CNCF</a> раскладывает медленные запросы к базе на пять непохожих причин:</p><ul><li>Лишняя работа. Обычно это полный перебор таблицы из-за отсутствующего или неприменимого индекса. Выборка по идентификатору клиента без индекса растёт с 20 мс на десяти тысячах строк до минут на десяти миллионах. Запрос не менялся, изменился объём данных.</li><li>Борьба за ресурсы. Идеально оптимизированный запрос стоит в ожидании блокировок или свободного соединения. Запрос, проводящий 95% времени в ожидании блокировки, оптимизацией текста не лечится: ему нужна перекройка транзакций.</li><li>Давление среды. Насыщение процессора, узкое место ввода-вывода и нехватка памяти замедляют любой запрос с любым планом: тот же текст запроса и тот же план на нагруженной машине отработает в разы дольше, чем на свободной, и оптимизировать тут нечего.</li><li>Деградация плана. Данные и текст запроса те же, а план исполнения изменился. Устаревшая статистика после массовой загрузки заставляет планировщик выбрать заведомо плохую стратегию.</li><li>Патологические шаблоны. Проблема N+1 выполняет сотню быстрых запросов по две миллисекунды последовательно, добавляя двести миллисекунд задержки на одно только выполнение, не считая сетевых издержек на каждый обмен с базой. Ни один запрос не является медленным, а шаблон катастрофичен и в журнал медленных запросов не попадает вовсе.</li></ul><h3>Чего не хватает встроенным инструментам базы</h3><p>Журналы медленных запросов, хранилища запросов и разбор планов прекрасно отвечают на вопрос, что дорого внутри базы. Они не отвечают на вопросы, которые задаёт дежурный инженер: какой сервис это вызвал, пользовательская это работа или фоновая, связано ли это со всплеском задержки, который сейчас расследуется.</p><p>Этот контекст приносит распределённая трассировка: каждый отрезок обращения к базе вложен в контекст запроса и знает сервис, конечную точку и инициатора. Вместо того чтобы вручную сшивать журналы базы с трассами постфактум, медленные запросы анализируются прямо из трасс со всем прикладным контекстом внутри.</p><p>Дальше из отрезков трасс выводятся метрики, и делается это в три приёма: сперва простое обнаружение медленных запросов, затем взвешивание по трафику, чтобы понять, что даст наибольший выигрыш при ускорении, и наконец поиск аномалий для дежурства. Первые два отвечают на вопрос оптимизации, третий — на вопрос реагирования на инцидент, и путать их не стоит: это разные задачи с разными приоритетами.</p><h2>Слой третий: не принять смену измерения за изменение продукта</h2><p>Третья ошибка самая обидная, потому что данные при этом верны. Метрика может быть абсолютно точной, а рассказанная по ней история — совершенно неверной.</p><p>Дальше примеры пойдут из веб-производительности, потому что там эта ошибка задокументирована лучше всего. Механика же общая: любой дашборд, где смешаны серии с разных популяций или с разных версий сбора, ведёт себя одинаково, будь то задержки бэкенда или отрисовка страницы.</p><h3>Общий тренд не объясняет вашу просадку</h3><p>В июньском наборе данных о реальных пользователях Chrome, опубликованном в середине июля, доля источников с хорошей отрисовкой основного содержимого упала до 67,7%, с хорошей задержкой отклика на взаимодействие до 85,9%, а доля проходящих все три ключевых показателя до 55,3%. Исключением оказалась стабильность вёрстки, поднявшаяся до 81,4%.</p><p>Google объяснил движение сезонностью, сравнив его с прошлым годом. Контекст полезный, но он не является доказательством того, что у вас локально ничего не сломалось. Релиз, рекламная кампания, изменение формы согласия, сдвиг в составе устройств или новый сторонний скрипт способны совпасть с общеотраслевым движением.</p><p>Гарри Робертс формулирует критерий проверки прямо: <a href="https://csswizardry.com/2026/07/web-perf-wednesday-002-the-metrics-dont-tell-the-whole-story/">если общая доля прошедших упала на 1,2 процентного пункта, а конкретный сайт просел на четыре, широкий тренд разницу не объяснил</a>. Верно и обратное: если сайт почти идеально повторяет рынок по браузерам и устройствам, срочное расследование в коде потратит время всей команды впустую.</p><p>Правильное сравнение поэтому не «этот месяц против прошлого». Сравнивайте движение сайта с общей дельтой, разделяйте мобильные и настольные устройства, смотрите на показатели отрисовки и отклика по отдельности и разбирайте важные шаблоны страниц, а не источник целиком.</p><h3>Изменение методики выглядит как изменение продукта</h3><p>Дальше будет сложнее. По мере того как браузеры начинают показывать переходы внутри одностраничных приложений, которые метрики первоначальной загрузки пропускали, на одном дашборде окажутся жёсткие навигации, мягкие навигации браузера и собственные виртуальные страницы приложения, причём каждая серия собрана с разной популяции пользователей.</p><p>Смешав их без оговорок, вы получите скачок графика, вызванный сменой методики, и потратите неделю на поиск несуществующей регрессии. Отсюда практическое требование: версия браузера, тип навигации, библиотека сбора данных и версия инструментирования перестают быть служебными деталями и становятся частью определения метрики. Дашборд должен нести отметки релизов, состав трафика и устройств и внятное указание, какую популяцию представляет каждый график.</p><h3>Компенсация это не исправление</h3><p>Ещё одна ловушка того же рода: браузеры учатся скрывать последствия проблем. Привязка прокрутки к содержимому подправляет позицию, когда над областью просмотра что-то вставилось или исчезло, и читателя перестаёт выбрасывать с того места, которое он разглядывал.</p><p>Улучшение реальное, но документ по-прежнему перевёрстывается, если у картинки не заданы размеры или объявление меняет высоту. Браузер убирает одно видимое следствие, а причина остаётся на месте. Проверять после такого изменения стоит липкие шапки, ленты, интерфейс согласия и встроенные блоки, а чинить всё равно вёрстку, а не полагаться на маскировку.</p><p>Тот же разрыв виден и в метрике отклика. Большинство команд сегодня способны сказать, плохой у них отклик или нет. Заметно меньше способны сказать, какое именно взаимодействие в этом виновато, на каком шаге пользовательского пути оно случилось и что его задержало. Весь разбор Гарри Робертса именно про этот разрыв между наличием числа и наличием понимания.</p><h2>Что забрать с собой</h2><p>Три слоя решают три разные задачи, и провал на любом из них выглядит одинаково: дашборд есть, ответа нет. Без покрытия вы не видите части системы. Без перевода трасс в метрики видите всё и не понимаете ничего. Без дисциплины в чтении принимаете смену методики за регрессию.</p><p>Начинать проще всего с третьего слоя: он не требует ни новой инфраструктуры, ни единой строчки кода, только дисциплины чтения. Сверьте движение своих метрик с движением рынка и убедитесь, что расследуете настоящую регрессию, а не смену методики. Дальше уже видно, чего не хватает: покрытия или перевода трасс в решения.</p><p>Материалы разбора: <a href="https://dev.to/neeraj_singhi_golang/ebpf-powered-request-tracing-in-go-microservices-without-instrumentation-tax-34kf">устройство трассировки Go-сервисов через eBPF</a>, <a href="https://www.cncf.io/blog/2026/08/21/how-to-turn-slow-queries-into-actionable-reliability-metrics-with-opentelemetry/">перевод медленных запросов в метрики надёжности</a> и <a href="https://csswizardry.com/2026/07/web-perf-wednesday-002-the-metrics-dont-tell-the-whole-story/">разбор того, как метрики вводят в заблуждение</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Идемпотентность и Outbox: как не выполнить одну операцию дважды</title>
      <link>https://tproger.ru/articles/idempotentnost-i-outbox-kak-ne-vypolnit-odnu-operaciyu-dvazhdy</link>
      <comments>https://tproger.ru/articles/idempotentnost-i-outbox-kak-ne-vypolnit-odnu-operaciyu-dvazhdy?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Tproger]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/idempotentnost-i-outbox-kak-ne-vypolnit-odnu-operaciyu-dvazhdy</guid>
      <description><![CDATA[<p>Как сделать ручку идемпотентной, где ломается наивная проверка ключа и зачем нужен transactional outbox. Забирайте код на Python, SQL и Node.js и чеклист.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/idempotentnost-i-outbox-kak-ne-vypolnit-odnu-operaciyu-dvazhdy">Идемпотентность и Outbox: как не выполнить одну операцию дважды</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Архитектура ПО]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 09 Sep 2026 05:00:35 GMT</pubDate>
      <content:encoded><![CDATA[<p>История, с которой начинает автор одного из разборов ниже, звучит буднично. Платёжный шлюз не ответил вовремя, клиентская библиотека повторила запрос, и покупателя списали дважды. Сумма небольшая, а возврат, тикет в поддержку и восстановление доверия заняли недели.</p><p>Виноват тут не шлюз. Виноват сервер, который исходил из того, что каждый запрос приходит ровно один раз. В сети, где теряются ответы, это допущение неверно всегда.</p><p>Идемпотентность — свойство операции, при котором повторное выполнение приводит к тому же состоянию, что и однократное. Сам ответ при этом может отличаться: повторный DELETE вернёт 404 вместо 200, и метод от этого идемпотентным быть не перестаёт. У HTTP это закреплено на уровне методов: <a href="https://www.rfc-editor.org/rfc/rfc9110">RFC 9110</a> относит к идемпотентным PUT, DELETE и безопасные методы, а POST идемпотентным по своей природе не является. Бизнес-операции почти всегда отправляют именно через POST.</p><p>Клиент не может отличить «сервер не получил запрос» от «сервер выполнил операцию, но ответ потерялся», поэтому повтор придёт в любом случае.</p><p>Ключ идемпотентности генерирует клиент, а сервер хранит связку ключа со слепком запроса и с готовым ответом, чтобы повтор получил тот же результат, а не новый.</p><p>Проверка «посмотреть и вставить» неатомарна: два одновременных повтора оба увидят отсутствие ключа. Нужен уникальный индекс или условная запись.</p><p>Запись в базу и отправка в очередь в одну транзакцию не помещаются. Обёртывать сетевой вызов в BEGIN и COMMIT вредно вдвойне: корректности не даёт, а пул соединений выедает.</p><p>Transactional outbox решает это одной таблицей: событие пишется в той же транзакции, что и бизнес-запись, а отдельный процесс доставляет его в очередь.</p><h2>Почему повтор неизбежен</h2><p>Сеть отказывает так, что установить факт доставки невозможно в принципе. Есть три типовых сценария, и внешне они неразличимы:</p><ul><li>Сервер обработал запрос, но ответ потерялся по дороге назад.</li><li>Сервер всё ещё считает, а у клиента уже сработал таймаут.</li><li>Балансировщик повторил запрос сам, никого об этом не уведомив.</li></ul><p>Для GET повтор безвреден. Для POST /payments это второе списание. Отсюда и правило: одна логическая операция должна приводить к одному записанному итоговому состоянию, сколько бы раз её ни отправили. Осознанно новая операция обязана прийти с новым ключом.</p><h2>Два способа сделать ручку идемпотентной и один в довесок</h2><h3>Способ первый: ключ идемпотентности</h3><p>Самый распространённый вариант: клиент генерирует уникальный идентификатор на одну логическую операцию и повторяет его при каждой попытке. Сервер хранит соответствие ключа и ответа, а на дубликате возвращает сохранённый результат вместо повторного выполнения работы.</p><p>Три детали, на которых ошибаются чаще всего. Ключ генерирует клиент, а не сервер: смысл в том, что сервер сам по себе не отличит новый запрос от повтора. Ключ должен быть с высокой энтропией, обычно это UUID v4; выводить его из изменяемого или малоразнообразного поля вроде номера клиента нельзя, потому что это повышает риск коллизии и переигрывания чужой операции.</p><p>И последнее: повтор должен получить <b>тот же самый ответ</b>. Если первая попытка вернула 201 с идентификатором платежа, то и повтор возвращает те же 201 и тот же идентификатор, а не 409 и не пустую двухсотку. Иначе клиент решит, что операция не прошла, и попробует ещё раз.</p><h3>Способ второй: сделать операцию идемпотентной по смыслу</h3><p>Иногда ключ не нужен вовсе, потому что семантику можно спроектировать идемпотентной с самого начала. Классический пример — PUT /users/42, который задаёт полное представление ресурса: отправьте его дважды, и состояние будет одним и тем же.</p><p>Для операций создания трюк в том, чтобы выводить идентификатор из самого запроса, а не генерировать случайный на каждый вызов:</p><p>Идентификатор детерминированно выводится из почты, поэтому повторный запрос даёт того же пользователя без дублирующей строки. Плата за простоту — необходимость естественного уникального ключа: почты, артикула, внешнего идентификатора. Хеш при этом считается от точной строки, поэтому почту нужно привести к нижнему регистру и обрезать пробелы до хеширования: иначе один и тот же ящик с заглавной буквы даст второго пользователя. И ключ должен быть неизменным: если пользователь сменит почту, выведенный из неё идентификатор либо останется прежним и перестанет соответствовать данным, либо изменится и оторвётся от всех ссылок на него в соседних таблицах. Нет подходящего ключа, возвращайтесь к первому способу.</p><h3>Довесок: оптимистичная блокировка</h3><p>Этот приём идемпотентности не даёт и в списке стоит по другой причине. Ключ защищает от повторов одного и того же запроса, но ничего не делает с двумя <b>разными</b> запросами, которые правят одну запись. Здесь работает проверка версии: клиент присылает версию, которую видел, а сервер отклоняет обновление при несовпадении.</p><p>Обратите внимание, что проверка версии живёт внутри самого UPDATE. Разнести её на отдельное чтение и последующую запись означало бы воспроизвести ровно ту гонку, о которой пойдёт речь в следующем разделе: два запроса с одной устаревшей версией оба прошли бы проверку и оба записали бы результат. Идемпотентным одиночный запрос этот приём не делает, зато закрывает частый источник задвоенных эффектов: двух писателей, затирающих работу друг друга.</p><h2>Где наивная реализация ключа разваливается</h2><h3>Гонка в проверке</h3><p>Последовательность «проверить наличие ключа, потом вставить» содержит зазор, в который помещаются оба одновременных повтора: обе стороны видят, что ключа нет, и обе выполняют работу. Резервировать ключ нужно атомарно, через уникальное ограничение базы, условную запись или транзакционный compare-and-set (атомарное сравнение с записью).</p><p>Это же относится и к примеру с платежом выше: замена словаря в памяти на Redis гонку не закрывает, пока проверка и вставка остаются двумя отдельными командами. Нужен атомарный примитив резервирования, вроде SET key value NX или INSERT ... ON CONFLICT DO NOTHING.</p><p>Проверяется это только настоящей конкуренцией. Юнит-тест, вызывающий функцию дважды подряд, гонку не поймает никогда. Отправьте полсотни одновременных запросов с одним ключом и убедитесь, что побочный эффект произошёл ровно один раз.</p><h3>Слепок запроса, а не только ключ</h3><p>Хранить один ключ недостаточно. Сервер канонизирует поля, определяющие бизнес-смысл операции, и считает от них хеш. Канонизация означает приведение к единому виду порядка полей, форматов чисел и дат, опущенных значений по умолчанию и незначащих пробелов. Если повторный вызов обязан воспроизвести решение, принятое по прежним правилам, в слепок включают ещё и версию политики. Пример: между первой попыткой и повтором поменялись тарифы, и повтор обязан вернуть старую цену, а не пересчитать по новой. Без версии в слепке сервер этого различия не увидит.</p><p>Когда тот же ключ приходит с другим слепком, это ошибка на стороне клиента, и отдавать ему старый результат нельзя. <a href="https://dev.to/seo_optimization_591fad6c/designing-idempotent-decision-endpoints-that-survive-real-retries-6c1">Разбор проектирования идемпотентных ручек</a> предлагает отвечать 409 Conflict; <a href="https://dev.to/sirmax/3-ways-to-make-your-api-requests-idempotent-with-working-code-4inl">автор практического руководства</a> в этом случае возвращает 422. Важно, чтобы выбранный код был задокументирован и никогда не подменяется молчаливой отдачей чужого ответа.</p><h3>Состояния и коды ответа</h3><p>Минимальная модель состояний записи выглядит так: PROCESSING, SUCCEEDED, FAILED_RETRYABLE и FAILED_FINAL. Рядом хранятся ключ операции, слепок, отметки времени, идентификатор решения, снимок ответа и версия политики. Клиенту нужна детерминированная карта из состояния в код ответа:</p><ul><li>201 или 200 — первый успешно завершённый результат.</li><li>200 с явной пометкой о повторе — проигрывание сохранённого ответа.</li><li>202 со ссылкой на статус — работу уже выполняет другой обработчик, начинать вторую не нужно.</li><li>409 — ключ переиспользован с другим содержимым.</li><li>Задокументированная финальная ошибка — обработка провалилась, и автоматическое продолжение небезопасно.</li></ul><p><b>Срок жизни ключей:</b><br />Хранить их вечно не нужно, это медленная утечка. Сутки покрывают практически любое реальное окно повторов, но выбирать срок стоит от риска предметной области: у платежей и у рекомендаций он разный. И помните, что ключ приходит снаружи: ограничьте длину и набор символов, привяжите его к арендатору и не дайте одному пользователю вытащить результат чужой операции.</p><h2>Вторая половина задачи: база и очередь</h2><p>Допустим, ручка стала идемпотентной. Остаётся более коварная проблема: почти всякая бизнес-операция пишет не в одно место. Заказ сохраняется в базу и публикует событие в очередь, чтобы склад начал сборку, почтовый сервис отправил подтверждение, а антифрод посмотрел на транзакцию.</p><p>Обе половины статьи растут из одного факта: ни HTTP, ни очередь не обещают доставку ровно один раз, они обещают её хотя бы один раз. Поэтому защищаться приходится дважды, на входе и на выходе.</p><p>Это две записи в две разные системы, и общей транзакции у них нет. Упал процесс, моргнула сеть, выкатился деплой между двумя вызовами — одна сторона зафиксирована, вторая нет. Заказ подтверждён на экране покупателя, а склад о нём не знает. Ошибка при этом нигде не залогирована и алерт не сработал.</p><h3>Почему обернуть это в транзакцию нельзя</h3><p>Соблазнительный и заведомо неверный вариант выглядит так:</p><p>Транзакция базы не имеет власти над очередью и умеет откатывать только операции базы. Если отправка прошла, а COMMIT упал, сообщение уже в очереди и забрать его оттуда нельзя.</p><p>Есть и вторая беда, чисто эксплуатационная. Такой код держит открытое соединение и блокировки строк всё время сетевого вызова. Обычно очередь отвечает быстро, но под нагрузкой, ретраями или деградацией вызов растягивается на секунды, и все запросы к тем же строкам стоят в очереди. Это надёжный способ исчерпать пул соединений и уронить заодно ни в чём не повинные части сервиса.</p><h3>Outbox: событие как строка в той же транзакции</h3><p>Идея паттерна в том, чтобы перестать считать публикацию второй записью. Вместо вызова очереди приложение вставляет строку в таблицу outbox в той же транзакции, что и бизнес-запись. Отдельный процесс читает таблицу и публикует сообщения дальше.</p><p>Откатилась транзакция, и вместе с ней исчезла строка outbox: осиротевшего сообщения в очереди не осталось. Упало приложение сразу после фиксации — строка на месте со статусом pending, и доставщик заберёт её на следующем проходе. Паттерн опирается ровно на одну гарантию, которую база и так даёт: атомарность одной транзакции.</p><p>Доставщик выбирает пачку необработанных строк и помечает их отправленными только после подтверждения очередью. Ключевая деталь здесь одна:</p><p>Этот SELECT и последующая простановка статуса выполняются в одной транзакции: блокировка живёт до фиксации. Благодаря SKIP LOCKED доставщик масштабируется горизонтально из коробки, каждый экземпляр берёт свой набор строк. А если он упадёт посреди пачки, вся пачка откатится и уйдёт повторно, что даёт ещё один довод в пользу идемпотентного потребителя.</p><p>Может показаться, что здесь мы делаем ровно то, что осудили выше: держим блокировку на время сетевого вызова. Разница в том, что блокируется не бизнес-таблица и соединение берётся не из пула, обслуживающего пользовательские запросы, а SKIP LOCKED не даёт одной медленной строке задержать остальные.</p><h3>Потребитель обязан быть идемпотентным</h3><p>Если доставщик упал посреди прохода, на следующем он переотправит те же строки. Очереди вроде SQS и Kafka в типовой конфигурации гарантируют доставку «хотя бы один раз», поэтому дедупликация на приёмной стороне обязательна, и уникальным ключом служит идентификатор события или решения.</p><p>Делает это условная запись. Важная деталь, на которой легко ошибиться: сама по себе она пустой операцией не становится. При несовпадении условия драйвер бросает исключение, и его нужно поймать явно, отличив штатный повтор от настоящей ошибки:</p><p>Настройки продюсера и подтверждения брокера снижают количество повторов, но не снимают с приложения ответственность за однократность бизнес-эффекта.</p><h3>Что добавить перед продакшеном</h3><p>Двух статусов мало. Нужен статус failed и счётчик попыток: после N неудач строка помечается провалившейся и перестаёт крутиться в цикле вечно. На стороне очереди настраивается очередь недоставленных сообщений, чтобы то, что потребитель не смог обработать, оседало в наблюдаемом месте, а не исчезало молча.</p><p>Когда задержка опроса становится критичной, полагающийся на периодический опрос доставщик заменяют захватом изменений: инструменты вроде Debezium читают журнал предзаписи PostgreSQL и публикуют изменения без паузы на опрос. Таблица outbox и потребитель при этом не меняются. Но это заметно более тяжёлое эксплуатационное обязательство, поэтому начинать почти всегда стоит с опроса.</p><h2>Что забрать с собой</h2><p>Обе части задачи выглядят избыточными ровно до первого инцидента. Тридцать строк кода с ключом идемпотентности стоят дешевле одного тикета с заголовком «вы списали дважды», а таблица outbox дешевле расследования, почему заказ есть у клиента и отсутствует на складе.</p><p>Коварство проблемы двух записей в том, что наивная реализация работает правильно почти всегда. Она отказывает в зазоре между двумя системами, и зазор этот становится виден только когда что-то пошло не так в самый неподходящий момент. К моменту, когда расхождение заметят в продакшене, данные уже разъехались, и красивого способа их починить не будет.</p><p>Как одно неверное допущение о порядке вызовов обернулось эпидемией задвоенных операций, показано в <a href="https://tproger.ru/articles/skrytyj-sboj-idempotentnosti-v-finteh-sisteme-razbor-incidenta">разборе реального инцидента в финтех-системе</a>.</p><p>Материалы, на которых основан разбор: <a href="https://dev.to/sirmax/3-ways-to-make-your-api-requests-idempotent-with-working-code-4inl">три паттерна идемпотентности с рабочим кодом</a>, <a href="https://dev.to/seo_optimization_591fad6c/designing-idempotent-decision-endpoints-that-survive-real-retries-6c1">проектирование ручек, переживающих реальные повторы</a> и <a href="https://www.freecodecamp.org/news/how-to-fix-the-dual-write-problem-in-node-js-with-the-outbox-pattern/">пошаговая сборка outbox на Node.js</a>.</p><p>Откройте самый денежный обработчик в своём сервисе и попробуйте отправить в него один и тот же запрос дважды. Если во второй раз что-то произошло, вы уже знаете, с чего начать понедельник.</p>]]></content:encoded>
    </item>
    <item>
      <title>7 стратегий модернизации легаси: что рефакторить, переносить, заменять или переписывать</title>
      <link>https://tproger.ru/articles/7-strategij-modernizacii-legasi-chto-refaktorit-perenosit-za</link>
      <comments>https://tproger.ru/articles/7-strategij-modernizacii-legasi-chto-refaktorit-perenosit-za?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Дима Дмитриев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/7-strategij-modernizacii-legasi-chto-refaktorit-perenosit-za</guid>
      <description><![CDATA[<p>7 стратегий модернизации легаси: когда оставить как есть, а когда рефакторить, переносить или переписывать. Практический гайд.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/7-strategij-modernizacii-legasi-chto-refaktorit-perenosit-za">7 стратегий модернизации легаси: что рефакторить, переносить, заменять или переписывать</a>»</p>]]></description>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Архитектура ПО]]></category>
      <category><![CDATA[Рефакторинг]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 25 Aug 2026 08:00:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Переписать проект с нуля — первое, что придет вам в голову, но по факту это месяцы работы без новых функций и без гарантии, что новая версия окажется лучше старой. Часто лучше обновить стек, разобрать один проблемный модуль или постепенно вынести часть логики в отдельный сервис.</p><h2>Сначала понять, нужно ли трогать систему</h2><p>Если приложение выдерживает нагрузку, получает исправления безопасности и не мешает выпускать новые функции, спешить с модернизацией незачем. Работает и работает.</p><p>Проблемы начинаются, когда разработчик меняет один модуль и роняет соседние, релизы начинают выкатываться реже, а поддержка системы забирает больше времени. Или большой монолит может долго запускаться, плохо масштабироваться и больно реагировать на сбой внутри одного модуля. Причин бывает сколько угодно, но стратегию подбирают под каждую отдельно. Где-то хватит новой версии фреймворка, где-то придётся отделять авторизацию, где-то — выносить отчёты в свой сервис.</p><p>Поэтому начинают с проблемы:</p><ul><li>старый стек больше не получает обновления;</li><li>новые функции делаются слишком долго;</li><li>систему трудно тестировать или масштабировать;</li><li>сбой одного модуля затрагивает всё приложение;</li><li>на поддержку уходит всё больше людей и рабочих часов.</li></ul><p>Всё это можно измерить, проверить и объяснить бизнесу. Дальше — варианты.</p><h2>1. Оставить систему как есть</h2><p>Иногда самое разумное решение состоит в том, чтобы ничего не менять.</p><p>Допустим, приложение решает одну понятную задачу, нагрузка на него почти не растёт, а новые функции добавляют пару раз в год. Переписывать такую систему только из-за возраста кода смысла мало: команда потратит квартал, а бизнес получит примерно ничего.</p><p>Следить за ней всё равно придётся. Обновления безопасности нужно ставить, резервные копии проверять, а документацию по запуску, интеграциям и восстановлению держать в актуальном состоянии.</p><p>Заранее стоит договориться, какое событие станет сигналом к началу модернизации. Например:</p><ul><li>платформа или библиотека перестала получать исправления безопасности;</li><li>поддержка стала занимать больше времени, чем раньше;</li><li>система перестала выдерживать нагрузку;</li><li>нужную бизнесу функцию нельзя добавить без большой переделки;</li><li>в команде не осталось людей, которые понимают код.</li></ul><p>Пока ничего из этого не случилось, систему оставляют в текущем виде.</p><h2>2. Вывести ненужную часть из эксплуатации</h2><p>Иногда часть легаси-системы уже никому не нужна: старый модуль, забытый API или интеграция с сервисом, который давно закрылся. Такой компонент проще отключить, чем поддерживать его дальше и тем более куда-то переносить.</p><p>Сначала придётся разобраться с зависимостями, потому что команда может просто не знать, что модуль дёргают соседние сервисы или другой отдел. Перед отключением стоит:</p><ul><li>проверить логи и запросы к компоненту;</li><li>найти связанные сервисы и задания;</li><li>узнать, какие команды пользуются его данными;</li><li>подготовить способ быстро вернуть его обратно.</li></ul><p>После проверки компонент выключают на тестовый период, и если за это время ошибок не появилось, код и инфраструктуру удаляют. Данные, которые ещё могут понадобиться, перед этим складывают в архив.</p><h2>3. Обновить стек без смены архитектуры</h2><p>Система остаётся монолитом: команда не делит её на микросервисы и не трогает основные связи между модулями. Меняется техническая начинка, то есть язык, фреймворк, библиотеки, база данных или среда выполнения.</p><p>Например, приложение переводят на поддерживаемую версию .NET, но оно по-прежнему остаётся одним приложением. Такой вариант подходит, когда архитектура со своими задачами пока справляется, а болит именно устаревшая технология.</p><p>Просто поменять номер версии в конфиге обычно не получается, потому что старые библиотеки отказываются работать с новым фреймворком, а часть API меняется или исчезает вовсе. Поэтому сначала собирают список зависимостей и смотрят, что из этого вообще можно обновить.</p><p>Дальше компоненты обновляют по очереди, прогоняя тесты после каждого шага. Отдельно проверяют интеграции, работу с базой данных и поведение под нагрузкой. Новую версию сначала разворачивают в тестовой среде, а для выката в продакшен готовят план отката.</p><p>Проблемы самого монолита при этом никуда не денутся: если модули сильно связаны между собой или приложение плохо масштабируется, одним обновлением стека дело не обойдётся.</p><h2>4. Перенести систему на другую платформу</h2><p>Здесь код приложения почти не меняют, меняется место, где оно работает. Например, систему можно перенести с физических серверов на виртуальные машины или в облако. Другой вариант — запустить приложение в контейнерах. Архитектура при этом остаётся прежней: монолит не превращается в набор микросервисов.</p><p>Перед переносом нужно проверить требования к процессору, памяти, дискам и сети. Ещё нужно учесть внешние сервисы, настройки безопасности и доступ к базе данных. Затем систему разворачивают на новой платформе и проверяют под рабочей нагрузкой.</p><p>Такой перенос сам по себе не ускоряет приложение. Если проблема находится в коде или базе данных, смена инфраструктуры её не решит. Зато команда может отказаться от устаревших серверов и упростить дальнейшую поддержку системы.</p><p>Старую среду лучше отключать только после проверки новой. Если при запуске возникнут ошибки, трафик можно будет вернуть обратно.</p><h2>5. Заменить готовым продуктом</h2><p>Некоторые внутренние системы дешевле заменить готовым решением. Типичная ситуация: компания годами поддерживает собственный сервис, хотя продукт с теми же функциями давно можно купить или взять по подписке.</p><p>Начинают со сравнения расходов. С одной стороны, зарплаты разработчиков, серверы, исправление ошибок и обновления своей системы. С другой, лицензия, внедрение, перенос данных и доработки готового продукта.</p><p>Дальше сверяют функции, потому что готовое решение может не поддерживать часть внутренних процессов или нужные интеграции. Команда составляет список обязательных возможностей и проверяет их до перехода, пока договор ещё не подписан.</p><p>Отдельно разбираются с данными: что переносить, в каком формате и как проверить результат. Старую систему держат включённой, пока пользователи не начнут работать в новой, а данные и интеграции не пройдут проверку.</p><h2>6. Рефакторить по частям</h2><p>При рефакторинге поведение системы снаружи сохраняется, а внутри код меняется: команда упрощает структуру, разделяет связанные компоненты, убирает дублирование и обновляет отдельные зависимости.</p><p>Переписывать для этого весь проект не нужно. Сначала выбирают модуль, который часто меняется, собирает много ошибок или мешает добавлять новые функции. Затем фиксируют его текущее поведение тестами и только после этого берутся за код.</p><p>Работу делят на небольшие этапы, и после каждого запускают тесты, чтобы убедиться, что система ведёт себя как раньше. Если что-то всё-таки сломалось, маленькое изменение откатить куда проще, чем трёхнедельный коммит.</p><p>Чтобы выбрать модули, нужно понимать их зависимости, частоту изменений и роль в бизнес-процессах. Когда внутри компании таких специалистов нет, зовут внешнюю команду.<a href="https://centicore.ru/services/legacy-modernization/"> Centicore</a> занимается модернизацией легаси-кода, баз данных и инфраструктуры, в услугу входят рефакторинг кодовой базы и обновление технологического стека.</p><h2>7. Переписать систему постепенно</h2><p>Систему можно заменять по одному модулю за раз, оставляя остальное работать как прежде. Подход называется Strangler Fig, по имени фикуса-душителя, который оплетает дерево и со временем занимает его место.</p><p>Новые функции сразу пишут на новом стеке, какое-то время старая и новая части работают параллельно, поэтому запросы приходится направлять в нужную версию системы. Новый сервис при этом может ходить в прежнюю базу данных, и если такая схема начинает мешать работе или масштабированию, данные позже переезжают в отдельную БД.</p><p>Когда функция переехала, старый модуль отключают. Монолит понемногу уменьшается, а новая система забирает его задачи.</p><h2>Как выбрать стратегию</h2><p>Для всей системы один подход выбирать необязательно. Стабильный модуль можно не трогать, старую интеграцию удалить, а авторизацию постепенно вынести из монолита.</p><p>Сначала каждую часть системы проверяют по нескольким критериям:</p><ul><li>как часто в ней меняют код;</li><li>сколько времени уходит на поддержку;</li><li>от каких сервисов и баз данных она зависит;</li><li>есть ли автоматические тесты;</li><li>сколько времени она может не работать;</li><li>хватает ли у команды людей и знаний для изменений.</li></ul><p>Рефакторинг подойдёт коду, который трудно менять, хотя заменять его целиком нет смысла. Когда готовый продукт закрывает те же задачи, считают стоимость перехода. А если архитектура уже мешает выпускать функции и масштабировать систему, отдельные модули переписывают постепенно.</p><h2>Что подготовить до начала работ</h2><p>Работу делят на этапы, и каждый должен давать результат, который можно проверить и выпустить отдельно. Задачу длиной в несколько месяцев тяжело оценивать, тестировать и откатывать.</p><p>До начала изменений нужно:</p><ul><li>составить список модулей, сервисов, баз данных и интеграций;</li><li>найти команды, которые пользуются системой;</li><li>проверить автоматические и ручные тесты;</li><li>измерить текущую нагрузку и время ответа;</li><li>определить порядок выпуска изменений;</li><li>подготовить откат к рабочей версии.</li></ul><p>Тестировать отдельные модули недостаточно. После изменений проверяют интеграции, работу с базой данных, нагрузку и основные пользовательские сценарии.</p><h2>Итого</h2><p>Легаси необязательно переписывать целиком. Сначала стоит понять, какая именно часть системы мешает работать и почему.</p><p>Неиспользуемый код удаляют, устаревший стек обновляют, а систему при необходимости переносят на новую платформу без изменения архитектуры. Отдельные модули рефакторят, заменяют готовым продуктом или переписывают по частям.</p><p>Обычно в одном проекте сочетаются сразу несколько стратегий. Так систему меняют постепенно, продолжают выпускать новые функции и проверяют результат после каждого этапа.</p>]]></content:encoded>
    </item>
    <item>
      <title>Роадмап в QA в 2026: что нужно знать, чтобы получить оффер</title>
      <link>https://tproger.ru/articles/roadmap-v-qa-v-2026-chto-nuzhno-znat-chtoby-poluchit-offer</link>
      <comments>https://tproger.ru/articles/roadmap-v-qa-v-2026-chto-nuzhno-znat-chtoby-poluchit-offer?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Дима Дмитриев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/roadmap-v-qa-v-2026-chto-nuzhno-znat-chtoby-poluchit-offer</guid>
      <description><![CDATA[<p>Как войти в QA в 2026: архитектура микросервисов, REST API, SQL, Kafka, автоматизация и инженерное мышление. Роадмап без тупиковых скиллов.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/roadmap-v-qa-v-2026-chto-nuzhno-znat-chtoby-poluchit-offer">Роадмап в QA в 2026: что нужно знать, чтобы получить оффер</a>»</p>]]></description>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Автоматизирование]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 19 Jun 2026 09:00:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Пять лет назад в тестирование заходили через ручное: кликаешь по чек-листу, смотришь результат, рынок прощает тебе отсутствие навыков. Сейчас на том же месте в вакансиях стоят Kafka, Kubernetes и автотесты на Java.</p><h2>Ручное тестирование как вход больше не работает</h2><p>В 2021-м стратегия «вкатиться через мануальное тестирование» ещё работала. Рынок принимал новичков: знаешь, что такое чек-лист и тест-кейс — уже кандидат. Можно было прийти без кода, без понимания API, без SQL и получить оффер на функциональное тестирование, дальше доучиваясь по ходу.</p><p>Дальше рынок начал двигаться, и двигался он быстрее, чем кажется внутри компании. В 2022-м в вакансиях QA появились приписки: «желательно знание автоматизации», «опыт с API», «базовый SQL». Слово «желательно» сбивает с толку — звучит как бонус, а на деле это знак, куда поедут требования через пару лет. И они поехали: то, что в 2022-м было «желательно», к 2024-му стало обязательным условием.</p><p>К 2024 году ситуация выглядит уже так: смотришь вакансии и ни в одной не встречаешь формулировку «требуется ручной тестировщик». Вместо неё везде QA Engineer со знанием автоматизации, опыт в финтехе, CI/CD, Docker, Kubernetes, углублённое понимание API. К концу 2025-го добавляется ещё и опыт работы с ИИ и LLM.</p><p>Вакансии чисто ручного тестирования из дикой природы не исчезли совсем, но их осталось мало, и условия там соответствующие: либо платят немного, либо требуют коммерческий бэкграунд за плечами. Параллельно реклама курсов «вкатись в IT за три месяца» нагнала на рынок толпу таких же новичков, и у компаний появилась роскошь выбирать.</p><p>Вывод для тех, кто планирует вход в 2026-м: начинать с чек-листов смысла мало, потому что это тупиковая ветка, с которой потом всё равно придётся переучиваться. Логичнее сразу собирать ту базу, которая позволит работать с первого дня и не упираться в потолок. Что в эту базу входит, дальше по разделам.</p><h3>Научиться понимать архитектуру</h3><p>Проектировать системы вам не придётся, это работа архитектора. Задача тестировщика — представлять, как устроено то, что он тестирует, чтобы видеть всю цепочку, а не отдельную кнопку.</p><p>На практике это четыре вещи:</p><ol><li>Как сервисы общаются между собой: синхронно через HTTP, когда один ждёт ответа другого, или асинхронно через очередь сообщений, когда событие кладётся в брокер и подбирается, когда получатель готов.</li><li>Где хранятся данные и как к ним обращаются разные компоненты.</li><li>Что произойдёт, если один из сервисов упадёт, и кто из соседних это заметит.</li><li>Как запрос трансформируется на каждом шаге пути от клиента до ответа.</li></ol><p>Зачем это тестировщику. Пока вы тестируете поверхностно — нажал, посмотрел результат, — вы можете зафиксировать, что баг есть, но не объясните почему. На вопрос «где сломалось» ответа нет, потому что система для вас непонятная. Как только появляется понимание потоков данных, сразу становится лучше. Вместо «кнопка не работает» вы говорите: запрос пришёл в Gateway, прошёл в Core-сервис, событие легло в Kafka, консьюмер его прочитал, но в базе нужной записи нет — значит, ищем разрыв на участке между консьюмером и базой. Это уже баг, с которым можно идти к разработчику.</p><p>Лучший способ это уложить в голову — поднять микросервисное приложение локально и посмотреть, как сервисы взаимодействуют. Перед практикой имеет смысл прочитать «Designing Data-Intensive Applications» Мартина Клеппмана (на русском вышла как «Высоконагруженные приложения»). Кода там нет, зато подробно разобрано, как системы устроены изнутри, — для QA это полезнее, чем уметь самому писать сервисы.</p><p>Дальше берём готовые демо-проекты с низким порогом входа. Они поднимаются одной командой через Docker Compose, так что копаться в коде не нужно, нужно исследовать: отправить запрос через Postman, проследить по логам, как он прошёл по цепочке, намеренно остановить один контейнер и посмотреть, что станет с остальными. Два репозитория подходящего формата:</p><ul><li>Microservice Kafka Sample — три сервиса (заказы, доставка, выставление счёта), между ними Kafka, у каждого своя база PostgreSQL, поднимается через docker-compose up. Создаёте заказ в одном сервисе, через какое-то время накладная и статус доставки появляются в других. Удобно трассировать запрос и искать, где он застрял.</li><li>Microservices with Spring Boot and Kafka Demo Project — посложнее: заказы, платежи, склад, распределённые транзакции по паттерну SAGA, поддержка Docker Compose и Testcontainers. Хорошо показывает, что происходит с транзакцией, когда она идёт через несколько сервисов и один из них падает.</li></ul><p>Если хочется теории вместе с практикой, на Stepik есть курс «Microservices — паттерны и практика построения микросервисов»: русскоязычный, разбирает паттерны взаимодействия, асинхронные системы, RabbitMQ. Он заточен под понимание концепций, а не под написание продакшн-кода, — то, что нужно.</p><h2>Три технологии, которые спрашивают всегда</h2><ol><li>HTTP и REST API. REST — это договорённость между клиентом и сервером о том, как они общаются. Клиент просит: дай данные о пользователе с ID 42. Сервер отвечает JSON-ом и кодом: 200 — всё нашлось, 404 — такого пользователя нет, 403 — прав не хватает. Тестировщик, который умеет вызывать API через Postman, curl или код, проверяет логику системы мимо интерфейса — раньше и точнее, чем через клики по экрану. Базовый минимум: методы (GET, POST, PUT, DELETE), коды ответов (2xx, 4xx, 5xx), заголовки, структура JSON, аутентификация.</li><li>Базы данных и SQL. Почти каждый дефект оставляет след в базе: либо лежит некорректная запись, либо записи нет вообще. Написать SELECT с джойнами, проверить результат агрегации, отловить дубли — ежедневная работа QA-инженера. На собесе это спрашивают как данность, а не как редкий бонус.</li><li>Брокеры сообщений и Kafka. Kafka даёт сервисам общаться асинхронно: один кладёт событие в топик, другой забирает его, и никто не висит в ожидании. В распределённых системах это стандарт. Если данные не появились там, где их ждали, возможно, они застряли в очереди, а не пропали из базы. Это две разных ситуации, и путать их дорого для бизнеса.</li></ol><p>Важное предупреждение, чтобы не отпугнуть: писать эти сервисы самому QA не нужно. Цель — понять, что происходит внутри, когда данные идут от одного сервиса к другому. Поднял проект, посмотрел Postman, почитал логи, остановил контейнер, посмотрел на последствия — этого достаточно, чтобы общаться с командой разработки.</p><h3>Научиться читать логи</h3><p>Когда сервис падает в продакшене, времени воспроизводить баг руками нет, и единственное, что у вас есть, — это логи. Особенно это нужно на критичной инфраструктуре вроде государственных контрактов, где инциденты идут потоком, а каждая минута простоя стоит денег.</p><p>Выглядит типичная диагностика так:</p><ul><li>Прилетает алерт: сервис X начал возвращать 500-е ошибки.</li><li>Открываете Kibana, фильтруете по временному интервалу и имени сервиса, чтобы отсечь лишний шум.</li><li>Находите трейс конкретного запроса — от входящего HTTP-вызова до ответа базы данных.</li><li>В трейсе видите stacktrace с исключением в определённом классе и конкретным сообщением.</li><li>Дальше тянете за эту нитку до корневой причины: например, оказывается, что упал не сам сервис, а внешний, к которому он обращался, и причина — таймаут.</li></ul><p>Помимо Kibana для разбора логов в работе пригодится связка Grafana и Prometheus для мониторинга метрик. Логи отвечают на вопрос «что именно сломалось в этом запросе», метрики показывают картину шире: когда началась деградация, какой сервис первым ушёл в красное, как менялась нагрузка перед инцидентом. Вместе они дают и точку отказа, и контекст вокруг неё.</p><p>Этот навык как раз отличает среднего тестировщика от хорошего. Средний по факту падения скажет «не работает» и пойдёт заводить тикет. Хороший откроет логи, пройдёт по трейсу и принесёт разработчику не жалобу, а готовую гипотезу о том, где и почему сломалось. Вторые на рынке зарабатывают больше, и тренируется это ровно на тех же демо-проектах: подняли, сломали контейнер, полезли в логи смотреть, что система об этом написала.</p><h2>Зачем QA язык программирования</h2><p>Помимо скорости код даёт понимание работы команды разработки. Когда QA пишет автотесты на том же языке, на котором разработчики пишут продукт, стирается граница между «вашим» и «нашим» кодом. Проблему можно обсудить на уровне реализации, быстро получить консультацию, а иногда разработчик и сам запускает ваши тесты, чтобы проверить свою фичу, или вносит правку в тестовый код, когда видит, в чём причина нестабильности.</p><p>Конкретно код у QA уходит на несколько вещей:</p><ul><li>Автотесты — заменяют ручной прогон регресса, гоняются хоть каждую ночь.</li><li>Тестирование API — написать авторизацию, отправить запрос, проверить JSON-схему ответа.</li><li>Генерация тестовых данных — создать тысячи записей с разными параметрами под нагрузочные и граничные сценарии.</li><li>Верификация в базе — SQL-запросы, которые проверяют, что в данных лежит именно то, что должно.</li><li>Shift-left — писать тесты параллельно с разработкой, ещё на этапе требований, чтобы дефекты ловились раньше.</li></ul><p>С чего начинать. Java или Python — хорошие первые языки, оба распространены в автоматизации и под оба полно вакансий. Но учить язык лучше в контексте задач тестирования, а не абстрактно по учебнику: сразу написать первый UI-тест через Selenium, сделать HTTP-запрос через RestAssured или requests, дёрнуть SQL-запросом реальную базу.</p><h2>Инженерное мышление вместо «кнопка не работает»</h2><p>Все навыки из предыдущих разделов держатся на одной привычке думать определённым образом. На заводе фраза «деталь бракованная» не закрывает вопрос: нужно найти причину в процессе, измерить отклонение, воспроизвести и устранить. Та же логика переносится на программные системы, и именно она отличает инженера от человека, который кликает по экрану и пишет «не работает».</p><p>Складывается это мышление из нескольких рабочих привычек:</p><ol><li>Спрашивать «почему», а не только «что». Не «кнопка не нажимается», а «почему запрос возвращает 403 именно для этой роли».</li><li>Держать в голове систему целиком: как правка в одном сервисе аукнется в соседних через Kafka-события, общую базу или контракты API.</li><li>Заранее прикидывать риски: что сломается первым под нагрузкой, какие граничные случаи опаснее остальных. Сюда же относится участие в проектировании: дефект, пойманный на этапе требований, обходится примерно в десять раз дешевле, чем тот же дефект, найденный в продакшене.</li><li>Оперировать цифрами: время прогона регресса, покрытие тестами, количество инцидентов.</li></ol><p>Хорошая новость для тех, кто приходит в тестирование из технической специальности. Физики, химики, инженеры с производства уже умеют работать с причинно-следственными связями и видеть систему как набор связанных процессов. Этот навык никуда не девается при смене сферы, его остаётся переложить на специфику софта: вместо станков и допусков — сервисы, запросы и базы данных. База, за которую в IT доплачивают, у вас по факту уже есть.</p><h2>Итого</h2><p>Если собрать роадмап в один список, маршрут получается такой:</p><ul><li>Разбираться в архитектуре и поднимать демо-микросервисы локально;</li><li>Знать HTTP с REST, SQL и брокеры вроде Kafka;</li><li>Уметь читать логи, потому что в проде это ваш основной инструмент;</li><li>Освоить язык под автоматизацию;</li><li>И приучать себя думать потоками данных, а не кнопками.</li></ul><p>Архитектура объясняет, зачем нужны API, базы и брокеры. Понимание этих технологий делает осмысленным чтение логов. Логи и автоматизация вместе подводят к коду.</p><p>И ещё одно наблюдение, ради которого статья была написана. Рынок QA за пять лет переписал требования дважды и продолжит переписывать. Гнаться за конкретной строчкой в вакансии бессмысленно — она устареет к следующему собесу. Работает другая установка: целиться не в «войти в IT через тестирование», а в «стать инженером, который умеет тестировать». Первое даёт оффер на год, второе — профессию, которая переживёт любую следующую волну требований.</p>]]></content:encoded>
    </item>
    <item>
      <title>Netflix построила Service Topology: живая карта микросервисов</title>
      <link>https://tproger.ru/articles/netflix-postroila-zhivuyu-kartu-servisov-kak-ustroena-service-top</link>
      <comments>https://tproger.ru/articles/netflix-postroila-zhivuyu-kartu-servisov-kak-ustroena-service-top?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/netflix-postroila-zhivuyu-kartu-servisov-kak-ustroena-service-top</guid>
      <description><![CDATA[<p>Как Netflix объединяет eBPF, IPC-метрики и tracing в единую карту зависимостей. Разбираем, почему статические схемы устарели и что перенести в свою систему.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/netflix-postroila-zhivuyu-kartu-servisov-kak-ustroena-service-top">Netflix построила Service Topology: живая карта микросервисов</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Архитектура ПО]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Графы]]></category>
      <category><![CDATA[Инфраструктура]]></category>
      <category><![CDATA[Архитектура приложений]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 19 Jun 2026 07:47:47 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если вы хоть раз отлаживали микросервис ночью, знаете главный вопрос: это мой сервис сломался или его уронило что-то выше по течению? В системе из тысяч сервисов ответ приходится искать по кускам — метрики, логи и трейсы показывают симптомы, но не дают единой карту зависимостей. Netflix столкнулась с этой же болью и построила инструмент под названием Service Topology, который рисует живую карту зависимостей в реальном времени.</p><p>Service Topology — это не статическая схема из вики, а динамическая карта связей между сервисами. Она обновляется по мере того, как меняется трафик, появляются новые зависимости или старые исчезают. Карта показывает не только «кто с кем говорит», но и контекст: уровень доступности, бизнес-домен, владельца и текущее состояние здоровья.</p><p>Если тема микросервисов для вас новая, начните с базового разбора <a href="https://tproger.ru/articles/chto-takoe-mikroservisy--arhitektura--plyusy-i-minusy--primery">«Что такое микросервисы»</a>, а если выбираете архитектуру для проекта — сравните варианты в материале <a href="https://tproger.ru/articles/monolit-ili-mikroservisy--kak-vybrat-arhitekturu-dlya-novogo-proekta">«Монолит или микросервисы»</a>. Авторский разбор внутреннего устройства Netflix читайте в статье <a href="https://tproger.ru/articles/razrabotchik-izuchal-sistemu-rekomendacij-netflix-mesyacami--vot-chto-skryvaetsya-vnutri">«Разработчик изучал систему рекомендаций Netflix месяцами»</a>.</p><ul><li>Netflix объединила три источника данных: eBPF-сетевые потоки, IPC-метрики и распределённые трейсы.</li><li>Каждый источник строит свой граф; общий вид получается параллельным слиянием слоёв.</li><li>Карта обновляется почти в реальном времени и отвечает на запросы быстрее секунды.</li><li>Инженеры используют её для поиска причин сбоев, оценки зоны поражения и планирования изменений.</li><li>Подход можно перенести в любую распределённую систему, где нужно понимать зависимости.</li></ul><h2>Почему обычной наблюдаемости мало</h2><p>Традиционные инструменты наблюдаемости показывают фрагменты картины. Метрики говорят, что что-то болит. Логи рассказывают, что конкретно произошло в одном сервисе. Трейсы прослеживают путь отдельного запроса. Но ни один из этих сигналов не показывает полную топологию зависимостей — ту самую основу, на которой держится распределённая архитектуры.</p><p>Инженеру в три часа ночи приходится мысленно склеивать данные из разных источников. Это медленно, чревато ошибками и добавляет стресса. Netflix проанализировала тысячи обращений в поддержку за четыре года и увидела повторяющиеся вопросы: кто мои upstream и downstream, что упадёт вместе со мной, почему сервис отображается в панели мониторинга как Unknown (неизвестный сервис). Ответы на них требовали единого представления о зависимостях.</p><h2>Три источника данных Service Topology</h2><p>Главный вывод Netflix: ни один источник не рассказывает всю историю. Поэтому система строит три независимых графа и объединяет их по запросу.</p><h3>Сетевые потоки eBPF</h3><p>На сетевом уровне Netflix собирает потоки ядра через eBPF. Это даёт полноту: сюда попадают все соединения, независимо от того, инструментирован сервис или нет. Слой показывает связи между кластерами и приложениями такими, какими они есть на самом деле. Недостаток — не хватает прикладного контекста: видно, что сервис А достучался до IP-адреса сервиса Б, но неизвестно, какой конкретно endpoint вызывался.</p><h3>IPC-метрики</h3><p>На прикладном уровне собираются метрики межпроцессного взаимодействия. Когда сервис обращается к другому через gRPC, GraphQL или REST, он фиксирует endpoint, ошибки, задержки и протокол. Этот слой даёт детали, которых нет у сетевого: какой именно путь вызывается и с какой вероятностью ошибки. Ограничение очевидно: если сервис не отправляет метрики, его вызовов здесь не будет.</p><h3>Распределённые трейсы</h3><p>Третий слой — трейсинг запросов от начала до конца. Он показывает не «может ли сервис А позвонить сервису Б», а «звонил ли он в рамках этого конкретного пользовательского запроса». Это помогает увидеть поведение во время выполнения, ветвления, фича-флаги и редкие пути. Поскольку трейсы собирают выборочно, редкие сценарии могут не попасть в агрегированный вид.</p><p>Когда инженер запрашивает общую картину, система обходит все три графа параллельно и сливает результаты. Сеть обеспечивает полноту, IPC добавляет контекст, трейсы показывают реальное поведение. Каждый источник компенсирует слабости остальных.</p><h2>Как собирают Service Topology</h2><h3>Приём и обработка потоков</h3><p>За кулисами работает конвейер, который держит миллионы событий в секунду. Потоки сетевых логов читаются из Kafka в нескольких регионах AWS. Для обработки Netflix использует Apache Pekko Streams — форк Akka, который разбивает нагрузку по группам автомасштабирования и сам управляет обратным давлением.</p><h3>Восстановление прямых связей</h3><p>Сетевой лог показывает отдельные сетевые прыжки: например, приложение → балансировщик → приложение или приложение → NAT-шлюз → приложение. Чтобы получить настоящие связи, запускается трёхступенчатая агрегация. Первая стадия забирает сырые записи, вторая распознаёт посредников и восстанавливает прямые пути между приложениями, третья финализирует агрегаты и добавляет статус здоровья. Такой градуированный подход раскидывает нагрузку и не даёт горячим узлам уронить весь конвейер.</p><p>Готовая топология хранится в графовой базе Netflix — абстракции поверх распределённого хранилища «ключ — значение». Она заточена под быстрый обход графа в несколько хопов. Поверх базы — gRPC-API с фильтрами по уровню доступности и домену, постраничным выводом больших выборок и ответом менее чем за секунду.</p><h3>Хранение и API</h3><p>Отдельно стоит возможность «путешествия во времени». Система не хранит каждый момент отдельно, а накапливает данные в скользящих окнах. Это позволяет спросить «как выглядела топология вчера в полночь» без взрыва объёмов хранения.</p><h2>Что даёт инженерам</h2><p>Интерфейс и API дают инженерам несколько рабочих сценариев — от ручного расследования до автоматических проверок.</p><ul><li>Видеть upstream и downstream для любого сервиса с фильтрами по уровню доступности и домену.</li><li>Переключаться между единым видом и отдельными слоями: только сеть, только IPC или только трейсы.</li><li>Одним кликом переходить от узла топологии к логам, трейсам и детальным метрикам.</li><li>Оценивать зону поражения перед отключением сервиса на обслуживание и понимать, кого уведомлять.</li><li>Накладывать статус здоровья на граф и быстро понимать, локальная ли это проблема или каскадный сбой.</li><li>Обращаться к топологии программно — например, чтобы автоматически проверять классификацию доступности критичных сервисов.</li><li>Смотреть историю зависимостей и находить, что изменилось перед инцидентом.</li></ul><h2>Как перенести в свою систему</h2><p>Не каждая компания работает в масштабе Netflix, но логика подхода универсальна. Если у вас десятки сервисов, уже появляется эффект «тысячи кусочков пазла». Начать можно с малого: собрать список зависимостей из существующих источников и периодически сверять его с реальным трафиком.</p><p><b>Чек-лист для первых шагов:</b><br />1. Выберите один настоящий источник связей: логи балансировщика, агент на хосте или метрики вызовов.<br />2. Не пытайтесь сразу построить идеальную модель — начните с автоматически обнаруженных рёбер.<br />3. Добавьте контекст: владельца сервиса, уровень критичности и домен.<br />4. Сделайте карту доступной программно, а не только в интерфейсе — инцидент-боты и скрипты будут благодарны.<br />5. Проверяйте актуальность: в динамичной среде карты, устаревшие на несколько часов, быстро теряют ценность.</p><p>Для иллюстрации вот минимальный скрипт, который строит рёбра графа из логов балансировщика:</p><h2>Часто задаваемые вопросы</h2><h2>Выводы</h2><p>Service Topology — не просто красивая картинка для панели мониторинга. Это операционная основа, которая ускоряет расследования, снижает риск изменений и даёт автоматическим системам общую картину инфраструктуры. Netflix называет её knowledge graph foundation — фундаментом для интеллектуальной автоматизации, в том числе для автоматического поиска первопричины сбоев.</p><blockquote>Service topology provides the knowledge graph foundation that makes this kind of intelligent automation possible.</blockquote><p>Для российских команд, где инфраструктура тоже стремительно усложняется, главный урок в другом: не ждите идеальной полноты данных. Начните с одного реального источника, добавьте контекст, сделайте карту программно доступной — и она начнёт приносить пользу раньше, чем вы построите «полноценную» систему.</p><h2>Источники</h2><ul><li><a href="https://medium.com/netflix-techblog/from-silos-to-service-topology-why-netflix-built-a-real-time-service-map-0165ba13a7bc">From Silos to Service Topology: Why Netflix Built a Real-Time Service Map</a></li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Agentic SRE: как ИИ-агенты меняют практику надёжности</title>
      <link>https://tproger.ru/articles/agentic-sre-kak-ii-agenty-menyayut-praktiku-nadyozhnosti</link>
      <comments>https://tproger.ru/articles/agentic-sre-kak-ii-agenty-menyayut-praktiku-nadyozhnosti?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/agentic-sre-kak-ii-agenty-menyayut-praktiku-nadyozhnosti</guid>
      <description><![CDATA[<p>Разбираем, как агентный подход к SRE ускоряет диагностику инцидентов и сокращает рутину. Пять рабочих сценариев, стек инструментов и правила безопасности. Читайте и внедряйте.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/agentic-sre-kak-ii-agenty-menyayut-praktiku-nadyozhnosti">Agentic SRE: как ИИ-агенты меняют практику надёжности</a>»</p>]]></description>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Архитектура ПО]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Организация разработки]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 31 May 2026 07:22:48 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если вы дежурите по ночам и проводите значительное время инцидента в поисках контекста — есть способ существенно сократить этот этап. <b>Agentic SRE</b> (агентный подход к Site Reliability Engineering) — это эволюция практики надёжности, где ИИ-агенты берут на себя рутину наблюдения, диагностики и безопасного реагирования. Цель не в том, чтобы заменить инженера, а в том, чтобы дать ему сверхспособности в моменты, когда каждая секунда дорога.</p><h2>Что такое Agentic SRE</h2><p>Agentic SRE — это практика, в которой автономные ИИ-агенты помогают наблюдать за системами, анализировать телеметрию (метрики, логи, трейсы) и выполнять ограниченные операционные действия при заданных человеком guardrails (правил безопасности). Агент не заменяет SRE-инженера, а работает как цифровой напарник: собирает контекст, предлагает гипотезы и выполняет только те действия, которые одобрены политикой.</p><p>Ключевое отличие от классической автоматизации — способность к <b>рассуждению</b>. Традиционные скрипты реагируют на жёсткие триггеры («если CPU &gt; 90%, то перезапустить»). Агент же может связать всплеск ошибок с недавним развёртыванием, проверить корреляцию по трейсам и предложить конкретный план действий — всё до того, как инженер откроет ноутбук.</p><p>Agentic SRE — это ИИ-агенты, которые помогают инженерам наблюдать, диагностировать и реагировать на инциденты.</p><p>Основная цель — сократить рутину и ускорить принятие решений, а не заменить человека.</p><p>Ключевые сценарии: триаж алертов, инцидент-копилот, автоматический RCA, безопасное исправление, обучение на инцидентах.</p><p>Безопасность превыше всего: агенты работают с allowlists, approval gates и полным аудитом.</p><p>Российские команды могут строить стек на OpenTelemetry, Prometheus/Grafana, собственных LLM и PagerDuty/Opsgenie.</p><h2>Почему это важно именно сейчас</h2><p>Сегодняшние системы стали слишком распределёнными, шумными и динамичными, чтобы человек успевал за ними вручную. Микросервисы, Kubernetes, feature flags и канареечные развёртывания создали ландшафт, где одно изменение может затронуть десятки сервисов, а сигналы о проблемах разбросаны по десяткам дашбордов.</p><p>Инженеры тратят значительное время на корреляцию метрик, чтение логов, проверку недавних выкаток и охоту за контекстом — до того, как начинают решать проблему. Agentic SRE решает это, превращая сырые телеметрические данные в структурированный контекст и автоматизируя безопасные части цикла реагирования.</p><p>Особенно это критично ночью и в выходные, когда на дежурстве один человек, а давление предельно велико. Задачи, которые легко стандартизировать, но сложно выполнить идеально в 2 часа ночи, — идеальная ниша для агентов, которые умеют обобщать, коррелировать и рекомендовать действия согласно политике.</p><h2>Из чего строится стек</h2><p>Практичная архитектура агентного SRE собирается из нескольких слоёв. При этом важно понимать: ценность приходит не от выбора модели, а от качества контекста, жёстких ограничений и дисциплины исполнения.</p><ul><li>Телеметрия: OpenTelemetry — стандарт сбора телеметрии — для сбора логов, метрик и трейсов в едином формате.</li><li>Наблюдаемость: Prometheus, Grafana, Datadog, New Relic, Elastic или облачные системы — хранилище и визуализация.</li><li>Оркестрация: MCP-серверы (Model Context Protocol от Anthropic), внутренние API или системы рабочих процессов, которые предоставляют агенту безопасные инструменты.</li><li>Среда выполнения агента: LLM-фреймворки с function calling, планированием и работой с инструментами.</li><li>Рабочий процесс при инцидентах: PagerDuty, Opsgenie, Slack, Jira, ServiceNow — куда агент пишет отчёты и запрашивает подтверждения.</li><li>Safety Layer: RBAC, approval gates, audit logs, allowlists и пути отката — неотъемлемая часть, а не дополнение.</li></ul><p><b>Принцип безопасности:</b><br />Агент должен уметь делать только то, что мог бы сделать дежурный инженер после одобрения. Это делает систему практичной и снижает риск случайного ущерба.</p><h2>Пять сценариев, которые уже работают</h2><h3>1. Триаж алертов: от шума к сути за секунды</h3><p>Когда срабатывает алерт, агент собирает связанные трейсы, проверяет недавние развёртывания, находит соответствующие всплески в логах и формирует краткое резюме на русском языке: вероятная причина, уверенность, рекомендуемые действия. Это решает проблему «с чего начать?», которая сжигает драгоценные минуты в начале инцидента.</p><h3>2. Инцидент-копилот: второй мозг в канале</h3><p>Агент подключается к каналу реагирования (Slack, Teams) и выполняет роль «второго мозга»: строит таймлайн, подтягивает ссылки на дашборды, отслеживает гипотезы по мере их проверки. Когда в инциденте участвуют несколько инженеров, это предотвращает фрагментацию контекста и дублирование усилий.</p><h3>3. Автоматический черновик RCA (Root Cause Analysis)</h3><p>После инцидента агент сравнивает таймлайн с недавними изменениями (развёртывания, конфиги, фичер-флаги), находит корреляции и генерирует первый черновик отчёта RCA с ссылками на доказательства. Инженер остаётся владельцем выводов, но экономит значительное время на подготовку документации.</p><h3>4. Безопасное исправление под контролем</h3><p>Для хорошо изученных типов инцидентов агент может рекомендовать или выполнять низкорискованные действия: перезапуск упавшего экземпляра сервиса, масштабирование развёртывания, отключение сломанного фичер-флага. Но всё, что влияет на пользовательский трафик, требует одобрения человека.</p><h3>5. Обучение на инцидентах: от пожаротушения к профилактике</h3><p>Агент анализирует паттерны в разных инцидентах, выявляет повторяющиеся корневые причины и предлагает, где улучшить наблюдаемость или сократить рутину. Со временем это создаёт обратную связь: боль в продакшене превращается в инвестиции в платформу. Точные алерты, подробные трейсы, недостающие дашборды — всё это становится следствием системной работы, а не хаотичных пост-инцидентов.</p><h2>Guardrails: почему доверие важнее интеллекта</h2><p>Главный риск агентного SRE не в том, что агент слишком умен, а в том, что он может быть <b>слишком уверен в себе</b>. LLM способны генерировать правдоподобные, но неверные объяснения. Поэтому каждая рекомендация должна быть прослежена до реальной телеметрии, а каждое действие — ограничено явными правами.</p><ul><li>Action allowlists: агент может делать только то, что в белом списке.</li><li>Approval gates: рискованные изменения требуют подтверждения.</li><li>Полный audit log: каждое действие агента записывается.</li><li>Read-only mode на этапе внедрения: сначала наблюдаем, потом действуем.</li><li>Разграничение прав по сервисам и командам.</li><li>Human override на каждом шаге: человек всегда может взять управление.</li></ul><blockquote>Если вы воспринимаете агента как стажёра с феноменальной памятью, но без здравого смысла, вы спроектируете систему с гораздо лучшей защитой.</blockquote><h2>Выводы</h2><p>Agentic SRE — это не модный тренд, а логичный ответ на растущую сложность инфраструктуры. Реальная ценность не в полной автономии, а в ускорении понимания, безопасной автоматизации и качественной коллаборации человека и машины в критические моменты.</p><p>Если строить это правильно, результат — продвинутая практика надёжности: меньше бесполезной работы, короче инциденты и больше времени для инженеров на системные улучшения вместо повторяющейся рутины. Настоящая ценность агентного SRE — не в замене инженера, а в том, чтобы дать ему модель работы с гораздо большей эффективностью.</p><p>Источник: <a href="https://devops.com/agentic-sre-the-next-frontier-of-reliability/">Agentic SRE: The Next Frontier of Reliability — DevOps.com</a> (Neel Shah, 2026).</p>]]></content:encoded>
    </item>
    <item>
      <title>Скрытый сбой идемпотентности в финтех-системе: разбор инцидента</title>
      <link>https://tproger.ru/articles/skrytyj-sboj-idempotentnosti-v-finteh-sisteme-razbor-incidenta</link>
      <comments>https://tproger.ru/articles/skrytyj-sboj-idempotentnosti-v-finteh-sisteme-razbor-incidenta?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Дмитрий Москалюк]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/skrytyj-sboj-idempotentnosti-v-finteh-sisteme-razbor-incidenta</guid>
      <description><![CDATA[<p>Разбор реального production-инцидента в финтех-системе: почему ошибка HTTP 500 не остановила операцию создания карты и как сбой идемпотентности в API Gateway вызвал массовые дубликаты. Практический кейс о микросервисной архитектуре, distributed systems, request-id, API idempotency и техническом долге.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/skrytyj-sboj-idempotentnosti-v-finteh-sisteme-razbor-incidenta">Скрытый сбой идемпотентности в финтех-системе: разбор инцидента</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Рефакторинг]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Финтех]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[faq]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 18 May 2026 04:55:17 GMT</pubDate>
      <content:encoded><![CDATA[<h2>Как все началось</h2><p>Всё началось с безобидного, почти рутинного тикета в саппорт:</p><p><i>«У меня тут несколько одинаковых карт создалось. Я вроде один раз нажимал, а их штук пять висит в приложении». </i></p><p>Для финтеха подобная фраза — не мелкая UI-аномалия, а сигнал тревоги высшего уровня. Когда речь идёт о платёжных инструментах, дубль сущности мгновенно переходит из разряда «странностей» в категорию «полноценный инцидент».</p><p>Поначалу казалось, что это просто один случай. Но на самом деле, проблема уже какое-то время была, хоть и скрытно: люди получали дубликаты своих банковских карт, но массово на это никто не жаловался. На уровне первой линии поддержки это ошибочно классифицировали как пользовательские ошибки</p><p>Настоящий шум поднялся не внутри компании, а уже в соцсетях. Один из клиентов выложил пост. Там была фотография посылки, а в ней — примерно сотня одинаковых карт. Пост очень быстро стал популярным, и вот тогда-то и возникли проблемы с репутацией, а команда разработчиков только тогда и узнала о случившемся. И особенно тревожно это звучало на фоне того, что мы считали что таких проблем быть не может - ведь считалось, что у  нас глобальная идемпотентность на все запросы.</p><p>Мы начали разбираться. Стандартный мониторинг показывал норму: дашборды зелёные, в логах тихо, метрики CPU и памяти без отклонений. При этом в базе обнаруживались дубликаты, которых быть не должно. И только тогда, когда мы внимательно посмотрели на коммунальный API Gateway, то поняли что одно изменение от другой команды поменяло идемпотентность работы endpoint-а.</p><p>Проблема была структурно невидима для тех, кто находился ближе всего к ней. Отсутствие видимой проблемы не равно отсутствию риска — система просто ждала подходящего момента.</p><h2>Что произошло: хронология инцидента</h2><p>Архитектура была классической: Клиент → API Gateway → микросервисы,.</p><p>Сценарий развивался почти незаметно для стандартных средств наблюдения:</p><p>1. Фронтенд: Пользователь нажимает кнопку «Выпустить карту».</p><p>2. Gateway: Запрос начинает обрабатываться в API Gateway.</p><p>3. Микросервис по созданию карт: честно выполняет работу: создаёт запись в БД и возвращает `200 OK` в Gateway.</p><p>4. Новый микросервис: API Gateway вызывает новый микросервис и получает HTTP 500 в ответ от него. Исключение возникает уже после успешного вызова нашего микросервиса, и это ключевая точка разрыва: Gateway считает весь запрос неудавшимся, а ответ нашего микросервиса теряется.</p><p>5. Клиент: получает HTTP 500</p><p>6. Реакция: Пользователь видит красную плашку ошибки и логично решает: «Не сработало, пробую снова». Более того, с точки зрения протокола HTTP - запросы, в ответ на которые пришла ошибка HTTP 500, можно пытаться отправлять опять.</p><p>7. Петля: Микросервис, ничего не зная о судьбе предыдущих ответов, послушно создавал карту за картой.</p><p>Круг замкнулся. Эпидемия началась.</p><p>В компании такого уровня это не было предусмотрено. И это такая обидная ошибка.</p><h2>Как так получилось?</h2><p>Вскрылось ошибочное предположение:</p><p><i>«В API Gateway вызов микросервиса создания карт всегда идет последним». </i></p><p>Таким образом идемпотентность достигалась «формально» - ведь если создание карты завершалось с ошибкой - это точно означало что и вызов API Gateway тоже завершится с ошибкой. Сработало ложное чувство безопасности.</p><p>Ответ на вопрос “почему так было сделано?” очень простой - это было осознанное упрощение на старте. Все знали об этом, но задача на фикс потерялась в недрах бэклога на очень долгое время. Это классический пример того, как архитектурное допущение и отложенный рефакторинг годами живут в проде, пока их не вскрывает редкая последовательность отказов.-</p><h2>Что потребовалось изменить</h2><p>Пришлось в срочном порядке внедрять полноценный механизм идемпотентности по request-id, который не зависел бы от порядка вызова downstream-сервисов. И это было достаточно тяжело, потому что окно для легкого внедрения закрывается в первый день продакшена: до этого момента нет ни живых пользователей, ни накопленных данных, ни клиентов старых версий, с которыми нужно сохранять обратную совместимость. Ниже — ответы на вопросы, которые мы получили от коллег, когда разбирали этот инцидент.</p><h2>FAQ: Часто задаваемые вопросы</h2><p><b>1. Почему нельзя просто заблокировать кнопку на фронте?</b></p><p>Блокировка кнопки решает проблему только при стабильной сети. Если запрос ушёл, сервер создал сущность, но ответ потерялся — кнопка разблокируется по таймауту, и пользователь нажмёт снова. Это не устраняет корневую причину, а лишь слегка снижает вероятность дубля.</p><p><b>2. Чем идемпотентность отличается от дедупликации в БД?</b></p><p>Дедупликация через уникальные индексы защищает от дублей в хранилище, но не решает проблему сайд-эффектов: повторный запрос всё равно вызовет отправку SMS, печать банковской карты, генерацию событий в шине или списание средств. Идемпотентность гарантирует, что вся цепочка выполнится ровно один раз — включая все внешние вызовы и побочные действия.</p><p><b>3. Как долго хранить ключи идемпотентности?</b></p><p>На практике мы хранили ключи в основной базе данных без ограничения срока — затраты на хранение UUID по всем сущностям оказались небольшими. В общем случае минимальный срок зависит от конкретных сценариев использования — кому-то хватит и  часа, а кому-то нужна неделя. В любом случае, окна должно быть достаточно, чтобы покрыть сценарии, когда пользователь возвращается к повтору запроса, например, на следующий день или когда клиентское приложение автоматически перезапускает отложенные запросы после восстановления сети. Бессрочное хранение не обязательно, но слишком короткий TTL создаёт риск дублей при длительных сетевых проблемах.</p><p><b>4. Что делать со старыми клиентами, которые не шлют request_id?</b></p><p>Мы сделали несколько версий API для создания карт — под разные версии приложения. Для новых клиентов работала полноценная идемпотентность с клиентским ключом. Для старых версий приходилось принимать риски и генерировать request_id на стороне сервера. Альтернативой может быть хэширование payload запроса, но это менее надежно и сложнее: таймстемпы и случайные поля могут отличаться от вызова к вызову. Поэтому мы выбрали  подход с генерацией ключа на сервере для устаревших клиентов: риски дублей на переходный период оказались меньше, чем сложность поддержки двух схем валидации одновременно.</p><p><b>5. Обязательно ли делать идемпотентность для всех методов API?</b></p><p>Идемпотентность требуется только для методов, которые изменяют состояние системы — POST, PUT, PATCH и иногда DELETE. Методы чтения (GET, HEAD, OPTIONS) не изменяют данные, поэтому считаются идемпотентными по умолчанию.</p><p><b>6. Как понять, что в вашей системе уже есть скрытая проблема с дублями?</b></p><p>Лучший способ — ввести метрики превентивно, не дожидаясь жалоб пользователей. Отслеживайте количество повторных вызовов с одинаковым ключом идемпотентности и сравнивайте его с общим числом запросов. Если метрики уже показывают ненулевое значение — проблема есть, даже если внешне всё работает незаметно.</p><p>Если метрик ещё нет, вот три косвенных признака, которые помогут заподозрить неладное:</p><ul><li>В базе данных периодически появляются записи с одинаковым содержимым, созданные с разницей в несколько секунд.</li><li>Пользователи жалуются на дубликаты карт, заказов или платежей, но вы не можете воспроизвести проблему локально, списываете на то, что пользователи что-то делают не так</li><li>В логах API Gateway периодически всплывают HTTP 500 ошибки, но downstream-сервисы при этом отрабатывают успешно.</li></ul><p>Если заметили хотя бы один из этих симптомов — простого решения уже не будет. Однако остаётся возможность исправить ситуацию до того, как проблему заметят пользователи. В нашем случае дубли проявлялись редко и стали массовыми только при повышении нагрузки. Если отложить решение, скрытая проблема перейдет на уровень, где её последствия станут заметны снаружи и потребуют значительно больших усилий.</p><h2>Итог</h2><p>Главный урок, который мы вынесли: идемпотентность — это общая ответственность всех команд разработки, и поломать её может быть проще, чем кажется. А добавить в уже работающую систему быстро и дёшево — почти невозможно.</p><p>Метрик на всплески повторных запросов у нас не было. А зря — это самый дешёвый способ увидеть проблему до того, как она обрушит продакшен. Системы, спроектированные на 10% нагрузки, ломаются на 60% — и обычно это становится неожиданностью для команды.</p><h2>Практический чек-лист: что проверить в своей системе уже сегодня</h2><ul><li>Убедитесь, что все критические мутирующие эндпоинты поддерживают ключ идемпотентности.</li><li>Настройте алерты на аномальное количество запросов на создание сущностей от одного пользователя за короткий промежуток времени.</li><li>Проверьте, как ваш API Gateway обрабатывает ошибки — не теряет ли он ответы downstream-сервисов.</li><li>Убедитесь, что фронтенд корректно обрабатывает не только 200, но и 500, 502, 504, не провоцируя пользователя на повторные клики без необходимости.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Как выбрать системного интегратора в 2026: 12 критериев для ЛПР</title>
      <link>https://tproger.ru/articles/kak-vybrat-sistemnogo-integratora-v-2026-12-kriteriev-dlya-lpr</link>
      <comments>https://tproger.ru/articles/kak-vybrat-sistemnogo-integratora-v-2026-12-kriteriev-dlya-lpr?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Лена Ф]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-vybrat-sistemnogo-integratora-v-2026-12-kriteriev-dlya-lpr</guid>
      <description><![CDATA[<p>Проверяете системного интегратора? 12 критериев для ЛПР: опыт в индустрии, техстек, санкционные риски, безопасность, репутация и красные флаги на каждом этапе.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-vybrat-sistemnogo-integratora-v-2026-12-kriteriev-dlya-lpr">Как выбрать системного интегратора в 2026: 12 критериев для ЛПР</a>»</p>]]></description>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Финтех]]></category>
      <category><![CDATA[Стартапы]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Инфраструктура]]></category>
      <category><![CDATA[Тимлид]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 08 May 2026 09:45:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>При выборе системного интегратора — понимайте, что это решение на несколько лет. Один из самых эффективных способов снизить риски — это проверить подрядчика на пилотной задаче, а уже потом доверять ему бизнес, архитектуру и данные. Помимо тестового, есть ещё много нюансов, которые нужно сделать на старте, чтобы потом не было судов или переписывания проекта с нуля. О них мы и поговорим, а статья будет полезна  тимлидам и ЛПР со стороны компаний, и внешним командам, которых проверяют.</p><p>Эксперты Centicore Group собрали чек-лист из 12 пунктов, которые реально работают при выборе интегратора, а когда у вас станет вопрос подрядчика – вы можете воспользоваться этим списком.</p><h2>1. Опыт в вашей индустрии</h2><p>Системный интегратор, который делал проекты для e-commerce, не обязательно справится с финтехом. У каждой индустрии свои особенности: требования к безопасности, специфика бизнес-процессов, регуляторные ограничения.</p><p>Что проверять:</p><ol><li>Портфолио с проектами в вашей сфере. Нужны конкретные кейсы: что делали, какой стек, какие результаты.</li><li>Понимание специфики. Если интегратор сразу задаёт правильные вопросы про ваши бизнес-процессы — хороший знак. Если предлагает типовое решение без погружения в специфику — советуем искать дальше.</li><li>Измеримые результаты. Везде понятные показатели: на сколько сократили время обработки заявок, сколько проект занял по времени, какая команда специалистов и к чему в итоге пришли.</li></ol><p>Запрашивайте кейсы из вашей индустрии. Если подрядчик работает в финансах, логистике, промышленности — пусть покажет, как решал похожие задачи Универсальные решения редко работают эффективно в специфичных отраслях.</p><h2>2. Что по техстеку и обновлениям</h2><p>В 2026 году оценивать интегратора по знанию условного языка программирования бессмысленно. Смотреть нужно на то, как команда работает с энтерпрайз-стеком и требованиями безопасности.</p><p>На что смотреть:</p><p><b>1. Соответствие вашему контуру.</b> Если у вас закрытый on-premise, а подрядчик умеет деплоить только в публичные облака — вам не по пути.</p><p><b>2. Релевантные сертификаты и лицензии.</b> Если делаете финтех — нужен опыт прохождения PCI DSS. Если работаете с госсектором или персональными данными — ищите подрядчика с лицензиями ФСТЭК и ФСБ.</p><p><b>3. Архитектурное ревью на входе.</b> Дайте подрядчику доступ к вашей текущей инфраструктуре под NDA. Нормальный интегратор сразу укажет на узкие места, проблемы с легаси и потенциальные сбои, если они реально есть.</p><p><b>4. Геополитические и санкционные риски.</b> В 2026 году для российского рынка это один из ключевых рисков. Что здесь нужно проверять:</p><ul><li>Зависимость от иностранных облаков и компонентов.</li><li>Отдельно open-source библиотек и фреймворков с высокой санкционной уязвимостью.</li><li>Наличие у подрядчика плана «Б» на случай новых ограничений (альтернативные поставщики, российские облака, on-premise).</li><li>Опыт работы с проектами, которые уже проходили через санкционные ограничения.</li></ul><p>Красный флаг: Подрядчик говорит «у нас всё на AWS и мы не видим в этом проблемы» или не может ответить, как будет развивать систему при усилении ограничений.</p><p><b>5. Отношение к ИИ-инструментам и low-code решениям.</b> В 2026 году почти все интеграторы так или иначе используют ИИ (Cursor, GitHub Copilot, Claude, внутренние агенты). Важно понимать политику компании. Что проверять:</p><ul><li>Есть ли у подрядчика регламент использования ИИ-инструментов (что разрешено, что запрещено, как проверяется код, сгенерированный ИИ).</li><li>Насколько активно они применяют low-code/no-code платформы и как это влияет на качество и поддержку решения.</li><li>Готовы ли они комбинировать ИИ + ручную разработку или полностью полагаются на «ИИ всё сделает».</li><li>Есть ли у них экспертиза по prompt engineering и проверке качества ИИ-генерируемого кода.</li></ul><p>Красный флаг: Подрядчик либо полностью игнорирует ИИ («мы всё пишем руками»), либо говорит «мы всё делаем через ИИ и это в 10 раз быстрее» без упоминания проверок и рисков.</p><h2>3. Насколько гибкие в разработке</h2><p>Коробочные решения работают, когда подходят, но чаще всего бизнесу нужна кастомизация. Здесь важно, насколько интегратор готов адаптироваться под ваши требования.</p><p>Что важно:</p><ol><li>Подход к кастомизации показывает философию компании. Если подрядчик сразу говорит о готовом решении и предлагает подстроить бизнес-процессы под него — это провал для специфичных задач. Подбор решения под клиента, а не наоборот — признак зрелого подхода.</li><li>Работа с изменениями — реальность любого проекта. Требования меняются в процессе, это нормально. Agile не на словах, а на деле означает готовность пересмотреть приоритеты, адаптировать бэклог, обсуждать изменения.</li><li>Понимание бизнес-задачи отличает хорошего интегратора от посредственного. Технари часто зацикливаются на том, как реализовать, забывая спросить, зачем это нужно. Вопрос о том, какую проблему решает функция, должен звучать чаще, чем обсуждение технологии.</li></ol><p>Спросите, как подрядчик работает с меняющимися требованиями в середине спринта. Если ответ сводится к пунктам контракта и доп.оплате — это может быть, но для начала лучше обсудить приоритеты и найти компромисс.</p><h2>4. Прозрачность процессов</h2><p>Вы должны понимать, что происходит на проекте в любой момент.</p><p>Как оценить прозрачность:</p><ol><li>Структура коммуникации определяет скорость решения вопросов. Кто ваш контакт — менеджер без технической экспертизы или техлид команды? Как быстро получаете ответы? Есть ли прямой доступ к разработчикам для обсуждения технических деталей?</li><li>Регулярная отчётность — это не бюрократия, а инструмент контроля. Демо каждый спринт, доступ к таск-трекеру вроде Jira, понимание прогресса в реальном времени. Компании с 24/7 поддержкой обычно имеют настроенные процессы коммуникации и реагирования.</li><li>Документация показывает зрелость процессов. Если подрядчик не может показать примеры технической документации, процессов разработки, архитектурных решений — это тревожный звонок.</li><li>Совпадение ценностей и корпоративной культуры. Технические навыки важны, но если ценности не совпадают — проект будет постоянным источником конфликтов. Попросите пообщаться не только с техлидом, но и с 1–2 разработчиками, которые будут работать над проектом. Задайте вопросы про их реальный опыт работы в компании. Что проверять:</li></ol><ul><li>Отношение к удалённой работе и овертаймам (есть ли культура «гореть на проекте» или уважают work-life balance).</li><li>Прозрачность внутри компании (как принимаются решения, насколько открыто руководство общается с командой).</li><li>Отношение к качеству vs скорость (готовы ли отказываться от «быстрых костылей» ради долгосрочного результата).</li><li>Корпоративные ценности: как компания относится к клиентам, к сотрудникам, к этике в разработке.</li></ul><p>Красные флаги:</p><ol><li>Вам говорят, что всё хорошо, но конкретики нет. Нет демо, доступа к репозиторию, промежуточных результатов. А потом в день дедлайна выясняется, что половины функционала нет. Нормальная практика — давать клиенту видимость работы: задачи, коммиты, тесты.</li><li>Проводите демо результатов каждые 1-2 недели. Так будете видеть рабочий код, сможете проверить функционал, задать вопросы напрямую техлиду. Ошибки дешевле исправлять на ранних этапах, чем в продакшене.</li><li>Команда говорит одно на собеседовании, а на деле — жёсткий overtime, токсичная культура и «мы просто кодим, а менеджеры решают».</li></ol><h2>5. Команда и культура разработки</h2><p>Код пишут люди, а люди работают эффективно только в правильной среде. Культура разработки подрядчика напрямую влияет на качество вашего продукта.</p><p>Что проверять:</p><ol><li>Квалификация разработчиков определяет скорость и качество работы. Соотношение мидлов и сеньоров в команде показывает, кто будет делать архитектурные решения, а кто — рутинные задачи. Если в команде только джуны под управлением одного сеньора — это риск.</li><li>Текучка кадров — критический показатель стабильности. Высокая текучка означает проблемы: либо с зарплатами, либо с управлением, либо с атмосферой. Всё это отразится на вашем проекте.</li><li>Практики разработки видны в деталях. Code review, автоматизированное тестирование, CI/CD — это страховка от багов в продакшене. Спросите, как организован процесс: делают ли ревью кода, какое покрытие тестами, как часто деплоят.</li></ol><p>Попросите пообщаться с командой, которая будет работать над проектом. Нормальные компании не скрывают разработчиков за менеджерами. Обратите внимание на культуру внутри компании. Человекоцентричный подход, забота о сотрудниках, корпоративная культура поддержки — всё это влияет на мотивацию команды.</p><h2>6. Пост-интеграционная поддержка</h2><p>Основная задача интегратора корректно внедрить решение, отловить баги в проде и передать проект вашей инхаус-команде.</p><p>На что смотреть:</p><ol><li>Гарантии и доработки. Что будет, когда система упадет из-за архитектурной ошибки вендора? Условия фикса багов и доработок после релиза должны быть зафиксированы в контракте.</li><li>Контроль ответственности. Должно быть четко расписано, где заканчивается зона ответственности интегратора и начинается зона ваших админов, девопсов или первой линии поддержки.</li><li>Документация и передача знаний. Подрядчик обязан выгрузить не только исходники, но и актуальную документацию: ADR (архитектурные решения), схемы инфраструктуры, регламенты развертывания.</li></ol><p>Юридическая и договорная часть. Условия расторжения договора и стратегия. Кто владеет кодом и данными после завершения проекта. Штрафы за срыв сроков и SLA. Право на аудит кода и инфраструктуры.</p><h2>7. Безопасность и комплаенс</h2><ol><li>Проверяйте сертификаты и стандарты: ISO 27001 по информационной безопасности, соответствие ФЗ-152 о персональных данных, отраслевые стандарты вроде PCI DSS для платёжных систем.</li><li>Пентесты, аудит кода на уязвимости, шифрование данных, управление доступами — всё это должно быть в процессе по умолчанию.</li><li>Убедитесь, что контракт чётко прописывает, кому принадлежит код, как защищаются ваши данные, какие санкции за утечку.</li></ol><p>Для финтеха, медтеха и госсектора это  базовое условие запуска. Если подрядчик не умеет работать в рамках обязательных требований по безопасности и комплаенсу, проект упрётся в согласования, аудит или ввод в эксплуатацию.</p><h2>8. Реальные кейсы и рекомендации</h2><p>Самый очевидный и простой способ проверить подрядчика — поискать в открытом доступе упоминания и кейсы в медиа или на специальных площадках. Вот на что смотреть:</p><ol><li>Соблюдение сроков — классический больной вопрос IT-проектов. Уложились ли в первоначальные оценки? Если были задержки — как объясняли и решали?</li><li>Работа с изменениями — насколько гибко подрядчик реагировал на новые требования? Были ли конфликты по поводу доп.функционала?</li><li>Качество коммуникации — как быстро отвечали, насколько понятно объясняли технические вещи, был ли прямой контакт с командой?</li><li>Пост-поддержка — что происходило после запуска? Быстро ли реагировали на проблемы? Помогли ли с развитием продукта дальше?</li></ol><h2>9. Финансовая прозрачность</h2><p>Цена проекта состоит не только из цифры в коммерческом предложении. Важно понимать, что входит в стоимость и какие могут быть скрытые расходы.</p><p>На что смотреть:</p><ol><li>Детализация оценки показывает зрелость процессов. Хорошее КП разбито на этапы, модули, компоненты. Вы видите, сколько стоит разработка каждой части, инфраструктура, тестирование, документация.</li><li>Скрытые расходы появляются, когда подрядчик не включил в оценку важные вещи: тестирование, документацию, обучение команды, настройку мониторинга. Уточняйте, что именно входит в стоимость, а что может потребовать доп.оплаты.</li></ol><p>Красные флаги:</p><ul><li>Слишком низкая цена по рынку — либо подрядчик неправильно оценил сложность и потом будет просить доплату, либо сэкономит на качестве: джуны вместо мидлов, отсутствие тестирования, урезанная документация.</li><li>Отказ детализировать оценку под предлогом коммерческой тайны. Нормальная практика — объяснить клиенту, из чего складывается стоимость. Если подрядчик этого не делает — он либо сам не понимает, либо что-то скрывает.</li></ul><h2>10. Масштабируемость решения</h2><p>Интегратор не сдает вам в аренду серверы, поэтому он должен спроектировать систему так, чтобы при х10 росте нагрузки вам не пришлось переписывать ядро, менять СУБД или сносить весь проект.</p><ol><li>Проектирование под рост бизнеса отличает стратегическое мышление от тактического. Хороший интегратор спросит о ваших планах: сколько пользователей сейчас, сколько планируется через год, через три года. И заложит архитектуру с запасом.</li><li>Постепенное расширение функционала дешевле полной переделки. Модульная архитектура, микросервисы, API-first подход — всё это позволяет добавлять новые возможности без переписывания существующего кода.</li><li>Управление техническим долгом. Любая разработка накапливает технический долг: быстрые решения, костыли, устаревшие зависимости. Профессионалы планируют рефакторинг, выделяют время на улучшение кода, следят за обновлениями библиотек.</li><li>Vendor lock-in и технологическая независимость. Хороший интегратор не строит систему так, чтобы вы навсегда зависели от его экспертизы, конкретного облака или проприетарного инструмента. Проверяйте: на каких лицензиях работает стек, можно ли сменить подрядчика без переписывания системы, кто владеет кодом и есть ли возможность развивать продукт силами инхаус-команды.</li></ol><p>Спросите подрядчика, как система переживёт рост нагрузки, где будут ограничения и как их снимут на уровне архитектуры, инфраструктуры и интеграции. И не доверяйте подрядчикам, которые проектируют архитектуру так, что без него систему не поддержать.</p><h2>11. Скорость и качество коммуникации</h2><p>Здесь должно быть все понятно, но на всякий случай зафиксируем:</p><ol><li>Время отклика на первый запрос — если на ваше обращение отвечают через неделю — представьте, как будет идти коммуникация в процессе проекта.</li><li>Интегратор должен задавать вопросы не только про технические требования, но и про то, какую проблему бизнеса решает система. Это показывает стратегическое мышление.</li><li>Хороший подрядчик не просто делает, что сказали, а предлагает улучшения: как сделать эффективнее, дешевле, быстрее. Это требует глубокого понимания вашего бизнеса.</li></ol><p>Кто ваш основной контакт — менеджер-посредник или техлид команды? Менеджеры нужны для координации, но технические вопросы эффективнее решать напрямую с разработчиками. Еженедельные синки, демо каждый спринт, оперативные ответы в мессенджерах — это инфраструктура взаимодействия, которая должна быть настроена с первого дня.</p><h2>12. Репутация на рынке и стабильность</h2><p>Последний пункт проверки — надёжность подрядчика как бизнеса. Вы инвестируете в долгосрочные отношения, и компания должна быть стабильной.</p><p>Что оценивать:</p><ol><li>Время на рынке — один из положительных сигналов, но не гарантия. Компании с опытом 8+ лет, как правило, пережили кризисы, накопили экспертизу и выстроили процессы. Но возраст сам по себе не означает качество: проверяйте кейсы, репутацию и стабильность команды, а не только дату основания. Стартапы могут быть инновационными — просто риски у них другие.</li><li>Финансовая устойчивость проверяется косвенно: по масштабу проектов, количеству офисов, размеру команды.</li><li>Участие в профессиональных мероприятиях показывает открытость. Компании, которые выступают на конференциях, пишут статьи, делятся опытом, обычно уверены в своей экспертизе. Это также помогает проверить репутацию через знакомых в индустрии.</li><li>Партнёрские отношения с крупными вендорами — ещё один индикатор.</li></ol><p>Проверка на негатив:</p><ul><li>Поищите упоминания компании в негативном контексте: судебные споры, публичные конфликты с клиентами, жалобы сотрудников. Одна претензия — не приговор, но если их много — стоит задуматься.</li><li>Отсутствие следов в интернете тоже настораживает. Нормальная IT-компания в 2026 году должна быть видна: сайт, соцсети, публикации, упоминания в медиа.</li></ul><h2>Как использовать чек-лист</h2><ol><li>Первичный скрининг отсекает неподходящих кандидатов. Пройдитесь по критичным пунктам: опыт в индустрии, технологический стек, безопасность, репутация. Если есть красные флаги — не тратьте время на глубокую оценку.</li><li>Глубокое интервью для финалистов. Возьмите 2-3 компании, которые прошли скрининг, и проверьте остальные пункты детально. Встречи с командой, разбор кейсов, общение с референсами, обсуждение процессов.</li><li>Пилотный проект снижает риски. Перед большим контрактом протестируйте подрядчика на небольшой задаче. Это покажет реальное качество работы, скорость коммуникации, соблюдение договорённостей. Дешевле потратить месяц на пилот, чем год на исправление ошибок.</li></ol><p>Чек-лист работает, когда применяете его последовательно. Не пропускайте пункты, которые кажутся очевидными — именно там часто скрываются проблемы. И помните: идеального подрядчика не существует. Важно найти того, чьи сильные стороны совпадают с вашими приоритетами, а слабые — не критичны для проекта.</p><p>Но даже с такими характеристиками важно пройти все этапы проверки. Запросить кейсы в вашей индустрии, пообщаться с референсами, провести техническое интервью, возможно, начать с пилотного проекта. Потратьте время на правильный выбор сейчас — сэкономите месяцы и бюджеты в будущем.</p>]]></content:encoded>
    </item>
    <item>
      <title>Что такое Kubernetes: оркестрация контейнеров простыми словами</title>
      <link>https://tproger.ru/articles/chto-takoe-kubernetes--orkestraciya-kontejnerov-prostymi-slovami</link>
      <comments>https://tproger.ru/articles/chto-takoe-kubernetes--orkestraciya-kontejnerov-prostymi-slovami?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Алексей Михайлишин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/chto-takoe-kubernetes--orkestraciya-kontejnerov-prostymi-slovami</guid>
      <description><![CDATA[<p>Kubernetes простыми словами: Pod, Node, Deployment, Service. Архитектура K8s, сравнение с Docker Compose и Swarm, старт с Minikube и облачных сервисов.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/chto-takoe-kubernetes--orkestraciya-kontejnerov-prostymi-slovami">Что такое Kubernetes: оркестрация контейнеров простыми словами</a>»</p>]]></description>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Облачные технологии]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 29 Mar 2026 05:31:34 GMT</pubDate>
      <content:encoded><![CDATA[<p>Представьте, что вы запустили десять микросервисов в Docker-контейнерах. Пока их три — всё управляется вручную. Но когда их становится тридцать, сто, тысяча — ручное управление превращается в кошмар: сервисы падают, нагрузка распределяется неровно, обновления выкатываются часами. Именно здесь на сцену выходит Kubernetes.</p><h2>Что такое Kubernetes</h2><p><b>Kubernetes</b> (произносится «кубернетес», сокращённо K8s) — это система оркестрации контейнеров с открытым исходным кодом, которая автоматизирует развёртывание, масштабирование и управление контейнеризированными приложениями. Kubernetes был создан компанией Google на основе внутренней системы Borg и передан в открытый доступ в 2014 году. Сегодня он управляется фондом Cloud Native Computing Foundation (CNCF).</p><p>Если <a href="https://tproger.ru/articles/chto-takoe-docker-prostymi-slovami--kontejnery--obrazy-i-docker-c">Docker</a> — это технология упаковки приложений в контейнеры, то Kubernetes — это система, которая управляет этими контейнерами в промышленном масштабе: решает, на каком сервере их запустить, следит за их здоровьем, перезапускает упавшие, масштабирует под нагрузку и обновляет без простоев.</p><p>- Kubernetes автоматизирует развёртывание, масштабирование и управление контейнерами
- Основные сущности: Pod, Node, Cluster, Deployment, Service, Namespace
- Архитектура делится на Control Plane (управление) и Worker Nodes (исполнение)
- K8s поддерживает самовосстановление: упавший Pod перезапускается автоматически
- Kubernetes подходит для больших распределённых систем; для небольших проектов достаточно Docker Compose
- Минимальный старт — Minikube или kind на локальной машине за 10 минут
- Облачные решения GKE, EKS, AKS берут на себя управление Control Plane
- По данным CNCF на 2024 год, Kubernetes используют или оценивают более 84% организаций (CNCF 2023)</p><h2>Зачем нужен Kubernetes — проблема управления контейнерами в масштабе</h2><p>Контейнеры решили проблему «у меня работает, у тебя не работает» — приложение вместе со всеми зависимостями упаковывается в изолированный образ. Но с ростом количества контейнеров появляются новые проблемы.</p><ul><li><b>Высокая доступность.</b> Если контейнер упал — его нужно перезапустить. Вручную это нереально при сотнях сервисов.</li><li><b>Балансировка нагрузки.</b> Трафик нужно распределять между несколькими экземплярами одного сервиса.</li><li><b>Масштабирование.</b> В час пик нужно быстро добавить экземпляры, ночью — убрать, чтобы сэкономить ресурсы.</li><li><b>Обновления без даунтайма.</b> Rolling update или blue-green деплой требуют координации.</li><li><b>Управление конфигурацией и секретами.</b> Переменные среды, токены, сертификаты — всё это нужно доставлять в контейнеры безопасно.</li><li><b>Размещение на серверах.</b> Решить, на каком из 50 серверов запустить очередной контейнер, учитывая доступные ресурсы CPU и памяти.</li></ul><p>По данным CNCF, организации, использующие <a href="https://tproger.ru/articles/chto-takoe-mikroservisy--arhitektura--plyusy-i-minusy--primery">микросервисную архитектуру</a>, в среднем управляют более чем 10 сервисами в продакшене, а крупные компании — тысячами. Вручную это не масштабируется. Kubernetes решает все перечисленные задачи декларативно: вы описываете желаемое состояние системы, а K8s сам приводит её к этому состоянию и поддерживает его.</p><h2>Основные концепции Kubernetes</h2><p>Прежде чем погружаться в архитектуру, важно понять базовые сущности, с которыми работает Kubernetes каждый день.</p><h3>Pod — минимальная единица развёртывания</h3><p><b>Pod</b> — это один или несколько контейнеров, которые всегда запускаются вместе на одном узле и разделяют сетевое пространство (один IP-адрес) и тома хранилища. Обычно один Pod = один контейнер с основным приложением. Второй контейнер в Pod используется как sidecar: например, для сбора логов или проксирования трафика.</p><h3>Node — рабочий узел кластера</h3><p><b>Node</b> (узел) — это физическая или виртуальная машина, на которой запускаются Pod-ы. Каждый узел содержит kubelet (агент, который следит за Pod-ами), kube-proxy (сетевые правила) и container runtime (Docker, containerd или CRI-O). В кластере обычно несколько узлов — от 3 до тысяч в крупных системах.</p><h3>Cluster — совокупность всех узлов</h3><p><b>Cluster</b> (кластер) — это набор узлов, управляемых единым Control Plane. Весь Kubernetes работает внутри кластера. Один кластер может объединять сотни серверов в разных датацентрах.</p><h3>Deployment — управление жизненным циклом приложения</h3><p><b>Deployment</b> — это объект, который описывает желаемое состояние для набора Pod-ов: сколько реплик должно работать, какой образ использовать, как выполнять обновления. Deployment следит за тем, чтобы нужное количество Pod-ов всегда было запущено, и управляет rolling-обновлениями.</p><h3>Service — стабильная точка доступа к Pod-ам</h3><p><b>Service</b> — это абстракция, которая предоставляет стабильный IP-адрес и DNS-имя для набора Pod-ов. Pod-ы могут создаваться и удаляться, их IP меняется — Service обеспечивает постоянную точку входа и балансирует нагрузку между ними. Основные типы: ClusterIP (внутри кластера), NodePort (снаружи по порту узла), LoadBalancer (облачный балансировщик).</p><h3>Namespace — изоляция ресурсов внутри кластера</h3><p><b>Namespace</b> — это виртуальный раздел внутри кластера. Позволяет изолировать ресурсы разных команд, проектов или окружений (dev, staging, production) в рамках одного кластера. По умолчанию существуют namespace-ы: default, kube-system, kube-public.</p><h2>Как работает Kubernetes — архитектура изнутри</h2><p>Kubernetes состоит из двух уровней: <b>Control Plane</b> (управляющий слой) и <b>Worker Nodes</b> (рабочие узлы). Разберём каждый компонент.</p><h3>Control Plane — мозг кластера</h3><ul><li><b>API Server (kube-apiserver)</b> — единственная точка входа для всех операций с кластером. Все компоненты общаются только через API Server. kubectl, CI/CD системы, внутренние контроллеры — всё идёт через него. Принимает REST-запросы, валидирует их и сохраняет состояние в etcd.</li><li><b>etcd</b> — распределённое хранилище типа «ключ-значение», где хранится всё состояние кластера: конфигурации, метаданные Pod-ов, секреты. Это единственное место с состоянием в Kubernetes — если etcd жив, кластер восстановим.</li><li><b>Scheduler (kube-scheduler)</b> — отвечает за размещение новых Pod-ов на узлах. Учитывает доступные ресурсы узлов, affinity-правила, ограничения и политики. Не запускает Pod-ы сам — только решает, на каком узле их запустить.</li><li><b>Controller Manager (kube-controller-manager)</b> — набор контроллеров, каждый из которых следит за определённым типом ресурсов. Deployment Controller следит, чтобы работало нужное число реплик. Node Controller реагирует на отказ узлов. ReplicaSet Controller поддерживает заданное количество Pod-ов.</li></ul><h3>Worker Nodes — исполнители</h3><ul><li><b>kubelet</b> — агент на каждом узле. Получает от API Server описание Pod-ов, которые должны работать на этом узле, запускает их через container runtime и сообщает статус.</li><li><b>kube-proxy</b> — управляет сетевыми правилами на узле (iptables или IPVS). Обеспечивает работу Service: трафик к виртуальному IP Service перенаправляется на реальные Pod-ы.</li><li><b>Container Runtime</b> — движок для запуска контейнеров. Kubernetes поддерживает containerd (рекомендован), CRI-O и Docker Engine через специальный shim.</li></ul><p>Типичный жизненный цикл запроса: вы применяете YAML через kubectl apply → API Server сохраняет объект в etcd → Scheduler находит подходящий узел → kubelet на том узле получает задание и запускает контейнер → Controller Manager следит, что всё работает как описано.</p><h2>Kubernetes vs Docker Compose vs Docker Swarm — когда что использовать</h2><p>Выбор инструмента зависит от масштаба задачи. Не стоит использовать Kubernetes там, где достаточно Docker Compose — это избыточная сложность.</p><ul><li><b>Docker Compose</b> — идеально для локальной разработки и небольших проектов на одном сервере. Простой синтаксис, быстрый старт, нет оверхеда. Не умеет автоматически восстанавливаться при отказе хоста, не масштабируется горизонтально.</li><li><b>Docker Swarm</b> — встроенная кластеризация Docker. Проще Kubernetes, подходит для небольших кластеров (2–10 серверов), когда не нужны продвинутые возможности. Экосистема значительно меньше, развитие заморожено.</li><li><b>Kubernetes</b> — для продакшен-систем с требованиями к высокой доступности, горизонтальному масштабированию, сложным сетевым политикам и богатой экосистеме. Оправдан при наличии хотя бы 3–5 сервисов и команды DevOps.</li></ul><blockquote>Если вы можете управлять системой через Docker Compose — используйте Docker Compose. Kubernetes стоит выбирать, когда боль от ручного управления стала больше, чем сложность K8s.</blockquote><p>Ключевые отличия в цифрах: Docker Compose запускается за секунды, Kubernetes требует минимум 3 узла для продакшена и несколько часов на начальную настройку. Зато Kubernetes поддерживает до 5000 узлов и 150 000 Pod-ов в одном кластере.</p><h2>Как начать работу с Kubernetes</h2><p>Для изучения и разработки не нужен облачный кластер. Есть несколько способов запустить Kubernetes локально.</p><h3>Minikube — классический локальный кластер</h3><p>Minikube запускает однонодовый кластер Kubernetes в виртуальной машине или контейнере. Поддерживает macOS, Linux и Windows. Встроен dashboard, поддержка нескольких профилей и дополнений.</p><h3>kind — Kubernetes в Docker</h3><p><b>kind</b> (Kubernetes IN Docker) запускает узлы кластера как Docker-контейнеры. Быстрее Minikube, идеален для CI/CD и тестирования, поддерживает многонодовые кластеры.</p><h3>Облачные управляемые сервисы</h3><p>Для продакшена большинство команд выбирает управляемый Kubernetes — облачный провайдер берёт на себя Control Plane, обновления и резервирование etcd.</p><ul><li><b>GKE (Google Kubernetes Engine)</b> — оригинальный управляемый K8s от Google. Лучшая интеграция с экосистемой Google Cloud, автопилот-режим для полностью управляемой инфраструктуры.</li><li><b>EKS (Amazon Elastic Kubernetes Service)</b> — Kubernetes на AWS. Глубокая интеграция с сервисами AWS: IAM, ALB, EBS. Самый популярный выбор среди enterprise-компаний.</li><li><b>AKS (Azure Kubernetes Service)</b> — K8s на Microsoft Azure. Хорошая интеграция с Azure Active Directory, бесплатный Control Plane.</li><li><b>Yandex Managed Service for Kubernetes</b> — российский вариант с серверами в РФ, интеграция с Yandex Cloud.</li></ul><p>Помимо самого кластера, при работе с <a href="https://tproger.ru/articles/chto-takoe-rest-api-prostymi-slovami--principy--metody-i-primery">REST API</a> сервисов внутри Kubernetes понадобится настроить Ingress-контроллер (nginx, Traefik) для маршрутизации внешних HTTP-запросов к нужным Service-ам.</p><h2>Выводы</h2><p>Kubernetes — это де-факто стандарт оркестрации контейнеров в 2024–2025 годах. По данным CNCF Annual Survey, более 84% компаний используют или оценивают K8s, а рынок контейнерной оркестрации продолжает расти двузначными темпами.</p><p>Kubernetes решает реальные проблемы масштаба: автоматическое самовосстановление, горизонтальное масштабирование, нулевой даунтайм при обновлениях, декларативное управление инфраструктурой. За это приходится платить сложностью — не стоит применять K8s там, где хватает Docker Compose.</p><p>Путь в Kubernetes начинается с понимания контейнеров, затем — знакомство с kubectl и Minikube, первые Deployment-ы и Service-ы, потом — изучение Ingress, ConfigMap, Secret, HorizontalPodAutoscaler. Это путь в несколько месяцев, но он открывает доступ к одной из самых востребованных технологий в DevOps.</p><p>Изучаете облачные технологии? Прочитайте наши статьи о <a href="https://tproger.ru/articles/chto-takoe-mikroservisy--arhitektura--plyusy-i-minusy--primery">микросервисной архитектуре</a> и <a href="https://tproger.ru/articles/chto-takoe-docker-prostymi-slovami--kontejnery--obrazy-i-docker-c">Docker</a> — они помогут выстроить полную картину современной облачной разработки. Автоматизировать деплой в Kubernetes поможет <a href="https://tproger.ru/articles/chto-takoe-ci-cd--nepreryvnaya-integraciya-i-dostavka">CI/CD</a>: пайплайн собирает образ, прогоняет тесты и автоматически деплоит в кластер.</p><p>Если хотите собрать Kubernetes не как отдельный страшный инструмент, а как часть цельного пути, посмотрите <a href="https://tproger.ru/articles/roadmap-devops-inzhenera-v-2026-godu--chto-uchit-i-v-kakom-poryadke">план обучения DevOps-инженера</a>. Там видно, почему Kubernetes появляется после Docker, CI/CD и инфраструктуры, а не вместо них.</p>]]></content:encoded>
    </item>
    <item>
      <title>Что такое микросервисы: архитектура, плюсы и минусы, примеры</title>
      <link>https://tproger.ru/articles/chto-takoe-mikroservisy--arhitektura--plyusy-i-minusy--primery</link>
      <comments>https://tproger.ru/articles/chto-takoe-mikroservisy--arhitektura--plyusy-i-minusy--primery?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Алексей Михайлишин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/chto-takoe-mikroservisy--arhitektura--plyusy-i-minusy--primery</guid>
      <description><![CDATA[<p>Что такое микросервисы и чем они отличаются от монолита. Разбираем преимущества, недостатки, Docker, Kubernetes, API Gateway и когда стоит переходить.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/chto-takoe-mikroservisy--arhitektura--plyusy-i-minusy--primery">Что такое микросервисы: архитектура, плюсы и минусы, примеры</a>»</p>]]></description>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sat, 28 Mar 2026 15:29:52 GMT</pubDate>
      <content:encoded><![CDATA[<p>Ваш монолитный сервер падает под нагрузкой, деплой занимает полдня, а любое изменение в одном модуле ломает три других? Вероятно, пора задуматься о микросервисах. Но подходят ли они именно вам — разбираемся в этой статье.</p><p><b>Микросервисы</b> (microservices) — это архитектурный подход, при котором приложение разбивается на набор небольших автономных сервисов. Каждый сервис отвечает за одну бизнес-функцию, имеет собственную базу данных, развёртывается независимо и взаимодействует с другими сервисами через API. Такой подход противопоставляется монолитной архитектуре, где всё приложение — единый неделимый блок.</p><p>— Микросервисы — это архитектура из независимых сервисов, каждый из которых решает одну задачу и развёртывается отдельно</p><p>— Главные преимущества: независимый деплой, масштабирование отдельных компонентов, свобода выбора технологий</p><p>— Главные недостатки: сложность отладки, сетевые задержки, необходимость оркестрации</p><p>— Переходить с монолита стоит при команде от 5-8 разработчиков и понятных границах доменов</p><p>— Ключевые технологии: Docker, Kubernetes, API Gateway, брокеры сообщений (Kafka, RabbitMQ)</p><h2>Монолит vs микросервисы — в чём разница</h2><p>В <b>монолитной архитектуре</b> всё приложение — один развёртываемый артефакт. Код UI, бизнес-логики и доступа к данным живёт в одной кодовой базе, компилируется и деплоится как единое целое.</p><p>В <b>микросервисной архитектуре</b> приложение разделено на несколько независимых сервисов. Например, интернет-магазин может состоять из сервиса каталога, сервиса заказов, сервиса оплаты и сервиса уведомлений — каждый работает в своём процессе и имеет свою БД.</p><p>Основные различия:</p><ul><li><b>Размер и сложность</b> — монолит проще на старте, но растёт в «комок грязи»; микросервисы сложнее изначально, но легче масштабируются</li><li><b>Деплой</b> — в монолите любое изменение требует передеплоя всего приложения; в микросервисах — только изменённого сервиса</li><li><b>Масштабирование</b> — монолит масштабируется только целиком; микросервис — точечно, по нагрузке</li><li><b>Технологии</b> — в монолите один стек; в микросервисах каждый сервис может быть на своём языке и фреймворке</li><li><b>Отказоустойчивость</b> — падение монолита роняет всё; падение одного микросервиса не обязательно роняет систему</li></ul><p>По данным <a href="https://www.oreilly.com/radar/microservices-adoption-in-2020/">O'Reilly</a>, к 2020 году 61% компаний, внедривших микросервисы, использовали их больше года, а 28% — больше трёх лет.</p><h2>Преимущества микросервисной архитектуры</h2><ol><li><b>Независимый деплой.</b> Каждая команда деплоит свой сервис без координации с другими. По данным отчёта DORA, это один из ключевых факторов высокой частоты релизов — лидеры индустрии деплоят изменения несколько раз в день</li><li><b>Точечное масштабирование.</b> Нагрузка на каталог товаров выросла в 10 раз? Масштабируем только его, не трогая сервис аналитики</li><li><b>Технологическая свобода.</b> Сервис рекомендаций можно написать на Python с ML-библиотеками, а высоконагруженный API — на Go или Rust</li><li><b>Изоляция сбоев.</b> Если сервис уведомлений упал, пользователь всё ещё может оформить заказ. Паттерн Circuit Breaker (автоматический выключатель) предотвращает каскадные отказы</li><li><b>Гибкость команд.</b> Каждый сервис — зона ответственности одной команды (2-8 человек). Это соответствует «правилу двух пицц» Джеффа Безоса</li><li><b>Упрощённый рефакторинг.</b> Переписать один сервис на 2000 строк проще и безопаснее, чем рефакторить монолит на 200 000 строк</li></ol><h2>Недостатки и когда НЕ стоит использовать микросервисы</h2><p>Микросервисы — не серебряная пуля. Вот реальные проблемы, с которыми сталкиваются команды:</p><ul><li><b>Сетевая сложность.</b> Вместо вызовов функций — HTTP-запросы и очереди сообщений. Это добавляет задержки (latency), а сеть может быть ненадёжной</li><li><b>Распределённые транзакции.</b> Обеспечить атомарность операции, затрагивающей 3 сервиса, — нетривиальная задача. Паттерн Saga решает это, но добавляет сложность</li><li><b>Отладка и мониторинг.</b> Баг, затрагивающий цепочку из 5 сервисов, искать сложнее, чем в одном процессе. Нужны распределённая трассировка (Jaeger, Zipkin) и централизованные логи</li><li><b>Дупликация данных.</b> Каждый сервис имеет свою БД — данные неизбежно дублируются, и обеспечивать их согласованность (eventual consistency) сложно</li><li><b>Операционные затраты.</b> Вместо одного сервера — десятки контейнеров, сетевые политики, секреты, CI/CD-пайплайны для каждого сервиса</li><li><b>Порог входа.</b> Команде нужно знать Docker, оркестрацию, паттерны распределённых систем — кривая обучения крутая</li></ul><p><b>Когда НЕ стоит переходить на микросервисы:</b></p><ul><li>Команда меньше 5 человек — overhead превысит выгоду</li><li>Проект на ранней стадии, когда границы доменов ещё не ясны</li><li>Нет DevOps-культуры и опыта с контейнерами</li><li>Монолит справляется с текущей и прогнозируемой нагрузкой</li></ul><blockquote>Если вы не можете построить хорошо структурированный монолит, что заставляет вас думать, что микросервисы — ответ?</blockquote><h2>Технологии микросервисной архитектуры</h2><p>Микросервисы опираются на экосистему инструментов. Разберём ключевые.</p><h3>Docker — контейнеризация</h3><p><a href="https://tproger.ru/articles/chto-takoe-docker-prostymi-slovami--kontejnery--obrazy-i-docker-c">Docker</a> упаковывает каждый сервис в контейнер — изолированную среду со всеми зависимостями. Контейнер работает одинаково на ноутбуке разработчика и в продакшене. Без контейнеризации управлять десятками сервисов с разными зависимостями было бы практически невозможно.</p><h3>Kubernetes — оркестрация</h3><p><a href="https://tproger.ru/articles/chto-takoe-kubernetes--orkestraciya-kontejnerov-prostymi-slovami">Kubernetes</a> (K8s) управляет кластером контейнеров: автоматически перезапускает упавшие сервисы, балансирует нагрузку, масштабирует реплики. Для небольших проектов можно обойтись <a href="https://docs.docker.com/compose/">Docker Compose</a>, но для продакшена с десятками сервисов Kubernetes стал стандартом де-факто.</p><h3>API Gateway — единая точка входа</h3><p>API Gateway (например, <a href="https://konghq.com/">Kong</a>, <a href="https://www.nginx.com/">NGINX</a> или облачные решения) принимает все внешние запросы и маршрутизирует их к нужным сервисам. Он также берёт на себя авторизацию, rate limiting и агрегацию ответов от нескольких сервисов.</p><h3>Брокеры сообщений — асинхронное взаимодействие</h3><p><a href="https://kafka.apache.org/">Apache Kafka</a> и <a href="https://www.rabbitmq.com/">RabbitMQ</a> обеспечивают асинхронную коммуникацию между сервисами. Вместо прямых HTTP-вызовов сервис публикует событие в очередь, а заинтересованные сервисы его обрабатывают. Это снижает связанность (coupling) и повышает отказоустойчивость.</p><p>Дополнительные инструменты, которые часто используются вместе:</p><ul><li><b>Service Mesh</b> (Istio, Linkerd) — управление трафиком между сервисами, mTLS-шифрование</li><li><b>Распределённая трассировка</b> (Jaeger, Zipkin) — отслеживание запроса через цепочку сервисов</li><li><b>Централизованные логи</b> (ELK Stack, Grafana Loki) — сбор логов со всех сервисов в одном месте</li><li><b>Feature Flags</b> (Unleash, LaunchDarkly) — постепенное включение функций без передеплоя</li></ul><p>Подробнее о паттернах проектирования, которые применимы к микросервисам, читайте в <a href="https://tproger.ru/translations/design-patterns-simple-words-1">нашей статье о шаблонах проектирования</a>.</p><h2>Заключение</h2><p>Микросервисы — мощный архитектурный подход, но не универсальное решение. Они дают независимый деплой, точечное масштабирование и технологическую свободу, но взамен требуют зрелую DevOps-культуру, инвестиции в инфраструктуру и опыт работы с распределёнными системами.</p><p>Прежде чем переходить на микросервисы, убедитесь, что ваш монолит действительно стал узким местом — и что команда готова к новому уровню сложности. Начните с хорошо структурированного модульного монолита, выделите чёткие границы доменов, а затем постепенно извлекайте сервисы по мере роста нагрузки и команды.</p><p>Для запуска микросервисов в продакшене нужно освоить всю связку инструментов: <a href="https://tproger.ru/articles/chto-takoe-docker-prostymi-slovami--kontejnery--obrazy-i-docker-c">Docker</a> обеспечивает упаковку и изоляцию каждого сервиса, <a href="https://tproger.ru/articles/chto-takoe-kubernetes--orkestraciya-kontejnerov-prostymi-slovami">Kubernetes</a> — оркестрацию в кластере, а <a href="https://tproger.ru/articles/chto-takoe-rest-api-prostymi-slovami--principy--metody-i-primery">REST API</a> определяет, как сервисы взаимодействуют между собой.</p>]]></content:encoded>
    </item>
    <item>
      <title>Создаём микросервис обработки изображений на Go с gRPC</title>
      <link>https://tproger.ru/articles/sozdayom-mikroservis-obrabotki-izobrazhenij-na-go-s-grpc-2</link>
      <comments>https://tproger.ru/articles/sozdayom-mikroservis-obrabotki-izobrazhenij-na-go-s-grpc-2?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Go разработчик]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/sozdayom-mikroservis-obrabotki-izobrazhenij-na-go-s-grpc-2</guid>
      <description><![CDATA[<p>В этой статье мы рассмотрим создание микросервиса обработки изображений на golang с использованием технологии gRPC. Цель статьи - показать как может выглядеть такой сервис и что он может в себя включать.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/sozdayom-mikroservis-obrabotki-izobrazhenij-na-go-s-grpc-2">Создаём микросервис обработки изображений на Go с gRPC</a>»</p>]]></description>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Golang]]></category>
      <category><![CDATA[Pet-проекты]]></category>
      <category><![CDATA[gRPC]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 17 Mar 2026 05:00:02 GMT</pubDate>
      <content:encoded><![CDATA[<p><b>Вступление</b></p><p>В этой статье мы рассмотрим создание микросервиса обработки изображений на golang с использованием технологии **gRPC**. Цель статьи - показать как может выглядеть такой сервис и что он может в себя включать. В результате мы получим полностью рабочий сервис по обработке изображений, который принимает данные, сохраняет исходную картинку,сжимает её, накладывает на неё ватермарку, изменяет размер изображения, и конвертирует его в нужный формат.</p><p>Разберём возможные варианты взаимодействия клиента с сервером для обработки больших объектов, в нашем случае это картинки:</p><p><b>1. HTTP/1.1 (REST)</b></p><p>Передача изображений в виде текстовых чанков (например, base64) приводит к значительным накладным расходам: бинарные данные увеличиваются на ~33% при кодировании в Base64, а текстовый формат неэффективен для больших объёмов.</p><p><b>2. WebSocket</b></p><p>Подходит для долгоживущих сессий и двустороннего обмена, но избыточен, если нам нужно просто «принять изображение → обработать → вернуть результат». Удержание тысяч соединений ради однократных операций — неоптимально.</p><p><b>3. gRPC</b> использует:</p><p><b>Protocol Buffers</b> — строго типизированный, компактный бинарный формат,</p><p><b>HTTP/2</b> — мультиплексирование, потоки, сжатие заголовков,</p><p><b>Client-Streaming</b> — идеально подходит для передачи одного большого файла (например, изображения) в одном вызове.</p><p><b>I. Постановка задачи</b></p><p><b>Сервис должен:</b></p><p>Принимать изображение и параметры (format, compress, watermark, width[], height[]),</p><p>Сохранять оригинал с уникальным путём (./download/YYYY/MM/DD/UUID/img/...),</p><p>Накладывать водяной знак,</p><p>Генерировать версии заданных размеров,</p><p>Сохранять полученные изображения,</p><p>Возвращать список путей.</p><p>Пример:</p><p>Запрос с width = [1920, 1280], height = [1080, 720], format = "webp", watermark = "logo.png"</p><p>→ Сервис вернёт два пути:</p><p>./download/2026/02/08/abc123/img/abc123_1920x1080.webp</p><p>./download/2026/02/08/abc124/img/abc124_1280x720.webp</p><p><b>II. Архитектура приложения</b></p><figure><img src="https://media.tproger.ru/user-uploads/136053/2026-02-23/af4f6a18-dac9-4728-bbb3-decfe99bc1c5.webp" alt="" /></figure><p><b>Обработка происходит в строгом порядке:</b></p><p>1.Приём → 2. Сохранение исходного файла→ 3. Сжатие → 4. Watermark → 5. Resize → 6. Конвертация → 7. Ответ.</p><p><b>Структура хранения:</b></p><p>./download/2026/02/08/a1b2c3d4-.../img/</p><p>├── a1b2c3d4-....jpg          ← оригинал</p><p>├── a1b2c3d4-..._800x600.png</p><p>└── a1b2c3d4-..._1024x768.png</p><p><b>Необходимые инструменты:</b></p><p>Для работы с WebP мы используем библиотеку <a href="https://pkg.go.dev/golang.org/x/image/webp" rel="nofollow">golang.org/x/image/webp</a> , а исходные утилиты можно скачать на <a href="https://developers.google.com/speed/webp/download?hl=ru" rel="nofollow">официальной странице Google</a>.</p><p>Для генерации protobuff нам нужен  <b>protoc-gen-go</b></p><p><b>protoc-gen-go-grpc</b></p><p>Позволяет генерировать определения сервисов Go для буфера протокола, заданного нашим .proto файлом <a href="https://github.com/grpc/grpc-go/releases" rel="nofollow">protoc-gen-go-grpc</a></p><p>Также для работы webp нам потребуется работа с CGO, которую мы рассмотрим отдельно.</p><p><b> III. Реализация proto файла</b></p><p>Для начала работы опишем наш proto файл. Это будет сервис с единственным rpc который будет обрабатывать картинки пользователей.</p><p>./proto/image.proto</p><p>Мы используем Client-Streaming RPC — клиент может отправить несколько сообщений, сервер — один ответ. Этот способ поможет нам в случае необходимости гибкого расширения и избежания ограничений на размер одного сообщения.</p><p><b>V. Реализация основных функций</b></p><p><b>1. Создание сервера</b></p><p><b>1.1 Генерация  go файлов из .proto:</b>  Сгенерируем файлы для реализации сервера с помощью protoc:</p><p>У нас должно получиться 2 файла image.pb.go и image_grpc.pb.go в директории proto</p><p><b>1.2 Реализуем конструктор сервера и interceptor</b> (аналог middleware в grpc) восстановления после паники:</p><p>./internal/app/server.go</p><p>Теперь реализуем функцию запуска нашего grpc сервера:</p><p>Мы создали наш grpc сервер, но пока нет никакой реализации ImageServiceServer который сгенерировал нам protoc, это просто интерфейс который нам и нужно реализовать.</p><p><b>2. Реализация ImageServiceServer</b></p><p>Нам необходимо создать структуру ImageServer которая реализует интерфейс ImageServiceServer с его методом DownloadImage, также создадим конструктор для него :</p><p>./internal/app/image.go</p><p>Нам осталось реализовать ключевые функции для нашего сервиса, а именно: saveSourceFiles: отвечает за сохранение исходных файлов и их сжатие, watermark: наложение ватермарки , resizeAndSave: изменения размера картинки и его конвертация в нужный формат изображения.</p><p><b>3. Сохранение оригинала</b></p><p>Мы создаем путь для сохранения картинки, сохраняем её с необходимым для клиента уровнем сжатия и потом для удобства всю метаинформацию об картинке помещаем уже в нашу структуру и работаем в дальнейшем только с ней:</p><p>./internal/app/save.go</p><p>Для ускорения нашего процесса обработки все этапы мы будем выполнять конкурентно с помощью горутин.</p><p><b>4. Водяной знак </b></p><p>Следующим этапом идёт наложение водяного знака на нашу картинку. Процесс наложения: мы передаем каждой горутине по изображению, они его обрабатывают, а для того чтобы убедиться что они все обработались мы применяем sync.WaitGroup. Сам процесс наложения водяного знака это задание параметров для установки его на исходную картинку, в нашем случае мы делаем её полупрозрачную с небольшим углом поворота и в случайном месте и сохраняем её:</p><p>./internal/app/watermark.go</p><p>Остаётся только изменить размер и сохранить в нужном формате наши обработанные изображения.</p><p><b>5. Resize и конвертация.</b></p><p>Теперь создадим файл resize.go и реализуем функцию изменения размера изображении и сохранения в нужном нам формате:</p><p>./internal/app/resize.go</p><p>Теперь реализуем main.go в котором создадим и вызовем наш сервис обработки изображений.</p><p>./internal/cmd/main.go</p><p><b>VI. CGO</b></p><p>Наше приложение полностью готово, но теперь нужно удостовериться, что у нас работает поддержка CGO. Для начала нужно убедиться что мы скачали и установили webp по ссылке [официальная страница Google](https://developers.google.com/speed/webp/download?hl=ru). Далее нам необходимо установить GCC, без него go не может распознать импортированные C файлы, скачиваем и устанавливаем [официальные зеркала GNU](https://gcc.gnu.org/mirrors.html). Теперь нужно проверить, что переменная CGO_ENABLED=1, для этого используем команду go env и проверяем, если она равна 0, то используем go set  CGO_ENABLED=1 и проверяем ,что она применилась, если нет то перезагружаем нашу систему и проверяем. Теперь мы готовы собрать наше приложение и приступить к тестированию.</p><p><b>VII. Тестирование и оптимизация</b></p><p><b>Тестирование с Bruno</b></p><p>Здесь вы можете тестировать удобными для вас средствами такими как Postman, Bruno, Yaak, grpccurl и т.д., главное чтобы они поддерживали тестирование grpc методов. Рассмотрим пример с Bruno:</p><p>1.Конвертируйте изображение в Base64: Image to Base64 Converter</p><figure><img src="https://media.tproger.ru/user-uploads/136053/2026-02-23/3b10f151-2654-42b1-b6a2-1e6805d79ba2.webp" alt="" /></figure><p>2.Откройте Bruno создайте новый grpc запрос</p><figure><img src="https://media.tproger.ru/user-uploads/136053/2026-02-23/94dba9c1-7930-43f5-accf-1753036005db.webp" alt="" /></figure><p>3. Выбираем метод grpc:</p><figure><img src="https://media.tproger.ru/user-uploads/136053/2026-02-23/b614edcd-171f-49e5-8ba2-cd4b73283551.webp" alt="" /></figure><p>4.Уберите ползунок с reflection и укажите .proto файл</p><figure><img src="https://media.tproger.ru/user-uploads/136053/2026-02-23/8a88b632-4d1a-41a0-9818-0822a6613551.webp" alt="" /></figure><p>5.Выберите метод DownloadImage</p><figure><img src="https://media.tproger.ru/user-uploads/136053/2026-02-23/2a0f8f65-cb62-4442-a867-10d3c69f145d.webp" alt="" /></figure><p>6.В поле message заполните поле в соответствии с параметрами, например:</p><figure><img src="https://media.tproger.ru/user-uploads/136053/2026-02-23/8f454490-7182-4641-8a31-f56fe6236546.webp" alt="" /><figcaption>если появляются проблемы при подключении к сервису, то не выносите текстовое представление картинки в переменную</figcaption></figure><p>В поле image нужно скопировать текстовую строку ,что идёт после запятой, сгенерированную на шаге 1</p><p>7.Далее нужно запустить наше приложение и подключиться к нему с помощью кнопки →</p><figure><img src="https://media.tproger.ru/user-uploads/136053/2026-02-23/4a166e9e-22d3-4369-be1e-b68534623765.webp" alt="" /></figure><p>В случае успеха должен появиться статус streaming</p><p>8.Отправляем наше сообщение/сообщения нажав на кнопку "Send message" один или несколько раз и завершаем нашу передачу сообщений с помощью кнопки → (если не нажать то приложение будет ожидать приёма сообщений). Результатом будет возврат путей наших обработанных сообщений</p><figure><img src="https://media.tproger.ru/user-uploads/136053/2026-02-23/7e269ec1-2cec-4926-8ccc-a9de76d3e9ff.webp" alt="" /></figure><p><b>VIII. Заключение</b></p><p>Подведем итоги, мы создали сервис который:</p><p>Использует gRPC для эффективной передачи данных,</p><p>Поддерживает WebP, JPEG, PNG,</p><p>Безопасен в конкурентной среде,</p><p>Можно легко масштабировать.</p><p>В результате получился сервис обработки изображений. Этот подход применим не только к изображениям, но и к любым бинарным данным.</p><p>Исходный код доступен по <a href="https://github.com/art9276/image-converter" rel="nofollow">ссылке</a></p><p><b>Спасибо за внимание!</b></p>]]></content:encoded>
    </item>
    <item>
      <title>Более 30 кластеров в продуктиве: как работает ДБО в Почта Банке на базе контейнерной платформы «Штурвал»</title>
      <link>https://tproger.ru/articles/bolee-30-klasterov-v-produktive--kak-rabotaet-dbo-v-pochta-banke-</link>
      <comments>https://tproger.ru/articles/bolee-30-klasterov-v-produktive--kak-rabotaet-dbo-v-pochta-banke-?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Екатерина Соколова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/bolee-30-klasterov-v-produktive--kak-rabotaet-dbo-v-pochta-banke-</guid>
      <description><![CDATA[<p>Внедрение контейнерной платформы «Штурвал» сократило время вывода нового функционала до двух часов и обеспечило нулевые простои при обновлениях.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/bolee-30-klasterov-v-produktive--kak-rabotaet-dbo-v-pochta-banke-">Более 30 кластеров в продуктиве: как работает ДБО в Почта Банке на базе контейнерной платформы «Штурвал»</a>»</p>]]></description>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 10 Feb 2026 09:34:28 GMT</pubDate>
      <content:encoded><![CDATA[<p>⭐ <b>Участник Продуктовой Премии Tproger 2025 — проголосовать за кейс <a href="https://tprg.ru/5h0W">можно по ссылке</a></b></p><p>Почта Банк имеет широкую разветвленную сеть и работает в 83 регионах нашей страны, в том числе и в отделениях Почты России. У банка несколько миллионов клиентов, которые создают высокую нагрузку на цифровые каналы обслуживания, прежде всего на систему дистанционного банковского обслуживания (ДБО).</p><p>К 2023 году рост числа клиентов, их массовый переход в онлайн, а также запуск федеральных инициатив, включая проект «Пушкинская карта», привели к резкому увеличению нагрузки на ДБО.</p><p>В этих условиях банку потребовалась глубокая технологическая модернизация ДБО с переходом на современную микросервисную архитектуру и российский технологический стек, в частности — <a href="https://tprg.ru/bDx1" rel="nofollow">контейнерную платформу «Штурвал»</a>.</p><p>Сейчас система выдерживает 120 тысяч одновременных сеансов, позволяет добавлять новые сервисы не более чем за два часа и обеспечивает управление 30+ кластерами.</p><h2>Задача: дать банку инструмент для управления десятками кластеров и простого масштабирования</h2><p>До старта проекта банку необходимо было решить следующие задачи:</p><ul><li>сократить релизные циклы;</li><li>ускорить обновления;</li><li>автоматизировать масштабирование;</li><li>импортозаместить инфраструктуру и ключевые компоненты ДБО;</li><li>увеличить скорость вывода новых сервисов.</li></ul><p>Почта Банк принял решение создать ДБО с нуля с переходом на микросервисную архитектуру, а также внедрить российскую платформу для управления контейнерной инфраструктурой на базе отечественной виртуализации и операционной системы.</p><p>В основе решения — контейнерная платформа «Штурвал», позволяющая централизованно управлять Kubernetes-кластерами, обеспечивать высокий уровень отказоустойчивости, безопасности и масштабируемости.</p><p><a href="https://tprg.ru/mozL" rel="nofollow">«Лаборатория Числитель»</a>, разработчик платформы «Штурвал», реализовала глубокую интеграцию с системой виртуализации zVirt, поддержку RedOS и встроенные механизмы безопасности. Платформа обеспечивает централизованное управление множеством кластеров из единого окна, автоматическое масштабирование и высокий уровень отказоустойчивости, что позволяет инфраструктуре расти вместе с цифровыми сервисами банка.</p><h2>Параметры проекта</h2><ul><li>Команда: 70 человек (со стороны банка и «Лаборатории Числитель»)</li><li>Сроки: один год, проект завершился в Q3 2024 г.</li><li>Масштаб клиента: несколько миллионов пользователей, 69% из которых используют онлайн-банкинг</li><li>Инфраструктура: 6 продакшн-кластеров Kubernetes для ДБО, более 500 виртуальных машин, 2 ЦОДа</li><li>Результаты: система выдерживает до 120 тысяч одновременных сеансов, на старте проекта было развернуто 3 кластера, теперь — больше 30</li></ul><h2>Почему банк выбрал «Штурвал»</h2><p>Почта Банк сравнил шесть решений, включая Deckhouse Kubernetes Platform, OpenShift, Rancher, «ванильный» Kubernetes и другие. На «Штурвале» остановились из-за ряда причин:</p><ul><li>Архитектура для enterprise. Централизованное управление, простое масштабирование, отказоустойчивость компонентов доступных «из коробки».</li><li>Готовые интеграции. «Штурвал» работал как с тем ПО, которое банк уже использовал, так и с тем, которое только собирался внедрить.</li><li>Гибкие права доступа. Можно сегментировать доступы между командами разработки, инфраструктуры, DevOps и ИБ на уровне всей платформы.</li><li>Высокий уровень безопасности. Механизмы информационной безопасности уже встроены в  платформу.</li><li>Масштабирование вместе с бизнесом. Платформа управляет десятками кластеров из одного окна. Новый кластер разворачивается за 15 минут.</li></ul><h2>Пять главных результатов для банка</h2><ul><li>Скорость внедрения сервисов</li></ul><p>Теперь на запуск нового сервиса требуется не более двух часов. Новый кластер можно создать за 15 минут, поэтому time-to-market сильно сократился.</p><ul><li>Нулевые простои</li></ul><p>Обновления проходят без простоев, а клиенты не замечают, что в инфраструктуре что-то меняется.</p><ul><li>Нагрузка на команды уменьшилась в пять раз</li></ul><p>Автоматизация рутинных задач освободила инженеров от ручной настройки. Теперь они занимаются развитием продуктов, а не поддержкой инфраструктуры.</p><ul><li>Система устойчива к высоким нагрузкам</li></ul><p>Платформа выдерживает до 120 тысяч одновременных онлайн-сеансов. При этом остается запас по масштабированию в несколько раз, что очень важно для банка с миллионами клиентов.</p><ul><li>Полная независимость от западных вендоров</li></ul><p>Переход на российский стек убрал зависимость от западных производителей. Банк получил контроль над развитием платформы и может быстро реагировать на требования регулятора и бизнеса.</p><h2>Сложности проекта</h2><p>🔴 Проблема: внешние балансировщики с постоянно меняющимися адресами</p><p>По требованиям банка внешний доступ к приложениям должен был обеспечиваться через балансировщиков нагрузки, вынесенных за пределы кластеров. Это повышало уровень контроля и соответствовало внутренним стандартам безопасности, но одновременно усложняло архитектуру.</p><p>Дополнительной трудностью стало то, что сами кластеры создавались автоматически и динамически: имена и сетевые адреса узлов постоянно менялись.</p><p>✅ Решение: автоматическая синхронизация состояния кластера</p><p>Перед командой встала нетривиальная задача — внешняя система балансировки должна была знать, куда именно направлять трафик, несмотря на постоянные изменения внутри платформы.</p><p>Специалисты реализовали механизм автоматической синхронизации, который позволил связать внешний контур доступа с реальным состоянием кластеров. Это решение обеспечило стабильность сервисов для бизнеса без необходимости ручного вмешательства и снизило операционные риски.</p><p>🔴 Проблема: недостаточная отказоустойчивость на уровне виртуализации</p><p>Банк требовал размещения управляющих компонентов кластеров на разных физических хостах, чтобы сбой одной части инфраструктуры не приводил к остановке критичных сервисов. Но в системе zVirt отсутствовали готовые механизмы для автоматического обеспечения такого распределения.</p><p>✅ Решение: разработка компонента, контролирующего размещение управляющих серверов</p><p>Команда разработала дополнительный компонент, который автоматически контролирует и корректирует размещение управляющих серверов. Это позволило добиться требуемого уровня надежности и соответствия внутренним требованиям банка, не меняя базовую платформу виртуализации.</p><p>🔴 Проблема: инсталляционная настройка десятков кластеров</p><p>После запуска платформы нужно было настроить большое количество кластеров.</p><p>✅ Решение: паттерн Apps-of-Apps</p><p>Команда использовала паттерн Apps-of-Apps для модуля непрерывной доставки приложений. Банк получил управляемую модель, где изменения вносятся быстро, предсказуемо и с контролируемыми рисками.</p><h2>Не лобовая замена, а технологический апгрейд</h2><p>Кейс Почта Банка показал, что переход на российский стек — это возможность построить систему надежнее и быстрее западных аналогов, снизить операционные расходы и ускорить вывод новых функций для клиентов. Для банка с широкой региональной сетью в стране это критически важное конкурентное преимущество.</p><h2>Дорожная карта проекта</h2><p><b>3Q 2023:</b> подготовка — уточнение ТЗ, формирование команды, разработка план-графика.</p><p><b>4Q 2023: </b>разработка документации, пилотное развёртывание  «Штурвала», перенос 10 пилотных микросервисов на тестовый кластер.</p><p><b>1Q 2024: </b>масштабирование кластера, подготовка платформы и развёртывание HA-кластера.</p><p><b>2Q 2024: </b>перенос пилотных микросервисов в продакшен, старт доработки остальных 150 микросервисов.</p><p><b>3Q 2024:</b> развёртывание новой платформы на RedOS, перенос пилотных сервисов.</p><p><i>Реклама. ООО «Лаборатория Числитель», ИНН 9731042193, erid: 2W5zFHR4LV7</i></p>]]></content:encoded>
    </item>
    <item>
      <title>17 месяцев, 7 человек и бесплатный мониторинг: как собрали систему управления IT-инфраструктурой с нуля</title>
      <link>https://tproger.ru/articles/17-mesyacev--7-chelovek-i-besplatnyj-monitoring--kak-sobrali-siste</link>
      <comments>https://tproger.ru/articles/17-mesyacev--7-chelovek-i-besplatnyj-monitoring--kak-sobrali-siste?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Екатерина Соколова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/17-mesyacev--7-chelovek-i-besplatnyj-monitoring--kak-sobrali-siste</guid>
      <description><![CDATA[<p>«Гравитон» за 17 месяцев сделал систему мониторинга без агентов. Она работает через обычные сетевые протоколы, шлёт уведомления в Telegram и показывает всё в реальном времени.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/17-mesyacev--7-chelovek-i-besplatnyj-monitoring--kak-sobrali-siste">17 месяцев, 7 человек и бесплатный мониторинг: как собрали систему управления IT-инфраструктурой с нуля</a>»</p>]]></description>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Анализ данных]]></category>
      <category><![CDATA[Аналитика]]></category>
      <category><![CDATA[Инфраструктура]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 02 Feb 2026 09:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p><b>⭐ Участник Продуктовой Премии Tproger 2025 — проголосовать за кейс <a href="https://tprg.ru/14rv">можно по ссылке</a></b></p><p>Когда в компании несколько сотен серверов, виртуальных машин и рабочих станций, мониторинг превращается в жуткую боль и беготню между разными системами. Обычно на каждое устройство ставят своего агента, настраивают подключения, обновляют клиенты — и всё это одновременно на сотнях машин. Мы используем агентов только для ПК, ноутбуков и моноблоков.</p><p><a href="https://tprg.ru/TxZr" rel="nofollow">«Гравитон»</a> за 17 месяцев сделал систему мониторинга без агентов. Она работает через обычные сетевые протоколы, шлёт уведомления в Telegram и показывает всё в реальном времени. Команда из 7 человек написала всё с нуля и выпустила бесплатно.</p><h2>Задача: мониторить всю инфраструктуру без установки агентов на каждый сервер</h2><p><b>Бизнес</b> хочет, чтобы вся инфраструктура работала без сбоев — серверы, виртуальные машины, рабочие станции. Администраторы должны знать, что происходит: сколько загружен процессор, какая температура, не заканчивается ли место на дисках, все ли сервисы работают.</p><p><b>Техническая часть</b> — сделать систему, которая подключается к устройствам без установки дополнительного софта. Использовать те протоколы, которые уже есть в оборудовании. Показывать проблемы сразу, а не через пять минут. Дать возможность не только смотреть, но и управлять удалённо.</p><h2>Параметры проекта</h2><ul><li>Срок разработки: март 2024 — август 2025 (17 месяцев)</li><li>Команда: 7 человек</li><li>Статус: продукт на рынке 5 месяцев, предоставляется бесплатно на первый год использования</li><li>Первый проект: мониторинг нескольких сотен моноблоков</li><li>Интерес рынка: несколько десятков запросов на тестирование с момента запуска</li></ul><p>Поддерживаемое оборудование: виртуальные машины, серверы, системы хранения данных, клиентские устройства (персональные компьютеры, моноблоки, многофункциональные устройства «Гравитон»).</p><h2>Архитектура: микросервисы и протоколы без агентов</h2><p>Систему собрали из микросервисов — каждый отвечает за свою часть:</p><p>Устройства в сети</p><p>→ Подключение через WebSocket, Redfish, IPMI, SNMP, Prometheus</p><p>→ Сервисы, которые собирают и обрабатывают данные</p><p>→ SQL для настроек, Prometheus для метрик по времени</p><p>→ PromQL для правил уведомлений</p><p>→ Веб-интерфейс с графиками</p><p>→ Уведомления в Telegram</p><p>Главное — для серверов и сетевого оборудования система не ставит агентов. Подключается к тому, что уже есть в устройствах. Агенты используются только для пользовательских устройств — ПК, ноутбуков и моноблоков.</p><h2>Пять главных фишек</h2><p><b>1. Всё в реальном времени через WebSocket</b></p><p>WebSocket — это двусторонняя связь. Устройство может само отправить сигнал, когда что-то меняется. Температура выросла, диск заканчивается — администратор видит это мгновенно в интерфейсе. При сканировании сети результаты появляются сразу, не нужно ждать и обновлять страницу.</p><p>Чем быстрее узнал о проблеме — тем быстрее починил.</p><p><b>2. Всё написано с нуля</b></p><p>Команда не взяла готовые библиотеки для важных частей. Авторизация, управление пользователями, уведомления — всё своё. Это дало полный контроль и возможность подстроить под российский рынок без зависимости от чужого кода.</p><p><b>3. Никаких агентов</b></p><p>Система использует протоколы, которые уже есть в оборудовании. Redfish для современных серверов, IPMI для управления на аппаратном уровне, SNMP для сетевых устройств, Prometheus для Linux-серверов. Не нужно ничего устанавливать, настраивать, обновлять на каждой машине.</p><p><b>4. Интеграция с Telegram для уведомлений</b></p><p>Вместо email-рассылок или SMS, которые легко пропустить, система отправляет уведомления о проблемах прямо в Telegram. Администратор получает сообщение на телефон: «Температура процессора сервера srv-db-01 достигла 85°C» или «Диск /dev/sda на сервере srv-web-03 заполнен на 95%». Можно настроить отдельные каналы для разных типов событий или разных команд.</p><p><b>5. PromQL для гибких условий мониторинга</b></p><p>Для составления выражений, которые запускают уведомления, используется PromQL — язык запросов Prometheus. Администратор может создавать сложные условия: «уведомить, если загрузка процессора выше 80% в течение 5 минут» или «предупредить, если свободное место на диске меньше 10% и скорость его уменьшения больше 1 ГБ в час». Это не просто пороговые значения, а гибкие правила с учётом трендов и контекста.</p><h2>Главная трудность: CORS и удалённое управление KVM</h2><p><b>🔴 Проблема: запуск KVM через браузер</b></p><p>KVM (клавиатура, видео, мышь) — технология удалённого управления сервером на уровне «железа», как будто вы сидите перед монитором с клавиатурой. Запуск инструмента KVM из веб-интерфейса системы мониторинга столкнулся со сложностями из-за ограничений CORS (Cross-Origin Resource Sharing) — механизма безопасности браузеров, который блокирует запросы между разными доменами.</p><p><b>✅ Решение: корректная авторизация, поддерживаемая сервером</b></p><p>Команда реализовала метод авторизации, который поддерживается сервером управления и корректно обрабатывается браузером с учётом политик CORS. Это позволило безопасно запускать KVM-сессии прямо из веб-интерфейса системы мониторинга без установки дополнительных приложений на компьютер администратора. Теперь можно подключиться к серверу и управлять им через браузер, даже если операционная система на сервере не загружается.</p><h2>Результаты и конкуренция на рынке</h2><p>Первый проект — мониторинг нескольких сотен моноблоков в коммерческой эксплуатации. Система показала стабильность работы и справилась с нагрузкой. С момента запуска пришло несколько десятков запросов на тестирование продукта от компаний с разной инфраструктурой.</p><p>Продукт на рынке 5 месяцев, в то время как конкуренты работают более 5 лет и имеют устоявшуюся клиентскую базу. По отзывам клиентов собран перечень функционала, который необходимо реализовать для успешной конкуренции: расширение набора метрик, поддержка большего числа типов оборудования, специфические интеграции с корпоративными системами.</p><p>Стратегия выхода на рынок — дать базовый функционал бесплатно, чтобы компании могли попробовать продукт без барьеров. В течение 2026 года появится дополнительный платный функционал для крупных инсталляций и специфических задач.</p><h2>Планы развития: от мониторинга к предсказанию проблем</h2><p>Команда <a href="https://tprg.ru/TxZr" rel="nofollow">«Гравитон»</a> развивает продукт по семи направлениям.</p><ol><li>Больше метрик и функций управления — новые показатели, управление питанием, настройка устройств удалённо.</li><li>Поддержка большего числа устройств — работа с оборудованием от разных производителей.</li><li>Платные функции — расширенная аналитика, интеграция с корпоративными системами, отчёты для проверок.</li><li>Предсказание поломок — анализ данных по времени, чтобы понять, когда диск или блок питания выйдет из строя. Замена до того, как сломалось.</li><li>Автоматизация — система сама делает что-то при проблемах. Процессор перегружен — перезапустить сервис. Диск заполнен — почистить логи.</li><li>Настройка интерфейса — каждый видит свои дашборды. Администратор — технические метрики, руководитель — сводки, топ-менеджмент — общую доступность.</li><li>Карта серверной — схема, где какой сервер стоит в стойках, с привязкой к состоянию. Видно, где проблемный сервер и что рядом с ним.</li></ol><p><i>Реклама. ООО «Ревотех», ИНН 9731071780, erid: 2W5zFJx4cjB</i></p>]]></content:encoded>
    </item>
    <item>
      <title>Python CQRS: Пишем распределенные системы без боли (Sagas, Outbox, Event Driven)</title>
      <link>https://tproger.ru/articles/python-cqrs--piwem-raspredelennye-sistemy-bez-boli--sagas--outbox--event-driven-</link>
      <comments>https://tproger.ru/articles/python-cqrs--piwem-raspredelennye-sistemy-bez-boli--sagas--outbox--event-driven-?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Вадим Козыревский]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/python-cqrs--piwem-raspredelennye-sistemy-bez-boli--sagas--outbox--event-driven-</guid>
      <description><![CDATA[<p>Пишете распределенные системы на Python? Узнайте, как python-cqrs решает проблемы согласованности через Оркестрируемые Саги и паттерн Mediator.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/python-cqrs--piwem-raspredelennye-sistemy-bez-boli--sagas--outbox--event-driven-">Python CQRS: Пишем распределенные системы без боли (Sagas, Outbox, Event Driven)</a>»</p>]]></description>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 13 Jan 2026 21:40:02 GMT</pubDate>
      <content:encoded><![CDATA[<blockquote>Говорят, что распределенная система — это когда вы не можете работать, потому что упал сервер, о существовании которого вы даже не подозревали. А если этот сервер ещё и успел списать деньги с карты пользователя, но “забыл” сообщить об этом складу — добро пожаловать в увлекательный мир согласованности данных, где COMMIT больше не гарантирует вам спокойный сон.</blockquote><p>Всем привет! Меня зовут Вадим, я техлид команды финансовой инфраструктуры в Timeweb Cloud. Сегодня я хочу рассказать об инструменте, который лежит в основе наших Python-микросервисов. Это пилотный пост-знакомство: без долгих историй “как мы дошли до жизни такой” (большая статья с архитектурными кейсами уже готовится), а чисто по делу.</p><p>Если вы пишете сложные распределенные системы и устали каждый раз заново изобретать велосипеды для Transactional Outbox, Sagas или Mediator — этот пост сэкономит вам кучу времени.</p><p>Представляю python-cqrs — фреймворк для реализации паттернов CQRS и Event-Driven Architecture. Он вырос из форка проекта <a href="https://github.com/akhundMurad/diator">diator</a>, но превратился в самостоятельный комбайн для построения надежных систем.</p><h2>Killer Features</h2><h3>Честный CQS и Mediator (База)</h3><p>По названию может показаться, что пакет исключительно про сложный CQRS и Event Sourcing. На самом деле, название родилось исторически: мы искали инструмент именно для ES-сервиса. Но в итоге создали универсальную реализацию паттернов Mediator и CQS (Command Query Separation).</p><p>Суть проста: мы разделяем операции изменения состояния (Команды) и чтения данных (Запросы). Это позволяет изолировать чистую бизнес-логику от инфраструктуры (HTTP, Kafka, CLI). Хендлер ничего не знает о том, как пришел запрос, он просто выполняет задачу.</p><figure><img src="https://media.tproger.ru/user-uploads/135308/2026-01-06/ad0d8b49-38b1-4675-830f-1f74b5da732c.png" alt="" /></figure><h3>Распределенные транзакции (Saga Pattern)</h3><p>Библиотека реализует Оркестрированные Саги с сохранением состояния:</p><ol><li>Автоматическая компенсация: Если шаг падает, фреймворк автоматически запускает логику отката (compensate) в обратном порядке для всех уже выполненных шагов.</li><li>Recovery Mechanism: Если под (pod) сервиса был убит (OOM, редеплой) посередине транзакции, при рестарте механизм восстановления вычитает состояние из SagaStorage и продолжит выполнение с прерванного места (или продолжит компенсацию).</li><li>SagaStorage &amp; SagaLog: Состояние саги персистентно. Каждый шаг (успех, ошибка, начало компенсации) пишется в SagaLog. Это позволяет не терять контекст транзакции даже при падении всего кластера.</li><li>Конкурентность: В SagaMediator встроена защита от гонок (race conditions). Даже если несколько инстансов сервиса попытаются обработать события одной саги одновременно, механизм блокировок (на уровне хранилища) гарантирует последовательное выполнение шагов.</li></ol><figure><img src="https://media.tproger.ru/user-uploads/135308/2026-01-06/637912d5-2104-4f74-a89a-2d4006244327.png" alt="" /></figure><h3>Transactional Outbox</h3><p>Классическая проблема “Dual Write”: мы сохранили сущность в БД, но упали перед отправкой события в Kafka. В итоге — рассинхрон. python-cqrs реализует Transactional Outbox, гарантируя, что события сохраняются в той же транзакции БД, что и бизнес-данные.</p><figure><img src="https://media.tproger.ru/user-uploads/135308/2026-01-06/511125e3-ffe7-4bab-9cdc-76364e91ed0b.png" alt="" /></figure><h3>Streaming Request Handlers</h3><p>Нужно обработать большой файл или вернуть прогресс-бар пользователю? StreamingRequestMediator позволяет отдавать данные по кускам (yield), идеально ложась на Server-Sent Events (SSE) в FastAPI.</p><figure><img src="https://media.tproger.ru/user-uploads/135308/2026-01-06/1be67d54-3df4-46e0-9e08-c0f4f6dfb95d.png" alt="" /></figure><h3>Разделение Domain Events и Notification Events</h3><p>В python-cqrs мы четко разделяем события на два типа. Это помогает не смешивать внутреннюю логику модуля с публичным контрактом сервиса.</p><h4>Domain Event (Внутренние)</h4><p>Это события, которые происходят внутри вашего bounded context. Они нужны, чтобы снизить зацепление (coupling) между компонентами одной системы.</p><ul><li>Как работают: Хендлер возвращает их через свойство events. Mediator перехватывает их и тут же (или в фоне) рассылает локальным подписчикам.</li><li>Пример: “Заказ создан” -&gt; (внутри того же сервиса) -&gt; “Отправить email”, “Обновить аналитику”.</li><li>⚠️ Важно: Этот механизм работает In-Memory и не дает гарантий доставки (at-most-once). Если процесс упадет во время обработки доменного события, оно (и его сайд-эффекты) будет потеряно.</li></ul><figure><img src="https://media.tproger.ru/user-uploads/135308/2026-01-06/541904d8-82b3-43db-b309-c76a5bbcdc5e.png" alt="" /></figure><h4>Notification Events (Публичные / Интеграционные)</h4><p>Это события, которые улетают наружу — в Kafka/RabbitMQ для других микросервисов.</p><ul><li>Как работают: Это обертки (NotificationEvent), которые содержат топик и пейлоад. Именно их мы сохраняем в Transactional Outbox, чтобы гарантировать доставку.</li><li>EventMediator: Для их обработки на стороне потребителя (Consumer) есть отдельный EventMediator, который умеет маршрутизировать входящие сообщения из брокера.</li></ul><figure><img src="https://media.tproger.ru/user-uploads/135308/2026-01-06/c1b28e58-f06b-4447-bdf3-132d55dc6789.png" alt="" /></figure><p>Почему это круто? Вы можете менять внутреннюю структуру доменных событий как угодно, не ломая контракты с внешними сервисами. Публичный API (Notification Events) стабилен, внутренняя кухня (Domain Events) гибка.</p><h3>Бесшовная интеграция (FastAPI &amp; FastStream)</h3><p>python-cqrs проектировался так, чтобы быть “клеем” между вашей бизнес-логикой и внешним миром. Интеграция происходит максимально нативно через Dependency Injection и встроенные bootstrap-утилиты.</p><h4>FastAPI (HTTP API)</h4><p>Вам не нужно вручную собирать медиатор. Используйте cqrs.requests.bootstrap для фабрики и fastapi.Depends для внедрения.</p><figure><img src="https://media.tproger.ru/user-uploads/135308/2026-01-06/42a0f5d1-e5f1-4204-943f-771926846ddd.png" alt="" /></figure><h4>FastStream (Kafka Consumer)</h4><p>Для обработки входящих Notification-событий из Kafka используем cqrs.events.bootstrap для создания EventMediator.</p><figure><img src="https://media.tproger.ru/user-uploads/135308/2026-01-06/6312d7e1-a136-46c6-807d-4d0c23072490.png" alt="" /></figure><p>Итог: Ваш Presentation Layer занимается только транспортом. Вся конфигурация собрана в bootstrap, а логика — в Handlers.</p><h3>Другие фичи</h3><ol><li>Modern Python: Полная типизация, поддержка Pydantic v2.</li><li>Dependency Injection: “First-class citizen” поддержка популярных DI-фреймворков. Есть готовые интеграции как для легковесного di, так и для мощного dependency-injector. Вы просто объявляете зависимости в init хендлера, и они “прилетают” автоматически.</li><li>Event-Driven &amp; Protobuf:<br />– Нативная поддержка Kafka (используем aiokafka под капотом, отлично дружит с faststream).<br />–  Поддержка Protobuf для Notification-событий “из коробки” — критично для высоконагруженных систем, где важен размер сообщения.</li><li>Parallel Event Processing: Хотите обрабатывать 10 доменных событий одной команды параллельно, но не положить базу? Просто настройте max_concurrent_event_handlers в медиаторе.</li><li>Chain of Responsibility: Цепочки обработчиков с возможностью построения диаграмм.</li><li>Mermaid Visualizations: Автоматическая генерация диаграмм для Saga и Chain of Responsibility. Планируем расширить это на все типы обработчиков, чтобы документация всегда соответствовала коду.</li><li>Bootstrap Tools: Набор утилит для быстрой настройки Presentation Layer (FastAPI, CLI). Не нужно писать тонны бойлерплейта, чтобы собрать медиатор, мапперы и DI-контейнер воедино — есть удобные bootstrap-функции.</li></ol><h3>Планы на будущее (Roadmap)</h3><p>Мы активно работаем над тем, чтобы библиотека следовала всем стандартам для HighLoad на Python. Вот ближайшие наши планы</p><h4>Архитектура и Гибкость</h4><ul><li>Отвязка от Pydantic: Сделать ядро библиотеки агностиком к моделям данных. Поддержка dataclasses, attrs, msgspec или простых TypedDict для тех, кому важна максимальная производительность и минимум зависимостей.</li></ul><h4>Observability</h4><ul><li>OpenTelemetry: Автоматический проброс trace_id сквозь цепочку Command → Saga → Event.</li><li>Метрики: Middleware для сбора Prometheus-метрик (длительность хендлеров, счетчики ошибок, лаг саг).</li></ul><h4>Resiliency</h4><ul><li>Idempotency Middleware: Механизм дедупликации сообщений (Redis/DB) для безопасной обработки “at-least-once”.</li><li>Circuit Breaker: Защита от каскадных сбоев внешних сервисов.</li><li>Unified Transport: Единый интерфейс для переключения между RabbitMQ, Redis Streams и NATS.</li></ul><h4>Developer Experience</h4><ul><li>Testing Harness: Удобный API для написания интеграционных тестов бизнес-флоу.</li><li>In-Memory Transport: Возможность прогонять тесты “Команда -&gt; Событие -&gt; Сага” в памяти без поднятия Docker-контейнеров.</li></ul><h3>Что дальше?</h3><p>Как я и сказал в начале, это лишь обзорный “выстрел в воздух”, чтобы найти единомышленников и собрать первый фидбек. В следующей большой статье я планирую рассказать:</p><ol><li>Как мы переписывали монолит на микросервисы и почему стандартные подходы не сработали.</li><li>Реальные кейсы использования TransactionOutbox и Саг в продакшене (где это спасло деньги).</li><li>Почему мы отказались от готовых решений и начали пилить своё.</li></ol><p>А пока — буду рад любым issues, звездам на GitHub и конструктивной критике в комментариях. Если вы пишете микросервисы на Python, используете Outbox-ы, CQRS или Саги в Python — расскажите, какие боли испытываете вы? Возможно, мы сможем решить их вместе.</p><h3>Ссылки</h3><p>1. <a href="https://github.com/vadikko2/python-cqrs">GitHub</a></p><p>2. <a href="https://pypi.org/project/python-cqrs/">PyPi</a></p><p>3. <a href="https://vadikko2.github.io/python-cqrs-mkdocs/">Документация</a></p><p>4. <a href="https://deepwiki.com/vadikko2/python-cqrs">DeepWiki</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Раскрыли 6 архитектурных паттернов 2025 года, которые реально работают</title>
      <link>https://tproger.ru/articles/raskryli-6-arhitekturnyh-patternov-2025-goda--kotorye-realno-rabotayut</link>
      <comments>https://tproger.ru/articles/raskryli-6-arhitekturnyh-patternov-2025-goda--kotorye-realno-rabotayut?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Михаил Сахаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/raskryli-6-arhitekturnyh-patternov-2025-goda--kotorye-realno-rabotayut</guid>
      <description><![CDATA[<p>В статье разберём шесть архитектурных паттернов, которые реально работают. Они помогут вам построить отказоустойчивый проект.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/raskryli-6-arhitekturnyh-patternov-2025-goda--kotorye-realno-rabotayut">Раскрыли 6 архитектурных паттернов 2025 года, которые реально работают</a>»</p>]]></description>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Архитектура приложений]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 07 Oct 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Перевод <a href="https://medium.com/devlink-tips/mastering-software-architecture-6-patterns-every-developer-should-know-and-actually-use-4471610bc750">статьи</a> с Medium. Предлагаем обсудить в комментариях!</p><p>Несколько лет назад архитектура казалась чем-то далёким. Сегодня разработчики сталкиваются с проектированием на каждом проекте. Пока одни спорят о модных словечках на митингах, другие строят устойчивые системы, которые не падают при первой же нагрузке.</p><p>Обычно всё начинается с небольшого проекта, который со временем разрастается. Строки кода торчат «из каждой щели». И тут ты понимаешь: «Наверное, стоило лучше структурировать это с самого начала».</p><p>Архитектура — не про красивые диаграммы. Это про системы, которые не падают, когда приложение набирает 1000 пользователей или добавляется очередная фича.</p><p>В статье разберём шесть архитектурных паттернов, которые реально работают и помогут вам построить отказоустойчивый проект.</p><h2>Монолитная архитектура</h2><p>Если бы архитектура программного обеспечения была видеоигрой, монолит стал бы сюжетной катсценой, которую нельзя пропустить. Это простейший способ что-то построить: один код, один деплой, один сервер. В монолитной архитектуре UI, бизнес-логика и доступ к базе данных упакованы вместе. Проект быстро запускается и идеально подходит для MVP.</p><p><b>Когда монолит сработает отлично:</b></p><ul><li>Стартапы на ранней стадии — там нужна скорость, а не сложность;</li><li>Внутренние инструменты — ими будут пользоваться от силы пара десятков человек;</li><li>Системы, где скорость развёртывания важнее масштабируемости.</li></ul><p><b>Когда он может навредить:</b></p><ul><li>В растущих командах, где каждое обновление рискует сломать несвязанные части;</li><li>Во время масштабирования конкретных сервисов — нельзя расширять только одну функцию;</li><li>Когда развёртывание проекта превращается в рулетку с девизом «всё или ничего».</li></ul><p>Пример: Instagram* начинался как монолит. Только после прихода миллионов пользователей   разработчики приложения начали разделять всё на сервисы. Поэтому нужно сначала запуститься, а потом уже думать о масштабируемости.</p><p>* — продукт компании Meta. Признана в РФ экстремистской и запрещена.</p><figure><img src="https://media.tproger.ru/user-uploads/115386/2025-09-25/e61f9d26-8b85-4c92-882a-077c16ba86d8.png" alt="" /></figure><h2>Слоистая архитектура</h2><p>Думая об N-слойной (Tiered) архитектуре, представляем лазанью. Каждый слой выполняет свою функцию, и лучше их не смешивать — получится каша, и проект рухнет.</p><p>Слоистая архитектура разбивает приложение на логические слои:</p><ul><li>Слой представления (UI, фронтенд);</li><li>Слой бизнес-логики (правила, рабочие процессы);</li><li>Слой доступа к данным (общение с базой данных).</li></ul><p>Иногда это называют N-уровневой (Layered) архитектурой, когда каждый слой физически работает на разных машинах или серверах.</p><p><b>Когда слоистая архитектура поможет:</b></p><ul><li>Традиционные веб-приложения — интернет-магазины, банковские порталы;</li><li>Стеки, которым нужны чёткие границы — например, фронтенд и бэкенд;</li><li>Системы, где изменения изолированы — можно поменять UI, не ломая базу данных.</li></ul><p><b>Когда может навредить:</b></p><ul><li>Слишком много слоёв — разработка замедлится;</li><li>Тесные связи в проекте — один сломанный сервис может вызвать эффект домино;</li><li>Чрезмерное усложнение простых приложений.</li></ul><p>Пример: классические Spring Boot Java-приложения или ASP.NET-проекты часто аккуратно разделены на слои, поэтому их очень легко поддерживать.</p><figure><img src="https://media.tproger.ru/user-uploads/115386/2025-09-25/8b949bfc-d068-415c-8436-1b3958abfa12.png" alt="" /></figure><h2>Микросервисная архитектура</h2><p>Микросервисы — это гигантская карта, разбитая на небольшие локации. На каждой из них свои квесты, уровни, монстры и чекпоинты. Вместо одного огромного файла с кодом приложение разделяется на независимые сервисы. Каждый из них хорошо выполняет одну функцию и может разворачиваться, обновляться и масштабироваться независимо.</p><p><b>Когда микросервисы помогут:</b></p><ul><li>В больших командах, работающих над разными частями приложения;</li><li>В высоконагруженных приложениях, требующих независимого масштабирования, например, для поиска, авторизации или оплаты подписки;</li><li>Когда нужна гибкость в использовании разных технологических стеков для каждого отдельного сервиса.</li></ul><p><b>Когда могут навредить:</b></p><ul><li>Если взаимодействие между сервисами превращается в адский спагетти-код;</li><li>При отладке приложения — поправить 20+ микросервисов займёт много времени;</li><li>Если пайплайны развёртывания нуждаются в серьёзной автоматизации. С микросервисами проект может превратиться в полный хаос.</li></ul><p>Пример: Netflix — эталон микросервисов. Тысячи мини-приложений обрабатывают всё: от рекомендаций до биллинга. Однако для налаживания правильной работы потребовались годы.</p><figure><img src="https://media.tproger.ru/user-uploads/115386/2025-09-25/3acbec32-f942-4624-a1ba-451cc5117ef9.png" alt="" /></figure><h2>Событийно-ориентированная архитектура</h2><p>Событийно-ориентированная архитектура — это частный случай SOA (сервисно-ориентированной архитектуры). Его можно представить как строительство гигантской системы из люков. Вместо прямой команды определённому сервису событие будто улетает в пустоту, и каждая из частей проекта реагирует на него, как может.</p><p>Событие — просто маленький факт: «Что-то произошло». Сервисы «подписываются» на события и решают, что делать дальше, сохраняя систему слабо связанной и очень гибкой.</p><p><b>Когда событийно-ориентированная архитектура поможет:</b></p><ul><li>В системах, которые требуют массивной масштабируемости — оформление заказов в интернет-магазинах, уведомления в реальном времени;</li><li>Когда сервисы должны реагировать на действия независимо — биллинг после покупки подписки;</li><li>При обработке высокообъёмных потоков данных без засорения системы.</li></ul><p><b>Когда может навредить:</b></p><ul><li>Если отладка превращается в детектив — ни одна часть системы не знает, кто выполнил действие;</li><li>Согласованность данных в данной системе не мгновенная, а конечная. Это требует особого подхода к проектированию;</li><li>Если события плохо документированы, понадобится экстрасенс, чтобы разобраться в них позже.</li></ul><p>Пример: Amazon использует тяжёлую событийно-ориентированную архитектуру для обработки заказов и управления складскими запасами — каждый размещённый заказ запускает множество независимых downstream-сервисов.</p><figure><img src="https://media.tproger.ru/user-uploads/115386/2025-09-25/9232eddd-de2d-40e3-8435-e4c0d75f6e8c.png" alt="" /></figure><h2>Serverless-архитектура</h2><p>«Serverless» звучит как магия — никаких серверов, только чистый код, работающий в облаке! В реальности серверы всё-таки есть, но мы ими не управляем.</p><p>В serverless-архитектуре нужно писать маленькие функции, которые облачные провайдеры (AWS Lambda, Azure Functions) запускают по требованию. Платить необходимо за фактическое время работы, а не за простой.</p><p><b>Когда serverless поможет:</b></p><ul><li>Приложения с непредсказуемым трафиком — огромные всплески, долгие затишья;</li><li>Легковесные API, фоновые задачи, скрипты автоматизации;</li><li>Стартапы, нуждающиеся в MVP без массивных инфраструктурных затрат.</li></ul><p><b>Когда может навредить:</b></p><ul><li>Холодные старты — придется ждать, пока функция «проснётся»;</li><li>Сложные приложения становится трудно координировать, если разделить на слишком много крошечных функций;</li><li>Привязка к вендору — уход от AWS/GCP/Azure позже может быть болезненным.</li></ul><p>Пример: Netflix использует serverless для программирования фич вроде триггеров уведомлений пользователей и пайплайнов обработки данных — особенно когда рабочие нагрузки непредсказуемы.</p><h2>Гексагональная архитектура</h2><p>«Гексагональная архитектура» — звучит сложно, но это один из самых дружелюбных к разработчикам паттернов из когда-либо созданных. Прозванный «Порты и Адаптеры», он защищает основную бизнес-логику от внешнего мира (базы данных, API, UI-фреймворки).</p><p>Представим, что приложение — замок. Важные вещи происходят внутри стен (основной домен), а порты (ворота) и адаптеры (подъемные мосты) позволяют внешнему миру с ним общаться — не касаясь ядра напрямую.</p><p><b>Когда гексагональная архитектура поможет:</b></p><ul><li>Долгосрочные проекты, где изменения гарантированы;</li><li>Системы, нуждающиеся в гибкости, — замена баз данных или API без проблем;</li><li>Чистая, тестируемая бизнес-логика без внешнего шума.</li></ul><p><b>Когда может навредить:</b></p><ul><li>Избыточна для крошечных приложений или одноразовых прототипов;</li><li>Требует дисциплины — нужно сразу установить все границы;</li><li>Может замедлить разработку на начальных этапах.</li></ul><p>Пример: Airbnb использует вариации этого паттерна, чтобы сохранить системы бронирования, платежей и листингов независимыми — это позволяет быстрее разрабатывать функции без нарушения основных процессов.</p><p>Совет: если устали переписывать всё потому, что какой-то внешний API изменился, гексагональная архитектура станет вашим лучшим другом.</p><figure><img src="https://media.tproger.ru/user-uploads/115386/2025-09-25/48cc9cd0-fa73-438a-85b3-4c1796a1852b.png" alt="" /></figure><h2>Выбираем оружие с умом</h2><p>Ни один архитектурный паттерн не универсален. Каждый из шести — монолит, слои, микросервисы, событийно-ориентированный подход, serverless, гексагональная архитектура — это инструмент. Выбор правильного паттерна — половина успеха.</p><p>Начинаем просто. Рефакторим код по мере роста и помним: хорошая архитектура невидима — пользователи никогда не знают, что она есть, но определенно чувствуют, когда она неправильная.</p><p>Освежим в памяти:</p><ol><li>Монолитная архитектура — простейший старт, всё в одном коде. Идеально для MVP и стартапов. Проблемы начинаются при росте команды и необходимости независимого масштабирования частей системы.</li><li>Слоистая архитектура — чёткое разделение UI, бизнес-логики и данных. Отлично для традиционных веб-приложений с устоявшимися процессами. Может замедлить разработку при избытке слоев.</li><li>Микросервисная архитектура — независимые сервисы для больших команд и высоких нагрузок. Даёт гибкость, но требует серьёзной автоматизации и усложняет отладку между сервисами.</li><li>Событийно-ориентированная архитектура — слабая связанность через события. Идеальна для систем реального времени и высоких нагрузок. Усложняет отладку и контроль согласованности данных.</li><li>Serverless-архитектура — функции по требованию без управления серверами. Экономична для непредсказуемых нагрузок. Создаёт проблемы с холодными стартами и привязкой к провайдеру.</li><li>Гексагональная архитектура — защита бизнес-логики от внешних изменений через порты и адаптеры. Лучший выбор для долгосрочных проектов с частыми изменениями требований. Может быть избыточной для простых приложений.</li></ol><p>У автора <a href="https://medium.com/devlink-tips/mastering-software-architecture-6-patterns-every-developer-should-know-and-actually-use-4471610bc750">статьи</a> есть еще большое количество гайдов по проектированию и разработке ПО, которые также будут полезны.</p>]]></content:encoded>
    </item>
    <item>
      <title>Post-GraphQL мир: стоит ли переходить на gRPC и tRPC</title>
      <link>https://tproger.ru/articles/post-graphql-mir--stoit-li-perehodit-na-grpc-i-trpc</link>
      <comments>https://tproger.ru/articles/post-graphql-mir--stoit-li-perehodit-na-grpc-i-trpc?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Денис Кудерин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/post-graphql-mir--stoit-li-perehodit-na-grpc-i-trpc</guid>
      <description><![CDATA[<p>Подробное сравнение технологий API для разработчиков. Разбираем сильные и слабые стороны GraphQL, gRPC и tRPC на реальных кейсах. Практические рекомендации по выбору технологии для вашего проекта.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/post-graphql-mir--stoit-li-perehodit-na-grpc-i-trpc">Post-GraphQL мир: стоит ли переходить на gRPC и tRPC</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Дизайн интерфейсов и UX]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Post-GraphQL]]></category>
      <category><![CDATA[gRPC]]></category>
      <category><![CDATA[Архитектура приложений]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 01 Oct 2025 12:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Архитектура API постоянно меняется. Несколько лет назад GraphQL казался панацеей от всех болезней REST. Сегодня всё чаще говорят о двух других технологиях — gRPC и tRPC. Это не означает, что GraphQL уже не актуален — он нашёл свою нишу и продолжает развиваться, но это уже не универсальное решение для любых задач. Фреймворки gRPC и tRPC открывают принципиально иные подходы к построению API. Они решают конкретные проблемы в конкретных контекстах.</p><p>Узнаем, что предлагает Post-GraphQL мир, в чём плюсы и минусы фреймворков gRPC и tRPC и в каких ситуациях стоит пользоваться новыми инструментами.</p><h2>От монолитов к микросервисам: как мы здесь оказались</h2><p>Чтобы понять современный ландшафт API, вернёмся на несколько лет назад. REST доминировал десятилетиями. Этот подход прост для понимания, но имеет фундаментальные проблемы.</p><p>Типичный сценарий разработки под REST выглядел так: фронтендеры постоянно просили бэкендеров добавить новые поля в ответы API или создать новые эндпоинты. Возникала тесная связь между командами, что замедляло разработку.</p><p>GraphQL решил эти проблемы, предоставив клиентам возможность запрашивать именно те данные, которые им нужны. Один запрос вместо десятков, строгая типизация, интроспекция — всё это сделало GraphQL популярным.</p><p>Но идеальных технологий не существует. GraphQL принёс свои сложности:</p><ul><li>кэширование на клиенте стало нетривиальной задачей;</li><li>сложные запросы создавали нагрузку на сервер;</li><li>необходимость изучать новый язык запросов отпугивала разработчиков.</li></ul><p>Эволюция продолжилась. Сегодня мы видим, как экосистема разделилась на два основных направления: высокопроизводительные межсервисные коммуникации (gRPC) и бесшовную разработку полного стека на TypeScript (tRPC).</p><h2>gRPC: высокопроизводительная связность для микросервисов</h2><p>gRPC — не просто ещё один протокол, а полноценная экосистема для построения эффективных распределённых систем. Технология создана Google для внутренних нужд, где критически важны производительность и надёжность.</p><p>gRPC использует Protocol Buffers (protobuf) в качестве языка описания интерфейсов и формата сериализации. Это бинарный формат, который значительно эффективнее текстового JSON. Сообщения занимают меньше места и быстрее обрабатываются.</p><p>HTTP/2 — ещё один козырь gRPC. Этот протокол поддерживает мультиплексирование запросов, server push и двунаправленные потоки. В отличие от традиционных HTTP-запросов, gRPC может работать с постоянными соединениями и потоковой передачей данных в реальном времени.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-30/ca6ce939-89ec-4b24-b4e4-dbccf40845cd.png" alt="" /></figure><h2>Когда gRPC действительно сияет</h2><p>gRPC идеально подходит для микросервисных архитектур, где сервисы общаются друг с другом внутри защищенной сети. Финансовые системы, телекоммуникационные платформы, игровые серверы — везде, где важны эффективность и минимальное время отклика.</p><p>Сильная сторона gRPC — потоковая передача данных. Представьте систему мониторинга, где сервер постоянно отправляет метрики, или чат-приложение с тысячами одновременных соединений. gRPC справляется с такими задачами лучше REST или GraphQL благодаря встроенной поддержке потоков на уровне протокола HTTP/2.</p><p>В отличие от REST, который требует постоянного установления новых HTTP-соединений, gRPC поддерживает двунаправленные потоки в рамках одного соединения, что снижает накладные расходы и позволяет эффективнее использовать сетевые ресурсы.</p><p>Межъязыковое взаимодействие — ещё одно преимущество. У вас могут быть сервисы на Go, Python, Java и C++, которые легко общаются между собой благодаря сгенерированному коду из protobuf-файлов.</p><h2>Ограничения gRPC</h2><p>Браузерная поддержка требует дополнительных усилий. Нативные gRPC-клиенты в браузерах не работают, нужен прокси gRPC-Web. Это добавляет сложности в настройке.</p><p>Человекочитаемость сообщений оставляет желать лучшего. Бинарный формат protobuf неудобен для отладки без специальных инструментов. Разработчики часто используют JSON-эквиваленты для разработки, жертвуя производительностью.</p><p>gRPC требует кодогенерации. При каждом изменении API нужно обновлять protobuf-файлы и перегенерировать код для всех языков. Это добавляет лишний шаг в процесс разработки.</p><h2>tRPC: типобезопасность без схем и кодогенерации</h2><p>tRPC занимает противоположную нишу. Это технология для полного стека на TypeScript, где важны скорость разработки и типобезопасность.</p><p>Философия tRPC — минимализм. Не нужны схемы, кодогенерация, сложные настройки. Вы определяете процедуры (запросы и мутации) на TypeScript, а клиент автоматически получает информацию о типах.</p><p>tRPC использует обычный HTTP поверх HTTP/1.x, что делает его совместимым с любым браузером. Транспортный формат — JSON, который легко отлаживать с помощью стандартных инструментов разработчика.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-30/f029279a-d51f-4666-bb04-1f409c22b18f.jpg" alt="" /></figure><h2>Сильные стороны tRPC</h2><p>Скорость разработки — главный плюс tRPC. Изменения на сервере сразу отражаются в типах на клиенте. Не нужно ждать кодогенерации или вручную синхронизировать типы.</p><p>Идеальная интеграция с экосистемой TypeScript. Если ваш стек — Next.js, React, Prisma и TypeScript, то tRPC станет естественным выбором. Разработка напоминает работу с монолитом, но с распределённой архитектурой.</p><p>tRPC отлично работает в монорепозиториях. Один репозиторий содержит и клиент, и сервер, что упрощает синхронизацию версий и рефакторинг.</p><h2>Когда tRPC не подходит</h2><p>tRPC привязан к экосистеме TypeScript. Если у вас мультиязычная архитектура или вы планируете публичное API для клиентов на разных языках, tRPC — не лучший выбор.</p><p>Отсутствие схемы может быть ограничением. GraphQL-схема служит документацией и основой для инструментов вроде Apollo Studio. tRPC не предоставляет аналогичных возможностей для интроспекции API.</p><p>tRPC не решает проблему over-fetching на том же уровне, что GraphQL. Клиент не может точно указать, какие поля нужны в ответе — он получает всю структуру данных, определённую процедурой.</p><h2>Сравнительная таблица: gRPC vs GraphQL vs tRPC</h2><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-30/94988143-b27a-40e5-a33a-f84a3c5a8013.png" alt="" /></figure><h2>GraphQL рано списывать со счетов</h2><p>Несмотря на рост популярности gRPC и tRPC, GraphQL остаётся сильным игроком на рынке API. Технология развивается, появляются новые инструменты и практики:</p><ul><li><b>GraphiQL 2.0.</b> Не просто обновление, а полный редизайн официального инструмента для разработки запросов. Новая версия, разрабатываемая GraphQL Foundation, предлагает модульную архитектуру с поддержкой плагинов для расширения функциональности.</li><li><b>Apollo MCP Server.</b> Адаптация GraphQL к новейшим технологическим трендам, в частности — к интеграции с искусственным интеллектом. Apollo MCP Server позволяет подключать большие языковые модели (LLM) и AI-системы к вашим API через GraphQL, выступая для них стандартизированным и безопасным интерфейсом. Это решает такие проблемы AI, как необходимость детерминированного выполнения запросов и контроля политик доступа.</li><li><b>Автоматические постоянные запросы</b> (Automatic Persisted Queries, APQ). Клиент может отправлять на сервер не текст запроса, а его хэш. Сервер, заранее получивший полный запрос, выполняет его, найдя по хэшу. Это значительно сокращает объем передаваемых данных и ускоряет работу, особенно в мобильных сетях.</li></ul><p>GraphQL незаменим, когда у вас множество клиентов с разными требованиями к данным. Мобильное приложение, веб-интерфейс, партнерские интеграции — каждый может запросить именно те данные, которые нужны, без изменения серверной логики.</p><p>Эволюция GraphQL продолжается. Подходы вроде GraphQL Federation позволяют распределить схему между разными командами, что решает проблему монолитной схемы в больших организациях.</p><p>Инструменты вроде graphql-tada и Grats улучшают процесс разработки с GraphQL, приближая его к удобству tRPC. Они обеспечивают типобезопасность без потерь в гибкости.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-30/05238f17-ec27-4483-90d6-4340e984d173.png" alt="" /></figure><h2>Как выбрать: практические рекомендации</h2><p>Выбор технологии зависит от конкретного контекста. Не следуйте трендам вслепую — это приводит к архитектурным ошибкам. Вместо вопроса «Что сейчас модно?» спросите: «Какую проблему я решаю?».</p><p>Проанализируйте свой проект по нескольким ключевым параметрам. Ответы помогут принять взвешенное решение.</p><h2>Вопрос первый: какую проблему вы решаете?</h2><p>Разные технологии созданы для разных сценариев. Определите основную боль вашего проекта:</p><ul><li>Нужна высокая производительность для внутренней коммуникации микросервисов → gRPC. Бинарный протокол и HTTP/2 дают преимущество в скорости при частых вызовах между сервисами.</li><li>Хотите дать клиентам гибкость в запросах данных → GraphQL. Разные потребители API могут запрашивать только нужные поля без изменения серверной логики.</li><li>Разрабатываете full-stack приложение на TypeScript и хотите максимальной типобезопасности → tRPC. Единая типовая система от бэкенда до фронтенда ускоряет разработку и снижает количество ошибок.</li></ul><h2>Вопрос второй: какая у продукта архитектура?</h2><p>Технологический стек определяет доступные опции. Оцените текущую и планируемую инфраструктуру:</p><ul><li>Один язык программирования по всему стеку (TypeScript) → tRPC. Тесная интеграция с экосистемой TypeScript становится приоритетом.</li><li>Несколько языков (Go, Python, Java, etc.) → gRPC или GraphQL. gRPC обеспечивает эффективную коммуникацию между разнородными сервисами, а GraphQL подходит для публичного API.</li><li>Планируете масштабирование на разные платформы → GraphQL. Единая схема API работает с любым клиентом, независимо от языка или платформы.</li></ul><h2>Вопрос третий: кто потребители вашего API?</h2><p>Проанализируйте, кто будет использовать ваш API:</p><ul><li>Внутренние сервисы → gRPC. Высокая производительность и эффективность важнее человекочитаемости.</li><li>Внешние клиенты (мобильные приложения, партнеры) → GraphQL. Возможность точного запроса данных снижает нагрузку на сеть и упрощает интеграцию.</li><li>Собственный фронтенд на TypeScript → tRPC. Максимальная скорость разработки и типобезопасность окупают ограничения по браузерной поддержке.</li></ul><h2>Вопрос четвертый: каковы требования к инструментарию?</h2><p>Разработка не заканчивается на написании кода. Оцените важность сопутствующих инструментов:</p><ul><li>Важна интроспекция API и полноценная экосистема инструментов → GraphQL. Встроенная интроспекция и инструменты вроде Apollo Studio предоставляют мощные возможности для отладки и мониторинга.</li><li>Нужна максимальная производительность и минимальные накладные расходы → gRPC. Бинарный формат и HTTP/2 обеспечивают эффективную передачу данных.</li><li>Приоритет — скорость разработки и минимальная конфигурация → tRPC. Отсутствие схем и кодогенерации ускоряет итерации.</li></ul><h2>Дополнительные практические соображения</h2><p>Командная экспертиза играет важную роль. Любая новая технология требует времени на освоение. Оцените готовность команды изучать новые инструменты.</p><p>Операционные расходы — ещё один фактор. gRPC требует инфраструктуры для мониторинга бинарных протоколов. GraphQL нуждается в инструментах для анализа запросов и защиты от перегрузки.</p><p>Рассмотрите возможность гибридного подхода. Крупные проекты часто используют разные технологии для разных задач. Внутренняя коммуникация — gRPC, публичное API — GraphQL, админ-панель — tRPC.</p><p>Проведите пилотные испытания. Реальные нагрузки могут преподнести сюрпризы. Протестируйте выбранную технологию на критически важных сценариях перед полным внедрением.</p><h2>Почему гибридные подходы набирают популярность</h2><p>Современные приложения редко бывают простыми. Один продукт может включать мобильное приложение, веб-интерфейс, админ-панель и интеграции с партнерами. Каждый компонент имеет уникальные требования к API.</p><p>Монолитная архитектура API часто не справляется с разнородными нагрузками. Один протокол пытается угодить всем, но в итоге не идеален ни для кого. Гибридный подход признает это разнообразие и предлагает адресные решения.</p><p>Технологическая зрелость инструментов позволяет легко комбинировать разные подходы. Контейнеризация, сервисная сетка и API-гейтвеи упрощают интеграцию разнородных компонентов.</p><h2>Реальные сценарии комбинирования технологий</h2><p>Рассмотрим типичный пример e-commerce платформы. Система состоит из нескольких логических частей, каждая со своими требованиями.</p><p>Микросервисы инвентаризации и платежей общаются через gRPC. Здесь важна низкая задержка и эффективность сети. Бинарный протокол и HTTP/2 идеально подходят для частых внутренних вызовов.</p><p>Публичное API для мобильных приложений и партнеров использует GraphQL. Разные клиенты могут запрашивать только нужные данные без переразработки серверной логики. Это снижает нагрузку на сеть и упрощает поддержку API.</p><p>Админ-панель и внутренние инструменты построены на tRPC. Разработчики работают в единой TypeScript-экосистеме, что ускоряет итерации. Типобезопасность от backend до frontend снижает количество ошибок.</p><h2>Техническая реализация гибридной архитектуры</h2><p>Ключевой элемент гибридной системы — API-шлюз. Он маршрутизирует запросы к соответствующим бэкендам, преобразует форматы данных и обеспечивает единую точку входа.</p><p>Шлюз принимает HTTP-запросы и определяет, куда их направить. GraphQL-запросы идут к GraphQL-серверу, gRPC-вызовы — к микросервисам, а tRPC-запросы — к соответствующим процедурам.</p><p>Преобразование протоколов происходит прозрачно для клиента. Например, мобильное приложение отправляет GraphQL-запрос, который шлюз может преобразовать в gRPC-вызов к внутренним сервисам.</p><p>Сервисная сеть (service mesh) упрощает управление гибридной инфраструктурой. Она обеспечивает обнаружение сервисов, балансировку нагрузки и мониторинг независимо от используемых протоколов.</p><h2>Организационные аспекты смешанного подхода</h2><p>Гибридная архитектура влияет на структуру команд. Вместо единой бэкенд-команды появляются специализированные группы:</p><ul><li>Команда платформы отвечает за базовую инфраструктуру: API-шлюз, сервисную сеть, мониторинг. Они обеспечивают совместимость различных технологий и единые стандарты качества.</li><li>Команды продукта фокусируются на конкретных функциональных областях. Они выбирают оптимальные технологии для своих задач в рамках установленных стандартов.</li></ul><p>Такое разделение требует чётких интерфейсов между командами. Контракты API становятся критически важными — они определяют точки взаимодействия между различными частями системы.</p><h2>Проблемы и решения при внедрении</h2><p>Гибридный подход не лишён сложностей. Основная проблема — высокая операционная нагрузка. Каждая технология требует специфических знаний и инструментов мониторинга.</p><p>Единая система мониторинга обязательна. Нельзя иметь отдельные дашборды для gRPC, GraphQL и tRPC. Нужен агрегированный взгляд на всю систему, который показывает взаимосвязи между компонентами.</p><p>Стандартизация практик разработки становится критически важной. Разные команды должны следовать единым принципам документирования, версионирования и тестирования API.</p><p>Обучение разработчиков — еще один вызов. Программисты должны понимать несколько технологий, а не специализироваться на одной. Это требует инвестиций в обучение и обмен знаниями.</p><h2>Когда гибридный подход оправдан</h2><p>Переход к смешанной архитектуре требует дополнительных ресурсов. Он не всегда целесообразен для небольших проектов или стартапов на ранней стадии.</p><p>Проекты с явно выраженными разнородными требованиями к API получают максимальную выгоду. Если у вас есть и высоконагруженные внутренние сервисы, и публичное API с разнообразными клиентами — гибридный подход может быть оптимальным.</p><p>Системы, которые эволюционируют из монолита в микросервисы, часто естественным образом приходят к гибридной архитектуре. Постепенное внедрение новых технологий менее рискованно, чем полный рефакторинг.</p><p>Команды с сильной DevOps-культурой лучше справляются со сложностью гибридных систем. Автоматизация развёртывания, мониторинга и масштабирования снижает операционную нагрузку.</p><h2>Эволюция вместо революции</h2><p>Гибридный подход — не про выбор одной технологии, а про использование сильных сторон каждой. Это признание того, что современные системы слишком сложны для универсальных решений.</p><p><b>Начинайте с простого.</b> Если ваш проект небольшой, одной технологии API может быть достаточно. По мере роста вы сможете постепенно вводить дополнительные протоколы там, где они дают максимальный эффект.</p><p><b>Измеряйте результаты.</b> Внедрение новой технологии должно решать конкретные проблемы: снижать задержки, ускорять разработку или улучшать пользовательский опыт. Без измеримых целей гибридная архитектура превращается в ненужное усложнение.</p><p>Главное — сохранять архитектурную гибкость. Технологии продолжат меняться, и ваша система должна быть готова адаптироваться к новым вызовам.</p><h2>Итоги: не следуйте трендам, решайте задачи</h2><p>GraphQL не умер — он занял свою нишу в мире API. gRPC и tRPC не заменят его полностью, а дополнят экосистему, предлагая решения для конкретных сценариев.</p><p>Выбирайте технологию исходя из потребностей проекта, а не модных трендов. Иногда простое REST API может оказаться лучшим решением, если ваши требования минимальны.</p><p>Технологии продолжат развиваться. Важно сохранять архитектурную гибкость и не замыкаться на одном стеке. Умение выбрать правильный инструмент для задачи — навык, который останется актуальным независимо от появления новых технологий.</p><p>Главное — решать реальные проблемы, а не создавать себе новые в погоне за модными фреймворками.</p>]]></content:encoded>
    </item>
    <item>
      <title>Архитектура микросервисов: как избежать 7 типичных ошибок — разбор реальных кейсов</title>
      <link>https://tproger.ru/articles/arhitektura-mikroservisov--kak-izbezhat-7-tipichnyh-owibok---razbor-realnyh-kejsov</link>
      <comments>https://tproger.ru/articles/arhitektura-mikroservisov--kak-izbezhat-7-tipichnyh-owibok---razbor-realnyh-kejsov?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Денис Кудерин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/arhitektura-mikroservisov--kak-izbezhat-7-tipichnyh-owibok---razbor-realnyh-kejsov</guid>
      <description><![CDATA[<p>Разбираем реальные ошибки при переходе на микросервисную архитектуру. Узнайте, как избежать распределенного монолита, чрезмерного дробления сервисов и проблем с коммуникацией между ними. Практические решения и чек-лист для вашего проекта на основе опыта команд 2023-2025 годов.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/arhitektura-mikroservisov--kak-izbezhat-7-tipichnyh-owibok---razbor-realnyh-kejsov">Архитектура микросервисов: как избежать 7 типичных ошибок — разбор реальных кейсов</a>»</p>]]></description>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Архитектура ПО]]></category>
      <category><![CDATA[Ошибки в ПО]]></category>
      <category><![CDATA[Архитектура приложений]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 01 Oct 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Архитектура микросервисов — не панацея от всех бед. Она не гарантирует успеха, но точно показывает слабые места в процессах команды. Некоторые компании проходят этот путь с блестящим результатом. Другие оказываются в ситуации, которую эксперт Крис Ричардсон, автор книги «Microservice Patterns», метко <a href="https://microservices.io/post/architecture/2025/02/03/microservices-ate-my-application.html">называет</a> «микросервисы съели моё приложение» — когда технологию незаслуженно назначают причиной собственных провалов.</p><p>Правда в том, что микросервисы не собираются стаями, чтобы атаковать ни в чём не повинные проекты. Проблемы возникают из-за неверных архитектурных решений или когда вы игнорируете явные сигналы, что что-то пошло не так.</p><p>Разберём семь провальных сценариев, которые допускают команды при переходе на микросервисы. Вы узнаете, как избежать этих ловушек и построить систему, которая будет по-настоящему гибкой и масштабируемой.</p><h2>Зачем вообще нужны микросервисы</h2><p>Архитектура микросервисов — это не универсальное решение, а альтернативный подход к построению систем.</p><p>Микросервисы подходят не для всех проектов. Они оправданы, когда:</p><ul><li>система действительно большая и сложная;</li><li>разные компоненты требуют разного масштабирования;</li><li>команды могут работать независимо;</li><li>нужно использовать разные технологии для разных задач.</li></ul><p>Монолит часто лучше для:</p><ul><li>небольших проектов с четкими границами;</li><li>команд до 10 человек;</li><li>ситуаций, когда важна простота развертывания;</li><li>проектов с неясными требованиями.</li></ul><p>Представьте монолит как специализированный магазин. Все товары в одном помещении. Покупатель быстро находит нужное. Владелец легко управляет ассортиментом.</p><p>Микросервисы работают иначе. Это сеть специализированных магазинов, расположенных в одном торговом центре. Хлебный магазин, мясная лавка, овощной павильон. Каждый работает независимо. Если в хлебном магазине ремонт, мясная лавка продолжает работать.</p><p>Конкретные преимущества микросервисов:</p><ul><li>Независимое развертывание. Можно обновлять один сервис без остановки всей системы.</li><li>Масштабируемость. Сервисы с высокой нагрузкой масштабируются отдельно от остальных.</li><li>Технологическая гибкость. Разные сервисы можно писать на разных языках и технологиях.</li><li>Устойчивость к ошибкам. Если один сервис упадёт, это не приведёт к коллапсу всей системы.</li></ul><p>Но эти преимущества работают только при правильной реализации. На практике слишком часто команды создают систему, где сервисы так тесно связаны, что преимущества независимости теряются. Возникает ситуация, когда каждый сервис по отдельности прост, но вместе они создают сложную для управления конструкцию. Проблема в одном сервисе при такой реализации отражается на всех остальных. Внесение изменений требует согласования с несколькими командами. Нет ни гибкости микросервисов, ни предсказуемости монолита. Вместо этого получается наихудший из вариантов.</p><p>Далее мы рассмотрим наиболее типичные антипаттерны, которые встречаются в практике разработки. Стоит изучить эти ошибки, чтобы не допускать их в своих проектах.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-30/cbd1b012-d704-4131-b3b5-ab4bf833766e.jpg" alt="" /></figure><h2>Ошибка 1: Распределенный монолит</h2><p>Команды хотят получить преимущества микросервисов, но не могут отказаться от мышления в стиле монолита.</p><p><b>В чем проблема:</b> Вместо независимых сервисов получается система, где все компоненты жёстко связаны. Это и есть распределённый монолит.</p><p><b>Реальный кейс:</b> Консультант IBM Холли Каммингс <a href="https://www.infoq.com/articles/microservices-seven-fail/">описывает</a> проект, где команда жаловалась: «каждый раз, когда мы меняем один микросервис, ломается другой». Сервисы были распределены по разным репозиториям, но использовали идентичные копии сложной объектной модели. Изменение одного поля требовало синхронного обновления всех сервисов. Команда потеряла преимущества монолита — компилятор больше не проверял типы, — но не получила преимуществ микросервисов — независимости развёртывания.</p><p>Как избежать:</p><ul><li>Проектируйте сервисы вокруг бизнес-доменов, а не технических слоев. Интерфейсы сервисов должны быть узкими и специфичными. Например, сервис заказов сам управляет своими данными, логикой и API для операций с заказами.</li><li>Откажитесь от общих библиотек с моделью данных. Каждый сервис должен владеть своими данными и иметь свою модель.</li><li>Используйте подход, когда клиенты сервиса задают ожидания от его API. Для этого подходят инструменты вроде Pact. Такой метод проверяет совместимость сервисов без громоздких интеграционных тестов.</li></ul><p>Распределённый монолит — это худший из возможных сценариев. Вы получаете сложность распределённых систем без преимуществ модульности.</p><h2>Ошибка 2: Чрезмерное дробление сервисов (декомпозиция)</h2><p>Стремление сделать сервисы как можно меньше приводит к противоположному эффекту. Система дробится на сотню мелких компонентов, которыми невозможно управлять.</p><p><b>В чем проблема:</b> Каждый микросервис — это отдельное приложение со своей базой данных, зависимостями и пайплайном развёртывания. Чрезмерное дробление увеличивает сложность управления, мониторинга и эксплуатации. Растут сетевые издержки — латентность становится узким местом, работа системы замедляется.</p><p><b>Реальный кейс: </b>Компания Gilt <a href="https://theburningmonk.com/2015/05/craftconf15-takeaways-from-scaling-micro-services-at-gilt/">перешла</a> на микросервисы в 2015 году и столкнулась с проблемой излишнего дробления. Изначально они создали более 450 микросервисов для платформы электронной коммерции. Многие сервисы были настолько малы, что выполняли лишь одну простую функцию. Это привело к экспоненциальному росту операционных расходов. Команда тратила больше времени на координацию взаимодействия между сервисами и устранение сетевых сбоев, чем на разработку новой функциональности. В итоге они провели рефакторинг, объединив сервисы с высокой связностью, что значительно упростило систему и ускорило разработку .</p><p>Как найти баланс:</p><ul><li>Объединяйте функциональности с высокой связностью. Если два компонента постоянно общаются, возможно, они должны быть одним сервисом.</li><li>Ориентируйтесь на функциональную связность. Сервис должен иметь чёткую зону ответственности в бизнес-логике.</li><li>Оценивайте операционные расходы, прежде чем создавать новый сервис. Спросите себя: готовы ли мы поддерживать ещё одну базу данных, ещё один конвейер развёртывания?</li></ul><p>Сервис должен быть достаточно автономным, чтобы его могла поддерживать одна команда. Ему необходимо решать конкретную бизнес-задачу. Если сервис слишком мал, он не принесет реальной пользы, но потребует полноценных затрат на поддержку. Золотая середина — когда команда полностью владеет одним или несколькими логически связанными сервисами и может развивать их без постоянной координации с другими.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-30/4b2ae5b4-4b86-4306-b1e1-08344636e3dc.jpg" alt="" /></figure><h2>Ошибка 3: «Болтливые» микросервисы</h2><p>Микросервисы много общаются друг с другом. Мелкозернистые API вынуждают делать десятки вызовов для одной операции. Это создаёт каскады зависимостей, где сбой одного сервиса вызывает цепную реакцию.</p><p><b>В чем проблема:</b> При такой структуре возникает следующий сценарий провала:</p><ul><li>Частые взаимодействия — сервисы обмениваются множеством мелких запросов, генерируя насыщенный сетевой трафик.</li><li>Каскад вызовов — один пользовательский запрос запускает длинную цепочку обращений к разным сервисам.</li><li>Мелкозернистые API — для выполнения одной бизнес-транзакции требуется множество вызовов.</li></ul><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-30/fe3bcc40-a9b3-43ba-8c5a-21baea22b4c7.png" alt="" /></figure><p><b>Реальный кейс:</b> Команда Amazon Prime Video <a href="https://amplication.com/blog/amazon-ditches-microservices-for-monolith-decoding-prime-videos-architectural-shift">столкнулась</a> с проблемой производительности своей системы мониторинга видео. Изначально они построили архитектуру на основе микросервисов, где каждый этап обработки видео (метаданные, детекция дефектов, анализ качества) был отдельным сервисом.</p><p>Система состояла из множества «болтливых» сервисов, которые постоянно обменивались сообщениями через AWS Step Functions. Это привело к резкому росту затрат и проблемам с производительностью из-за постоянной сериализации/десериализации данных между сервисами. В итоге команда консолидировала несколько сервисов в единый монолит, что снизило затраты на 90% и улучшило производительность .</p><p>Решение:</p><ul><li>Используйте асинхронную коммуникацию через очереди событий.</li><li>Проектируйте крупнозернистые API, которые охватывают полный бизнес-контекст за один вызов.</li><li>Внедряйте архитектурные паттерны типа API Gateway для агрегации данных и Backend For Frontend для оптимизации под конкретные клиенты.</li></ul><p>Сервисы должны обмениваться данными минимально необходимое количество раз. Каждый лишний вызов между сервисами увеличивает задержки и создаёт новые точки отказа. Вместо потока мелких запросов проектируйте взаимодействие вокруг завершённых операций. Один запрос должен передавать все данные, необходимые для выполнения следующего шага бизнес-процесса.</p><h2>Ошибка 4: Игнорирование сквозной функциональности</h2><p>Команды часто откладывают на потом реализацию системных компонентов: логирование, аутентификацию, кеширование, мониторинг, поэтому разработка быстро останавливается.</p><p><b>В чем проблема:</b> Разработка бизнес-сервисов начинается до подготовки общесистемных компонентов. В результате каждый сервис изобретает собственные способы логирования и аутентификации. Приходится переделывать готовый код, чтобы добавить единый стандарт.</p><p><b>Реальный кейс:</b> Команда, создающая микросервисы на Go, <a href="https://habr.com/ru/articles/459130/">разработала</a> единый подход к обработке ошибок и логированию. Они используют структурированное логирование с обязательным контекстом — идентификаторами пользователей, транзакциями, следами запросов. При необходимости специалисты сразу находят корневые причины проблем, не переключаясь между десятками лог-файлов.</p><p>Правильный подход:</p><ul><li>Сначала создайте базовые сервисы для логирования, кеширования, управления пользователями и мониторинга.</li><li>Разработайте стандарты и библиотеки для их использования. Командам не придётся дублировать функциональность.</li><li>Внедрите централизованное логирование с самого начала. Без него невозможно отлаживать распределённую систему.</li></ul><h3>Наблюдаемость как основа стабильности</h3><p>Современные микросервисные системы требуют полноценной наблюдаемости (observability). Это не просто мониторинг, а понимание, что именно происходит внутри системы, без дополнительных вопросов к разработчикам.</p><p>Три столпа наблюдаемости:</p><ol><li>Логи — записи о конкретных событиях с временными метками и контекстом.</li><li>Метрики — числовые показатели, отслеживаемые во времени (загрузка CPU, latency, error rate).</li><li>Трассировка — отслеживание пути запроса через распределённую систему.</li></ol><h2>Ошибка 5: Нечеткие границы сервисов</h2><p>Сервисы без чётких границ начинают обрастать несвязанной функциональностью. Order Service вдруг получает отчётность, а Payment Service — нотификации. На выходе — монстр с размытой ответственностью.</p><p><b>В чем проблема:</b> Нарушается принцип единой ответственности. Сервисы становятся большими и сложными. Их трудно тестировать и поддерживать. Код дублируется — разные команды реализуют одинаковую функциональность в разных сервисах.</p><p><b>Реальный кейс: </b>Компания Kong (тогда еще Mashape) <a href="https://buttercms.com/books/microservices-for-startups/breaking-up-a-monolith/">начала</a> декомпозицию монолита в 2013 году. Монолитное приложение, написанное на Java, объединяло функциональность маркетплейса API, включая биллинг, аналитику и управление каталогом. В процессе декомпозиции команда столкнулась с трудностями, которые позже были признаны классическими ошибками.</p><p>Первоначально четкие границы между компонентами со временем размылись, что привело к серьезным проблемам:</p><ul><li>Сложность развертывания. Любое небольшое изменение требовало полного переразвертывания всей системы.</li><li>Размытие границ. Компоненты маркетплейса стали переплетаться, границы ответственности стерлись.</li><li>Технический долг. Система становилась все сложнее для поддержки и развития.</li></ul><p>Попытка исправить ситуацию переходом на микросервисы изначально ухудшила положение. Команда, разделенная на две части (одна поддерживала монолит, другая разрабатывала новую архитектуру), столкнулась с трудностями координации. В итоге процесс разработки замедлился, а не ускорился.</p><p>Как избежать:</p><ul><li>Используйте Domain-Driven Design (DDD). Определяйте Bounded Context — чёткие границы бизнес-доменов.</li><li>Перед созданием сервиса документально зафиксируйте его зону ответственности. Что он делает? Какими данными владеет?</li><li>Сопротивляйтесь искушению добавить «ещё одну маленькую функцию» в существующий сервис. Часто лучше создать новый, но для начала нужно разобраться с конкретной задачей продукта.</li></ul><h3>Антипаттерн Entity Service</h3><p>Частный случай размытых границ — создание сервисов по принципу «одна сущность — один сервис». Это кажется логичным: сервис пользователей, сервис заказов, сервис товаров. Но на практике такой подход создаёт ещё больше проблем. Entity Service (сервис одной сущности) часто превращается в обычный CRUD-интерфейс к базе данных. Вся бизнес-логика перемещается в вызывающие сервисы, которые вынуждены делать десятки вызовов для выполнения одной операции.</p><p><b>Альтернатива:</b> Создавайте сервисы вокруг бизнес-операций, а не данных. Вместо общего «сервиса пользователей», который отвечает за всё подряд, выделите отдельные сервисы с конкретными зонами ответственности:</p><ul><li>сервис регистрации — создает новые учетные записи;</li><li>сервис аутентификации — проверяет логины и пароли;</li><li>сервис управления профилем — обновляет личные данные.</li></ul><p>Каждый такой сервис содержит и данные, и логику своей операции. Названия сразу показывают, что сервис делает. Такой подход помогает избежать «божественных» сервисов, которые знают слишком много.</p><h2>Ошибка 6: Смешивание баз данных</h2><p>Общая база данных для нескольких микросервисов — это красный флаг. Сервисы теряют независимость. Изменение схемы данных одним сервисом ломает остальные.</p><p><b>В чем проблема:</b> Единая база данных создает скрытую связность между сервисами. Невозможно выбрать оптимальную СУБД для конкретного сервиса — все используют одно решение. Затрудняется горизонтальное масштабирование.</p><p><b>Реальный кейс:</b> Крис Ричардсон <a href="https://microservices.io/patterns/data/shared-database.html">описывает</a> классическую проблему, возникающую при использовании общей базы данных. В этом сценарии сервисы OrderService и CustomerService напрямую обращаются к таблицам друг друга в единой базе данных.</p><p>Это создает тесную связность на уровне разработки и времени выполнения:</p><ul><li>Зависимость разработки. Разработчик, вносящий изменения в OrderService, должен согласовывать изменение схемы таблиц с командой, отвечающей за CustomerService, что значительно замедляет работу.</li><li>Блокировки времени выполнения: Длительная транзакция в CustomerService, которая удерживает блокировку на таблице ORDERS, может полностью заблокировать работу OrderService.</li></ul><p>Такой подход лишает микросервисы их ключевых преимуществ — независимости развертывания и масштабирования.</p><p>Правила работы с данными:</p><ul><li>У каждого сервиса должна быть собственная база данных. Сервис владеет своими данными — другие сервисы получают доступ только через его API.</li><li>Используйте шаблон Saga для управления распределёнными транзакциями вместо двухфазного коммита.</li><li>Реализуйте CQRS (Command Query Responsibility Segregation) для отделения операций записи от операций чтения, когда это необходимо.</li></ul><p>Общая база данных создаёт жесткую зависимость между сервисами. Изменение схемы данных в одном месте может сломать функциональность в другом. Команды теряют возможность независимо развивать свои сервисы — любая правка требует согласования со всеми участниками.</p><p>Такая архитектура лишает микросервисы их главного преимущества — автономности, и напоминает жизнь в студенческом общежитии. Вместо независимых компонентов получается система, где всё связано невидимыми нитями зависимостей.</p><h2>Ошибка 7: Неготовность организации</h2><p><b>В чем проблема: </b>Микросервисы требуют изменений в структуре команды и процессах. Если продолжать работать как с монолитом, ничего не получится.</p><p><b>Реальный кейс:</b> в одной из <a href="https://medium.com/@b.stoilov/a-short-horror-story-about-migrating-from-monolith-to-microservices-28d35801b188">компаний</a> команда разрабатывала микросервис, но была вынуждена тесно интегрировать его с унаследованным монолитом. Они зависели от его цикла выпуска, что свело на нет все преимущества независимой разработки. Проект в итоге закрыли.</p><p>Какие организационные изменения помогут:</p><ul><li>Перейдите к командам по сервисам — небольшим автономным группам, которые полностью владеют своими сервисами (You Build It, You Run It).</li><li>Внедрите культуру DevOps — автоматизацию сборки, тестирования и развёртывания для каждого сервиса.</li><li>Наладьте независимые циклы выпуска. Возможность развёртывать сервисы без координации с другими командами — ключевое преимущество микросервисов.</li></ul><p>Успешный переход на микросервисы требует изменения мышления всей команды. Разработчики должны стать ответственными за свои сервисы на протяжении всего жизненного цикла — от проектирования до эксплуатации в продакшене.</p><p>Что меняется:</p><ul><li>Ответственность. Разработчики отвечают не только за написание кода, но и за работоспособность сервиса в продакшн.</li><li>Коммуникация. Команды должны чётко определять контракты между сервисами и соблюдать их.</li><li>Экспертиза. Появляется потребность в специалистах по DevOps, наблюдаемости, распределенным системам.</li></ul><p>Микросервисы — это не про технологии, а про архитектуру и организацию работы. Без правильной культуры даже самая совершенная техническая реализация обречена на провал.</p><h2>Чек-лист для вашего перехода</h2><p>Прежде чем переходить на микросервисы, проверьте себя по этому списку:</p><ul><li>вы определили бизнес-проблему, которую будете решать микросервисами (а не просто хотим «быть как Netflix»);</li><li>спроектировали границы сервисов на основе бизнес-доменов — DDD, Bounded Context;</li><li>у каждого сервиса будет собственное хранилище данных;</li><li>предусмотрели кросс-каттинговые сервисы — логирование, аутентификацию, мониторинг;</li><li>готовы к организационным изменениям — автономные команды, DevOps;</li><li>выбрали правильный уровень детализации сервисов (не слишком мелкий);</li><li>продумали межсервисную коммуникацию — асинхронную, через события.</li></ul><p>Netflix, Amazon и Uber прошли этот путь. Они не избежали ошибок, но выстроили процессы для развития сложных систем. Микросервисы — это эволюция архитектуры и команды. Начинайте с малого, не бойтесь менять решения. Главный критерий успеха — скорость доставки ценности пользователям без поломок продакшена. Если этот показатель растет — вы на правильном пути.</p>]]></content:encoded>
    </item>
    <item>
      <title>WebAssembly выходит за пределы браузера: серверные и embedded-применения</title>
      <link>https://tproger.ru/articles/webassembly-vyhodit-za-predely-brauzera--servernye-i-embedded-primeneniya-257873</link>
      <comments>https://tproger.ru/articles/webassembly-vyhodit-za-predely-brauzera--servernye-i-embedded-primeneniya-257873?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Денис Кудерин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/webassembly-vyhodit-za-predely-brauzera--servernye-i-embedded-primeneniya-257873</guid>
      <description><![CDATA[<p>Как WebAssembly используют в серверных и embedded-системах. Преимущества WASM: безопасность, переносимость и эффективность. Примеры внедрения от Fastly и других компаний. Перспективы технологии в 2025 году.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/webassembly-vyhodit-za-predely-brauzera--servernye-i-embedded-primeneniya-257873">WebAssembly выходит за пределы браузера: серверные и embedded-применения</a>»</p>]]></description>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Компиляторы]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Отладка]]></category>
      <category><![CDATA[Браузеры]]></category>
      <category><![CDATA[WebAssembly]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 17 Sep 2025 12:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>WebAssembly (WASM) — язык программирования низкого уровня для стековой виртуальной машины. Когда он только появился, его воспринимали  исключительно как технологию для ускорения веб-приложений. Сегодня WASM стремительно выходит за границы браузера, открывая новые возможности для серверных и встраиваемых систем. Кардинально меняется сам подход к созданию кроссплатформенных приложений.</p><h2>WebAssembly в браузере: как всё начиналось</h2><p>Прежде чем говорить о настоящем и будущем WebAssembly, вспомним, с чего он начинался. Технология создавалась исключительно для работы в браузере. WebAssembly использовался (и используется сейчас): для оптимизации производительности, миграции legacy-нативных приложений, запуска кода на языках, отличных от JavaScript.</p><p>Ярче всего успех этого подхода демонстрирует Figma — популярный редактор для дизайнеров интерфейсов. Для многих стало неожиданностью, что редактор Figma, будучи веб-приложением, написан на C++.</p><p><b>Александр Коротаев</b>, фронтенд-разработчик, автор ТГ канала «Трудно быть Коротаевым»:</p><blockquote>На заре появления WASM многие ошибочно считали его то ли машиной для ускорения JS, то ли нативным модулем, который имеет доступ к операционной системе. Буквально чудо-коробочка, в которую можно поместить весь код, и он станет быстрее в три раза. Но в реальности технология столь ограничена в применении, что она до сих пор остается нишевой, хотя и очень перспективной.</blockquote><p>До WebAssembly разработчики Figma использовали технологию asm.js — предшественника WASM. Специальный компилятор преобразовывал (транспилировал) код C++ в высокооптимизированный JavaScript, который браузерные движки могли выполнять с близкой к нативной производительностью. У этого подхода были недостатки: большой размер получаемого кода и затраты на его парсинг и компиляцию в браузере.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-12/ca50f24f-8007-4880-b346-6b7e63692456.png" alt="" /></figure><p>Переход на WebAssembly стал переломным моментом. Поскольку WASM — это бинарный машинно-ориентированный формат, он гораздо компактнее и требует меньше ресурсов для обработки браузером. В результате миграции с asm.js на WebAssembly, Figma получила трёхкратный прирост производительности.</p><p>Этот кейс наглядно показал, что WebAssembly — это не просто ещё одна веб-технология, а настоящий прорыв, который стирает границы между нативными и веб-приложениями. Успех Figma и подобных проектов заложил фундамент для следующего логического шага: если WebAssembly так эффективен в браузере, почему бы не запускать его где угодно?</p><h2>Почему WebAssembly выходит за пределы браузера</h2><p>WebAssembly изначально создавался как безопасная, эффективная и портируемая платформа для компиляции высокоуровневых языков. Ключевые преимущества этого инструмента — изоляция выполняемого кода, платформонезависимость и высокая производительность — оказались востребованы не только в вебе.</p><p>Серверные и встроенные системы долгое время страдали от проблем совместимости, безопасности и сложности распространения кода. Традиционные подходы к изоляции (например, контейнеризация) требуют значительных ресурсов и не всегда дают достаточный уровень безопасности. WebAssembly предлагает альтернативу: песочницу с минимальными накладными расходами и встроенными механизмами безопасности.</p><p>Главным катализатором этого процесса стал стандарт WASI (WebAssembly System Interface), разработанный при участии Mozilla, Fastly и других компаний. WASI предоставляет стандартизированный интерфейс, где WebAssembly-модули взаимодействуют с операционной системой и решают проблему переносимости между различными платформами.</p><p><b>Александр Коротаев</b>, фронтенд-разработчик, автор ТГ канала «Трудно быть Коротаевым»:</p><blockquote>Открытая «кроссплатформенная» обертка WASI — это довольно большой прорыв в разработке, так как в текущем состоянии все современные продукты, выпускающиеся для разных ОС с одной кодовой базой, имеют большие, подчас legacy модули совместимости, или же запускаются внутри особых песочниц, сильно увеличивающих размер бандла. Например, браузерный движок Electron или React Native.</blockquote><h2>Как WebAssembly работает вне браузера</h2><p>Вне браузера WebAssembly исполняется в специальных средах выполнения (runtimes), которые взаимодействуют с операционной системой через WASI. Известные примеры — <a href="https://wasmtime.dev/">Wasmtime</a> от Mozilla, <a href="https://github.com/bytecodealliance/lucet">Lucet</a> от Fastly и <a href="https://wasmer.io/">Wasmer</a>.</p><p>Эти среды выполняют роль «концептуальной операционной системы», предоставляют модулям WebAssembly стандартизированный доступ к системным ресурсам: файлам, сети, случайным числам и другим функциям.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-12/029b3ae4-a5db-416b-817f-b296969a3226.png" alt="" /></figure><p>WebAssembly принципиально отличается от традиционных подходов тем, что изолируется на уровне инструкций, а не процессов. Каждый модуль выполняется в собственной песочнице с чётко определенными границами доступа к ресурсам. Это значительно снижает риск компрометации системы даже в случае уязвимостей в самом коде.</p><h2>Безопасность как фундаментальное преимущество</h2><p>Безопасность WebAssembly основана на нескольких уровнях защиты. Модули выполняются в изолированной среде, отделённой от хост-системы с помощью техник изоляции отказов. Это означает, что приложения выполняются независимо и не могут покинуть песочницу без явного разрешения через API.</p><p>Система контролирует выполнение кода с помощью статической проверки типов — все функции нужно явно объявлять перед использованием. Даже косвенные вызовы проверяются на соответствие сигнатурам прямо во время работы программы. Такой подход блокирует распространённые атаки — переполнение буфера и внедрение вредоносного кода.</p><p>Память в WebAssembly изолирована — напрямую с ней работать нельзя. Когда система обращается к памяти, она проверяет границы доступа, а локальные переменные хранятся в защищённом стеке вызовов.</p><p>Важность такого подхода к безопасности сложно переоценить в свете общих трендов защиты данных. К 2025 году безопасность и конфиденциальность стали ключевыми приоритетами для индустрии. Это особенно актуально на фоне растущих рисков при работе с большими языковыми моделями (LLM), которые могут невольно запоминать и воспроизводить конфиденциальные данные из тренировочных наборов.</p><p>Если запускать изолированные модули WebAssembly на своей инфраструктуре вместо публичного облака, можно безопасно обрабатывать чувствительные данные без риска утечки.</p><p><b>Александр Коротаев</b>, Фронтенд-разработчик, автор ТГ канала «Трудно быть Коротаевым»:</p><blockquote>Здесь явно подчеркивается безопасность платформы из коробки, но не стоит забывать, что на разработчике все еще лежит ответственность за безопасность данных и пользователей. Режим «разрешить все» — стандарт для любого MVP, и без аудита перед релизом тут все еще не обойтись. Платформа лишь гарантирует, что память процесса будет защищена от несанкционированного доступа, что уже давно делается во всех популярных операционных системах. Чтобы выйти за пределы стека или прочитать чужую память, надо использовать очень старые компиляторы или сильно низкоуровневые средства разработки.</blockquote><h2>Серверные применения WebAssembly</h2><p>Серверный ландшафт традиционно строился на монолитных приложениях и виртуальных машинах, но сегодня индустрия движется к более легковесным и изолированным компонентам. WebAssembly предлагает компромисс между производительностью нативного кода и безопасностью интерпретируемых сред. Эта технология особенно востребована в сценариях, где критически важны быстрое масштабирование и минимальное время запуска.</p><h2>Микросервисы и бессерверные архитектуры</h2><p>WebAssembly идеально подходит для микросервисных архитектур благодаря легковесности и быстрому запуску. В отличие от традиционных контейнеров, WASM-модули не требуют отдельной ОС и запускаются за миллисекунды.</p><p>Кейс: компания Fastly использует WebAssembly для исполнения пользовательского кода на серверах. Их технический директор Тайлер МакМаллен <a href="https://habr.com/ru/articles/446764/">отмечает</a>: «Мы рассматриваем WebAssembly как платформу для быстрого и безопасного кода в облаке на границе сети».</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-12/45f4a6a2-5b2f-440c-a634-a3b4a3f4accf.jpg" alt="" /></figure><h2>Безопасные расширения приложений</h2><p>Многие приложения позволяют пользователям запускать собственный код через плагины и расширения. Но это создаёт риски для безопасности. В WebAssembly пользовательский код выполняется с минимальными рисками.</p><p>Веб-сервер Angie <a href="https://angie.software/news/articles/wasm/">использует</a> WASM для безопасности пользовательских модулей. Это решает проблему совместимости, характерную для традиционных модулей, написанных на C.</p><p>Экономическая эффективность таких вариантов становится решающим фактором. По <a href="https://explodingtopics.com/blog/list-of-llms">данным на 2025 год</a>, глобальный рынок больших языковых моделей (LLM), чьи backend-системы часто используют микросервисные архитектуры, демонстрирует колоссальный рост. Прогнозируется, что к 2033 году он достигнет $140,8 млрд.</p><p>Для таких масштабов нужны технологии с качествами, которые как раз предоставляет WebAssembly: безопасность, переносимость и эффективное использование ресурсов. Почти все компании из списка Fortune 500 уже <a href="https://cybernews.com/security/ai-adoption-outpace-security-at-fortune500-firms/">используют</a> генеративный ИИ в своих бизнес-процессах, и для многих из них WebAssembly — ключевой инструмент для развёртывания и масштабирования этих рабочих нагрузок.</p><p><b>Александр Коротаев</b>, Фронтенд-разработчик, автор ТГ канала «Трудно быть Коротаевым»:</p><blockquote>Здесь все закономерно: бизнес всегда выбирал решения, где можно было написать код один раз и поставить его сразу на несколько платформ. Даже если сами решения  сырые и небезопасные, дешевле было увеличить поддержку пользователей и настроить аудит безопасности, чем реализовать фичу для каждой платформы отдельно. Так на рынок вышли Python, Node.js, React Native, стремительно обгоняя конкурентов за счет скорости разработки.</blockquote><p><br /></p><h2>WebAssembly в embedded-системах</h2><p>WebAssembly успешно работает на серверах, но главные изменения происходят во встроенных системах. В IoT всегда была проблема совместимости: разные процессоры, операционные системы и периферийные устройства.</p><p>Технология предлагает принципиально новый подход — единую бинарную форму, способную работать на любом микроконтроллере с минимальными адаптациями. Теперь разработчики могут не привязываться к конкретным платформам и сосредоточиться на бизнес-логике приложения.</p><h2>Удаленные интерфейсы и централизованный мониторинг</h2><p>Производители встраиваемых систем всё чаще нуждаются в удаленных интерфейсах и централизованном мониторинге. WebAssembly позволяет повторно использовать код, написанный для embedded-устройств, в веб-интерфейсах для удалённого управления.</p><p>Согласно <a href="https://www.qt.io/blog/does-webassembly-matter-for-embedded-systems-makers">исследованию</a> Qt Company, более 77% респондентов из промышленной автоматизации считают удалённое управление и централизованный мониторинг критически важными в ближайшие десять лет. WebAssembly предоставляет экономичный способ реализации таких решений.</p><p><b>Александр Коротаев</b>, Фронтенд-разработчик, автор ТГ канала «Трудно быть Коротаевым»:</p><blockquote>А это, пожалуй, самая продающая фича: обычно у компаний, которые выходят на рынок со своими железками, базами данных и прочими продуктами, все продажи буквально построены на том, что программисты у клиента знают, как это быстро встроить. Так, бизнес готов платить деньги. Обычно у них есть проблемы с API для разных языков программирования, ОС и девайсов: либо хорошо все в JS, а в мобилках не заводится, либо наоборот. А то и вообще: стоит забросить поддержку платформы хоть на полгода, сразу всёперестает работать. Потому поставлять модуль для WASI должно быть дёшево, при этом  потенциально можно закрыть даже платформы будущего. Это инновация сродни изобретению стандарта USB.</blockquote><p><br /></p><h2>Прототипирование и сотрудничество</h2><p>WebAssembly упрощает процесс прототипирования и обратной связи для embedded-устройств. Разработчики могут скомпилировать приложение, разместить его на веб-сервере и предоставить доступ всем заинтересованным сторонам. При этом не нужно распространять устройства или проходить сложные процессы публикации.</p><p>Компания Qt использует этот подход в Qt Design Viewer, позволяя разработчикам делиться интерактивными дизайнами, созданными в Qt Design Studio, с коллегами по всему миру.</p><h2>Примеры внедрения: история ByteFog</h2><p>Компания Inetra из Новосибирска <a href="https://habr.com/ru/companies/jugru/articles/441140/">разработала</a> технологию peer-to-peer для доставки видео ByteFog. Система работает на множестве платформ: Windows, Linux, Android, iOS, Web и Tizen.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-12/2ec3300a-dcc3-41aa-acf5-7e51b78f9131.webp" alt="" /></figure><p>Изначально веб-версия использовала Netscape Plugin API, но когда основные браузеры прекратили поддержку этой технологии в 2015 году, компания осталась без веб-версии на два года. Поэтому в 2017 году они обратились к WebAssembly.</p><p>Используя компилятор Emscripten, разработчики перенесли существующее C++-приложение в браузер. Главной сложностью было разграничить транспортный слой и бизнес-логику через интерфейсы. Основной канал доставки видео заменили на AJAX, а P2P-слой — на WebRTC.</p><p>Результат компиляции — двоичный.wasm-файл и «клеевой код» на JavaScript, взаимодействующий с браузерными API. Это позволило запускать сложную P2P-систему Peers.TV напрямую в браузере без плагинов.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-12/6f383fd2-9857-497f-848a-d296791fb36e.png" alt="" /></figure><h2>Fastly Terrarium: экспериментальная платформа для WebAssembly-приложений</h2><p>В 2021 году инженеры Fastly <a href="https://www.fastly.com/blog/terrarium-reframes-compiler-sandbox-relationship">выпустили</a> Terrarium — экспериментальную платформу для запуска WebAssembly-модулей на периферийных устройствах (edge devices), над которой работали несколько лет. Сейчас проект всё ещё в демо-версии.</p><p>Terrarium  показывает, как можно запускать пользовательский код в изолированных средах с минимальной задержкой. Платформа использует рантайм Lucet, разработанный инженерами Fastly, и поддерживает компиляцию из Rust, C++ и AssemblyScript.</p><p>Ключевая особенность подхода — стандарт WASI для системных вызовов, что помогаетпереносить модули между разными средами. Это особенно важно для edge-вычислений, где код должен работать на разнородном оборудовании.</p><p>По данным тестирования, время запуска модулей составляет около 50 микросекунд, а потребление памяти измеряется килобайтами на инстанс. Такие показатели достигаются за счёт изоляции на уровне инструкций, а не процессов.</p><p>Хотя Terrarium не стал коммерческим продуктом, его наработки повлияли на другие решения Fastly. Компания <a href="https://www.fastly.com/blog/how-fastly-and-developer-community-invest-in-webassembly-ecosystem">развивает</a> направление WebAssembly-вычислений далее — экосистема постоянно обновляется.</p><h2>Технические вызовы и ограничения</h2><p>Несмотря на впечатляющие возможности WebAssembly за пределами браузера, технология сталкивается с объективными сложностями в реальных проектах. Разработчикам приходится решать две задачи одновременно: изолировать код для безопасности и при этом давать доступ к системе. Важно также сохранить кроссплатформенность, но не терять в производительности на конкретных устройствах.</p><p>Эти компромиссы особенно заметны в embedded-среде, где каждое решение напрямую влияет на энергопотребление, стоимость и надежность системы.</p><p><b>Александр Коротаев</b>, Фронтенд-разработчик, автор ТГ канала «Трудно быть Коротаевым»:</p><blockquote>А здесь кроется главное: почему такое решение не было написано ранее? Дело в том, что оно явно затратное по ресурсам, если сравнивать ту же логику, написанную на низком уровне. Сейчас любые устройства стали мощнее, чем ранее, и теперь разница уже не так заметна. Поэтому WASI может широко распространяться, без типичных минусов высокоуровневых абстракций: потребления памяти и энергии сильно выше чем у конкурентов.</blockquote><p><br /></p><h2>Доступ к аппаратным ресурсам</h2><p>WebAssembly ограничивает прямой доступ к аппаратуре во встроенных системах — это плата за безопасность. Это усложняет работу embedded-разработчикам.</p><p>Сообщество WebAssembly уже решает проблемы. Стандарт WASI продолжает развиваться, и в будущем появятся более гибкие способы работы с оборудованием.</p><h2>Размер файлов и производительность</h2><p>WebAssembly-модули могут иметь значительный размер, особенно при включении стандартных библиотек. В случае ByteFog размер бандла достигал 100 МБ, что создавало проблемы для инструментов сборки и загрузки в браузере.</p><p>Чтобы уменьшить размер, нужно тщательно удалять неиспользуемый код и подбирать настройки компиляции. Кроме того, передача данных между хост-системой и WebAssembly-модулем обходится дорого.</p><p><b>Александр Коротаев</b>, Фронтенд-разработчик, автор ТГ канала «Трудно быть Коротаевым»:</p><blockquote>Тут имеется ввиду краеугольная проблема WASM модулей — ввод и вывод. Дело в том, что он довольно низкоуровневый, и если в случае с микроконтроллерами они буквально будут говорить на «одном языке» с железом, то более высокоуровневые системы, передающие данные в том же JSON, столкнутся с довольно затратным процессом сериализации данных. Чтение строки с английскими буквами это одно, а текст на разных языках — это уже задачка со звездочкой. Так что в случае LLM надо будет серьезно работать надо протоколом обмена данными.</blockquote><h2>Инструменты и экосистема</h2><p>Экосистема WebAssembly вне браузера всё ещё развивается. Поддержка различных языков программирования неравномерна: лучше всего дела обстоят у C/C++ и Rust, с интерпретируемыми языками всё сложнее.</p><p>Отладка WebAssembly-модулей ограничена в сравнении с традиционными средствами. Разработчикам часто приходится использовать косвенные методы и работать с преобразованным кодом. Это особенно важно в контексте другой быстрорастущей тенденции — переносить выполнение ИИ-моделей с серверов на сами устройства пользователей (edge computing).</p><p>Например, современные компактные LLM, такие как Phi-4-mini-flash, демонстрируют впечатляющую производительность на мобильных чипах ARM, обрабатывая запросы за 90–100 мс прямо на устройстве без облака. Для подобных сценариев WebAssembly с его переносимостью и низким потреблением ресурсов выглядит идеальной средой, если сможет предложить более прямой и эффективный доступ к специфическим возможностям железа.</p><h2>Будущее WebAssembly вне браузера</h2><p>Перспективы WebAssembly вне браузера выглядит многообещающим. Стандарт WASI совершенствуется,  поддерживая новые системные интерфейсы и возможности. Разработчики получают всё более мощные инструменты для создания и отладки WASM-модулей.</p><p>В embedded-сфере WebAssembly может стать стандартом для безопасного выполнения кода на различных устройствах IoT (интернета вещей). Его способность работать на ресурсо-ограниченных устройствах при изоляции делает инструмент привлекательной альтернативой традиционным подходам.</p><p>Майлз Боринс, технический директор руководящего комитета Node.js, <a href="https://habr.com/ru/articles/446764/">видит</a> потенциал WebAssembly в решении одной из наибольших проблем фреймворка: «Это способ достичь скорости, близкой к нативной, и повторно использовать код, написанный на других языках (C и C++), сохранять портативность и безопасность».</p><p><b>Александр Коротаев</b>, Фронтенд-разработчик, автор ТГ канала «Трудно быть Коротаевым»:</p><blockquote>Как я понял, под фундаментальными проблемами имеется в виду ограничение на кол-во операций с потоками и файлами в текущий версиях Node.js, что не дает серверам на «ноде» тягаться с Nginx на равных.</blockquote><p><br /></p><h2>Итоги</h2><p>WebAssembly превращается из узкоспециализированной веб-технологии в универсальную платформу для выполнения кода. Безопасность, переносимость и производительность WebAssembly делают его эффективным решением для серверных и встраиваемых систем.</p><p>У WebAssembly всё ещё есть проблемы с доступом к аппаратным ресурсам и большим размерам модулей. Однако инструменты и стандарты активно развиваются — скорее всего, эти ограничения постепенно устранят.</p><p>Для разработчиков WebAssembly открывает новые возможности повторного использования кода и создания безопасных, переносимых приложений. Для индустрии в целом — это шаг к более безопасным и эффективным моделям распределения и выполнения кода.</p><p>Как <a href="https://habr.com/ru/articles/446764/">отмечает</a> Шон Уайт, директор Mozilla по R&amp;D: «WebAssembly уже меняет способы доставки людям новых видов привлекательного контента. С WASI преимущества WebAssembly получат больше пользователей и больше устройств в разных местах».</p><p>WebAssembly больше не ограничивается браузером — он становится универсальной платформой для среды, где код должен выполняться безопасно и эффективно везде: от облачных серверов до крошечных устройств интернета вещей.</p>]]></content:encoded>
    </item>
    <item>
      <title>Разработчик изучал систему рекомендаций Netflix месяцами. Вот что скрывается внутри</title>
      <link>https://tproger.ru/news/razrabotchik-izuchal-sistemu-rekomendacij-netflix-mesyacami--vot-chto-skryvaetsya-vnutri</link>
      <comments>https://tproger.ru/news/razrabotchik-izuchal-sistemu-rekomendacij-netflix-mesyacami--vot-chto-skryvaetsya-vnutri?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/razrabotchik-izuchal-sistemu-rekomendacij-netflix-mesyacami--vot-chto-skryvaetsya-vnutri</guid>
      <description><![CDATA[<p>Разработчик изучил рекомендательную систему Netflix: как алгоритмы и инфраструктура персонализируют контент и удерживают зрителей</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/razrabotchik-izuchal-sistemu-rekomendacij-netflix-mesyacami--vot-chto-skryvaetsya-vnutri">Разработчик изучал систему рекомендаций Netflix месяцами. Вот что скрывается внутри</a>»</p>]]></description>
      <category><![CDATA[Алгоритмы и структуры данных]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[CDN]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 14 Aug 2025 03:48:26 GMT</pubDate>
      <content:encoded><![CDATA[<p>Путь Netflix от сервиса проката DVD к стриминговому гиганту — это история о том, как данные превратились в главный актив компании.</p><p>Сегодня их рекомендательная система экономит более $1 млрд в год, удерживая подписчиков и увеличивая время просмотра. И именно ее решил <a href="https://beyondit.blog/blogs/Inside-Netflixs-1-Billion-Algorithm">изучить</a> разработчик на платформе BeyondIT.</p><p>В основе персонализации — анализ каждого клика, паузы, поиска и жанровых предпочтений. Алгоритм строит уникальный «профиль зрителя» и превращает библиотеку из тысяч фильмов в персональную витрину.</p><p>Такой подход помогает избежать «паралича выбора» и быстрее находить интересный контент.</p><h2>Сердце системы — матричная факторизация</h2><p>Ключевая технология, популяризованная ещё во времена конкурса Netflix Prize в 2006 году — матричная факторизация.</p><p>Она превращает гигантскую и разреженную таблицу «пользователь — фильм» в два компактных набора «скрытых факторов»: вкусов пользователя и характеристик фильмов.</p><p>Перемножив их, алгоритм предсказывает оценку, даже если зритель ещё не видел конкретный фильм. Обучение идёт методом стохастического градиентного спуска, с учётом смещений (bias terms) и регуляризации, чтобы модель не переобучалась.</p><h2>Больше, чем просто «похожие на вас»</h2><p>Современный Netflix учитывает десятки сигналов: от истории просмотров и пропусков до времени суток, устройства, локальных трендов и намерений поиска.</p><p>Интерфейс и обложки фильмов постоянно проходят A/B-тесты, чтобы максимизировать вовлечённость.</p><p>Помимо классического коллаборативного фильтра, используются модели глубокого обучения, такие как Neural Collaborative Filtering, способные находить сложные, нелинейные зависимости, и мультизадачное обучение.</p><p>Это нужно для баланса между точностью, разнообразием и новизной рекомендаций.</p><h2>Реакция в реальном времени</h2><p>Предпочтения меняются и Netflix реагирует на них за миллисекунды. Платформа а реальном времени обрабатывает миллионы событий в секунду, обновляя рекомендации на лету.</p><p>Инфраструктура включает Kafka, Spark, микросервисы в AWS, кэширование в памяти и edge-вычисления для минимальной задержки.</p><h2>Почему это важно</h2><p>Такой масштаб требует устойчивости, низкой задержки и отказоустойчивости. Рекомендательная система Netflix — это не только алгоритмы, но и мощная инженерная экосистема, в которой даже хэш-таблицы играют ключевую роль для мгновенного доступа к данным.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как найти работу в IT за границей в 2025 году: ответы на часто задаваемые вопросы и рекомендации экспертов</title>
      <link>https://tproger.ru/articles/kak-najti-rabotu-v-it-za-granicej-v-2025-godu--otvety-na-chasto-zadavaemye-voprosy-i-rekomendacii-ekspertov</link>
      <comments>https://tproger.ru/articles/kak-najti-rabotu-v-it-za-granicej-v-2025-godu--otvety-na-chasto-zadavaemye-voprosy-i-rekomendacii-ekspertov?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Мария Грищенко]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-najti-rabotu-v-it-za-granicej-v-2025-godu--otvety-na-chasto-zadavaemye-voprosy-i-rekomendacii-ekspertov</guid>
      <description><![CDATA[<p>Свежая статистика, исследования и советы экспертов: как российским IT-специалистам найти работу за границей в 2025 году.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-najti-rabotu-v-it-za-granicej-v-2025-godu--otvety-na-chasto-zadavaemye-voprosy-i-rekomendacii-ekspertov">Как найти работу в IT за границей в 2025 году: ответы на часто задаваемые вопросы и рекомендации экспертов</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Языки программирования]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Статистика]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Microsoft]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Amazon]]></category>
      <category><![CDATA[VPN]]></category>
      <category><![CDATA[На английском языке]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[MIT]]></category>
      <category><![CDATA[Intel]]></category>
      <category><![CDATA[OpenAI]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Маркетинг]]></category>
      <category><![CDATA[Стартапы]]></category>
      <category><![CDATA[Английский]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Data Science]]></category>
      <category><![CDATA[GTK]]></category>
      <category><![CDATA[Дизайн]]></category>
      <category><![CDATA[Машин]]></category>
      <category><![CDATA[Игра]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Кибербезопасность]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 18 Jul 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p><i>Российские IT-специалисты востребованы не только у себя на родине, но и за рубежом. В 2024 году иностранные технологические компании наняли <a href="https://www.kommersant.ru/doc/7675878">более 5 тыс. сотрудников</a> из России — это в два раза больше, чем годом ранее. Чаще всего наших айтишников приглашают работать китайские IT-гиганты Huawei, Alibaba и Tencent, также активизировались европейские работодатели SAP, Delivery Hero и американские Amazon, OpenAI. </i></p><p>Если вы хотите стать одним из них и расширить свои горизонты, сделать первые шаги вам поможет наш материал. Здесь мы собрали ответы на часто задаваемые вопросы по поиску работы в IT за рубежом: наиболее перспективные направления, вспомогательные сервисы, особенности виз, рекомендации, как адаптировать резюме для иностранного рынка и получить оффер мечты.</p><p>Бонус — комментарии экспертов с многолетним опытом работы за границей и глубоким пониманием международного рынка труда.</p><h2>Какие IT-профессии наиболее востребованы за рубежом</h2><p>По данным <a href="https://www.rbc.ru/business/29/01/2025/6799966d9a794709c7932279">сервиса по поиску работы HeadHunter</a>, в 2024 году наибольшим спросом за границей пользовались российские:</p><ul><li>менеджеры по продажам и работе с клиентами (13%),</li><li>операторы колл-центров (5%),</li><li>дизайнеры, менеджеры по маркетингу, интернет-маркетологи, художники (по 4%),</li><li>учителя, SMM- и контент-менеджеры (по 3%),</li><li>секретари, помощники руководителя, ассистенты (по 2%).</li></ul><p>Программисты и разработчики заняли почётное второе место (10%). А специалисты технической поддержки и тестировщики набрали всего по 2%.</p><p>Но в исследовании <a href="https://netology.ru/blog/news/03-07-2023-europe-it">образовательной онлайн-платформы «Нетология» и международного коммуникационного агентства Zecomms Agency</a> специалист технической поддержки — наоборот, наиболее востребованная профессия за рубежом. С ним связано 17% от общего массива IT‑вакансий, что делает специалиста техподдержки абсолютным лидером по количеству открытых вакансий.</p><figure><img src="https://media.tproger.ru/user-uploads/114863/2025-06-30/dd2413cd-3aac-48e1-a29c-30620bdccf1d.png" alt="" /><figcaption>Самые востребованные за рубежом IT-специальности, данные исследования «Нетологии» и Zecomms Agency</figcaption></figure><p>На втором месте расположился программный инженер (16%), на третьем — бизнес-аналитик (6%) и IT-консультант (6%).</p><p><b>Максим Оганов, ментор, бизнес-консультант, автор проекта Oganov.Consulting:</b></p><blockquote>Российские IT-специалисты всё ещё остаются востребованными за рубежом, но по сравнению с 2022 годом ситуация изменилась. Международные компании уже не так охотно берут в штат сотрудников из России, известны случаи сокращений из-за гражданства. Причина — политика компаний, особенно тех, которые решили покинуть российский рынок. Зато за последние три года многие отечественные стартапы релоцировались в другие страны, и они отдают предпочтение сотрудникам из России.</blockquote><p><b>Евгений Козак, senior фронтенд-разработчик компании With Intelligence, живёт в Лондоне, более 10 лет опыта работы за границей: </b></p><blockquote>В 2022 году интерес к российским IT-специалистам был выше, но в 2025 ситуация изменилась из-за экономической нестабильности, роста процентных ставок и замедления найма во многих странах. Вакансий стало меньше, особенно без разрешения на работу. Однако IT по-прежнему остаётся одной из самых высокооплачиваемых и востребованных сфер.</blockquote><h2>Языки программирования, актуальные для иностранных компаний</h2><p>Согласно <a href="https://netology.ru/blog/news/04-07-2023-top-programming-languages">исследованию «Нетологии» и Zecomms Agency</a>, Java признан самым популярным языком программирования — его активно используют компании по всему миру. На Java приходится более четверти всех открытых вакансий (26%) в сфере IT в Европе, США, Латинской Америке, Азии и на Ближнем Востоке.</p><p>Java — это универсальный язык программирования, который отличаются стабильностью, масштабируемостью и кроссплатформенностью. На нём пишут крупные корпоративные приложения в банках, промышленных, страховых и телеком-компаниях, облачные, распределённые и IoT- системы, микросервисы. Также Java считается неотъемлемой частью бэкенд-разработки.</p><p>На втором месте по популярности находится язык SQL, который используют для разработки баз данных и систем аналитики. На него пришлось 24% всех вакансий, бóльшая часть из них в Европе, Азии и на Ближнем Востоке.</p><p>Замыкает тройку лидеров Python (23%) — более половины открытых вакансий в Азии и на Ближнем Востоке связано именно с этим языком. Оно и неудивительно: на Python пишут модели для машинного обучения, анализа данных и автоматизации.</p><figure><img src="https://media.tproger.ru/user-uploads/114863/2025-06-30/6a35cec4-e5d1-4991-a1a8-ef49722d59ea.png" alt="" /><figcaption>Самые востребованные за рубежом языки программирования, данные исследования «Нетологии» и Zecomms Agency</figcaption></figure><h2>Сколько айтишникам платят за границей</h2><p>Более высокая зарплата — <a href="https://www.cnews.ru/news/top/2023-10-27_polovinu_rossijskih_it-shnikov">одна из главных причин</a>, почему российские IT-специалисты хотят работать за границей.</p><p><b>Евгений Козак, senior фронтенд-разработчик компании With Intelligence, живёт в Лондоне, более 10 лет опыта работы за границей:</b></p><blockquote>Трудоустройство за границей открывает доступ к международным командам, передовым технологиям и крупным проектам мирового уровня с лучшими практиками разработки, высокими стандартами качества кода и современными архитектурными подходами. Всё это способствует быстрому профессиональному росту. Мне переезд позволил быть ближе к центру IT-индустрии и дал возможность развиваться в высококонкурентной среде.</blockquote><p>В большинстве европейских стран зарплаты индексируются и официально растут вслед за инфляцией. За счёт этого доходы, пусть и медленно, но увеличиваются. К сожалению, не все отечественные компании могут такое гарантировать — практика индексации зарплат в России пока не так распространена.</p><p>Но ключевое — размер оклада. По данным <a href="https://ruitunion.org/posts/2024-04-24-market-and-wages-state/">«Профсоюза работников ИТ»</a>, медианная зарплата специалистов уровня senior в России составляет 276 362 рубля в месяц, в то время как за рубежом она равна 386 730 рублей в месяц. Российские миддлы получают 170 000 рублей, а работающие за границей — 205 142 рубля. Зарплата джунов несильно отличается, хотя «за бугром» она всё-таки немного больше: 85 000 рублей против 80 000 рублей в России.</p><p>Таким образом, зарплата IT-специалистов за рубежом как минимум в 1,5 раза больше, чем в России.</p><p>Дополнительное преимущество — оплата в валюте: долларах, евро или фунтах. После пересчёта на рубли итоговая сумма все равно будет выше средней зарплаты в России — и это без учёта премий и бонусов.</p><figure><img src="https://media.tproger.ru/user-uploads/114863/2025-06-30/caf0a60b-53e5-4468-9c37-44101399c92c.png" alt="" /><figcaption>Медианная зарплата IT-специалистов в России и за рубежом, статистика «Профсоюза работников ИТ»</figcaption></figure><h2>Где IT-кадры пользуются спросом</h2><p>Найти работу в IT сейчас везде нелегко, но чуть проще это сделать там, где активно развивается IT-сектор и требуется много кадров соответствующего профиля:</p><p><b>Германия. </b>Наибольший дефицит IT-специалистов наблюдается в Германии — в 2023 году было опубликовано <a href="https://netology.ru/blog/news/03-07-2023-europe-it">103 089 вакансий</a>. Особенно остро нехватка кадров ощущается в таких областях, как разработка программного обеспечения, Data Science, кибербезопасность и DevOps. А в 2025 году страна планирует выдать <a href="https://prian.ru/news/germaniya-vydast-200-000-viz-kvalificirovannym-kadram-iz-za-nehvatki-rabochey-sily.html">на 10%</a> больше рабочих виз, чем годом ранее.</p><p><b>Нидерланды.</b> В стране большое внимание уделяется IT-стартапам. Так, в 2024 году голландские технологические компании привлекли <a href="https://tech.eu/2025/06/12/the-growth-and-opportunities-of-the-netherlands-tech-ecosystem/">€3,7 млрд венчурных инвестиций</a> — это около 5% от общего объёма капитала, вложенного в европейскую экосистему. Благодаря этому Нидерланды вошли в топ‑10 стран Европы по объёму инвестиций в технологии. Особенно быстро растёт сектор DeepTech («глубоких технологий») — полупроводники, искусственный интеллект и квантовые технологии.</p><p><b>Канада.</b> Такие канадские города как Торонто, Ванкувер и Монреаль считаются настоящей IT-меккой. Здесь активно развиваются стартапы и работают подразделения крупнейших технологических компаний — Google, Microsoft, Amazon. Кроме того, для IT-специалистов есть много иммиграционных программ, например, <a href="https://www.canadacareersite.com/blog/global-talent-stream-canada-work-permit-application">Global Talent Stream</a>, которая позволяет получить разрешение на работу в течение двух недель.</p><p><b>США.</b> В 2023 году объём IТ-рынка США достиг <a href="https://www.comnews.ru/content/233424/2024-05-29/2024-w22/1008/rossiyskiy-it-rynok-ustupil-obemu-rynkam-stran-briks">$1,3 трлн</a> и продолжает развиваться <a href="https://www.mordorintelligence.com/industry-reports/united-states-it-services-market">высокими темпами</a>. В Европейском союзе он составил <a href="https://www.comnews.ru/content/233424/2024-05-29/2024-w22/1008/rossiyskiy-it-rynok-ustupil-obemu-rynkam-stran-briks">$1,05 трлн</a>, в Китае — <a href="https://www.comnews.ru/content/233424/2024-05-29/2024-w22/1008/rossiyskiy-it-rynok-ustupil-obemu-rynkam-stran-briks">$348 млрд</a>, в России — <a href="https://www.comnews.ru/content/233424/2024-05-29/2024-w22/1008/rossiyskiy-it-rynok-ustupil-obemu-rynkam-stran-briks">$36,1 млрд</a>. Таким образом, американский технологический рынок в 36 раз больше российского, в 1,24 раза больше европейского и почти в четыре раза превосходит китайский. Это подтверждает его статус мирового лидера. Соответственно, IT-специалистов нужно много.</p><h2>Куда уехать проще всего</h2><p>По данным <a href="https://www.rbc.ru/business/29/01/2025/6799966d9a794709c7932279">HeadHunter</a>, активнее всего российских специалистов приглашают на работу компании из:</p><ul><li>Белоруссии — 172,3 тыс. приглашений,</li><li>Казахстана — 150,9 тыс. приглашений,</li><li>Грузии и Турции — 69,7 тыс. и 67,8 тыс. приглашений соответственно,</li><li>Узбекистана — 57,2 тыс. приглашений.</li></ul><p>Самый большой рост интереса продемонстрировали китайские работодатели — он увеличился почти в шесть раз. В 2023 году количество предложений для жителей России о работе в Китае составляло всего 4,8 тыс., тогда как в 2024 году цифра достигла 27,6 тыс. предложений.</p><p>Кроме того, за год потребность в российских специалистах выросла в Сербии с 5,8 тыс. до 26,3 тыс. (+356,3%), в Турции — с 23,5 тыс. до 67,8 тыс. (+188,6%), на Кипре — с 4,6 тыс. до 12 тыс. (+160,9%), в Польше — с 4,1 тыс. до 9,0 тыс. (+119,6%) и в ОАЭ — с 19,2 тыс. до 41,7 тыс. (+117,2%).</p><p>А Европа стала лидером по количеству предложений для IT-специалистов со знанием русского языка — <a href="https://netology.ru/blog/news/03-07-2023-europe-it">3%</a> всех IT-вакансий в регионе. На других рынках доля таких предложений не превышает 1%. Чаще всего русскоязычных специалистов ищут <a href="https://netology.ru/blog/news/03-07-2023-europe-it">в Польше — 2 200 вакансий, Венгрии — 752 вакансии, Австрии — 178 вакансий, Греции — 152 вакансии</a>.</p><p><b>Максим Оганов, ментор, бизнес-консультант, автор проекта Oganov.Consulting: </b></p><blockquote>Не все страны охотно принимают специалистов из других стран. Если раньше одними из самых популярных направлений для релокации были Канада и США, то сейчас переехать туда стало значительно сложнее. Больше шансов на трудоустройство в компании Испании, Португалии, Кипра, ОАЭ.</blockquote><h2>Как IT-специалисту найти работу за границей: четыре шага</h2><h3>1. Зарегистрируйтесь на международных платформах</h3><p>Принцип поиска работы за рубежом такой же, как и в России. Нужно зарегистрироваться на платформах по типу HeadHunter и откликаться на понравившиеся вакансии. Чем больше откликов, тем лучше.</p><p>Вот подборка сайтов для поиска работы за границей:</p><ul><li><a href="https://ru.linkedin.com/">LinkedIn</a> — профессиональная социальная сеть, где можно искать вакансии и налаживать контакты;</li><li><a href="https://www.indeed.com/">Indeed</a> — международный агрегатор вакансий, позволяющий фильтровать их по странам, городам и отраслям;</li><li><a href="http://relocate.me">Relocate.me</a> — платформа для вакансий с релокацией;</li><li><a href="https://remoteok.com/">Remote OK</a> — площадка для поиска удалённой работы;</li><li><a href="https://weworkremotely.com/">WWR</a> — сервис, где публикуют вакансии крупные зарубежные компании, например, Amazon или Google.</li><li><a href="https://www.angellist.com/careers">AngelList Talent</a> — каталог вакансий в иностранных стартапах.</li></ul><p>Некоторые из них открываются только с VPN.</p><p><b>Максим Оганов, ментор, бизнес-консультант, автор проекта Oganov.Consulting: </b></p><blockquote>Удобнее всего искать вакансии зарубежных компаний через LinkedIn. По моему опыту, большинство специалистов находят работу за границей именно через эту площадку. Но есть и альтернативные варианты — например, телеграм-каналы с профильными вакансиями. Будьте готовы к тому, что придётся отправлять много откликов. В среднем на 100 откликов приходится не более 5 ответов.</blockquote><p><b>Евгений Козак, senior фронтенд-разработчик компании With Intelligence, живёт в Лондоне, более 10 лет опыта работы за границей: </b></p><blockquote>В основном я искал работу через LinkedIn. Это самая эффективная платформа: я обновил профиль, загрузил резюме и активно взаимодействовал с рекрутерами. Также полезно размещать резюме на популярных job-порталах и быть открытым к предложениям — тогда многие специалисты по подбору персонала сами выходят на связь.</blockquote><h3>2. Адаптируйте резюме для иностранного рынка</h3><p>Если вы собираетесь искать работу на европейском или американском рынке, разумеется, резюме должно быть составлено на английском языке. В англоязычных странах резюме называют Curriculum Vitae или CV.</p><p>Эксперты компании EP Advisory, которая помогает российским специалистам строить карьеру за рубежом, <a href="https://ep-advisory.com/ru/statii/rabotayushhee-rezyume-na-anglijskom-na-osnove-30-000-proverennyh-rezyume/">рекомендуют</a> включать в CV разделы Name, Profile, Education, Experience, Skills &amp; Other. Названия предыдущих компаний и занимаемые должности следует выделять, а каждый блок —  разграничить чертой.</p><figure><img src="https://media.tproger.ru/user-uploads/114863/2025-06-30/2f6d7e8d-fa4e-4d6c-8925-e3c2228fc0cb.png" alt="" /><figcaption>Пример грамотно составленного резюме на английском языке от экспертов EP Advisory</figcaption></figure><p>Кроме того, в некоторых странах, например, Великобритании, США и Канаде не принято добавлять фото в резюме. Такое правило стало следствием законов против дискриминации в этих странах, поэтому его несоблюдение может вызвать негативную реакцию и привести к мгновенному отказу.</p><p>Дополнительно к резюме стоит приложить мотивационное письмо (Cover Letter), подготовленное специально под конкретную вакансию. В мотивационном письме уже не пишут об образовании и навыках — эти сведения указывают только в резюме. А в Cover Letter особый упор делается на кейсах и объяснении, чем для вас интересна компания и почему вы для неё — самый подходящий кандидат.</p><p><b>Максим Оганов, ментор, бизнес-консультант, автор проекта Oganov.Consulting: </b></p><blockquote>Необходим большой и подтверждённый опыт работы. Придётся конкурировать со специалистами уровня senior со всех концов света. Особенно много кандидатов из Индии, Ирана, Пакистана.</blockquote><h3>3. Обратитесь в агентство по трудоустройству</h3><p>Самостоятельно найти работу за границей и разобраться во всех сопутствующих вопросах, связанных с написанием резюме, оформлением виз и переездом, может быть сложно. Поэтому стоит обратиться в агентства по трудоустройству, которые все эти моменты возьмут на себя.</p><p>Вот список наиболее известных рекрутинговых агентств:</p><ul><li><a href="https://www.adecco.com/">Adecco </a>— крупнейшее агентство с вакансиями по всему миру;</li><li><a href="https://manpower.ru/">Manpower</a> — международная стаффинговая, аутсорсинговая и HR-консалтинговая компания из России;</li><li><a href="https://www.michaelpage.com/">Michael Page</a> — международная компания, которая специализируется на подборе персонала среднего и высшего звена;</li><li><a href="https://www.hays.com/">Hays</a> — британская рекрутинговая компания, которая предоставляет услуги по подбору персонала в 33 странах мира;</li><li><a href="https://www.harveynash.com/">Harvey Nash</a> — международная компания, которая специализируется на IT-аутсорсинге;</li><li><a href="https://www.randstad.pl/ru/">Randstad</a> — голландская консалтинговая компания, которая сотрудничает с ведущими зарубежными работодателями.</li></ul><p>Агентства также консультируют по вопросам адаптации и помогают с поиском жилья.</p><p><b>Евгений Козак, senior фронтенд-разработчик компании With Intelligence, живёт в Лондоне, более 10 лет опыта работы за границей: </b></p><blockquote>Чтобы найти работу в Лондоне, я сотрудничал с международными и британскими рекрутинговыми агентствами — Hays, Harvey Nash и Michael Page. Примерно 50% предложений приходили именно от них. Эти агентства играют важную роль на IT-рынке и обладают широкой сетью контактов с работодателями по всей Европе. Они помогали мне в поиске подходящих позиций и сопровождали на всех этапах — от первичного отклика до собеседования и подписания оффера.</blockquote><h3>4. Получите визу и разрешение на работу</h3><p>Без визы и разрешения приступить к работе за границей не получится. Здесь доступны два варианта — Digital Nomad Visa или обычные рабочие визы.</p><p><b>Digital Nomad Visa.</b> Digital Nomad Visa или «виза цифрового кочевника» позволяет легально жить за рубежом, но при этом продолжать удалённо работать на родину. В отличие от туристической визы, Digital Nomad Visa даёт право длительно находиться в определённой стране, а в сравнении с рабочей визой — не требует трудоустройства на местном рынке.</p><p>Это не классическая рабочая виза. Она разрешает трудиться из разных частей мира, но с ней нельзя работать на компании из страны пребывания. Также не всегда можно перевести семью.</p><p>Чтобы получить визу цифрового кочевника, нужно подтвердить минимальный доход (чаще всего <a href="https://ep-advisory.com/ru/statii/digital-nomad-visa-zit-v-evrope-i-rabotat-udalenno/?ref=journal.zarplata.ru">не ниже 2000 евро в месяц</a>) и наличие медицинской страховки. Также может понадобиться трудовой договор или договор подряда, доказывающие, что вы работаете удалённо. Сейчас Digital Nomad Visa оформляют в<a href="https://www.globalcitizensolutions.com/digital-nomad-visa/"> 66 странах</a>, включая Португалию, Испанию, Эстонию, ОАЭ и Южную Корею.</p><p><b>Классические рабочие визы.</b> Это визы EU Blue Card или виза H‑1B.</p><ul><li>Голубая карта (EU Blue card) — виза для работы в Европе. Чтобы получить её, нужен диплом о высшем образовании (не ниже бакалавра) и оффер с зарплатой от 48 300 евро год (43 760 евро для IT‑специалистов) на срок минимум шесть месяцев. В случае одобрения выдаётся вид на жительство, действующий до четырёх лет с возможностью продления.</li></ul><ul><li>Виза H‑1B — виза для работы в США. Она также требует наличия высшего образования и оффера от местной компании. Но американское законодательство устанавливает лимит на выдачу H‑1B — 65 000 базовых и 20 000 дополнительных виз для специалистов с магистерской степенью из США. Всего 85 000 виз в год. Виза предоставляется максимум на три года с возможностью продления до шесть лет.</li></ul><p>Рабочие визы позволяют получить полноценный правовой статус резидента страны, в которую вы планируете переезжать, а вместе ним — все социальные гарантии: медстраховку, оплачиваемый отпуск, пенсионные отчисления.</p><h2>Официальное трудоустройство или фриланс</h2><h3>Удалённая работа на фрилансе</h3><p>Фриланс — самый простой способ начать работать с зарубежными компаниями без лишней бюрократии и сложностей с оформлением. Достаточно зарегистрироваться на зарубежную фриланс-платформах <a href="https://www.upwork.com/">Upwork</a> или <a href="https://www.fiverr.com/">Fiverr</a>, и можно сразу браться за международные проекты. Единственное, могут возникнуть трудности с оплатой, поэтому стоит завести себе иностранную банковскую карту.</p><p>Главные минусы фриланса — нет оплачиваемого отпуска и больничных, а доход крайне нестабилен.</p><h3>Официальное трудоустройство с релокацией</h3><p>Официальное трудоустройство гарантирует стабильную зарплату и полный соцпакет, а при релокации — помощь с переездом и адаптацией в новой стране.</p><p>Однако получить оффер с переводом в местный офис не так просто. Иностранные компании редко берут на себя расходы, связанные с релокацией российских специалистов и их семей. Чаще всего они нанимают тех, кто уже легально живёт за границей — например, по рабочей визе или с видом на жительство. В таком случае проще оформить перевод в местный офис или принять человека на работу через филиал в этой стране.</p><p>Максим Оганов, ментор, бизнес-консультант, автор проекта Oganov.Consulting:<b></b></p><blockquote>Найти работу будет проще, если вы уже находитесь в стране, и компании не придётся заниматься вашей релокацией. Поэтому хороший вариант — попробовать переехать самостоятельно, продолжая работать удалённо в российской компании или на фрилансе. У вас будет время присмотреться к стране, понять, подходит ли она вам. А если вы достаточно активны и коммуникабельны, можно будет попробовать найти вакансию через местные сообщества российских эмигрантов.</blockquote><p><b>Евгений Козак, senior фронтенд-разработчик компании With Intelligence, живёт в Лондоне, более 10 лет опыта работы за границей: </b></p><blockquote>В первую очередь, нужно убедиться, что у вас есть правовой статус или разрешение на работу в стране, где вы планируете трудоустроиться. Это значительно повышает ваши шансы на успех.</blockquote><h2>Какой уровень владения английским языком нужен</h2><p>Для оценки владения иностранными языками, включая английский, в Европе используют систему CEFR (Common European Framework of Reference). CEFR выделяет шесть уровней знания языка: A1, A2, B1, B2, C1, C2.</p><p>Чтобы успешно строить карьеру за границей, рекомендуется уровень не ниже B1-B2, который позволит понимать профессиональные тексты, участвовать во встречах и вести рабочую переписку.</p><p><b>Максим Оганов, ментор, бизнес-консультант, автор проекта Oganov.Consulting:</b></p><blockquote>Обязательное требование — свободное владение английским: например, в Португалии большинство сотрудников IT-компаний общаются на нём. Но иногда кандидату необходимо знание местных языков — так, если вы хотите переехать во Францию, шансы на трудоустройство без владения французским минимальны.</blockquote><p><b>Евгений Козак, senior фронтенд-разработчик компании With Intelligence, живёт в Лондоне, более 10 лет опыта работы за границей: </b></p><blockquote>Главной трудностью для меня был язык. Технический английский у меня на хорошем уровне, особенно когда речь идёт о собеседованиях, терминах и обсуждении архитектуры — в этом я чувствую себя уверенно. Однако повседневный английский, особенно неформальное общение, давался сложнее. Кроме того, структура интервью в других странах немного отличается, но к ней я быстро адаптировался. Повысить уровень языка и стать увереннее в повседневном общении мне помогли постоянная практика, разговоры с носителями языками и участие в командных митингах.</blockquote><h2>Коротко о главном</h2><ul><li>Иностранные компании активно используют Java, Python, SQL и нуждаются в программистах, умеющих писать на этих языках.</li><li>IT-специалисты особенно востребованы в Германии, Нидерландах, Канаде и США — странах с наиболее интенсивным ростом технологического сектора.</li><li>Проще всего уехать в Белоруссию, Казахстан, Турцию, Грузию и Китай.</li><li>Работать за границей можно официально или на фрилансе.</li><li>Чтобы получить оффер, следует зарегистрироваться на международных платформах для поиска работы, адаптировать резюме, оформить визу и, при необходимости, обратиться в агентство.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Чиповые войны: как кризис железа озолотил программистов</title>
      <link>https://tproger.ru/articles/chipovye-vojny--kak-krizis-zheleza-ozolotil-programmistov</link>
      <comments>https://tproger.ru/articles/chipovye-vojny--kak-krizis-zheleza-ozolotil-programmistov?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Михаил Сахаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/chipovye-vojny--kak-krizis-zheleza-ozolotil-programmistov</guid>
      <description><![CDATA[<p>Разберемся, как дефицит кремния породил золотую лихорадку среди разработчиков и почему программисты стали дороже железа.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/chipovye-vojny--kak-krizis-zheleza-ozolotil-programmistov">Чиповые войны: как кризис железа озолотил программистов</a>»</p>]]></description>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Hardware]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Apple]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[Машинное обучение]]></category>
      <category><![CDATA[Windows]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Microsoft]]></category>
      <category><![CDATA[Tesla]]></category>
      <category><![CDATA[Amazon]]></category>
      <category><![CDATA[Samsung]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[IBM]]></category>
      <category><![CDATA[ICO]]></category>
      <category><![CDATA[Intel]]></category>
      <category><![CDATA[NVIDIA]]></category>
      <category><![CDATA[Россия]]></category>
      <category><![CDATA[AMD]]></category>
      <category><![CDATA[Сбер]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Дата-центр]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 14 Jul 2025 10:00:04 GMT</pubDate>
      <content:encoded><![CDATA[<p>Два года назад GPU стоила как подержанная Camry. Сегодня за нее дают как за новую Tesla. Пока весь мир страдает от нехватки чипов, программисты неожиданно превратились в самый дорогой ресурс на планете. Когда железа не хватает, компании готовы платить любые деньги за тех, кто умеет выжимать максимум из ограниченных ресурсов.</p><p>В мае 2024 по всему миру <a href="https://www.embedded.com/how-the-chip-shortage-deepens-the-engineering-skills-crisis/">разлетелись</a> скриншоты писем от HR с внезапными повышениями зарплат на 40%. Текучка кадров в сфере производства полупроводников выросла с 40% до 53%, и теперь компании дерутся за каждого специалиста.</p><h2>Масштаб проблемы</h2><p>169 отраслей <a href="https://www.spglobal.com/mobility/en/research-analysis/briefcase-another-semiconductor-shortage-may-be-coming.html">пострадали</a> из-за дефицита чипов — от автомобилестроения до бытовой техники. Tesla и Volvo останавливали заводы, цены на подержанные автомобили <a href="https://www.embedded.com/engineering-shortage/">выросли</a> на 10% за квартал. Даже стиральные машины подорожали из-за недостатка микросхем.</p><p>Но настоящая битва кипит в кабинетах бигтехов. США заблокировали экспорт технологий в Китай, Европа <a href="https://www.techrepublic.com/article/global-chip-shortage-cheat-sheet/">запустила</a> программу на €43 миллиарда, а Азия <a href="https://www.embedded.com/how-the-chip-shortage-deepens-the-engineering-skills-crisis/">удерживает</a> 77% мирового производства чипов.</p><p>Технологическая война изменила ИТ-индустрию навсегда. Компании теперь не могут просто купить больше серверов — приходится искать тех, кто умеет делать софт быстрее и эффективнее. Apple создала собственные M1 и M2, Google разработал TPU, Amazon — процессоры Graviton. Каждый хочет стать независимым от поставок.</p><h2>Обрушение цепей поставок</h2><p>В 2020 автопроизводители массово отменили заказы чипов, думая, что спрос на машины упадет. Но случилось обратное — спрос на автомобили <a href="https://www.embedded.com/engineering-shortage/">восстановился</a> быстрее ожидаемого во второй половине года, а производственные линии уже переключились на потребительскую электронику.</p><p>Мир оказался в заложниках у нескольких азиатских гигантов. Тайвань <a href="https://www.embedded.com/how-the-chip-shortage-deepens-the-engineering-skills-crisis/">контролирует</a> 65% мирового рынка чипов, TSMC делает процессоры для Apple, AMD и NVIDIA. Samsung доминирует в производстве памяти и накопителей.</p><p>Различные отрасли посыпались, как домино. Время ожидания полупроводников Broadcom выросло до 22 недель против 12 недель в феврале 2020. Автоиндустрия потеряла миллионы машин, дата-центры замедлили расширение, даже PlayStation 5 стали дефицитом.</p><p>США первыми объявили технологическую войну. Пошлины уже изменили процессы производства у Nvidia, Intel и AMD. Китай ответил санкциями против Micron Technology.</p><p>Ключевые игроки <a href="https://news.ycombinator.com/item?id=33436834">разделились</a> на два лагеря. На стороне США — Intel, NVIDIA, AMD, Qualcomm. Китай развивает SMIC и вкладывает миллиарды в собственные технологии. TSMC и Samsung балансируют между сторонами, строя заводы и в Америке, и в Азии.</p><p>Национальные программы превратились в гонку вооружений. CHIPS Act выделил $50 миллиардов на американское производство. Европейская программа нацелена на производство 20% мировых чипов к 2030 году. Китай <a href="https://www.techrepublic.com/article/global-chip-shortage-cheat-sheet/">инвестирует</a> $143 миллиарда в полупроводники.</p><h2>Гонки в мире чипов</h2><p>Рынок AI-чипов взлетел в 15 раз за десятилетие. Компании <a href="https://www.marketsandmarkets.com/Market-Reports/artificial-intelligence-chipset-market-237558655.html">научились</a> делать процессоры умнее, но каждое новое поколение требует больше денег и экспертизы.</p><p>Техпроцессы сжимаются в размере. TSMC освоила 3-нанометровый процесс, Samsung догоняет. Каждый нанометр <a href="https://www.techtarget.com/searchDataCenter/tip/Top-AI-hardware-companies">стоит</a> миллиарды инвестиций и годы разработки. Apple M4 имеет Neural Engine в три раза быстрее M1, но производство одного такого чипа <a href="https://www.techtarget.com/searchDataCenter/tip/Top-AI-hardware-companies">требует</a> сотни инженеров.</p><p>AI-чипы стали новой золотой жилой. Intel <a href="https://www.rootsanalysis.com/ai-chip-market">запустила</a> Gaudi 3, который на 50% быстрее NVIDIA H100. NVIDIA ответила платформой Blackwell с 208 миллиардами транзисторов. Qualcomm Cloud AI 100 <a href="https://www.techtarget.com/searchDataCenter/tip/Top-AI-hardware-companies">обошел</a> H100 по энергоэффективности — 227 запросов на ватт против 108.</p><p>Квантовые технологии пока остаются в лабораториях, но IBM и Google уже тестируют прототипы. Нейроморфные чипы, которые имитируют работу мозга, обещают революцию в энергоэффективности.</p><p>Делать чипы стало сложнее и дороже. Современная фабрика стоит $20 миллиардов, срок окупаемости — 10 лет. Поэтому крупные компании строят собственные решения: Apple создала M-серию, Google — TPU, Amazon — Graviton.</p><p>Компании поменяли философию. Вместо покупки большего количества серверов они <a href="https://www.edge-ai-vision.com/2024/04/ai-chip-market-to-grow-10x-in-the-next-ten-years-and-become-a-300-billion-industry/">нанимают</a> инженеров для оптимизации кода. Netflix <a href="https://pmc.ncbi.nlm.nih.gov/articles/PMC10186304/">использует</a> персонализированные рекомендации и алгоритмы ранжирования для оптимизации вычислений. Meta* оптимизировала машинное обучение и уменьшила количество GPU на 40%.</p><p>Массовый переход на ARM изменил рынок. Amazon перевела часть ресурсов на собственные процессоры. Microsoft адаптировала Windows под ARM-архитектуру. Даже Intel вынуждена выпускать подобные решения.</p><p>Россия также <a href="https://www.reuters.com/technology/russias-yandex-reports-record-annual-revenues-2024-2025-02-20/">планирует</a> наладить массовое производство 28 нм чипов к 2030 году. Росатом присоединился к разработке нейроморфных процессоров. Сбер тестировал отечественный Эльбрус-8С, но выявил проблемы с памятью и оптимизацией.</p><p>*– компания признана в РФ экстремистской и запрещена.</p><h2>Айтишники в центре шторма</h2><p>Зарплаты разработчиков взлетели вместе с ценами на чипы. Средняя зарплата embedded-инженера <a href="https://www.salary.com/research/salary/listing/performance-engineer-hourly-wages">выросла</a> до $153,383, а топовые специалисты получают до $175,000 в год. Performance-инженеры зарабатывают в среднем $100,522, но спрос превышает предложение. Оптимизация под ARM-архитектуру, разработка драйверов для AI-ускорителей, программирование FPGA — навыки, за которые компании готовы переплачивать. IT-зарплаты в Северной Америке выросли в среднем до $113,211.</p><p>Embedded-разработчики неожиданно стали востребованнее ML-инженеров. Когда Tesla не может купить нужные чипы, она нанимает программистов, которые выжмут из имеющихся процессоров максимум. Один такой специалист экономит компании миллионы долларов на железе.</p><p>География возможностей сместилась. Калифорния лидирует по зарплатам — $126,707 в Сан-Хосе, но спрос есть везде. Даже компании из Техаса и Флориды <a href="https://www.salary.com/research/salary/listing/embedded-software-engineer-salary">переманивают</a> embedded-разработчиков зарплатами в $120,000-150,000.</p><p>Системные администраторы, знающие Kubernetes и контейнеризацию, стали дефицитом. Компании переходят на микросервисы и edge-решения — нужны те, кто умеет управлять распределенной инфраструктурой.</p><p>Прогноз на ближайшие пять лет простой: спрос на оптимизацию будет только расти. Эра дешевого железа закончилась. Началась эра дорогих мозгов. Чем сложнее становятся чипы, тем больше нужно программистов, которые умеют с ними работать.</p><h2>Свет в конце туннеля</h2><p>Эксперты расходятся в прогнозах восстановления. CEO Intel Пат Гелсингер <a href="https://en.wikipedia.org/wiki/2020%E2%80%932023_global_chip_shortage">ожидал</a> дефицит до 2024 года, но рынок полупроводников уже показал рост на 15,2% в начале года. К 2023-му автоиндустрия в основном восстановилась, глобальное производство автомобилей выросло на 3%.</p><p>Новые фабрики меняют географию производства. Intel строит заводы в Аризоне за $20 миллиардов и расширяется в Огайо. TSMC открыла завод в Японии в феврале 2024 и планирует второй к 2027 году. Samsung инвестирует в производство в Техасе.</p><p>Европа также <a href="https://www.techrepublic.com/article/global-chip-shortage-cheat-sheet/">входит</a> в игру. European Chips Act нацелен на производство 20% мировых чипов к 2030 году с бюджетом €43 миллиарда. Intel проектирует заводы в Ирландии и Германии, Micron строит завод в Нью-Йорке, а GlobalFoundries расширяется на Мальте.</p><p>Будущее отрасли — в диверсификации. Тайвань по-прежнему контролирует 65% производства, но объемы будут снижаться. К 2030 году США планируют удвоить свою долю в мировом производстве чипов.</p><p>За четыре года индустрия изменилась больше, чем за предыдущее десятилетие. Компании научились строить собственные чипы, программисты — выжимать максимум из доступных ресурсов, а правительства — инвестировать в технологическую независимость.</p><p>Бигтехи готовы переплачивать за надежность поставок и «мозги». Программисты в выигрыше: чем сложнее становится производство чипов, тем больше нужно людей, которые умеют эффективно их использовать.</p>]]></content:encoded>
    </item>
    <item>
      <title>Техлиды и продуктовые менеджеры — всё? Зачем нужны Technical Owner и Unit-лид в IT-командах</title>
      <link>https://tproger.ru/articles/tehlidy-i-produktovye-menedzhery-vsyo--zachem-nuzhny-technical-owner-i-unit-lid-v-it-komandah</link>
      <comments>https://tproger.ru/articles/tehlidy-i-produktovye-menedzhery-vsyo--zachem-nuzhny-technical-owner-i-unit-lid-v-it-komandah?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Владислав Устинов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/tehlidy-i-produktovye-menedzhery-vsyo--zachem-nuzhny-technical-owner-i-unit-lid-v-it-komandah</guid>
      <description><![CDATA[<p>Что приходит на смену классическим техлидам и продакт-менеджерам в IT: рассказываем, зачем нужны Technical Owner и Unit-лид, какие проблемы они решают в реальной разработке и как меняются роли в командах.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/tehlidy-i-produktovye-menedzhery-vsyo--zachem-nuzhny-technical-owner-i-unit-lid-v-it-komandah">Техлиды и продуктовые менеджеры — всё? Зачем нужны Technical Owner и Unit-лид в IT-командах</a>»</p>]]></description>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Яндекс]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Аналитика]]></category>
      <category><![CDATA[5g]]></category>
      <category><![CDATA[Дизайн]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Тимлид]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 11 Jul 2025 10:24:50 GMT</pubDate>
      <content:encoded><![CDATA[<p>Проект выстрелил, команда растёт, но вместе с этим растёт и хаос. Интеграция с другим отделом не работает, бизнес хочет новую фичу, где надо впихнуть невпихуемое, а старый код висит на балансе неизвестно у кого.</p><p>Всё это — обычная история для быстрорастущих IT-компаний. Пока команда маленькая, хватает одного тимлида. Но когда людей становится больше, старые процессы начинают сбоить.</p><p>Здесь и появляются новые роли — Technical Owner и Unit-лид. Их задача — взять на себя куски ответственности, которые раньше выпадали из поля зрения команды.</p><blockquote>В российских компаниях эти роли пока не получили широкого распространения, особенно в небольших и средних организациях, где функции часто распределены между тимлидами, продакт-оунерами и проектными менеджерами. Однако в крупных IT-компаниях и продуктовых командах, таких как Avito и другие, Unit-лид и Technical Owner становятся всё более востребованными, поскольку помогают разграничить ответственность и повысить прозрачность управления сложными продуктами и командами.</blockquote><h2>Technical Owner: кто это и зачем нужен</h2><p>Представим ситуацию: компания разрабатывает маркетплейс на Python и React, всё вроде идёт по плану, пока менеджеры не просят срочно добавить новую систему оплаты. Они не вникают, что для этого придётся переделать схему платежей, разнести микросервисы, рискуя уронить старые заказы. Разработчики объясняют, что быстро не выйдет, но их не слышат — и в итоге проект зависает между требованиями бизнеса и возможностями команды. Именно в таких случаях нужен Technical Owner.</p><h3>Кто это такой</h3><p>У такого специалиста обычно есть технический бэкграунд, он хорошо понимает, что под капотом, и может общаться с командой разработки на одном языке. Также разбирается в бизнес-процессах, понимает дорожную карту развития продукта. За счёт этих особенностей технический владелец может переводить язык разработчиков на язык бизнеса и обратно, избегая недопониманий.</p><h3>Какие у него обязанности</h3><p>Вот примерный список того, что делает ТО:</p><ul><li>Консультирует заказчиков и владельцев по техническим вопросам.</li><li>Составляет дорожную карту развития проекта, с учётом требований к разработке.</li><li>Помогает с разработкой решений, начиная с архитектуры.</li><li>Участвует в расстановке приоритетов.</li><li>Поддерживает команды и отслеживает их зависимости.</li></ul><p>Это неполный список, и обязанности отличаются в разных компаниях, всё зависит от специфики продукта и процессов.</p><h3>Чем отличается от продуктового менеджера, техлида и архитектора</h3><p><b>Чем ТО отличается от продуктового менеджера</b></p><p>Продуктовый менеджер обычно больше фокусируется на управлении командой. Он отвечает за общее видение продукта, общение с клиентами, организацию и сроки. Но чем сложнее продукт и процессы, тем сильнее нужен человек, который сможет управлять и разработкой, и продуктом в целом. Для таких задач есть ТО, который, с одной стороны, понимает, куда движется продукт, какое его позиционирование, с другой — знает, какие нюансы в разработке могут возникнуть и как продукт лучше всего спроектировать.</p><p><b>Чем отличается от тимлида, техлида и архитектора</b></p><p>Тимлид, техлид — это руководители команды, которые отвечают только за её задачи. TO, хоть и глубоко понимает техническую сторону, но его роль шире —  он связывает технику с бизнесом и даже консультирует клиентов. Technical Owner отвечает за общее техническое и архитектурное видение продукта. Масштаб его ответственности больше.</p><p>В отличие от архитектора, технический владелец не только принимает участие в проектировании, но и доносит эти решения до клиентов и руководства.</p><blockquote>Technical Owner (Технический владелец) ответственен за долгосрочное здоровье и развитие конкретного компонента/системы/продукта. Фокус на технической стратегии, архитектуре, надёжности и поддержке в течение всего жизненного цикла.<br /><br />Техлид руководит командой, отвечающей за разработку. Фокус на распределении задач, наставничестве и решении технических проблем.<br /><br />Архитектор решений определяет технологический стек и взаимодействие компонентов. Фокус на общей структуре и дизайне решения.<br /><br />Технический владелец может делегировать задачи техлиду и руководствоваться архитектурой, предложенной архитектором, но конечная ответственность за успех компонента лежит на нём.</blockquote><h2>Сколько зарабатывает и какие нужны навыки, чтобы стать ТО</h2><p>Если мы сейчас пойдём на hh.ru и введём в поиск Technical Owner, то, в лучшем случае, найдём только пару вакансий. Technical Owner нужен для больших продуктов в крупных компаниях, поэтому должность встречается на рыке редко и пробиться туда сложно.</p><p>Зарплата и навыки зависят от конкретной компании, её процессов и задач. Обычно это что-то на уровне топ-менеджмента. Вот пример заработной платы в одной из <a href="https://getmatch.ru/vacancies/24808-technical-owner-disk">вакансий</a> от Яндекс 360:</p><figure><img src="https://media.tproger.ru/user-uploads/105039/2025-06-24/37fe6863-ca0d-432e-8285-fbb18098f941.jpg" alt="" /><figcaption>Пример зарплаты на вакансию Technical Owner от Яндекс 360</figcaption></figure><p>А вот так выглядят обязанности и необходимые навыки:</p><figure><img src="https://media.tproger.ru/user-uploads/105039/2025-06-24/ff7d27db-b585-4548-80c6-4432b0110a14.jpg" alt="" /><figcaption>Описание задач для Technical Owner</figcaption></figure><figure><img src="https://media.tproger.ru/user-uploads/105039/2025-06-24/e680ef81-cb5c-4a13-8c73-02b17ec95ce3.jpg" alt="" /><figcaption>Требования к Technical Owner</figcaption></figure><p>Вот пример ещё одной такой <a href="https://volgograd.hh.ru/vacancy/121349277?query=Itransition+Technical+Owner&amp;hhtmFrom=vacancy_search_list">вакансии</a> от компании Itransition:</p><figure><img src="https://media.tproger.ru/user-uploads/105039/2025-06-24/c548e397-d04a-4bb1-9db5-8e6137079283.jpg" alt="" /><figcaption>Требования к Technical Owner в вакансии от Itransition</figcaption></figure><p>Как видно, здесь есть требования к опыту работы в качестве продуктового менеджера и аналитика, технической подкованности и определённому стеку.</p><p>Чтобы стать таким специалистом, нужно хорошо разбираться в разработке, подходить по стеку и иметь опыт управления командой.</p><h2>Кто такой Unit-лид, зачем он нужен</h2><h3>Кто это такой</h3><p>Юнит-лид — это руководитель, который возглавляет «юнит» – объединение нескольких команд (обычно 3-5), работающих над частью общего продукта или бизнес-направления. Он отвечает за стратегию и бизнес-результаты своего юнита.</p><blockquote>В последние полгода в нашей компании появилась новая управленческая роль — Unit Lead. Это ответственный руководитель,который координирует работу всего юнита: от стратегии до найма и развития сотрудников. Мы внедрили эту модель не просто ради структуры — она стала ответом на быстрый рост бизнеса и усложнение внутренних процессов.<br /><br />Что такое юнит? Это самостоятельный бизнес-модуль, включающий несколько стримов (направлений). Каждый стрим, в свою очередь, состоит из команд по 5-10 человек. Таким образом, один юнит может объединять от 5 до 12 команд, представляющих разные IT-направления: фронтенд, бэкенд, мобайл и др.</blockquote><h3>Какие у него обязанности</h3><p>Обязанности юнит-лида очень обширны и зависят от типа юнита:</p><p><b>Стратегическое развитие и планирование</b>: юнит-лид определяет общую стратегию развития своего юнита, составляет планы проектов, согласовывает их со стейкхолдерами.</p><p><b>Управление командами и сотрудниками</b>: управляет командами, например, аналитиков, разработчиков, QA-инженеров, занимается развитием их компетенций, формирует портфель проектов, следит, чтобы эти проекты были реализованы.</p><p><b>Взаимодействие со стейкхолдерами</b>: активно общается со множеством внутренних и внешних заказчиков, лидерами бизнеса и продукта, регулирующими органами и партнёрами. Он занимается привлечением и защитой необходимых ресурсов, которые нужны для продукта.</p><p><b>Ответственность за результаты</b>: вся ответственность за вектор развития и конечный результат юнита лежит на юнит-лиде. Иногда на нём висит даже отчётность по финансовым результатам.</p><p><b>Разработка и развитие продуктов/инструментов</b>: юнит-лиды могут адаптировать существующие инструменты, разрабатывать новые под потребности команд, а также создавать внутренние платформы и технически сложные продукты.</p><h3>Чем отличается от продуктового менеджера и тимлида</h3><p>Роль юнит-лида схожа с некоторыми другими позициями, но всё же от них отличается. Рассмотрим несколько таких отличий.</p><p><b>Что делает продуктовый менеджер</b></p><p>Продуктовый менеджер (PM или Product Owner) отвечает за конкретный продукт или его отдельные части. Его главная задача — понять, что нужно пользователям и бизнесу, сформировать требования и приоритеты, а затем воплотить эти требования в жизнь. PM постоянно держит руку на пульсе метрик, проводит A/B-тесты и собирает обратную связь.</p><p><b>Что делает тимлид</b></p><p>Тимлид — это руководитель разработки внутри одной команды. Он отвечает за техническое качество кода, выполнение задач в срок и развитие команды. Его основная забота — чтобы код был качественным, архитектура — адекватной, а команда справлялась с поставленными задачами без перегрузок и постоянных авралов.</p><p><b>Чем занимается юнит-лид</b></p><p>Юнит-лид работает на другом уровне. Если представить компанию как армию, то тимлид руководит взводом, продуктовый менеджер отвечает за успешность операции, а юнит-лид — полковник, который решает, какие операции вообще нужны, какими силами их проводить и как это повлияет на общую картину. Он отвечает за бюджет, координацию нескольких команд и стратегическое развитие целого направления.</p><p>Например, в Avito есть <a href="https://habr.com/ru/companies/avito/articles/885968/">аналитический юнит-лид</a>, который управляет одной командой аналитики и двумя техническими. Первая команда занимается ценами: изучает разные способы образования цен на услуги Avito, анализирует результаты изменения цен, оценивает эффективность промокампаний.</p><p>Две другие команды отдают цены в другие сервисы, организуют скидки, интегрируют новые категории товаров и услуг в систему.</p><blockquote>Unit-лид — это такая гибридная роль, которая объединяет менеджерские навыки с техническим пониманием. От тимлида он отличается тем, что не погружается в код-ревью и техническую детализацию спринтов, а больше занимается координацией между командами. <br /><br />В отличие от обычного проектного менеджера, Unit-лид разбирается в архитектурных решениях и может принимать технические решения сам, без долгих согласований. Он следит за тем, чтобы команда двигалась в рамках продуктовой стратегии, а не только закрывала текущие задачи по списку. Такой специалист становится связующим звеном между разными уровнями управления.<br /><br />В нашей практике в Юнисофт мы сталкивались с ситуацией, когда отсутствие такой роли приводило к хаосу и потере общего видения проекта.</blockquote><h3>Сколько зарабатывает unit-лид, какие нужны навыки и как им стать</h3><p>Наткнуться на вакансию юнит-лида на просторах hh.ru тоже непросто. Это новая роль, которая нужна только для сложных продуктов в крупных IT-компаниях.</p><p>С зарплатой и обязанностями всё индивидуально, зависит от компании. Вот пример одной из <a href="https://getmatch.ru/vacancies/14624-unit-lead">вакансий</a> от Купера:</p><figure><img src="https://media.tproger.ru/user-uploads/105039/2025-06-24/3d95de82-4238-4845-96c0-5026093fe9b4.jpg" alt="" /><figcaption>Пример зарплаты юнит-лида в Купере</figcaption></figure><p>Зарплата вполне на уровне топ-менеджмента. А вот обязанности и ожидания:</p><figure><img src="https://media.tproger.ru/user-uploads/105039/2025-06-24/fc1da5fa-ed76-47ee-a599-3339cee29908.jpg" alt="" /><figcaption>Обязанности и ожидания юнит-лида</figcaption></figure><p>Как видим, помимо менеджерских навыков здесь тоже нужно понимание стека. Но в отличие от Technical Owner, юнит-лид больше сфокусирован на управлении продуктом, чем на его технической составляющей.</p><p>А вот ещё один пример обязанностей и ожиданий в <a href="https://yandex.ru/jobs/vacancies/yunitlid-v-komandu-postavki-dannih-v-crm-31805">другой вакансии</a>, на этот раз от Яндекса:</p><figure><img src="https://media.tproger.ru/user-uploads/105039/2025-06-24/96ce7071-00ca-4bbe-ad2b-e660bad75e85.jpg" alt="" /><figcaption>Описание задач для юнит-лида</figcaption></figure><p>Как видно из обеих вакансий, для того чтобы стать юнит-лидом нужно иметь технический бэкграунд, но при этом обладать опытом управления командами, работать с процессами, ставить и выполнять задачи.</p><h2>Где и когда эти роли реально нужны (а где — нет)</h2><h3>Какие компании и проекты выигрывают от появления таких ролей</h3><p>Technical Owner и Unit-лид подходят не всем. В стартапах и небольших командах, где каждый знает свои задачи и зоны ответственности, эти позиции будут избыточными и просто усложнят работу.</p><p>Но в крупных компаниях и быстрорастущих проектах, которые уже переросли старые схемы управления, эти роли реально помогают. Если проект вырос до нескольких команд, которые работают над разными продуктами или направлениями, то Unit-лид поможет держать фокус на стратегических целях. Technical Owner пригодится, когда задачи настолько усложнились, что нужен человек, который свяжет технические решения и требования бизнеса, предотвращая недопонимания.</p><h3>Сигналы, что команде пора подумать о Technical Owner или Unit-лиде</h3><p>Есть несколько явных признаков, когда стоит задуматься о введении этих ролей:</p><ul><li>Постоянные споры о том, кто должен заниматься интеграциями, техническим долгом и сложными архитектурными вопросами.</li><li>Регулярные задержки и проблемы с релизами из-за несогласованности между командами.</li><li>Непонимание между менеджерами и разработчиками: одни требуют невозможного, другие объясняют технические сложности.</li><li>Наличие нескольких продуктовых направлений, для которых нужны люди, умеющие координировать работу сразу нескольких команд.</li></ul><blockquote>Создание этих ролей актуально, когда бизнес выходит за рамки одной команды и одного продукта. Если у компании несколько направлений, которые требуют отдельного фокуса и развития, то Unit-лид — необходимый управленец для децентрализации и роста. <br /><br />Technical Owner нужен, когда продукт становится достаточно сложным, и необходимо, чтобы один человек держал в фокусе его техническую эволюцию, а не просто оперативную реализацию. Это позволяет стратегически управлять качеством кода, архитектурой и техническими рисками<b>.</b></blockquote>]]></content:encoded>
    </item>
    <item>
      <title>Микросервисная архитектура: от монолита к гибкой системе</title>
      <link>https://tproger.ru/articles/mikroservisnaya-arhitektura--ot-monolita-k-gibkoj-sisteme</link>
      <comments>https://tproger.ru/articles/mikroservisnaya-arhitektura--ot-monolita-k-gibkoj-sisteme?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/mikroservisnaya-arhitektura--ot-monolita-k-gibkoj-sisteme</guid>
      <description><![CDATA[<p>«Монолит или микросервисы» — вопрос, который до сих пор вызывает споры в IT. СТО Сервисной цифровой платформы в Газпромбанке делится личным опытом перехода к микросервисной архитектуре, разбирает реальные кейсы и объясняет, почему однозначного ответа не существует.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/mikroservisnaya-arhitektura--ot-monolita-k-gibkoj-sisteme">Микросервисная архитектура: от монолита к гибкой системе</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Ретро]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Аналитика]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Grafana]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[Архитектура приложений]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 27 Jun 2025 08:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Привет! Меня зовут Андрей Бирюков, я СTO Сервисной цифровой платформы в Газпромбанке. За свою карьеру поработал в нескольких компаниях — от стартапов до крупных корпораций — и видел разные архитектурные подходы.</p><p>И вот начала копиться усталость от обсуждения, что использовать — монолиты или микросервисы. Этот вопрос стал преследовать меня на конференциях, в офисе, в личных сообщениях. Я потратил столько времени на обсуждение этой темы, что иногда хочется просто распечатать какой-нибудь емкий ответ на футболке и ходить в ней на все митапы.</p><p>Шутки шутками, но тема действительно важная. Я прошел путь от классических монолитных приложений до сложных микросервисных, проектировал системы, которые работают под большой нагрузкой, и пришел к выводу, что однозначного ответа здесь не существует. И вообще, «монолит или микросервисы» — это неправильная постановка вопроса.</p><p>Недавно сходил с Витей на запись <a href="https://vkvideo.ru/video-145457488_456239831">подкаста</a> на эту тему и настолько преисполнился, что решил в текстовом виде формализировать свое отношение к теме (я гнался за вами три дня, чтобы сказать, как вы мне безразличны, ага), обобщить то, о чем говорили, и попытаться дать ответ на вопрос «когда микросервисы действительно помогают и как не сойти с ума, если вы с ними работаете». Порассуждаю о проектировании, поддержке, DevOps-культуре и попробую немного заглянуть в микросервисную архитектуру.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-06-27/98a19000-c584-440e-bf7a-af36d4409a2a.png" alt="" /><figcaption>Подкаст «Техно.Логично»</figcaption></figure><h2>Микросервисы: зачем они нужны и в чем их плюсы</h2><h3>Архитектура приложений: немного базы</h3><p>Под капотом современных приложений обычно скрываются три основные части:</p><ul><li>множество библиотек и зависимостей;</li><li>единый store, в котором живут состояние и данные;</li><li>компоненты, которые нужно собрать, чтобы сделать из них приложение.</li></ul><p>Собрать это все можно по-разному. Можно сложить в монолит, а можно попробовать модульный подход.</p><p>Монолитное приложение — старое доброе приложение, которое, как правило, создают один или несколько разработчиков, потом его дорабатывает армия джунов, синьоров и всех, кто оказался рядом. Каждый «чуть-чуть поправил», и вот уже никто не понимает, почему оно работает, — но трогать страшно. Монолиты пишут и сейчас — все зависит от бизнеса. Если нужно приложение для небольшого проекта, микросервисы могут и не понадобиться.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-06-27/02011912-2de9-4c86-9de2-44865eb93fab.png" alt="" /><figcaption>Как выглядит монолит</figcaption></figure><p>Однако наступает момент, когда бизнес расширяется, аудитория растет, нагрузка увеличивается — а масштабировать монолит становится все сложнее. Тогда и приходят на помощь микросервисы.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-06-27/739de2ec-05c4-4f68-bf1a-356380611028.png" alt="" /><figcaption>А вот приложение с микросервисной архитектурой</figcaption></figure><p>Масштабировать можно и монолиты, но у них всегда остается какая-то единая точка отказа — например, база данных. Особенно если это реляционная СУБД, завязанная на Oracle или PostgreSQL. Когда база достигает сотен гигабайт или даже терабайт, масштабировать такую штуку становится дорого, больно и ненадежно.</p><h3>Микросервисы — панацея? Не совсем</h3><p>Тренд на микросервисный подход появился в начале 2010-х годов, вместе с проникновением интернета в широкие слои населения. Первый iPhone вышел в 2007 году, люди стали гораздо ближе к интернету, к данным, к информации. Бизнес захотел дотянуться до этой аудитории, и тогда началась диджитализация, сложность систем стала повышаться. Особенно остро это почувствовали крупные организации вроде банков: функциональность увеличивалась, и монолит начал «трещать» не только технически по инфраструктуре, но и по возможностям команд разработки, которые с ним работали.</p><p>Плюсы микросервисов очевидны: масштабируемость, независимая разработка, изоляция компонентов. Но вместе с этим пришли новые проблемы — усложнились мониторинг и поддержка, стали требоваться все новые инструменты, чтобы обеспечивать работу огромной инфраструктуры. Так появился DevOps.</p><h2>Распространение DevOps-культуры и инструменты оркестрации</h2><p>Раньше разработчик писал код, собирал артефакт и перекидывал его через забор в поддержку. Коллеги за забором его деплоили, запускали — и разработчику можно было больше не думать про плоды своей работы.</p><p>В новой реальности количество артефактов, которые нужно перекидывать через забор, кратно выросло. Вместе с этим появилась и стала распространяться DevOps-культура: понимание, что за качественную раскатку в проде отвечает не только команда поддержки, но и разработчики.</p><p>Важно учитывать еще и то, что сложность поддержки кратно увеличилась. Если монолит можно было отдебажить, просто заглянув в логи, то с сотней микросервисов так не получится. Поэтому появились такие инструменты, как централизованное логирование, распределенный трейсинг — и сотни, если не тысячи других, связанных в первую очередь с observability. В таких обстоятельствах DevOps-культура стала особенно важна.</p><h2>Проектируем микросервисы без боли: от стандартов до DDD</h2><h3>Стандартизация — наше все</h3><p>Если каждый микросервис пишет логи в своем формате и использует свои библиотеки, получается зоопарк. Нужно, чтобы были выровнены стек и CI/CD pipeline, существовали одинаковые библиотеки логирования и формат.Микросервисы дают свободу писать на разных языках, но с ней приходит и ответственность: под каждый язык придется придумывать и поддерживать разные инструменты. А это приведет к еще большему увеличению сложности. Так что с языком тоже лучше соблюдать стандартизацию: если пишете на Java, то и решать все проблемы стоит с помощью этого языка.</p><p>При этом иногда другой язык вполне оправдан. Например, просто потому, что Java не может работать с такой высокой скоростью, какая нужна. В некоторых случаях даже на Java приходится писать особым образом, либо можно использовать C++, Go или Rust. Но это скорее исключение из правила.</p><p>Инженеры — натуры увлекающиеся и любят паттерн CV driven development, когда хочется новую технологию потрогать и внедрить у себя. А потом похвастаться этим на каком-нибудь ивенте по принципу «just because I can» («просто потому что могу»). При этом может оказаться, что бизнесу технология особо и не была нужна. Чтобы избегать таких ситуаций, необходим технологический радар — список того, что можно использовать в компании, а что нет. И исключения из такого радара должны приниматься и допускаться очень взвешенно.</p><h2>DDD: как правильно нарезать сервисы</h2><p>Одна из опасностей при проектировании микросервисов — скатиться в очень мелкую гранулярность, когда логика нарезается чуть ли не по отдельной функции на микросервис (на отдельный deployment unit). Это может привести к такой сложности, которой потом будет очень трудно управлять. Такая проблема была, например, у Uber в начале их пути, и им пришлось пересматривать свою архитектуру. Избежать этого помогает Domain-driven design (DDD) — предметно-ориентированное проектирование.</p><p>Вместо того чтобы пилить отдельные сервисы для авторизации, логирования и уведомлений, команда может подумать вот над чем: все это части одного бизнес-контекста — пользовательского доступа. И целесообразно оставить их в одном сервисе. Это и есть DDD в действии.</p><p>Существует и еще одна проблема, с которой DDD помогает справиться, — неправильная нарезка сервисов с точки зрения бизнесовой функциональности. Если не понимать бизнес-контекста, можно получить «распределенный монолит»: будет много отдельно стоящих сервисов, но профита никакого, только все сложности микросервисов плюс проблемы монолита с масштабируемой базой данных. Особенно остро это проявляется, когда изменения в одной части бизнес-процесса (в одном сервисе) влекут за собой изменения еще в трех-четырех-пяти других сервисах.</p><p>DDD помогает выделить bounded context — согласованные по бизнесу участки. Они позволяют более или менее правильно нарезать большой бизнес-функционал на отдельные части.</p><p>Еще один важный принцип правильной архитектуры микросервисов — у каждого микросервиса должна быть своя независимая маленькая база данных (если она вообще нужна).</p><p><b>Два эмпирических правила, которые касаются размера сервисов и помогают понять, правильно ли они спроектированы:</b></p><ul><li>Если вы не можете переписать сервис за две недели, значит, возможно, он неправильно нарезан, и его нужно декомпозировать.</li><li>Если вам страшно браться за переписывание сервиса, значит, он точно кандидат на декомпозицию.</li></ul><p>Внедрение микросервисов: с чего начать?</p><p>С микросервисным подходом есть проблема — нет четкого ответа, куда идти и что делать, чтобы научиться его создавать. Это одна из главных сложностей микросервисной архитектуры, особенно когда только начинаешь с ней работать. Если хочется изучить Spring или Oracle, можно почитать официальную документацию. А к такой большой и необъятной теме, как микросервисы, даже и непонятно, с какой стороны подступиться. Туториала к ней нет, есть только куча статей, подходов и практик. Причем одни практики подойдут конкретной команде, а другие — нет.</p><p>И вот тут возникает реальная сложность, особенно когда вы только начинаете, — глаза разбегаются. Здесь Kubernetes, здесь ELK, здесь Grafana, здесь observability, здесь всякие паттерны отказоустойчивости, CAP-теорема и прочее. Непонятно, куда бежать. И каждый день появляются новые инструменты, которые так или иначе упрощают жизнь.</p><p>Совет: задавайте себе вопрос о каждом инструменте, который вы хотите внедрить (будь то Kubernetes, OpenTelemetry с Jaeger или любой другой) — какую проблему мы решаем, втаскивая его в свою инфраструктуру? Ответ на этот простой вопрос может дать много инсайтов и просветлений.</p><p>Чтобы в первом приближении ознакомиться с темой, можно почитать материалы <a href="https://sre.google/books/">SRE</a> от Google, также будут полезны статьи и книги в<a href="https://martinfowler.com/"> блоге</a> Мартина Фаулера, в том числе <a href="https://martinfowler.com/microservices/">Microservices Guide</a>. Если вам нужна практика, можно попробовать пойти на тот же Udemy, где есть множество курсов по микросервисной архитектуре с хорошими рейтингами и отзывами.</p><p>И вот что важно: при проектировании и внедрении микросервисов лучше избегать «велосипедостроения». Если индустрия уже решила проблему, нет смысла изобретать новое логирование или оркестрацию. Собственное решение вряд ли будет работать лучше, а сил, времени ресурсов на него можно потратить очень много.</p><h2>Поддержка микросервисной архитектуры</h2><p>Мы каждый день используем разные приложения — например, мобильный банк. Если в магазине длинная очередь, а на кассе у вас вдруг вылетает ошибка, — это раздражает. Поэтому у бизнеса нет права на ошибку: мониторинг должен срабатывать раньше, чем клиент успеет заметить, а инциденты необходимо устранять за минуты.</p><p>В крупных организациях микросервисов могут быть сотни: например, в некоторых системах насчитывается почти 700 микросервисов на продакшене. Каждый инстанс еще масштабирован — это тысячи подов, которые постоянно обрабатывают клиентский трафик. И при этом в современных условиях нужно стремиться к доступности системы на уровне четырех девяток (99,99%), то есть к простою всего в несколько минут в год.</p><p>Если вы хотите достичь того, чтобы простой вашего приложения был минимальным, приходится продумывать много разных подходов, приемов и инструментов.</p><h3>Паттерны отказоустойчивости</h3><p>Микросервисы — это не про «разбили монолит», это про то, что сбой одного сервиса не должен валить весь продукт. Поэтому если какой-то важный сервис упал, то максимум, который нужно сделать, — чтобы клиент не увидел упавший кусочек функционала приложения.</p><p>Еще один хороший вопрос: как мониторить аварии? Необходимо очень быстро находить точку отказа. Для этого, собственно, и нужен observability-подход, трейсинг. Нужно смотреть, где какой RPS (число запросов в секунду), не произошло ли резкого скачка трафика, важно следить за latency (задержками).</p><p>Бывали случаи, когда из-за бага в мобильном приложении трафик внезапно удваивался, и системы не выдерживали такой нагрузки. Любая малейшая задержка в самом незначительном компоненте может привести к тому, что по цепочке пойдет отказ, — будут копиться потоки, соединения, и рано или поздно упадет вообще все. Чтобы подготовиться к таким ситуациям, важно изучить хотя бы <a href="https://sre.google/sre-book/monitoring-distributed-systems/">четыре «золотых сигнала» мониторинга</a> из SRE от Google.</p><p>Совет: возьмите на вооружение парадигму проектирования на отказ. Исходите из того, что в любой момент что угодно может пойти не так. Сеть будет нестабильной, железо начнет падать, интеграции станут работать неправильно. Если изначально придерживаться этого принципа, вы здорово подстрахуете себя завтрашнего. Это всегда спасает, особенно когда получаешь по наследству что-то, что не было спроектировано с учетом этого принципа.</p><p>Сейчас часто используют паттерны, которые помогают поддерживать отказоустойчивость системы:</p><ul><li><b>Circuit Breaker</b> — если сервис спамит ошибками, лучше временно прекратить попытки до него достучаться. Для клиента ничего не изменится, он как получал ошибки, так и будет получать. Но, по крайней мере, можно дать системе возможность восстановиться. А еще лучше — позволить ей переключиться на какой-то резервный канал, например сходить в кэш с неактуальными данными.</li><li><b>Rate Limiter</b> — абсолютно банальная, но необходимая вещь. Нужно ограничивать входящий поток на примерно максимальном уровне от того, который ожидается. Чтобы все не развалилось, если произойдет резкий скачок трафика.</li><li><b>Blue-Green Deployment</b> — значительно снижают на продакшене количество аварий и проблем, связанных с кривыми релизами. Можно не раскатывать новую фичу сразу на все 100 подов, а выкатить ее только на 1% трафика и проверить.</li></ul><p>И это только малая часть паттернов.</p><p>Все это must have для абсолютно любой системы. Даже если у вас низкая нагрузка, она когда-нибудь увеличится. Лучше вовремя предусмотреть это, заранее потратив чуть больше времени и реализовав эти паттерны.</p><h3>Как эффективно работать с инцидентами</h3><p>Начало всех начал в траблшутинге — мониторинг. Здорово, когда разработчики понимают, как устроена их система, и уже вложились в мониторинг: есть дашборд, где можно посмотреть по уровням абстракций основные точки отказа.</p><p>Первый уровень — это application-слой, сами сервисы, которые в подах крутятся в Kubernetes. Нужно проверить, все ли у них хорошо по точкам интеграции — нет ли тайм-аутов. Все ли в порядке у них по железу — по CPU, по памяти, по дискам.</p><p>Если на первом уровне все нормально, нужно опуститься на уровень ниже — либо на виртуалки, на которых Kubernetes развернут, либо на железки, если он развернут на Bare-metal. Недавно мы столкнулись с интересным случаем: виртуалка показывала нормальную загрузку CPU, но физический гипервизор, на котором она крутилась, был загружен на 99%. Естественно, виртуалка страдала, но уровнем выше этого не было видно.</p><p>Совет: если вы вдруг нашли что-то, что еще не мониторится, — это повод поскорее добавить эту метрику, начать ее мониторить и ретроспективно отслеживать.</p><p>Еще одна важная вещь в работе с инцидентами — культура постмортемов. Ретроспективы по каждой аварии пишутся не просто так — их можно свести по категориям и понять, из-за чего чаще всего происходят аварии: например, из-за протухших сертификатов либо человеческого фактора в конфигурации. Категорий причин отказа обычно не так много. С постмортемами проще выработать стратегию технического инженерного развития.</p><p>Вообще, человеческий фактор — это отдельная боль. Все привыкли менять что-нибудь руками: заходить в виртуалки, поправлять конфиг. Чтобы такого было как можно меньше, важно вкладываться в infrastructure as a code и даже everything as a code. В идеале следует стремиться к zero access production — нулевому доступу к продакшену — и все раскатывать через Git, через конфигурации, включая политики безопасности.</p><h2>Культура ответственности и изменение ролей в команде</h2><p>Представим, что происходит инцидент — падают 15 микросервисов. Как должна быть устроена система, которая позволит оперативно справляться с авариями?</p><p>Организационно все достаточно просто — хотя не так просто на земле, при устранении инцидента. Все сервисы должны быть каталогизированы, сгруппированы по командам или продуктовым стримам. Необходима матрица эскалации, позволяющая найти по зоне ответственности человека, которому можно позвонить и попросить подключить необходимых инженеров.</p><p>Подобную конструкцию важно поддерживать в актуальном состоянии. Это часть процесса непрерывности, и в нее надо вкладываться. В крупных компаниях этим занимаются целые отделы, в небольших организациях — отдельный человек, но такая информация всегда должна быть в общем доступе. Иначе время «отскока» после инцидента увеличится кратно.</p><p>Желательно, чтобы в компании был специальный ситуационный центр, в котором сразу можно создать конференцию, если случилась авария, и поделиться информацией, чтобы все подключились к решению проблемы.</p><p>Однако эти организационные моменты еще не гарантируют быстрого решения проблемы. Ключевой фактор — культура компании. На людей часто нападает отстраненность — авария случилась, и все думают: «Кто-нибудь другой разрулит. Я разработчик, ну, что я там сделаю?»</p><p>Многие привыкли жить по старой парадигме: написали код, потестировали, отдали поддержке и забыли. Но культура в команде должна дорасти до такого уровня, когда каждый понимает: я не только разрабатываю или тестирую код, но еще и отвечаю за него на продакшене.</p><p>Из-за этого разрыва в осознании между командами поддержки и разработки возникают конфликты. У каждой разные цели, и зачастую одна команда не понимает, чего хочет другая. Чтобы лучше понять природу этих конфликтов, важно вспомнить про DevOps-культуру и SRE. В их парадигме разработчики не только пишут код, но и деплоят в продакшен.</p><p>Проще говоря, есть два варианта взаимодействия с поддержкой: классический, когда она административно отделена, и SRE-подобный, когда сотрудники «второй линии» прямо интегрированы в команду разработки. Могу сказать, что второй эффективнее.</p><p>При этом не обязательно сливать всех в одну плоскую структуру на уровне административного деления. Достаточно, чтобы люди, даже находясь в разных административных юнитах, работали как команда и коммуницировали постоянно, а не от случая к случаю. Важно, чтобы все были проактивными — если что-то случилось, сразу подрывались и по инструкции пытались устранить проблему.</p><p>Это то самое SRE, о котором пишет Google. Но людей нужно долго обучать такой культуре — это не дело одного месяца. Благодаря такому подходу инженеры, которые раньше были просто разработчиками или аналитиками, глубже осознают свою ответственность за стабильность продакшена. И это действительно правильное направление развития. Потому что и DevOps, и SRE — это в первую очередь культура, а уже во вторую — набор инструментов.</p><h3>Будущее микросервисов: тренд на AI Ops</h3><p>Разработчики уже используют AI как copilot — и это очень мощный инструмент в умелых руках. Он не заменяет инженера, но сильно экономит ему время. Эту помощь от нейросетей очень хочется растянуть и на инфраструктуру, и на эксплуатацию, чтобы получить крутой AI Ops.</p><p>Нейросеть будет находить протухшие сертификаты внутри инфраструктуры, работать инструментом для early warning, подсвечивать риски.Кажется, что все инструменты для этого есть уже сейчас. Надо только, чтобы кто-то сложил этот пазл в рабочее решение.</p><p>Есть прототипы — например, Big Panda или Moocsoft (который был недавно куплен Dell), но пока это точечные решения. Возможно, на горизонте 5–7 лет (скорее 5, чем 10) они станут серьезной частью индустрии и очень мощным прорывом, который упростит разработчикам жизнь.Кроме того, важно, чтобы развивались и более «приземленные» технологии: инструменты контейнеризации, оркестрации, observability, а также APM — Application Performance Monitoring.</p><h3>Инженер остается в центре всего</h3><p>Никакие микросервисы, Kubernetes и AI Ops не спасут, если за системой не стоит инженер, который думает головой, правильно работает руками и отвечает за результат. Важны его навыки, кругозор и культура работы. Именно такие люди превращают набор сервисов в работающий продукт. Все остальное — только инструменты.</p><p>P. S. Если интересно, как мы решаем эти задачи на практике, <a href="https://technologichno.mave.digital/">слушайте </a>(и <a href="https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fvkvideo.ru%2Fvideo-145457488_456239831&amp;postId=1982175">смотрите</a>) наш подкаст «Техно.Логично» — там регулярно обсуждаем самое актуальное в IT-сфере.</p>]]></content:encoded>
    </item>
    <item>
      <title>5 инструментов, которые используют айтишные команды</title>
      <link>https://tproger.ru/articles/5-instrumentov--kotorye-ispolzuyut-ajtiwnye-komandy</link>
      <comments>https://tproger.ru/articles/5-instrumentov--kotorye-ispolzuyut-ajtiwnye-komandy?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Анна Ельцова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/5-instrumentov--kotorye-ispolzuyut-ajtiwnye-komandy</guid>
      <description><![CDATA[<p>Показываем, какими инструментами пользуются внутри айтишных команд и какие можно использовать для себя здесь и сейчас или внедрить в свою команду.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/5-instrumentov--kotorye-ispolzuyut-ajtiwnye-komandy">5 инструментов, которые используют айтишные команды</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Статистика]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[Отладка]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Windows]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Ruby on Rails]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Adobe]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Маркетинг]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Аналитика]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Grafana]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 26 Jun 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>В статье собрали 5 решений — от трекеров задач и онлайн-досок до комплексных платформ для управления проектами. Инструменты помогут закрывать горящие дедлайны, ускорять разработку и четко распределять задачи — все то, что используют в больших командах. Рассказываем, что делать с этими фичами и как их использовать.</p><h2>1. МояДоска</h2><p><a href="https://moyadoska.com/">«МояДоска»</a> — это российский SaaS-сервис для совместной работы и визуализации идей. У онлайн-доски бесконечный размер: это значит, что вы можете размещать сколько угодно элементов и никогда не упретесь в границу. Так, команды, преподаватели и креативные специалисты могут проводить брейнштормы, планирования, презентации и обучение в одном пространстве.</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-06-26/4fe2215f-6b29-4d0c-a490-281b2d045ddc.jpeg" alt="" /></figure><h3>Что под капотом</h3><p>Фронт написан на React + PixiJS, а бэк — Node.js + PostgreSQL. Это обеспечивает быстрый и понятный интерфейс и стабильную работу даже при большом объёме объектов на доске. Команда выпускает обновления несколько раз в месяц, а о новинках можно узнать в <a href="https://t.me/moyadoska">Telegram-канале</a> сервиса. Например, в недавнем апдейте появилась возможность превратить фрейм в таблицу или тетрадь за пару кликов, а еще задать нужное число столбцов, колонок, толщину границ и цвет.</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-06-26/0f1a8489-ffe3-4003-8ecc-09d25bbba3b3.png" alt="" /></figure><p><b>Из главных функций:</b></p><ul><li>Понятный интерфейс</li><li>Совместная работа в реальном времени</li><li>Привычные инструменты: фигуры, стрелки, стикеры, текст, загрузка файлов, маркер, карандаш</li><li>Обрезка фото прямо на доске, воспроизведение аудио, поддержка PDF</li><li>Гибкое управление доступом</li><li>Возможность повторного использования шаблонов</li><li>Поддержка фреймов и создание логичных пространств для разных задач</li></ul><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-06-26/21a6ecbd-a6b5-40c9-ae19-71a85b919c46.png" alt="" /></figure><h3>Переезд на сервис</h3><p>«МояДоска» интегрируется в процессы на разных этапах, упрощая жизнь команде. Например, сама команда сервиса перешла с Miro на свою доску для стратегического планирования. С помощью стикеров и стрелок они построили дерево решений, чтобы лучше расставить приоритеты. А одно маркетинговое агентство перевело все документы и сессии планирования на доску, отказавшись от Google Docs и таблиц. Это ускорило принятие решений: сотрудники работали с данными в одном формате, точно собрались в одном кабинете перед маркерной доской.</p><h2>2. METEOR</h2><p><a href="https://u-meteor.ru">METEOR</a> — инструмент управления проектами. Это трекер задач с дашбордами, досками канбан, диаграммами Ганта и API, который работает в виде веб-приложения как в облаке, так и на своих серверах. Продукт создавался как универсальный центр управления задачами: он объединяет в себе все — от разработки и тестирования до маркетинга и поддержки. Сейчас его используют более 250 команд и свыше 2000 пользователей ежедневно.</p><h3>Что под капотом</h3><p>В основе — стек Ruby on Rails, React и TypeScript, PostgreSQL и Redis, плюс современная инфраструктура на Docker и Kubernetes.</p><p>Система разбита на микросервисы — за фоновую обработку, нотификации и работу с файлами отвечает отдельный функционал. Авторизация построена через OAuth 2.0 (Google, Yandex), а для аналитики используется Posthog и ELK-стек. Мониторинг реализован на Prometheus + Grafana. Обновления выходят каждую неделю, а обратная связь приходит разработчикам METEOR через Telegram-бот.</p><p><b>Вот главные функции:</b></p><ul><li>Гибкие доски задач (Kanban, Scrum) — 6 видов.</li><li>Списки задач с группировками и иерархией.</li><li>Автоматические отчеты (ежедневные/еженедельные сводки).</li><li>Умные напоминания (Telegram-бот, email).</li><li>Глубокая аналитика (время выполнения задач, загрузка команды).</li><li>Потоковая автоматизация процессов</li></ul><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-06-26/60e0eb0a-c1b1-473b-b343-1c4fb1b3fbd6.png" alt="" /><figcaption>Упрощенная схема сущностей системы</figcaption></figure><p>METEOR — мощный инструмент для автоматизации процессов, с триггерами, серверными функциями и ИИ-аналитикой. Он позволяет гибко настраивать сложные операции.</p><p>Все данные анализируются, и внутри самого сервиса можно понять, как работает команда: кто загружен, сколько времени уходит на задачи, где стопперы в процессе.</p><p>Разработчики используют METEOR для линковки задач с pull-requests и контроля бэклога. Менеджеры получают отчеты автоматически и не тратят часы, чтобы собрать всю информацию вручную. QA ведут тест-кейсы и баги в удобных досках, а DevOps отслеживают инциденты и шаги деплоя. Даже HR подключаются — через систему проходят кандидаты и стажеры.</p><h3>Переезд на сервис</h3><p>После внедрения METEOR команды замечают, что продуктивность их работы сильно повышается:</p><ul><li>скорость выполнения задач увеличивается в среднем на 25% — благодаря автоматическим напоминаниям и чётким процессам;</li><li>количество потерянных задач снижается на 70% — исчезают хаотичные чаты и забытые письма;</li><li>на составление отчетов и сбор метрик уходит не 5 часов, а всего 30 минут в неделю;</li><li>а экономия времени — около 75 часов в месяц на команду из 10 человек.</li></ul><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-06-26/f3f086f0-5846-4a35-adba-dc4fbe17f1c0.png" alt="" /><figcaption>Карточка задачи</figcaption></figure><p>METEOR не просто помогает контролировать задачи — он становится частью операционного «ядра» команды, избавляя от хаоса, ускоряя работу и делая все немного спокойнее.</p><h2>3. Gitlife</h2><p><a href="https://gitlife.ru">GitLife</a> — это универсальная платформа для хостинга репозиториев и построения полного DevOps-процесса внутри компании. Разработана с прицелом на закрытые контуры, импортозамещение и гибкость — подходит как для современных Git-проектов, так и для инфраструктур, где все еще используется SVN.</p><p>Помимо самого Gitlife, разработчики делают Gitlife AI, в котором есть доступ к топовым ИИ-моделям и инструментам, чтобы разрабатывать ИИ-решения.</p><h3>Что под капотом</h3><p>Внутри Gitlife собраны модули для:</p><ul><li>Кода — репозитории, ветвление.</li><li>Задач — бэклоги, спринты, дашборды.</li><li>Документации — совместное редактирование документов, управление правами.</li><li>Аналитики — карты потока ценности, качество кода, метрики по инженерам.</li><li>Пайплайны — модуль «Конвейер» управляет сборками и CI/CD.</li></ul><p>Gitlife используется ИТ-отделами и R&amp;D-подразделениями в компаниях с высокими требованиями к информационной безопасности. Подходит как для небольших команд, так и для распределённых корпораций с десятками проектов.</p><p>Что решает:</p><ul><li>Безопасный и полностью локальный хостинг исходного кода (Git + SVN)</li><li>Управление задачами и CI/CD в одном месте</li><li>Централизованный доступ, права, аудиты и история изменений</li><li>Полная поддержка DevOps-процессов на российском ПО</li><li>Альтернатива GitHub, GitLab и Bitbucket в условиях ограниченного доступа и санкционных рисков</li></ul><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-06-26/bb3f815f-ce07-4c9d-9243-7ace4b14d5ba.png" alt="" /><figcaption>Создание пайплайна</figcaption></figure><h3>Переезд на сервис</h3><p>Инструмент подходит практически всем командам — от инди-разработчиков до крупных проектов с множеством ролей. Например, гейм-девелопер может разрабатывать персональный проект и хранить код бесплатно, стартап — разрабатывать MVP, а крупный бизнес — управлять большими командами и проектами максимально безопасно.</p><h2>4. Cerebro</h2><p><a href="https://cerebrohq.com/ru/">Cerebro</a> — профессиональная система для совместной работы и управления проектами. Она помогает ставить задачи, планировать этапы, следить за выполнением, обмениваться файлами и комментировать их прямо в системе. Особенно полезна для команд, которые делают VFX, 3D, анимацию или дизайн — но при этом легко адаптируется и под другие команды.</p><p>Платформа охватывает полный цикл — от первых идей и планирования до комментирования финальных шотов (отдельных сцен или кадров в видео/анимации) и соблюдения дедлайнов. Такой подход помогает команде ускорить работу на 20%, сократить время на правки и держать весь процесс под контролем — от начала до сдачи проекта.</p><p>Cerebro подходит для команд от 1 до 1000+ человек с задачами на проекте от 1 до 10000+. Сервис работает с 2009 года, сейчас им пользуются более 400 команд в России и СНГ.</p><h3>Что под капотом</h3><p>Cerebro поддерживает десктоп (Windows, Mac и Linux), веб-версию и мобильное приложение, локальное, облачное и гибридное развертывание. Инструмент построен на клиент-серверной архитектуре — она гибкая, поэтому можно настраивать конфиги исходя из потребностей бизнеса.</p><p>Из технологий:</p><ul><li><b>Backend:</b> C, C++, Python, SQL</li><li><b>Frontend:</b> JS, TypeScript, ReactJS, Qt, PyQt</li><li><b>Мобильные клиенты:</b> React Native</li><li><b>БД: </b>PostgreSQL с проприетарными расширениями + SQLite</li><li><b>Файловое хранилище:</b> Cargador</li><li><b>Плагины: </b>Tentaculo (встраивается в производственные программы)</li></ul><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-06-26/d51c709f-2b9c-4e0b-95c0-2b78d61f5c1e.png" alt="" /></figure><p>Cerebro покрывает весь пайплайн — от идеи до финала. Вот основные возможности сервиса:</p><ul><li>Множественные уровни вложенности задач — подходит для сложных иерархий продакшена</li><li>Планирование с помощью диаграммы Ганта и специального инструмента «План»</li><li>Канбан-доска для визуального контроля задач</li><li>Инструмент «Моё пространство» — для персонализированной фильтрации и отбора задач</li><li>Уровни доступа и ролевое управление</li><li>Расширенная статистика по проектам, командам, сотрудникам</li><li>Совместная работа над большими файлами (видео, изображения, 3D) — Mirada позволяет комментировать, делать подрисовки, оставлять голосовые заметки</li><li>Интеграция с пакетами Adobe, Autodesk и мессенджерами, возможность встраивать в любые пайплайны</li><li>Удобное подключение фрилансеров</li></ul><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-06-26/5411ad9d-a74b-46ed-9774-61d60ff69885.png" alt="" /><figcaption>Навигатор и форум</figcaption></figure><h3>Переезд на сервис</h3><p>Обычно внедрение начинается еще на этапе препродакшена — во время разработки концепции и четкого плана действий. Затем система сопровождает проект на всех стадиях, вплоть до постпродакшена (финального тестирования и релиза), где она закрывает 80-100% задач. Cerebro позволяет собирать всё в одном месте: задачи, правки, сроки, бюджеты, загрузку сотрудников и статус проекта в целом.</p><p>После переезда снимается много рутинных задач: больше не нужно вручную назначать исполнителей, комментировать медиаконтент, передавать файлы между программами и так далее. В среднем проекты выполняются на 20% быстрее, без потери качества. В больших студиях объем выпускаемых шотов может вырасти до 20+ тысяч — это уже работает у других клиентов, среди которых СберМаркетинг, Sinners, Black Point и другие. Cerebro также помогает переехать с других такс-трекеров и систем для управления проектами.</p><h2>5. Replit Teams</h2><p><a href="https://replit.com/teams">Replit Teams</a> — это платформа для совместной разработки в реальном времени. По сути, это интегрированная IDE + git-репозиторий + система управления задачами — и все доступно через браузер. Подходит как для командной работы в стартапах, так и для образовательных проектов, хакатонов и небольших продуктовых команд.</p><p>А главная фишка — встроенный ИИ, к которому можно обращаться прямо во время написания кода. Инструмент разработан с акцентом на простоту входа, командную работу и быстрое прототипирование. Поддерживает более 50 языков программирования и позволяет запускать полноценные веб-приложения в облаке.</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-06-26/70b00e25-9ec7-4858-911c-b2d7a181104e.png" alt="" /></figure><h3>Что под капотом</h3><p>Внутри Replit Teams есть интерфейсы для:</p><ul><li>Кода — редактор с автокомплитом, подсветкой синтаксиса, терминалом и интеграцией с Git.</li><li>Задач — встроенный таск-менеджер с распределением задач по участникам.</li><li>Общения — встроенные комментарии в коде, возможность ревью и обсуждений.</li><li>CI/DevOps — запуск и отладка приложений без настройки окружения.</li><li>Доступа — гибкие роли, приглашения по ссылке, настройки приватности.</li></ul><h3>Переезд на сервис</h3><p>Replit Teams позволяет моментально начать работу: не нужно ставить зависимости, конфигурировать CI или закупать сервера. Подходит как для быстрой прокачки навыков, так и для реальных командных проектов в продакшене.</p><p>Сейчас инструмент активно используют в стартапах — для быстрого MVP, парного программирования, хакатонов и удаленных командах — как замена локальным IDE и конфигурациям.</p><p>Рассказывайте в комментариях, какими сервисами пользуетесь вы.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как мы строим агрегатор финансовых продуктов в Казахстане: история Finance.kz</title>
      <link>https://tproger.ru/articles/kak-my-stroim-agregator-finansovyh-produktov-v-kazahstane--istoriya-finance-kz</link>
      <comments>https://tproger.ru/articles/kak-my-stroim-agregator-finansovyh-produktov-v-kazahstane--istoriya-finance-kz?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Жандос Байдильденов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-my-stroim-agregator-finansovyh-produktov-v-kazahstane--istoriya-finance-kz</guid>
      <description><![CDATA[<p>Как из обычного сайта-витрины вырастить финтех-продукт? Расскажу, как строится агрегатор финансовых продуктов в Казахстане.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-my-stroim-agregator-finansovyh-produktov-v-kazahstane--istoriya-finance-kz">Как мы строим агрегатор финансовых продуктов в Казахстане: история Finance.kz</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[SEO]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Финтех]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Техподдержка]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Дизайн]]></category>
      <category><![CDATA[Машин]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 22 Jun 2025 09:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Я — Жандос, руководитель проекта <a href="https://finance.kz">Finance.kz</a>. Последний год активно развиваем агрегатор финансовых продуктов в Казахстане, и за это время рынок изменился кардинально. Хочу поделиться опытом создания финтех-решения с нуля и рассказать, как мы конкурируем с зарубежными игроками за счёт глубокой локализации.</p><h2>Откуда началось: мой путь в финтех</h2><p>До Finance.kz я работал в казахстанских финтех-проектах — bai.kz и finbee.kz. Там понял, что рынок агрегаторов в Казахстане находится в зачаточном состоянии. Пользователи мучились, сравнивая предложения банков вручную, а сами финансовые организации не умели эффективно работать с цифровыми каналами привлечения клиентов.</p><p>Finance.kz существовал уже более 3 лет, но работал как классический сайт-витрина. Когда я пришёл в проект год назад, стало ясно: нужно полностью переосмыслить подход и создать технологическое решение нового поколения.</p><h2>Состояние рынка: от монополии к жёсткой конкуренции</h2><p>Казахстанский рынок агрегаторов финансовых продуктов переживает бум. Ещё два года назад здесь было 2-3 локальных игрока с простейшим функционалом. Сегодня ситуация кардинально изменилась — зашли зарубежные команды: vbr.kz, fintree.kz, moneypanda.com и другие.</p><p>Эти компании привозят готовые решения, которые хорошо работали в России или других рынках. На первый взгляд их продукты выглядят более зрелыми — красивые интерфейсы, отработанные воронки конверсии. Но у импортных решений есть критический недостаток: они плохо адаптированы под специфику казахстанского рынка.</p><h2>Технологические вызовы: интеграция с госсервисами и банками</h2><p>Главная боль при разработке агрегатора в Казахстане — это интеграции. В отличие от рынков СНГ, здесь нельзя обойтись простым партнёрским трафиком. Пользователи хотят получить продукт онлайн, полностью, без походов в офисы.</p><h3>API-интеграции с банками и МФО</h3><p>За год мы реализовали прямые API-интеграции с крупнейшими игроками рынка. Это означает, что пользователь может не просто сравнить условия кредитов, но и подать заявку, пройти скоринг и получить одобрение, не покидая наш сайт.</p><p>Техническая сложность — в разнородности API. Каждый банк использует собственные протоколы, форматы данных и методы аутентификации. Пришлось создать унифицированный слой-адаптер, который «переводит» наши запросы в формат, понятный конкретной финансовой организации.</p><h3>Интеграция с госорганами</h3><p>Finance.kz интегрируется с государственными сервисами eGov и Палаты предпринимателей (ПКБ). Это позволяет автоматически подтягивать справки о доходах, данные о трудоустройстве и другие документы, необходимые для получения кредита.</p><p>Работа с госAPI — отдельная история. Протоколы меняются, документация часто устаревает, а техподдержка работает в режиме «как получится». Но результат того стоит: время оформления кредита сокращается с нескольких дней до 15-30 минут.</p><h2>Архитектура продукта: ставка на микросервисы</h2><p>При проектировании архитектуры Finance.kz мы отказались от монолитного подхода в пользу микросервисов. Это решение диктовалось спецификой агрегатора — нам нужно было обеспечить высокую доступность при интеграции с десятками внешних систем.</p><h3>Backend</h3><p>Основные сервисы написаны на Node.js с использованием Express.js. Для работы с базами данных используем PostgreSQL для транзакционных данных и Redis для кэширования. Очереди сообщений реализованы через RabbitMQ — это критично для обработки заявок пользователей.</p><p>Отдельно выделили сервис интеграций, который отвечает за взаимодействие с внешними API. Он построен по принципу circuit breaker — если один из банков не отвечает, это не ломает работу всего агрегатора.</p><h3>Frontend</h3><p>Фронтенд построен на React с использованием Next.js для серверной отрисовки. Это важно для SEO — львиная доля трафика приходит из поисковых систем по запросам типа «кредит онлайн».</p><h2>Стратегия «единого окна»: от поиска до получения</h2><p>Наша главная идея — превратить агрегатор из витрины в полноценный финтех-сервис. Пользователь должен получить продукт полностью онлайн: от сравнения условий до перечисления денег на карту.</p><p>Для этого мы реализовали несколько ключевых функций:</p><ul><li>Умный подбор продуктов на основе данных пользователя и машинного обучения</li><li>Предварительный скоринг для оценки вероятности одобрения ещё до подачи заявки</li><li>Автоматическое заполнение анкет с подтягиванием данных из госсервисов</li><li>Отслеживание статуса заявки в реальном времени</li></ul><h2>Монетизация: CPS как основа устойчивого бизнеса</h2><p>Мы работаем по модели CPS (Cost Per Sale) — получаем комиссию только за успешно выданные продукты. Для кредитов это 2% от суммы, для микрозаймов — фиксированная сумма от 7 до 15 тысяч тенге.</p><p>Такая модель выгодна всем участникам: банки платят только за результат, пользователи получают продукт бесплатно, а мы мотивированы повышать качество трафика и конверсию.</p><h2>Конкурентные преимущества: локализация против красивых интерфейсов</h2><p>Главное отличие Finance.kz от зарубежных конкурентов — интеграция в казахстанскую финтех-экосистему. Пока они тратят месяцы на адаптацию готовых решений, мы изначально строили продукт под местную специфику.</p><h3>Что даёт локальный подход:</h3><ul><li>Знание рынка: мы понимаем особенности работы казахстанских банков и МФО</li><li>Связи с регуляторами: легче договариваться об интеграциях с госорганами</li><li>Техническая экспертиза: наша команда уже прошла путь интеграции с местными API</li><li>Гибкая настройка продукта под изменения законодательства и требований ЦБ</li></ul><h3>Результаты и метрики</h3><p>За год активного развития мы достигли:</p><ul><li>150 000 уникальных пользователей в месяц</li><li>Интеграция с 15+ финансовыми организациями</li><li>Конверсия заявка-выдача на уровне 35-40% (против 15-20% у конкурентов)</li><li>Средний чек по кредитам — 1,2 млн тенге, по микрозаймам — 85 тысяч</li></ul><h2>Планы на будущее: от агрегатора к экосистеме</h2><p>Ближайшие 1-2 года будут критичными для всего рынка. Мы видим несколько ключевых направлений развития:</p><h3>Расширение продуктовой линейки</h3><p>Планируем добавить страхование, депозиты и инвестиционные продукты. Цель — стать единой точкой входа для всех финансовых потребностей пользователя.</p><h3>Внедрение ИИ и машинного обучения</h3><p>Работаем над персонализацией предложений и предиктивной аналитикой. Хотим научиться предлагать продукты до того, как пользователь их осознанно найдет.</p><h3>Международная экспансия</h3><p>Рассматриваем возможность выхода на рынки Узбекистана и Кыргызстана. Наша технологическая платформа легко масштабируется на соседние рынки.</p><h3>Собственные финансовые продукты</h3><p>В долгосрочной перспективе планируем получить лицензию МФО и предлагать собственные займы наиболее качественным клиентам.</p><h2>Уроки и выводы</h2><p>Главный урок последнего года: в финтехе побеждает не тот, у кого красивее интерфейс, а тот, кто лучше решает реальные проблемы пользователей. Красивый дизайн можно скопировать за месяц, а на создание качественной технологической интеграции уходят годы.</p><p>Второй важный момент — команда решает всё. Мы собрали людей, которые понимают как технологии, так и специфику финансового рынка. Это даёт нам фору перед конкурентами, которые пытаются адаптировать готовые решения силами удалённых команд.</p><p>Рынок агрегаторов в Казахстане только формируется, и впереди ещё много интересных вызовов. Уверен, что следующие два года покажут, кто готов строить долгосрочный бизнес, а кто просто пытается заработать на хайпе.</p>]]></content:encoded>
    </item>
    <item>
      <title>Почему ваше приложение тормозит: архитектурные bottlenecks, которые никто не замечает</title>
      <link>https://tproger.ru/articles/pochemu-vawe-prilozhenie-tormozit--arhitekturnye-bottlenecks--kotorye-nikto-ne-zamechaet</link>
      <comments>https://tproger.ru/articles/pochemu-vawe-prilozhenie-tormozit--arhitekturnye-bottlenecks--kotorye-nikto-ne-zamechaet?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/pochemu-vawe-prilozhenie-tormozit--arhitekturnye-bottlenecks--kotorye-nikto-ne-zamechaet</guid>
      <description><![CDATA[<p>Как найти и устранить архитектурные bottleneck'и: причины тормозов, типовые ошибки и пошаговая методика диагностики.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/pochemu-vawe-prilozhenie-tormozit--arhitekturnye-bottlenecks--kotorye-nikto-ne-zamechaet">Почему ваше приложение тормозит: архитектурные bottlenecks, которые никто не замечает</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Аналитика]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Дата-центр]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[OpenTelemetry]]></category>
      <category><![CDATA[Тимлид]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 19 Jun 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Ваше приложение тормозит, хотя сервер мощный, код вроде нормальный, а метрики — не очень-то и загружены? Возможно, вы столкнулись с архитектурным bottleneck'ом — скрытым ограничением, которое убивает производительность под нагрузкой. Вместе с Никитой Ульшиным, тимлидом команды разработки архитектурных инструментов в Т-Банк и автором тг-каналов <a href="https://t.me/ulshinblog">Никита Ульшин про IT</a> и <a href="https://t.me/tech_fit">ТехнофITнес | Никита Ульшин</a>, разбираем типовые узкие места в системах, от неэффективной аллокации до однопоточных участков, и показываем пошаговый подход к их поиску и устранению.</p><h2>Почему «тормоза» — это не всегда про код</h2><p>Когда пользователь жалуется на «медленное приложение», большинство разработчиков по привычке лезет в код. Профилируем, ищем неэффективные циклы, оптимизируем до запятых. Но в реальности причина часто не в логике, а в том, что её окружает.</p><p>Современное приложение — это сложный организм: десятки микросервисов, базы данных, кэши, брокеры, сети. И тормозить может любой из этих компонентов. А ты в это время профилируешь ни в чём не виноватый for.</p><p>Вот что тормозит, когда код ни при чём:</p><p><b>Архитектура</b></p><ul><li>Цепочки вызовов: каждый хоп — +latency.</li><li>Синхронные зависимости: завис один сервис — тормозят все.</li><li>Общие ресурсы: shared state, глобальные очереди, блокировки.</li></ul><p><b>Базы данных</b></p><ul><li>Нет индексов или плохой план запроса.</li><li>N+1-запросы — особенно при неосторожной ORM.</li><li>Частый доступ к одним таблицам — гонка за IO и блоки.</li><li>Нет шардинга или репликации в масштабируемой нагрузке.</li></ul><p><b>Сеть</b></p><ul><li>Высокая задержка между регионами (особенно multi-cloud).</li><li>Потери пакетов, DNS-проблемы, нестабильность.</li><li>Отсутствие connection reuse: TLS-handshake на каждый вызов.</li></ul><p><b>Очереди и брокеры</b></p><ul><li>Один медленный потребитель тормозит всех.</li><li>Нет защиты от от backpressure или дедупликации.</li><li>Неправильные batch- и ack-настройки.</li></ul><p><b>Аллокаторы и GC</b></p><ul><li>Фрагментация памяти, нагрузка на GC.</li><li>Финалайзеры, слабые ссылки, плохо настроенный heap.</li></ul><p><b>Конфигурации</b></p><ul><li>Маленький пул соединений — пул заканчивается, запросы ждут.</li><li>Агрессивные retry-политики — система перегружается.</li><li>CPU throttling в Kubernetes — контейнеру не хватает ресурсов.</li></ul><p><b>Сериализация и форматы</b></p><ul><li>Перегруженные JSON/Protobuf.</li><li>Вложенные base64 + gzip + JSON — боли сериализации.</li></ul><h3>Почему bottlenecks остаются невидимыми до продакшена</h3><p>Многие из них —  не баги, а последствия архитектурных решений. В дев-среде всё летает, потому что:</p><ul><li>мало данных,</li><li>нет конкуренции за ресурсы,</li><li>нет распределённой нагрузки.</li></ul><p>В проде начинается хаос. Рассмотрим на конкретных примерах:</p><ul><li>На деве — 2 запроса в секунду, в проде — миллион. Кто-то запустил маркетинговую рассылку, аналитик тащит big report, а клиент ретраит ошибки.</li><li>Архитектура «в лоб»: всё синхронно, каждый сервис вызывает по цепочке десяток других. Пока нагрузка мала — все живет. Как только одно звено не выдерживает — перестает жить.</li><li>Иллюзия масштабируемости: до 100 пользователей —  всё окей, на 1000 — каскадная деградация.</li><li>«Невидимая боль» между сервисами: каждый по отдельности быстрый, но блокирует друг друга на базе.</li></ul><h2>Слои архитектуры и где в них зарыты проблемы</h2><p>Когда приложение тормозит, мы часто копаемся в отдельных компонентах — фронте, бэке, базе. Но bottleneck может быть не внутри компонента, а между ними: в конфигурации, связях, сетевых задержках, очередях вызовов.</p><p>Чтобы понять, где искать узкое место, нужно пройтись по всей цепочке — от клиента до внешних сервисов.</p><h3>На уровне клиента</h3><ul><li>Тяжёлые бандлы. Огромный JS, куча аналитики, трекеры — и вот страница загружается 8 секунд на старом телефоне.</li></ul><ul><li>Чрезмерные запросы. После загрузки — 10 fetch в секунду. API захлёбывается, браузер — тоже.</li></ul><ul><li>Нет кеша. Даже статичные справочники каждый раз грузятся заново.</li></ul><ul><li>Лаги рендеринга. Бэкенд дал ответ за 100ms, но интерфейс лагает — сложные таблицы, графики, reflow.</li></ul><h3>На уровне API Gateway / BFF</h3><ul><li>Непрозрачная маршрутизация —  скрытые таймауты, ошибки ретраев.</li><li>Сборка ответов из микросервисов — цепочка из 5 вызовов на каждый клиентский запрос.</li><li>Синхронные вызовы без деградации — если один микросервис недоступен, падает весь endpoint.</li></ul><h3>На уровне Backend / бизнес-логики</h3><ul><li>Цепочки вызовов. Один сервис вызывает другой, тот — ещё один… И так далее.</li><li>Ограниченный пул соединений —  сервис готов работать, но все worker-ы ждут ресурсы.</li><li>Логика в цикле по данным —  N+1-запросы, сериализация, дублирование работы.</li></ul><h3>На уровне базы данных / кэша</h3><ul><li>Full table scan. Работает быстро на 1000 строках. Умирает на 10 миллионах.</li></ul><ul><li>Локи и гонка за ресурсы. Один UPDATE лочит строку, остальные ждут.</li></ul><ul><li>Кэш не промахивается, но и не помогает —  stale данные, повторные чтения, инвалидация не работают, как ожидалось.</li></ul><p><b>На уровне внешних сервисов (API, брокеры, платёжки)</b></p><ul><li>Без timeout и fallback. Внешний API залип — вы вместе с ним.</li><li>QPS-лимиты. Вы не знали, а вас уже зарейт-лимитили.</li><li>Нестабильная сеть. DNS тормозит, соединения рвутся, задержки скачут между регионами.</li></ul><p>Оптимизация кода важна. Но если система тормозит, искать нужно по всей цепочке —  от кнопки на фронте до брокера в соседнем дата-центре.</p><blockquote>Есть архитектурные паттерны риска, которые часто приводят к тормозам через полгода. Во-первых, общий ресурс на всех: один Redis, один Kafka-топик, одна таблица. Пока нагрузка маленькая — ок. Потом начинается бойня за доступ. Во-вторых, микросервисный монолит: формально разделены, но живут как один. Масштабировать невозможно. В-третьих, цепочки вызовов: 5–6 сервисов на путь одного запроса. Один подвис — и вся цепочка тормозит.</blockquote><h2>Базы данных: когда даже SELECT тормозит всё</h2><p>В бэкенде одна из самых коварных фраз — «ну это же просто SELECT, что с ним будет». Ответ — сначала ничего. Но со временем появляется 10 миллионов строк, и ваш innocuous SELECT превращается в full scan, который лочит диск, ест CPU и тормозит всё, что движется.</p><p>Типичная ситуация: в таблицу пишут JSONB без нормализации и индексов. Пока строк мало — жить можно. Но при росте объёмов каждый запрос превращается в медленное последовательное чтение. Это не просто «долго», а начинает мешать соседним транзакциям: подгружаются stale данные, вытесняется кэш, система начинает проседать вся — вплоть до API.</p><p>Отдельная ловушка — смешение OLTP и OLAP нагрузки. Днём — INSERT и UPDATE от клиентов, ночью — фоновая аналитика, высчитывающая отчёт за год с десятком JOIN и чтением всей таблицы. Если все запросы идут в один инстанс, происходит конкуренция за ресурсы: аналитика сбивает кеш, вызывает блокировки, а продакшн-метрики начинают сыпаться.</p><h3>Как понять, что тормоза идут из базы, а не из бэкенда?</h3><p>Вот несколько типичных признаков:</p><ul><li>Бэкенд «висит» на запросах к базе — в логах видно, что приложение ждёт результат запроса (долгий await, query(), findMany() и т. д.).</li></ul><ul><li>Latency растёт, а CPU и память в норме — сервис сам по себе не перегружен, но ответ приходит медленно.</li></ul><ul><li>В базе фиксируются медленные запросы — например, SELECT или JOIN занимают секунды, хотя раньше проходили за миллисекунды.</li></ul><p>Чтобы подтвердить гипотезу, можно:</p><ul><li>Включить логирование SQL-запросов с таймингом;</li><li>Посмотреть трейс: если шаг DB заметно длиннее остальных — это тревожный сигнал;</li><li>Запустить EXPLAIN ANALYZE на типовые запросы и проверить, где зарыта сложность.</li></ul><h3>Архитектура доступа к данным: как закладываются тормоза</h3><p>Архитектура доступа к данным — фундамент, на котором держится производительность всей системы. Даже идеальный алгоритм или быстрый backend не спасут, если данные извлекаются медленно, неэффективно или избыточно.</p><p>На что здесь стоит обратить внимание:</p><ul><li><b>Количество и характер обращений. </b>Один пользовательский запрос не должен порождать десятки обращений к базе. Планирование кэшей, агрегаций, prefetch, нормализация — всё это часть архитектуры.</li><li><b>Уровень абстракции над данными.</b> ORM может быть удобным, но часто скрывает десятки неэффективных SELECT’ов. Нужно понимать, какие запросы реально идут в базу, и не превращать каждый use case в потенциальный bottleneck.</li><li><b>Стратегия хранения и агрегаций.</b> Если вы пытаетесь на лету агрегировать 100 миллионов строк без шардинга и партиционирования — тормоза неизбежны. Архитектура должна учитывать нагрузку, частоту агрегаций, структуру данных.</li></ul><h2>Очереди и событийные системы: скрытые замедления</h2><p>Событийные архитектуры и очереди вроде Kafka или RabbitMQ часто воспринимаются как универсальное средство от всех проблем: «Сделаем асинхронно — и всё полетит». Но это не серебряная пуля. Очередь не решает проблему — она её откладывает. А иногда сама становится bottleneck’ом.</p><p>Типовые ситуации, когда очередь тормозит систему:</p><ul><li><b>Медленные консьюмеры.</b> Очередь принимает сообщения с высокой скоростью, но обработчики не успевают, и начинается накопление беклога. В результате задержки накапливаются, SLA летит, а вы только недоумеваете, почему всё так тормозит.</li><li><b>Неправильный размер batch’ей.</b> В Kafka и аналогах размер и частота batch'ей критичны. Слишком большие — ждём, пока соберётся партия. Слишком маленькие — тратим ресурсы на лишнюю загрузку и пересылку. В итоге получаем либо высокую задержку, либо низкую производительность.</li><li><b>Неравномерное партиционирование</b>. Если сообщения распределяются по партициям неравномерно, то часть узлов будет простаивать, а часть захлёбываться под нагрузкой. Одна горячая партиция может стать bottleneck’ом всей системы.</li><li><b>Проблемы с retry.</b> Если нет чёткой стратегии повторных попыток, логирования и DLQ (dead-letter queue), битое событие может крутиться в системе бесконечно, тормозя всё остальное. Также если что-то пошло не так и включились retry-механизмы, задержка может вырасти в разы. Особенно если есть backoff или дедлоки.</li></ul><h3>Почему «асинхронно» ≠ «мгновенно»</h3><p>Асинхронность — это не про скорость, а про отложенность. Событие отправлено — но когда оно будет обработано, никто не знает. Через секунду, через минуту, через час?</p><p>Типичные причины задержек в асинхронной обработке:</p><ul><li>Очередь перегружена, и событие просто стоит в хвосте.</li><li>Обработчик падает или рестартится, и событие ждёт.</li><li>Политики повторной обработки не настроены — событие крутится бесконечно.</li><li>Слишком много этапов внутри одного воркера: валидация, запись в БД, вызов API — всё это задержки, которые суммируются.</li></ul><h3>Что происходит, когда очередь переполнена — и почему это тяжело заметить</h3><p>Когда очередь переполняется, события в ней начинают задерживаться или теряться, в зависимости от конфигурации. Но хуже всего то, что это происходит тихо. Формально система работает: события принимаются, воркеры их обрабатывают. Но обработка начинает всё сильнее и сильнее отставать.</p><p>Очередь продолжает принимать события, но обрабатываются они с огромным отставанием. Новое сообщение встаёт в хвост и ждёт своей очереди десятки секунд или минут. Такую ситуацию легко не заметить, если у вас не настроен грамотный мониторинг.</p><p>Для защиты от переполнения очереди нужно мониторить несколько важных показателей:</p><ul><li>Глубина очереди (в Kafka — consumer lag, в RabbitMQ — queue.messages_ready или queue.messages): показывает, сколько сообщений накопилось и ждёт обработки.</li><li>Publish rate: сколько сообщений в секунду публикуется.</li><li>Processing rate: сколько сообщений в секунду обрабатывается.</li><li>Утилизация ресурсов воркеров (CPU, memory, I/O).</li><li>End-to-end latency: сколько времени проходит от публикации события до его обработки.</li></ul><blockquote>Есть самые частые причины накопления сообщений:<br /><br />1) Медленные потребители, которые не успевают обработать весь поток сообщений. <br />2) Шумная архитектура: 10 сообщений там, где можно было обойтись и одним. <br />3) Неправильное масштабирование брокера (например, неправильно выбранный ключ партиционирования в Kafka).</blockquote><h2>API и микросервисы: где тормозит взаимодействие</h2><p>Микросервисная архитектура на бумаге выглядит идеально: каждый сервис автономен, команды независимы, масштабирование прозрачно. Но на практике все часто превращается в болото синхронных вызовов, где каждый сервис делает запросы в пять других.</p><h3>Что тормозит в микросервисах?</h3><p><b>Много лишних вызовов</b></p><p>Один пользовательский запрос вызывает лавину внутренних HTTP/gRPC-запросов. Каждый из них — это:</p><ul><li>сетевые задержки (latency),</li><li>сериализация/десериализация данных,</li><li>ретраи при сбоях,</li><li>риск таймаутов и обрывов.</li></ul><p>Если таких вызовов много, задержка накапливается каскадом.</p><p><b>Цепочка зависимостей</b></p><p>Классика жанра: заказ зависит от оплаты, оплата — от биллинга, биллинг — ещё от трёх микросервисов.</p><p>Если тормозит хотя бы один, сыплется всё. Получается эффект домино и каскадные отказы, где неполадка в одном звене рвёт всю цепочку.</p><p><b>Нет fallback'а и таймаутов</b></p><p>Если вызов к нужному сервису не отвечает, а у вас нет fallback'а или таймаута — всё встаёт. Особенно плохо, если вызов синхронный и блокирует поток.</p><p><b>Наносервисы</b></p><p>Иногда архитекторы увлекаются и дробят сервисы до абсурда. Начинается с «давайте переиспользуем», а заканчивается 10 API-вызовами ради одного действия.</p><p>Вместо бизнес-логики система начинает заниматься оркестрацией — координирует сама себя.</p><h2>Кэш и CDN: почему «ускорители» тоже могут тормозить</h2><p>Кэш традиционно считается палочкой-выручалочкой для производительности. «Добавим кэш — и всё полетит», — думают команды, особенно под нагрузкой. Но в реальности кэш может не только не ускорить, но и наоборот — замедлить или даже уронить систему, если использовать его без понимания.</p><p>Вот несколько типичных ошибок, которые приводят к деградации производительности:</p><h3>Невалидные или слишком агрессивные стратегии</h3><p>Если кэш живёт слишком долго — пользователи получают устаревшие данные. Если обновляется слишком часто — создаются лишняя нагрузка на базу и почти постоянные «промахи».</p><p>А если кэш сбрасывается при каждом изменении, он вообще не успевает выполнять свою роль.
В итоге: нестабильное поведение, непредсказуемая производительность и раздражённые пользователи.</p><h3>Перегрузка кэша</h3><p>Когда кэш настолько загружен, что сам по себе начинает тормозить — это уже не помощь, а вред. Такое часто случается с Redis, Memcached или in-memory решениями, особенно если они:</p><ul><li>работают на одной машине без шардинга;</li><li>содержат тяжёлые объекты;</li><li>используются как универсальный ответ на все проблемы.</li></ul><p>В таких случаях кэш из «ускорителя» может падать под нагрузкой быстрее, чем база данных.</p><h3>Кэш-миссы и лавины запросов</h3><p>Классическая проблема: TTL у популярных ключей истекает одновременно, и тысячи запросов идут мимо кэша в базу.
Это может случиться после деплоя, сброса кэша или при пиковой нагрузке.</p><p>Вместо одного запроса вы получаете 10 000, и тормозит всё. Особенно критично это для систем с CDN, где внезапное истечение кэша популярных страниц может вызвать DDoS-подобную нагрузку.</p><h3>Несогласованность кэшей</h3><p>Если в системе несколько уровней кэширования (CDN, фронтовый кэш, Redis) и они обновляются по-разному, возникает несогласованность. Один пользователь видит новые данные, другой — старые. Один сервис работает с актуальной версией, другой — с устаревшей. Начинается охота за фантомами: баги вроде есть, но не у всех.</p><h2>Вычисления и память: что не так с аллокацией</h2><p>Почему мощные сервера с десятками ядер и гигабайтами памяти тормозят? Потому что производительность упирается не в «железо», а в то, как именно это железо используется. От плохого управления памятью до блокирующих операций — в системе может быть множество узких мест, которые незаметно душат throughput.</p><h3>Частые и крупные аллокации</h3><p>Каждый раз, когда создаётся новый объект, память выделяется из кучи. При интенсивной работе (например, при парсинге JSON или обработке больших структур) это может происходить слишком часто, и тогда запускается сборщик мусора (GC).</p><p>Сборка мусора — это не бесплатная операция: она останавливает выполнение программы. Частые GC-паузы создают «плавающую» производительность, когда всё работает быстро, но время от времени подвисает даже на секунду.</p><h3>GC-паузы</h3><p>Автоматическое управление памятью — благо, но оно же и ловушка. В языках вроде Go, Java или Python невозможно точно контролировать, когда сработает сборщик. Даже задержка в 50 миллисекунд может ощутимо ударить по RPS или нарушить real-time обработку.</p><p>Некоторые компании придумывают обходные пути. Так, в Twitch <a href="https://blog.twitch.tv/en/2019/04/10/go-memory-ballast-how-i-learnt-to-stop-worrying-and-love-the-heap/">использовали</a> технику memory ballast для Go-приложений, чтобы стабилизировать поведение GC и избежать всплесков пауз.</p><h3>Синхронные и блокирующие операции</h3><p>Если операции с файлами, сетью или базой данных выполняются синхронно, поток блокируется — и в это время не может обрабатывать другие задачи. Это особенно критично, если такой поток обслуживает пользовательские запросы.</p><p>Классический пример — однопоточный web-сервер, который просто ждёт ответ от другой системы. Или библиотека, использующая mutex.Lock() в горячем участке, из-за чего десятки горутин встают в очередь.</p><h3>Ограниченные ресурсы и очереди</h3><p>Даже в многопоточном приложении можно легко создать узкое место. Например:</p><ul><li>доступ к объекту синхронизирован через mutex или RW-lock;</li></ul><ul><li>пул соединений имеет жёсткий лимит;</li></ul><ul><li>очередь задач не может масштабироваться под нагрузку.</li></ul><p>В таких случаях нагрузка растёт, а пропускная способность — нет. Всё упирается в искусственное ограничение, введённое «на всякий случай».</p><h3>Однопоточные горячие участки</h3><p>Даже в многопоточной архитектуре может оказаться, что 80% времени тратится в одном месте, которое не масштабируется — например, в процессе сериализации, расчёта или шифрования. Иногда этот участок реализован однопоточно (особенно в Node.js, Python или старом Go-коде) и становится главным тормозом системы. Под высокой нагрузкой это становится особенно заметно.</p><h2>Что делать: подход к поиску и устранению bottlenecks</h2><p>Когда система тормозит, возникает соблазн сразу «что-то сделать» — добавить кэш, увеличить ресурсы, ускорить базу. Но без системного подхода можно попасть в замкнутый круг, где проблема будет возвращаться снова и снова. Чтобы избежать этого, лучше использовать пошаговую стратегию: зафиксировать симптомы, локализовать проблему, подтвердить и только потом оптимизировать.</p><h3>Шаг 1. Зафиксировать симптомы и контекст</h3><p>Важно понять, что именно «тормозит» и в каких условиях. Типовые вопросы:</p><ul><li>Когда проявляется проблема: под нагрузкой, в пиковые часы, у конкретных пользователей?</li><li>Что именно работает медленно: API, отчёты, фоновая обработка?</li><li>Как это влияет на систему: задержки, таймауты, ошибки?</li></ul><p>Пример: пользователи жалуются, что отчёты стали строиться дольше. Вчера — 5 секунд, сегодня — 20.</p><h3>Шаг 2. Проверить очевидные метрики</h3><p>Начинаем с того, что уже доступно в мониторинге:</p><ul><li>латентность API (p50, p95, p99);</li><li>загрузка CPU, использование памяти и диска;</li><li>глубина очередей и backlog;</li><li>паузы GC;</li><li>кэш hit/miss ratio.</li></ul><p>Если латентность растёт, а CPU загружен на 20%, это может указывать на проблемы в синхронных вызовах, аллокации или неэффективной работе кэша.</p><h3>Шаг 3. Сузить область через трейсинг и логирование</h3><p>Чтобы выяснить, не «тормозит» ли другой сервис, используйте распределённый трейсинг (Jaeger, OpenTelemetry, Sentry Performance) или логирование таймингов внутри запроса.</p><p>Пример (Go, обёртка для http.RoundTripper):</p><p>Так можно увидеть, что, например, сторонний сервис отвечает 3 секунды, или Redis стал отдавать ответ за 300 мс вместо обычных 3 мс.</p><h3>Шаг 4. Воспроизвести нагрузку</h3><p>Если проблема зависит от объёма данных, воспроизведите реальный сценарий или нагрузку:</p><ul><li>используйте инструменты вроде k6, Locust, Artillery;</li><li>проверьте реальные условия (например, отчёт за 30 дней, а не за 3).</li></ul><p>Если латентность растёт нелинейно, это может быть признаком N+1-запросов, неоптимального SQL или проблем с аллокацией.</p><h3>Шаг 5. Подтвердить проблему профилированием</h3><p>Если есть подозрение на перегрузку CPU или утечку памяти, используйте профилировщики:</p><ul><li>Go — pprof;</li></ul><ul><li>Java — JFR, VisualVM;</li></ul><ul><li>Node.js — clinic.js, chrome://inspect.</li></ul><p>Пример (Go, локальный pprof):</p><p>Профиль покажет, где тратится CPU, как распределяются аллокации, как часто запускается GC и в каком коде.</p><h3>Шаг 6. Оптимизировать, перепроверить и зафиксировать</h3><p>После подтверждения проблемы можно переходить к исправлениям:</p><ul><li>кэшировать внешний вызов;</li></ul><ul><li>заменить тяжёлую сериализацию (например, на easyjson в Go);</li></ul><ul><li>убрать блокирующую операцию;</li></ul><ul><li>перейти на batch-обработку.</li></ul><p>После изменений обязательно перепроверьте метрики, чтобы убедиться, что оптимизация действительно дала эффект — и не добавила новых узких мест.</p><h2>Итоги: как не попасть в архитектурную ловушку</h2><p>Bottleneck’и возникают даже в самых технологичных проектах. Это не всегда следствие «плохого кода» — куда чаще они появляются из-за архитектурных просчётов: недооценили нагрузку, не предусмотрели масштабирование, сделали ставку на неправильное решение.</p><p>Главная проблема в том, что узкие места проявляются не сразу, а под нагрузкой. В разработке и тестах всё летает, потому что ресурсов хватает. А вот в проде — особенно при росте аудитории — на поверхность всплывает всё, что не выдерживает реального объёма данных или конкуренции за ресурсы.</p><p>Чтобы избежать таких проблем, важно не просто писать чистый код, а мыслить системно: проектировать архитектуру так, чтобы она могла жить под давлением. Вот несколько принципов, которые помогут.</p><h3>Думайте об объёмах и росте</h3><p>Архитектура должна выдерживать не только текущую нагрузку, но и разумный рост. Строить систему на «миллиард пользователей» с первого дня — избыточно. Но если вы рассчитываете, что пользователей станет в 5 раз больше через год — закладывайте это сейчас. Узкие места не любят сюрпризов.</p><h3>Настраивайте метрики с первого дня</h3><p>Без данных вы работаете вслепую. Любой анализ будет превращаться в гадание: виноват код или Redis, где тормозит — непонятно. С самого начала следите за ключевыми метриками: latency, очереди, GC, hit/miss в кэше, ошибки. Это не «доработка потом», а часть живой системы.</p><h3>Проектируйте с учётом деградации</h3><p>Любая система может начать тормозить — вопрос в том, как она себя при этом поведёт. Важно предусмотреть мягкую деградацию: таймауты, очереди, резервные сценарии, ограничение входящего трафика.</p><h3>Не усложняйте архитектуру без повода</h3><p>Микросервисы, шины, очереди, event-driven — всё это мощные инструменты. Но сложность должна быть оправданной. Простая, понятная архитектура с мониторингом и масштабируемыми точками зачастую выигрывает у перегруженной модульной схемы, которую никто не может отладить.</p><p>Bottleneck’и — это не баг, а симптом. И хороший архитектор — это не тот, кто устраняет тормоза, а тот, кто их не допускает.</p><p>Больше боли коддеров — <a href="https://t.me/+ezugB7gnIEsxNGMy">тут</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как я развернул сайт на Java Spring Boot + Angular SSR с Docker и Nginx: личный опыт</title>
      <link>https://tproger.ru/articles/kak-ya-razvernul-sajt-na-java-spring-boot---angular-ssr-s-docker-i-nginx--lichnyj-opyt</link>
      <comments>https://tproger.ru/articles/kak-ya-razvernul-sajt-na-java-spring-boot---angular-ssr-s-docker-i-nginx--lichnyj-opyt?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Александр Тюрин ]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-ya-razvernul-sajt-na-java-spring-boot---angular-ssr-s-docker-i-nginx--lichnyj-opyt</guid>
      <description><![CDATA[<p>Как развернуть сайт на Spring Boot и Angular с SSR, Docker и Nginx: пошаговый опыт настройки, устранения ошибок, подключения HTTPS и защиты от ботов.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-ya-razvernul-sajt-na-java-spring-boot---angular-ssr-s-docker-i-nginx--lichnyj-opyt">Как я развернул сайт на Java Spring Boot + Angular SSR с Docker и Nginx: личный опыт</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[SEO]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Angular]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sat, 31 May 2025 09:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Проект представляет
собой веб-приложение на Spring Boot и Angular.
Первоначально я выбрал простую монолитную
архитектуру, но по мере роста требований
и целей пришлось перейти на микросервисный
подход. Здесь я расскажу, как это
происходило: с конфигурациями, ошибками
и решениями.</p><h2>Монолитная архитектура</h2><p>Исходная схема:</p><ul><li>Backend: Spring Boot</li><li>Frontend:
	Angular</li></ul><p>Так как у меня уже
был арендованный VDS, я зарегистрировал
домен у одного известного провайдера,
а хостил сайт уже на VDS сервере.
Для простоты интегрировал Angular-сборку
в Spring Boot как статику через
frontend-maven-plugin.
Всё собиралось в один JAR. Почему так?
Ранее уже был такой опыт, и я решил пойти
этим путем.</p><p>После регистрации
домена необходимо подождать, чтобы ввести доменное имя.
Значит есть время для запуска и настройки
приложения. Однако при тестировании
проявились ключевые недостатки:</p><ul><li>Отсутствие SSR в
	Angular негативно влияло на SEO;</li><li>Ошибка в Angular ломала Maven-сборку;</li><li>Сложно поддерживать и масштабировать.</li></ul><h2>Переход на микросервисы</h2><p>Было принято решение
разделить фронтенд и бэкенд на отдельные
сервисы и использовать микросервисный
подход с SSR для Angular:</p><p>Новая структура:</p><ul><li>Backend: Spring Boot</li><li>Frontend:
	Angular Universal (SSR)</li><li>Инфраструктура:
	Docker Compose, Nginx, HTTPS</li></ul><h3>Docker, Nginx и запуск</h3><p>Создана базовая
структура docker-compose.yml:</p><p>И соответствующий
Nginx:</p><p>После запуска проект
открывался по IP, но появилось множество
проблем:</p><ul><li>Дублирование
	API-префиксов: /api/api/endpoint
→
	Решение: корректировка proxy_pass
	и URL в Angular</li><li>Редиректы
	на POST: Spring добавлял лишние слеши
→
	Решение: правильные аннотации и настройка
	Nginx</li><li>405
	Method Not Allowed
→ Решение: использовать
	@PostMapping</li><li>Docker-сети
→
	Решение: задать общую сеть в
	docker-compose.yml</li></ul><h3>Безопасность: HTTPS, SSL, CORS</h3><p>Чтобы сайт открывался
по имени с панели провайдера для моего
домена, значения DNS-сервера оставил без
изменений (провайдер предоставляет их
бесплатно), а для ресурсной записи @ и
www указал ip адрес своего хостинга. Так
как провайдер домена бесплатно
предоставил SSL-сертификаты (Let's Encrypt), то
как я их интегрировал:</p><p>Скачал с панели
провайдера и перенес на хостинг такие
файлы:</p><p>domain.crt — сертификат</p><p>domain.key — приватный
ключ</p><p>ca_bundle.crt — цепочка
доверия</p><p>Добавил
в Nginx такую запись для HTTPS:</p><p>Но при обращении к сайту по https конечно же возникли ошибки.
А именно: в логах Nginx были ошибки на
SSL_CTX_use_PrivateKey_file.
Оказалось формат был PKCS#7, а
требовался PEM. Конвертировал через
OpenSSL:</p><p>Так
как сертификаты имеют срок действия,
не стоит забывать об их продлении и
обновлении.</p><p>К
тому же всегда следует проверять логи
Nginx (error.log), там могут находится ответы
на вопросы, почему сайт не работает.</p><p>На стороне Spring Boot
были CORS-проблемы, решено так:</p><h3>Атаки ботов и защита</h3><p>После запуска сайта
в логах Nginx стали появляться тысячи
запросов от ботов, ищущих уязвимости
WordPress, PHPMyAdmin и других популярных утилит,
хотя мой сайт работает на Java/Angular. Пример
лога:</p><p><i>45.155.205.213
- - [01/Jan/2023:04:12:11 +0000] "GET /wp-login.php HTTP/1.1"
404 153</i></p><p>Добавлен фильтр в
nginx.conf:</p><h3>Финальная конфигурация</h3><p>После
всех настроек мой сайт
работает и полностью функционирует.
Конфигурация сильно изменена по сравнению
с первоначальной. Вот как они выглядят
сейчас.</p><p><i>docker-compose.yml</i></p><p><i>
nginx.conf</i></p><p><i>
Dockerfile backend</i></p><p><i>
Dockerfile frontend</i></p><p>Разделение сервисов
улучшило поддержку и масштабируемость, к тому же, я получил ценные знания. Надеюсь,
статья будет полезна тем, кто разворачивает
подобные конфигурации на Java и Angular.</p>]]></content:encoded>
    </item>
    <item>
      <title>Большой гайд по инструментам для разработчиков от Tproger: фреймворки, базы, AI и DevOps в одной подборке</title>
      <link>https://tproger.ru/articles/bolwoj-gajd-po-instrumentam-dlya-razrabotchikov-ot-tproger--frejmvorki--bazy--ai-i-devops-v-odnoj-podborke</link>
      <comments>https://tproger.ru/articles/bolwoj-gajd-po-instrumentam-dlya-razrabotchikov-ot-tproger--frejmvorki--bazy--ai-i-devops-v-odnoj-podborke?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/bolwoj-gajd-po-instrumentam-dlya-razrabotchikov-ot-tproger--frejmvorki--bazy--ai-i-devops-v-odnoj-podborke</guid>
      <description><![CDATA[<p>Подборка топовых инструментов и технологий для разработчиков: от Elixir и DevOps-платформ до no-code, AI-инструментов и новых фреймворков.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/bolwoj-gajd-po-instrumentam-dlya-razrabotchikov-ot-tproger--frejmvorki--bazy--ai-i-devops-v-odnoj-podborke">Большой гайд по инструментам для разработчиков от Tproger: фреймворки, базы, AI и DevOps в одной подборке</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Функциональное программирование]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Советы]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 04 May 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Мы собрали для вас огромную подборку наших статей про самые полезные инструменты, технологии и практики.
Если вы хотите работать быстрее, чище и с кайфом — сохраняйте себе этот гайд, чтобы не искать потом по всему интернету. Внутри — топовые фреймворки, AI-помощники, базы данных, лайфхаки и советы от практиков.</p><h2>Основные инструменты и технологии</h2><p>Статьи, с которых стоит начать, если хочется обновить стек или разобраться в новых подходах:</p><p><a href="https://tproger.ru/articles/top-60-luchwih-instrumentov-dlya-razrabotki-po-v-2025">ТОП 60 лучших инструментов для разработки ПО в 2025</a> — Собрали шестьдесят лучших инструментов для разработки программного обеспечения в 2025 году. От трекеров и редакторов до библиотек и фреймворков.</p><p><a href="https://tproger.ru/articles/top-11-trendov--kotorye-nuzhny-ajtiwniku-v-2025-godu">Топ 11 трендов, которые нужны айтишнику в 2025 году</a> — Представляем одиннадцать ключевых трендов в IT, которые будут актуальны в 2025 году. Краткий гид по технологиям, которые будут на слуху.</p><p><a href="https://tproger.ru/articles/obzor-populyarnyh-frejmvorkov-dlya-veb-razrabotki">Фреймворки, меняющие игру: выбираем идеальный инструмент для ваших веб-проектов</a> — Обзор современных веб-фреймворков, которые могут изменить подход к разработке ваших проектов.</p><p><a href="https://tproger.ru/articles/instrumenty-i-frejmvorki-qa--kotorye--ne--nuzhno-znat">Инструменты и фреймворки QA, которые (не) нужно знать</a> — о том, что реально используется в тестировании.</p><p><a href="https://tproger.ru/articles/chto-izuchat-nachinashhemu-razrabotchiku-na-c-">Что изучать начинающему разработчику на C#</a> — рассматриваем  языки, среды и подходы, которые пригодятся новичкам. Рекомендуем, с чего начать изучение C# и какие темы освоить в первую очередь.</p><p><a href="https://tproger.ru/articles/reactjs-na-izi--chto-realno-nuzhno-znat-frontend-razrabotchiku-v-2025-godu">ReactJS на изи: что реально нужно знать фронтенд-разработчику в 2025 году</a> — Краткий гайд по ключевым знаниям и навыкам, необходимым для работы с ReactJS в 2025 году.</p><h2>Базы, API, DevOps и CI/CD</h2><p>Набор инструментов и практик, которые помогут масштабироваться и не выгорать:</p><p><a href="https://tproger.ru/articles/top-10-instrumentov-devops--kotorye-uprostyat-vawu-zhizn-i-izbavyat-ot-nochnyh-relizov">Топ-10 инструментов DevOps, которые упростят вашу жизнь и избавят от ночных релизов</a> — must-have решения для DevOps-команд.</p><p><a href="https://tproger.ru/articles/postgresql-vs--clickhouse-vs--duckdb--kakuyu-opensors-bazu-vybrat-dlya-analitiki-v-2025-godu-">PostgreSQL vs. ClickHouse vs. DuckDB: какую опенсорс базу выбрать для аналитики в 2025 году?</a> — Сравниваем три популярные опенсорс СУБД для аналитики: возможности, производительность и кейсы использования.</p><p><a href="https://tproger.ru/articles/10-api--kotorye-sokratyat-vam-nedeli-razrabotki">Семь API, которые сократят вам недели разработки</a> — Подборка решений, которые можно быстро внедрить.</p><p><a href="https://tproger.ru/articles/razvorachivaem-instrumenty-ci-cd--praktiki-ot-devops-inzhenerov">Разворачиваем инструменты CI/CD: практики от DevOps-инженеров</a> — Делимся практическими советами по развертыванию инструментов CI/CD от профессионалов.</p><p><a href="https://tproger.ru/articles/kak-avtomatizirovat-prostye-zadachi-s-pomoshhyu-skriptov-">Как автоматизировать простые задачи с помощью скриптов?</a> — Гайд по быстрой автоматизации без боли.</p><p><a href="https://tproger.ru/articles/luchwie-praktiki-dlya-raboty-s-komandnoj-strokoj">Лучшие практики для работы с командной строкой</a> — Рассказываем, что такое командная строка. Рассматриваем пошаговую инструкцию по использованию.</p><h2>AI-инструменты и нейросети</h2><p>Что может помочь вам уже сейчас — от подсказок до генерации кода:</p><p><a href="https://tproger.ru/articles/top-5-ii-instrumentov-dlya-programmistov-v-2025">Топ-5 ИИ-инструментов для программистов в 2025 году</a> — Самые полезные AI-ассистенты по мнению редакции.</p><p><a href="https://tproger.ru/articles/deepseek-ili-claude--kakaya-nejroset-napiwet-kod--za-kotoryj-ne-stydno-">DeepSeek или Claude: какая нейросеть напишет код, за который не стыдно?</a> — Сравниваем возможности нейросетей DeepSeek и Claude в контексте генерации качественного кода.</p><p><a href="https://tproger.ru/articles/edge-ai--kak-rabotayut-nejroseti-na-ustrojstvah-s-ogranichennymi-resursami">Edge AI: как работают нейросети на устройствах с ограниченными ресурсами</a> — Объясняем, как нейросети работают на устройствах с ограниченными ресурсами и где это применимо.</p><p><a href="https://tproger.ru/articles/10-sposobov-zarabotat-na-iskusstvennom-intellekte-v-2025">10 способов заработать на искусственном интеллекте в 2025</a> — Рассказываем о десяти способах монетизации искусственного интеллекта в 2025 году.</p><h2>Утилиты, лайфхаки и неожиданно полезные штуки</h2><p>То, что экономит время, силы и нервы:</p><p><a href="https://tproger.ru/articles/sobral-11-sajtov--ekonomyashhih-vremya--kotorye-nuzhny-kazhdomu-razrabotchiku">11 сайтов, экономящих время, которые нужны каждому разработчику</a> — Подборка must-have ресурсов.</p><p><a href="https://tproger.ru/articles/luchwie-biblioteki-dlya-animacij-na-react">7 библиотек для анимаций на React</a> — Обзор популярных библиотек для создания анимаций в React: от простых эффектов до сложных переходов.</p><p><a href="https://tproger.ru/articles/30-samyh-poleznyh-bibliotek-python-dlya-veb-razrabotki-v-2024-godu">30 самых полезных библиотек Python для веб-разработки в 2024 году</a>  — Подборка тридцати полезных библиотек Python, которые пригодятся веб-разработчикам в 2025 году.</p><p><a href="https://tproger.ru/articles/7-programm-dlya-wifrovaniya-dannyh">7 программ для шифрования данных</a> —  Базовая кибер-гигиена для всех, кто работает с пользовательскими данными.</p><p><a href="https://tproger.ru/articles/top-samyh-poleznyh-magicheskih-komand-dlya-zavsegdataev-colab">Топ самых полезных магических команд для завсегдатаев Colab</a> — Рассказываем, как использовать магические команды в Colab, чтобы ускорить работу с данными и кодом.</p><p><a href="https://tproger.ru/articles/otkryvaem-cikl-statej-etl-dlya-zooparka-botov">5 ETL для обработки данных из Python-ботов</a> — Представляем пять ETL-инструментов, которые помогут автоматизировать сбор, трансформацию и загрузку данных от Python-ботов</p><p><a href="https://tproger.ru/articles/rabota-s-excel-gde-on-primenyaetsya-chem-polezen-i-gde-osvoit-etot-navyk-erid-ljn8klxkn">Работа с Excel: где он применяется, чем полезен и где освоить этот навык</a> — Объясняем, где и как используется Excel, почему он важен для аналитиков и где научиться работать с ним.</p><h2>Немного философии</h2><p>Когда хочется не просто выбрать инструмент, а понять, зачем он вам нужен:</p><p><a href="https://tproger.ru/articles/yazyk-elixir-i-funkcionalnoe-programmirovanie--chto-eto-za-zver-i-pochemu-on-horow-dlya-otkazoustojchivyh-sistem">Язык Elixir и функциональное программирование: что это за зверь и почему он хорош для отказоустойчивых систем</a> — Знакомим пользователей с Elixir и его применением.</p><p><a href="https://tproger.ru/articles/pochemu-mikroservisy-ne-nuzhny--antihajpovyj-razbor">Почему микросервисы не нужны: антихайповый разбор</a> — Анализируем случаи, когда микросервисная архитектура может быть излишней и неэффективной.</p><p><a href="https://tproger.ru/articles/10-luchwih-platform-dlya-sozdaniya-prilozhenij-bez-edinoj-strochki-koda">10 лучших платформ для создания приложений без единой строчки кода</a> — Обзор десяти лучших no-code платформ, позволяющих создавать приложения без программирования.</p><p>Скорее пользуйтесь нашим гайдом и читайте предыдущие. Вот, например, по <a href="https://tproger.ru/articles/bolwoj-gajd-po-mobilnoj-razrabotke-ot-tproger--poleznye-stati--praktiki-i-sovety">мобильной разработке</a> и <a href="https://tproger.ru/articles/bolwoj-gajd-po-react-ot-tproger--topovye-stati-i-instrumenty">React</a>.</p><p>Кстати! Забрать все самые топовые нейронки для айтишников можно в нашем <a href="https://tprg.ru/LN8a">большом гайде с 70+ ИИ-инструментами </a></p>]]></content:encoded>
    </item>
    <item>
      <title>Почему микросервисы не нужны: антихайповый разбор</title>
      <link>https://tproger.ru/articles/pochemu-mikroservisy-ne-nuzhny--antihajpovyj-razbor</link>
      <comments>https://tproger.ru/articles/pochemu-mikroservisy-ne-nuzhny--antihajpovyj-razbor?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Денис Кудерин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/pochemu-mikroservisy-ne-nuzhny--antihajpovyj-razbor</guid>
      <description><![CDATA[<p>Почему микросервисная архитектура нужна не во всех случаях. Причины популярности микросервисов — маркетинг, хайп и законы рынка. </p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/pochemu-mikroservisy-ne-nuzhny--antihajpovyj-razbor">Почему микросервисы не нужны: антихайповый разбор</a>»</p>]]></description>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Отладка]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Яндекс]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Маркетинг]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Spotify]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sat, 19 Apr 2025 09:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Микросервисы действительно ускоряют разработку и обладают массой других достоинств. Netflix и Amazon построили на них свои гигантские системы — это на самом деле гибко, современно и обеспечивает проекту масштабирование.</p><p>Но правда в том, что это решение подходит далеко не всем компаниям. В 90% ситуаций микросервисная архитектура (она же MSA) — избыточность, а не необходимость. Это не просто сложно, а очень сложно. Микросервисы требуют мощной инфраструктуры, глубоких знаний DevOps, тонкой настройки мониторинга и отказоустойчивости. И самое главное — они редко нужны на старте проекта.</p><p>Если ваш сервис пока обслуживает десятки и сотни, а не миллионы пользователей, если у вас маленькая команда и ограниченный бюджет, если вы просто хотите сделать   работающий продукт, забудьте про микросервисы — они вам не нужны. И мы подробно расскажем, почему. Статья основана на опыте сотен разработчиков, которые в свое время наступали на одни и те же грабли. Материал поможет избежать их ошибок и убережет от лишних трат.</p><h2>Почему все говорят про микросервисы</h2><p>Архитектура микросервисов — прогрессивная модель для создания ПО, при которой приложение состоит из автономных, почти не связанных друг с другом модулей. Это упрощает разработку проектов и управление ими, поэтому подход применяют известные крупные бренды типа PayPal и Netflix.</p><p>Если вы погружены в ИТ-тематику, интересуетесь вакансиями для специалистов, читаете каналы и блоги программистов, у вас может сложиться впечатление, что микросервисы — волшебная кнопка для разработчиков, без которой не обойтись. Но это не так: популярность этой темы — результат нескольких причин. О них — ниже.</p><h3>Маркетинг на волне хайпа</h3><p>Разработчики инструментов в этой сфере хорошо зарабатывают на своих продуктах.</p><p>Микросервисы — не просто архитектура, это целая индустрия. Компании вроде Google и AWS активно продвигают Kubernetes, Istio и прочие сложные инструменты. Им это выгодно: чем больше людей верят, что без этого стека нельзя, тем больше подписок, лицензий и консультаций продаются.</p><p>Реальность более прозаична. Вам говорят, что «Kubernetes нужен всем», но для стартапа из трех-пяти человек это слишком дорогое удовольствие. Половина постов и кейсов про «успешный переход на микросервисы» спонсирована компаниями, которые продают инструменты для этого перехода.</p><h2>Ориентированность на резюме</h2><p>Многие разработчики (особенно начинающие) учат микросервисы не потому, что столкнулись с их необходимостью, а потому, что это круто звучит. В итоге в вакансиях пишут «знание Docker/K8s — огромный плюс», а на собеседованиях спрашивают про «опыт работы с распределенными системами», даже если у компании всего лишь сайт-визитка.</p><p>Это создает порочный круг:</p><ul><li>новички учат Kubernetes, потому что это востребовано;</li><li>компании требуют Kubernetes, потому что так делают конкуренты;</li><li>в итоге люди тратят месяцы на сложные технологии, которые никогда не применят.</li></ul><p>Факт. Несмотря на универсальность микросервисов, далеко не все гиганты перешли на такой формат работы. Например, GitLab и Spotify до сих пор работают на монолитах.</p><h3>Завышенные ожидания по проекту</h3><p>Создатели стандартного проекта искренне считают, что он слишком сложен для монолита. Начинающие разработчики часто переоценивают масштаб своих задач. Они внимательно читают доклады Netflix про архитектуру и решают, что их pet-проект тоже нуждается в распределенной системе.</p><p>Что происходит на практике:</p><ul><li>Вместо одного приложения — 10 сервисов, которые падают вразнобой.</li><li>Вместо локальной отладки — часы борьба с сетью и синхронизацией данных.</li><li>Вместо «гибкости» — множество лишних элементов.</li></ul><p>В итоге пока вы разбираетесь с Istio и мониторингом, ваш конкурент уже запустит тот же функционал на монолите и получит первых клиентов.</p><h2>Нужны ли вашему проекту микросервисы</h2><p>Прежде чем принимать решение о переходе на микросервисную архитектуру, необходимо трезво оценить текущие и прогнозируемые потребности вашего проекта. Микросервисы — это не универсальное решение, а архитектурный подход со строго определенной областью применения. Его внедрение должно быть обосновано конкретными техническими и бизнес-требованиями, а не модными тенденциями в разработке.</p><p>Чтобы понять, стоит ли внедрять в ваш проект микросервисы, ответьте на три важных вопроса.</p><h3>Действительно ли ваш проект настолько масштабен?</h3><p>Микросервисы — это не разделение кода на части, это создание независимых продуктовых единиц, каждая из которых могла бы работать как отдельное приложение.</p><p>Сразу проверьте себя:</p><ul><li>Если ваш сервис — это один API, который обслуживает 5 конечных адресов, микросервисы вам не нужны.</li><li>Если вы не можете четко объяснить, какие части системы могут жить автономно (например, платежи без каталога товаров), значит, у вас монолит. И это нормально.</li></ul><p>Монолит — низкие начальные затраты, но с ростом кода поддержка становится дороже. Микросервисы — огромные стартовые вложения (DevOps, оркестрация, мониторинг), зато потом система масштабируется с меньшими расходами. Второй вариант выгоднее лишь в том случае, если у вас миллионы пользователей и десятки команд. До этой точки монолит — более целесообразное решение.</p><p>Далеко не все приложения достаточно масштабны, чтобы разбить их на более мелкие составные части. Но даже в случае, если на начальной стадии запуска сложно оценить потенциал продукта, лучше начать с монолита. А грамотный код всегда можно перевести на микросервисы, когда это понадобится.</p><h3>Действительно ли вам необходимо масштабировать части приложения автономно?</h3><p>Типичный аргумент за микросервисы: «У нас нагрузка только на платежи, а не на каталог — выгодно масштабировать их по отдельности». На самом деле 99% стартапов никогда не сталкиваются с такой нагрузкой, где это критично. Кроме того, современные облака (AWS, GCP) умеют масштабировать отдельные модули монолита.</p><p>Пример. Команда разбила HR-систему на 10 микросервисов. В итоге форма подачи заявок зависела от сервиса сотрудников, который в свою очередь зависел от сервиса отделов. При пиковой нагрузке (раз в месяц) все равно масштабировали все сервисы сразу.</p><p>Если вы не Amazon — вам, скорее всего, хватит вертикального масштабирования (+1 сервер) или модульного монолита.</p><h3>Есть ли у вас услуги, связанные с транзакциями?</h3><p>В монолите транзакция — это пара строк кода. В микросервисах — сложный квест.</p><p>Вот как это выглядит:</p><ol><li>Платежный сервис списал деньги.</li><li>Инвентарный сервис не ответил (упал или залагал).</li><li>Теперь у пользователя списаны деньги, но заказ не создан.</li></ol><p>Микросервисы создают проблемы согласованности. В монолите вы обновляете данные одной транзакцией, в MSA это стоит в 10 раз дороже.</p><h2>7 причин не лезть в микросервисы</h2><p>Значительная часть начинающих прогеров по умолчанию считает, что микросервисы — это прогрессивно и круто. Но они просто не видят подводных камней. На самом деле MSA — это компромисс со сложностью, деньгами и нервами. И не нужно считать, что монолит — это отсталая технология. Решения, касающиеся архитектуры продукта, нужно принимать, основываясь на объективных данных, а не хайпе.</p><p>Рассмотрим главные причины, по которым вам не стоит связываться с микросервисами.</p><h3>Сложность съедает пользу</h3><p>Итак, ваша небольшая команда из 5-10 человек решила перейти на микросервисы с расчетом на гибкость, масштабируемость и прочие фишки новой архитектуры.</p><p>На практике получается следующее:</p><ul><li>Kubernetes (или иной подобный инструмент) становится источником проблем. Вместо написания кода вы теперь разбираетесь, почему поды (базовые строительные блоки) не стартуют, настраиваете контроллеры, обновляете Helm-чарты. Это занимает 30-50% рабочего времени.</li></ul><ul><li>Раньше логи были в одном файле, теперь размазаны по 15 сервисам, хранятся в разных форматах, требуют сложной агрегации. Чтобы найти одну ошибку, приходится тратить кучу времени.</li><li>Проблемы с сетевым взаимодействием. Каждый вызов между сервисами — это таймауты, повторные запросы, непонятные ошибки.</li></ul><p>Команда тратит полгода на переход. Но сервис получает те же 100 запросов в секунду. Только теперь он становится медленнее, сложнее в поддержке, дороже в эксплуатации.</p><p>Сложность ради сложности — это точно не про эффективность. Прежде чем переходить на микросервисы, подумайте — готовы ли вы тратить половину времени не на продукт, а на борьбу с инфраструктурой?</p><h3>Микросервисы не лечат плохой код</h3><p>У вас есть монолит — большой, тяжелый, с запутанными зависимостями. И вот вы решаете: «Давайте разобьем это на микросервисы!» В теории звучит отлично: каждый сервис — маленький, независимый, аккуратный.</p><p>Но на практике оказывается, что вы просто взяли ваш запутанный код и разделили его на несколько сервисов, не устранив существующие зависимости. Они не исчезают, а лишь меняют форму: вместо вызовов методов внутри одного приложения появляются HTTP-запросы между сервисами. Это не решение проблемы неорганизованного кода, вы создаете новую зависимость — сетевые взаимодействия.</p><p>Микросервисы не улучшают плохой код, они лишь усложняют его структуру. Если архитектура изначально плохо организована, сначала необходимо устранить хаос, и только затем рассматривать вопросы масштабирования. Для этого требуется квалифицированная команда специалистов</p><h3>Нужна подготовленная команда</h3><p>Микросервисами нужно умело управлять. В теории все выглядит красиво — независимые сервисы, гибкое масштабирование, быстрые обновления. Но на практике оказывается, что для такой архитектуры нужны особые люди и процессы, которых у большинства команд просто нет:</p><ul><li>Без полноценного DevOps или SRE-инженера вы быстро утонете в бесконечной настройке и мониторинге. Это не та работа, которую можно взвалить на бэкендера — она требует специфических знаний и постоянного внимания.</li><li>Когда сервисов становится много, появляется новая головная боль — согласование контрактов между командами. Кто за что отвечает? Как тестировать изменения? Что делать, если один сервис ломает другой? Без четких договоренностей и CI/CD-культуры это превращается в хаос.</li><li>В большинстве стартапов два бэкендера, один стажер и горящие сроки. Они едва успевают пилить фичи, не то что разбираться с продвинутыми практиками DevOps.</li></ul><p>В таких условиях попытка внедрить микросервисы чаще всего заканчивается тем, что команда тратит 80% времени на поддержку инфраструктуры вместо разработки продукта.</p><h3>Деньги тратятся быстрее</h3><p>Когда речь заходит о микросервисах, многие почему-то забывают простую истину — за все надо платить:</p><ul><li>Без профессионального DevOps-инженера (а хорошие специалисты стоят дорого) ваш «распределенный рай» быстро превратится в ад. Кто будет настраивать Kubernetes, разбираться с падающими подами и оркестрировать логи?</li><li>Базовый мониторинг вроде Prometheus + Grafana — это только начало. Когда сервисов станет много, вам понадобятся системы трассировки и еще десяток инструментов, каждый из которых требует времени и денег.</li><li>Главная скрытая цена микросервисов — время инженеров. В монолите проверка занимает минуты. В мире микросервисов вам сначала придётся поднять пол-инфраструктуры, чтобы просто удостовериться, что код вообще работает.</li></ul><p>Для проектов с нагрузкой меньше 100k пользователей микросервисы обходятся в 2-3 раза дороже монолита. И это без учета скрытых затрат — нервов, задержек и упущенных возможностей.</p><h3>Отладка микросервисов — это головная боль</h3><p>Отладка в микросервисной архитектуре требует серьезных затрат времени и финансов. В монолите все просто — есть трассировка стеков (список вызовов), есть логи, и обычно проблема лежит где-то между ними.</p><p>Но в мире микросервисов ошибка может прятаться где угодно: в сервисе А, который не так ответил сервису Б, который передал кривые данные сервису В, а тот и вовсе решил ничего не отвечать. И все это с таймаутами, повторными запросами и загадочными HTTP-статусами.</p><p>Можно потратить целый день, чтобы понять, почему падает система. В итоге окажется, что проблема была в том, что два сервиса по-разному интерпретируют дату. В монолите такая ошибка обнаружилась бы за 5 минут. В микросервисах — это полноценное расследование с изучением логов каждого участника цепочки.</p><p>Если вы не готовы к тому, что поиск каждой ошибки будет напоминать путешествие с непредсказуемым пунктом назначения, возможно, микросервисы — не ваш выбор. Ведь время, потраченное на отладку — это время, которого не хватило на создание новых возможностей для вашего продукта.</p><h3>Легкого масштабирования не будет</h3><p>Многие думают, что стоит только разбить приложение на микросервисы, и масштабирование станет решением всех проблем. В реальности все не так просто. Микросервисы — это не автоматическое масштабирование по щелчку пальцев, а сложный механизм, который требует тщательной настройки.</p><p>Для эффективного масштабирования вам понадобятся четкие границы и детально продуманные контракты между сервисами, иначе вы получите клубок зависимостей.</p><p>Без этого масштабирование не сработает. Вместо того чтобы увеличивать только перегруженный сервис, вам придется масштабировать весь кластер целиком. Так что прежде чем разбивать систему, подумайте: действительно ли ваша нагрузка требует таких сложных решений?</p><h2>Когда микросервисы все же нужны</h2><p>Иногда микросервисная архитектура действительно необходима. Но точно не тогда, когда об этом кричат маркетологи или модные блогеры.</p><p>Вот три реальных ситуации, когда MSA имеет смысл.</p><h3>Независимые продукты под одной крышей</h3><p>Типичный пример — Яндекс. Это не просто такси, но и доставка еды, и грузоперевозки. Абсолютно разные бизнес-процессы, которые разрабатываются отдельными командами, используют разные технологии, масштабируются независимо.</p><p>Здесь микросервисы — не прихоть, а необходимость.</p><h3>Огромные масштабы</h3><p>Если у вас одновременно работают 100+ разработчиков, миллионы запросов в секунду, десятки дата-центров по всему миру, монолит просто не выдержит такой нагрузки. Но обратите внимание — мы говорим про реальных гигантов уровня Amazon.</p><h3>Технический стек из разных компонентов</h3><p>Иногда часть системы логичнее писать на Go (где важна скорость), часть на Python (для ML), а часть оставить на JVM (для legacy).</p><p>Микросервисы позволяют:</p><ul><li>использовать оптимальный язык для каждой задачи;</li><li>обновлять компоненты независимо;</li><li>не тащить в проект лишние зависимости</li></ul><p>Все эти случаи объединяет одно: микросервисы решают конкретные проблемы, а не внедряются «на всякий случай». Если ваш проект не подпадает под эти критерии — возможно, стоит еще раз подумать. Использовать микросервисы без необходимости — это неоправданная роскошь.</p><h2>Итоги</h2><p>Микросервисы обрели свой культовый статус вполне заслуженно — в свое время они решили множество проблем, которые ранее считались в индустрии почти неразрешимыми. Истории Uber, SoundCloud и других гигантов индустрии стали для нового поколения программистов источниками вдохновения.</p><p>Однако сегодня ясно, что безосновательное внедрение этой архитектуры ведет к непредсказуемым затратам и последствиям. Стоит учесть все факторы — от  масштаба проекта до его бюджета — прежде чем считать микросервисы самым эффективным решением по умолчанию.</p><p>А если хочешь писать код, который не стыдно показывать, собрали всё для фронтендеров и бэкендеров в <a href="https://t.me/+c6lPaQBXLvE4YmMy">одном месте</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Context Collapse: как микросервисы могут сойти с ума</title>
      <link>https://tproger.ru/articles/context-collapse--kak-mikroservisy-mogut-sojti-s-uma</link>
      <comments>https://tproger.ru/articles/context-collapse--kak-mikroservisy-mogut-sojti-s-uma?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Анна Ельцова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/context-collapse--kak-mikroservisy-mogut-sojti-s-uma</guid>
      <description><![CDATA[<p>Даже самая идеальная микросервисная архитектура может упасть. В статье обсудим зарубежный материал, где автор рассказывает о проблеме Context Collapse.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/context-collapse--kak-mikroservisy-mogut-sojti-s-uma">Context Collapse: как микросервисы могут сойти с ума</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[Отладка]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[OpenTelemetry]]></category>
      <category><![CDATA[Grafana]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 25 Mar 2025 12:40:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>В феврале на Medium вышла статья <a href="https://levelup.gitconnected.com/context-collapse-the-silent-microservices-killer-76a60058561e">Context Collapse: The Silent Microservices Killer</a>. Перевели ее для вас, так как тема довольно редкая и интересная. Ниже предлагаем обсудить проблему контекста и как он может упасть.</p><h2>Что вообще такое context collapse</h2><p>Есть вероятность, что вы слышите этот термин в первый раз. Немного лирики: в мире микросервисов есть два понятия: технический контекст и доменный контекст (Bounded Context).</p><h2>Технический контекст</h2><p>Технический контекст — это информация, которая передается между микросервисами для выполнения запросов или операций. В нем лежит большое количество данных: идентификаторы запросов (например, TraceID в трассировке), пользовательские сессии, метаданные или параметры аутентификации.</p><p>Без технического контекста микросервисы не могут:</p><ul><li>отслеживать, откуда пришел запрос и куда он направляется,</li><li>сохранять согласованность данных между сервисами,</li><li>выявлять сбои (например, через логи или трассировку).</li></ul><h2>Доменный контекст (Bounded Context)</h2><p>Доменный контекст происходит из методологии Domain-Driven Design (DDD) — это про четкое разделение бизнес-логики между микросервисами. У каждого сервиса должна быть своя «ограниченная область» (Bounded Context), где термины, данные и правила имеют уникальное значение.</p><p>Например, в интернет-магазине слово «заказ» может означать разные вещи для сервиса оплаты (финансовая транзакция) и сервиса доставки (отправка покупателю). Если границы контекста не определены четко, возникает путаница: сервисы начинают дублировать логику или интерпретировать данные по-разному.</p><p>Без доменного контекста:</p><ul><li>код будет дублироваться и появится избыточность,</li><li>усложнится взаимодействие между сервисами,</li><li>систему будет сложнее поддерживать.</li></ul><h2>Вернемся к коллапсу контекста</h2><p>Автор статьи просит нас представить следующую картину: вы сделали новую архитектуру, она масштабируется, разделяется, деплои проходят гладко, CI/CD пайплайны цветут и пахнут — другими словами, не архитектура, а мечта. Все работает как часы, поэтому вы сидите, попивая кофе и раскладывая пасьянс.</p><p>Вдруг приходит пользователь и сообщает, что платеж был проведен дважды. На панели мониторинга появляются задержки, и логи здесь вообще бесполезны. Вы начинаете разбираться и спустя несколько часов споров с терминалом, находите причину: один из сервисов забыл, кто вообще такой этот пользователь, прямо во время проведения транзакции.</p><p>Тра-та-та, это и есть контекстный коллапс. Как называет его автор — тихий убийца микросервисов в 2025 году. Поймать этот баг с помощью breakpoints нельзя, при этом он будет уничтожать вашу производительность и код в целом.</p><h2>Что на самом деле происходит</h2><p>Представьте, что микросервисы — это эстафетный забег: каждый сервис передает «эстафетную палочку» — идентификаторы пользователей, сессионные данные, намерения — следующему участнику. Контекстный коллапс случается, когда эта палочка выпадает на бегу.</p><p>Сервис теряет важное состояние, например:</p><ul><li>«Это корзина Пети»</li><li>"Этот платеж уже прошел"</li></ul><p>И начинается хаос: дублирующиеся API-запросы, потерянные транзакции или, что еще хуже, повреждение данных.</p><p>В 2025 году появляется все больше слишком фрагментированных архитектур и гипермасштабируемых систем. Ваши запросы могут проходить через 10, 20 и даже 30 сервисов, но если на каком-то этапе отвалился контекст, то это конец.</p><p>В статье автор не делает акцента на том, какой именно это контекст — технический или доменный. На самом деле может произойти все что угодно: это может быть как потеря технического контекста, так и нарушение доменных границ (когда сервисы лезут не в свое дело). Оба случая приводят к хаосу: данные становятся несогласованными, ошибки множатся, а разработчики теряют контроль над системой.</p><h2>Как понять, что контекст вот-вот может «коллапснуться»</h2><p>Вы наверняка были в такой ситуации: вы на 100% уверены, что система должна работать, но она не работает, хотя ошибок в коде никаких, казалось бы, нет. Вот основные признаки коллапса, с которыми вы можете столкнуться:</p><ul><li>Всплеск пинга: сервисы запрашивают данные, которые должны бы уже знать, создавая огромное количество лишних вызовов и перегружая API.</li><li>Дублирующиеся действия: повторные списания, задвоенные отправки писем, неожиданные повторные заказы. Пользователи возмущены, рейтинг падает.</li><li>Мистические баги: логи говорят «всё в порядке», но результат явно неверный. Код не видит проблему, а отладка превращается в кошмар.</li></ul><p>Давайте рассмотрим на примере. Клиент решает перевести деньги с одного счёта на другой. Сервис транзакций отправляет запрос в модуль проверки лимитов, затем передаёт его в систему обработки платежей. Но из-за потери контекста на одном из этапов модуль проверки лимитов теряет информацию о сессии клиента и воспринимает его как нового пользователя. В результате:</p><ul><li>Лимиты не распознаются, и транзакция блокируется, даже если у пользователя достаточно денег.</li><li>Либо, наоборот, проверка пропускается, и клиенту позволяют перевести больше лимита.</li><li>Сервис обработки платежей не получает подтверждение проверки и отправляет повторный запрос, а это может привести к двойному списанию средств.</li></ul><p>Клиент идет громить службу поддержки, она — разработчиков, а они размахивают руками, потому что в логах все отлично.</p><p>Опрос CNCF за 2024 год показал, что 68% команд, которые используют микросервисы, сталкиваются с необъяснимыми проблемами производительности. И всему виной в том числе контекстный коллапс.</p><h2>5 решений, как бороться с контекстным коллапсом</h2><p>Да, контекстный коллапс — крайне неприятный баг. Главное — чтобы все сервисы работали слаженно и «знали» друг друга.</p><h3>1. Правильно передавайте контекст</h3><p>Вам нужно передавать критические важные данные — идентификаторы пользователей, состояние транзакций, метаданные запроса — в каждом шаге цепочки. Стоит использовать OpenTelemetry, чтобы распространять контекст по сервисам.</p><p>Вот пример реализации middleware автором на Go:</p><h3>2. Кэшируйте с умом</h3><p>Нет смысла заставлять сервисы угадывать, если они просто могут запомнить. Быстрый кэш, например, с Redis, может хранить временный контекст — например, токены сеанса или состояния запросов, — поэтому сервисы не будут постоянно спрашивать «кто это?» Вот фрагмент кода на Питоне, где используется Redis для хранения и извлечения контекста:</p><p>Это позволяет поддерживать контекст во всех вызовах, не перегружая вашу базу данных. А еще TTL (time-to-live) Redis сам за собой убирает — устаревшие данные не скрываются.</p><h3>3. Используйте Event-Driven Architecture</h3><p>Микросервисы без сохранения состояния выглядят отлично, пока не контекст не коллапснется. Событийная архитектура идет от обратного: вместо того чтобы надеяться, что службы все запомнят, регистрируйте каждый шаг как событие. Если служба все-таки забудет, воспроизведите поток. Вот пример на Node.js с Kafka:</p><p>Здесь также можно использовать RabbitMQ. В общем, больше никаких отговорок со стороны сервиса из разряда «я забыл».</p><h3>4. Проверяйте логи</h3><p>Когда контекст теряется, логи — ваше место преступления. Настройте Grafana Loki или Datadog для поиска «потерянных контекстов». Вот пример с Grafana:</p><p>Тэгните логи с помощью request_id или user_id, а затем вызовите Loki:</p><h3>5. Тестируйте на коллапсы</h3><p>Профилактика лучше, чем лечение. Добавьте хаос-тестирование с помощью, например, Chaos Mesh, чтобы моделировать потери контекста.</p><p>Хаос-тестирование — это метод преднамеренного введения сбоев в систему, чтобы проверить, насколько она устойчива и надежна. Обычное тестирование и мониторинг могут выявить проблемы, но хаос-тестирование (Chaos Engineering) помогает увидеть, как система поведет себя в случае неожиданных отказов.</p><p>Прервите mid-requests к сервисам — сможет ли система восстановится в таком случае? Если нет, значит, ваша передача контекста недостаточно надежна.</p><p>Эти решения не универсальны. Начните с правильного распространения контекста для быстрых улучшений, затем добавьте кэширование или событийную архитектуру для масштабируемости и постоянно аудируйте систему.</p>]]></content:encoded>
    </item>
    <item>
      <title>«Хаос и беспорядок»: эксперт назвал минусы микросервисной архитектуры</title>
      <link>https://tproger.ru/news/-haos-i-besporyadok---ekspert-nazval-minusy-mikroservisnoj-arhitektury</link>
      <comments>https://tproger.ru/news/-haos-i-besporyadok---ekspert-nazval-minusy-mikroservisnoj-arhitektury?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/-haos-i-besporyadok---ekspert-nazval-minusy-mikroservisnoj-arhitektury</guid>
      <description><![CDATA[<p>Микросервисы — это не всегда решение. Эксперт разобрал главные минусы: хаос в архитектуре, рост затрат, сложная отладка и непредсказуемость системы</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/-haos-i-besporyadok---ekspert-nazval-minusy-mikroservisnoj-arhitektury">«Хаос и беспорядок»: эксперт назвал минусы микросервисной архитектуры</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 13 Mar 2025 05:30:44 GMT</pubDate>
      <content:encoded><![CDATA[<p>Микросервисная архитектура обещала упростить жизнь разработчикам: независимое масштабирование, ускорение релизов, гибкость.</p><p>Однако на практике многие компании сталкиваются с лавинообразным ростом сложности, перегруженными бюджетами на инфраструктуру и постоянными сбоями в продакшене.</p><p>Эксперт с 25-летним опытом в IT <a href="https://medium.com/mr-plan-publication/microservices-the-architectural-cult-thats-bankrupting-your-sanity-and-your-startup-877e33453785">разобрался</a>, почему микросервисы часто становятся проблемой, когда они действительно оправданы и как можно избежать ненужных усложнений.</p><h2>Почему микросервисы приводят к хаосу</h2><h2>Рост сложности</h2><p>Микросервисы заменяют понятные связи внутри монолитного приложения на хаотичную сеть распределённых систем.</p><p>Отладка становится настоящим испытанием: теперь поиск одной ошибки требует глубокого погружения в распределённые логи и сложные инструменты мониторинга.</p><h2>Высокие затраты на инфраструктуру</h2><p>Монолитное приложение можно развернуть на одном сервере или в простом контейнере.</p><p>В случае с микросервисами требуются десятки вспомогательных инструментов: Kubernetes, сервис-меши, системы распределённых логов, очереди сообщений. Всё это приводит к значительному росту расходов.</p><p>Пример: стартап из 12 человек использовал 87 микросервисов. В результате 60% бюджета уходило на AWS для поддержки этой сложной архитектуры.</p><h2>Низкая предсказуемость работы</h2><p>Каждый дополнительный сервис создаёт новую точку отказа. В распределённых системах отказ одного компонента может вызвать цепную реакцию, приводящую к полному падению приложения.</p><h2>Когда микросервисы действительно оправданы</h2><ol><li><b>Глобальные сервисы</b> – Netflix, Amazon, Google используют микросервисы из-за огромного количества пользователей и высоких требований к масштабируемости.</li><li><b>Разные технологии в одной системе</b> – если одна часть системы требует Python, другая – C++, третья – Java, разделение на микросервисы может быть оправдано.</li><li><b>Сильная изоляция сервисов</b> – если разные команды разрабатывают независимые части продукта, микросервисы помогают снизить конфликты в коде.</li></ol><p>Во всех остальных случаях разделение монолита может привести к необоснованному росту сложности.</p><h2>Как избавиться от избыточных микросервисов</h2><ol><li><b>Аудит архитектуры</b> – если сервис не изменялся 6 месяцев, возможно, он не нужен.</li><li><b>Оценка альтернатив</b> – вместо нового микросервиса можно реализовать модуль, библиотеку или просто улучшить код монолита.</li><li><b>Оптимизация инфраструктуры</b> – сокращение количества сервисов снижает нагрузку на DevOps и упрощает отладку.</li></ol><h2>Вывод</h2><p>Микросервисная архитектура не является универсальным решением.</p><p>В большинстве случаев компаниям выгоднее работать с хорошо структурированным монолитом, чем раздувать сложность ради тренда. Если новый микросервис не приносит очевидной бизнес-ценности, лучше от него отказаться.</p>]]></content:encoded>
    </item>
    <item>
      <title>Модульность кода: как не утонуть в миллионной строке и писать масштабируемые проекты</title>
      <link>https://tproger.ru/articles/modulnost-koda--kak-ne-utonut-v-millionnoj-stroke-i-pisat-maswtabiruemye-proekty</link>
      <comments>https://tproger.ru/articles/modulnost-koda--kak-ne-utonut-v-millionnoj-stroke-i-pisat-maswtabiruemye-proekty?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/modulnost-koda--kak-ne-utonut-v-millionnoj-stroke-i-pisat-maswtabiruemye-proekty</guid>
      <description><![CDATA[<p>Узнайте, что такое модульность кода, почему она критически важна для масштабируемости проектов. Разбираем ключевые принципы, ошибки и лучшие практики модульного программирования. </p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/modulnost-koda--kak-ne-utonut-v-millionnoj-stroke-i-pisat-maswtabiruemye-proekty">Модульность кода: как не утонуть в миллионной строке и писать масштабируемые проекты</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 05 Mar 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Современная разработка ПО уже давно вышла за рамки небольших скриптов и монолитных приложений. Сегодня кодовая база большинства проектов измеряется сотнями тысяч или даже миллионами строк, а без продуманной структуры работа превращается в хаос. Поэтому программисты и архитекторы ПО уделяют внимание модульности — принципу, который помогает сохранить порядок, упростить поддержку и снизить количество багов. Сегодня разберем, что это за термин, и как его применять в своих проектах.</p><h2>Почему модульность кода — не тренд, а необходимость</h2><p>Модульность — фундаментальный принцип, который упрощает сопровождение кода и делает его адаптивным к изменениям. Давайте разберёмся, почему без модульности крупные проекты просто не выживают.</p><h3>Без модульности всё разваливается</h3><p>Начинающий разработчик может не задумываться о модульности — когда у тебя небольшой скрипт на Python или несколько файлов с кодом веб-приложения, кажется, что всё под контролем. Но по мере роста проекта возникают новые проблемы:</p><ul><li>Код становится слишком большим, чтобы его можно было легко понять. Если в начале у вас был один файл на 500 строк, то через год в проекте уже тысячи файлов, десятки зависимостей, а изменение одной строчки может вызвать неожиданный каскад ошибок.</li><li>Любые изменения могут нарушить работу всего, что угодно. Монолитный код, в котором всё взаимосвязано, делает проект хрупким: добавляя новый функционал, разработчик может случайно затронуть совершенно неожиданные части.</li><li>Тестирование становится сложнее. Если компоненты системы зависят друг от друга, их невозможно тестировать по отдельности, а значит, каждая ошибка требует длительного анализа.</li><li>Новые разработчики тратят недели на разбор чужого кода. Чем больше в коде скрытых взаимосвязей, тем дольше человеку приходится разбираться, как что работает.</li></ul><h3>Модульность решает множество проблем</h3><p>Когда проект только начинается, кажется, что модульность — излишнее усложнение. Но чем больше развивается кодовая база, тем очевиднее становится, что без чёткой структуры работать невозможно. Модульность решает сразу несколько критических проблем разработки, каких?</p><h4>Упрощает сопровождение кода</h4><p>В коде без модульности даже небольшое изменение может превратиться в кошмар. Представьте, что вам нужно исправить баг, но код настолько запутан, что затрагивает десятки файлов и зависимостей. Из-за этого разработчик тратит часы (а то и дни), чтобы понять, где именно вносить правки.</p><p>При модульном подходе каждая часть системы отвечает за свою функциональность и слабо связана с остальными. Это означает, что:</p><ul><li>Разработчики смогут изменять один модуль, не боясь сломать остальную систему;</li><li>Новый человек в команде быстрее разберётся в коде, так как модули работают автономно;</li><li>Логика кода станет прозрачнее: у каждого модуля чётко определённые границы ответственности.</li></ul><h4>Снижает количество багов, связанных с зависимостями</h4><p>Когда кодовая база сильно связана, малейшее изменение в одном месте может вызвать каскад ошибок в других частях системы. Например, если функция обработки данных напрямую взаимодействует с интерфейсом, изменения в логике могут неожиданно нарушить отображение информации на фронтенде.</p><p>Модульность решает эту проблему за счёт принципа низкой связанности и высокой когезии (о них поговорим позже).</p><p>Допустим, в проекте есть модуль, отвечающий за отправку электронных писем. Если он спроектирован правильно, то любые изменения в бизнес-логике приложения (например, добавление нового типа транзакций) не затронут этот модуль.</p><h4>Делает тестирование проще и быстрее</h4><p>Когда код представляет собой единый монолит, его сложно тестировать: чтобы проверить одну функцию, приходится запускать весь проект.</p><p>При модульной архитектуре каждый компонент можно тестировать отдельно:</p><ul><li>Юнит-тесты проверяют конкретные модули без запуска всей системы;</li><li>Интеграционные тесты оценивают взаимодействие между модулями;</li><li>Тестирование становится параллельным — можно одновременно проверять разные модули.</li></ul><h2>Основные принципы модульного кода</h2><h3>Принцип единой ответственности (SRP): каждый модуль выполняет ровно одну задачу</h3><p>Одна из самых распространённых проблем в коде — комбайны, или перегруженные модули, которые выполняют сразу несколько несвязанных задач. Такой код сложно понимать, тестировать и изменять.</p><p>Принцип единой ответственности говорит о том, что каждый модуль (класс, функция, компонент) должен решать только одну задачу. Это делает код чище, понятнее и проще в сопровождении.</p><p>Если один модуль отвечает сразу за несколько задач, это приводит к нескольким проблемам:</p><ol><li>Любые правки могут затронуть совершенно несвязанные части кода;</li><li>Покрыть тестами такой модуль становится сложно, потому что у него слишком много точек отказа;</li><li>Если модуль выполняет несколько задач, его трудно переиспользовать в других частях системы.</li></ol><p><b>Если нарушить SRP:</b></p><p>Допустим, у нас есть класс OrderProcessor, который должен обработать заказ. Но вместо этого он делает слишком многое:</p><ul><li>Валидирует данные заказа;</li><li>Вычисляет стоимость;</li><li>Обрабатывает оплату;</li><li>Отправляет email-подтверждение.</li></ul><p>Что произойдёт, если нам нужно изменить процесс оплаты? Мы рискуем сломать логику валидации или отправки email, потому что всё завязано в одном месте.</p><p>Решение простое: разделить обязанности. Мы выносим каждую отдельную задачу в свой модуль или класс:</p><p>Теперь каждый класс отвечает только за свою задачу. Изменения в логике оплаты не затронут валидацию или отправку email, а тестировать каждый модуль можно отдельно.</p><p>SRP особенно полезен в ситуациях, где код часто меняется и развивается:</p><ul><li>В API и микросервисах — каждый сервис выполняет одну задачу, что упрощает поддержку;</li><li>В UI-компонентах — разделение логики интерфейса (рендеринг, обработка данных) помогает избежать громоздких компонентов;</li><li>В бизнес-логике — SRP делает код более гибким и адаптируемым под новые требования.</li></ul><h3>Слабая связность и высокая когезия: модули взаимодействуют минимально, но логика внутри них цельная</h3><p>Один из главных принципов хорошей модульной архитектуры — минимальная связность между модулями и максимальная цельность внутри каждого.</p><p><b>Связность (coupling)</b> — степень зависимости одного модуля от другого. Что происходит при высокой связности?</p><ol><li>Любые изменения ведут к каскадным поломкам — обновление одной части кода требует изменений во множестве других мест.</li><li>Тестирование становится сложным — чтобы протестировать один модуль, нужно учитывать все его зависимости.</li><li>Повторное использование затруднено — если модуль слишком тесно связан с кодом, его трудно применять в других проектах.</li></ol><p>Пример плохой высокой связности:</p><p>Здесь OrderProcessor напрямую создаёт экземпляр PaymentProcessor, что делает их жёстко связанными. Если нам понадобится заменить Пеймент на другую реализацию (например, добавить поддержку PayPal), возникнут трудности.</p><p>Но как уменьшить связность? Нужно использовать инъекцию зависимостей (Dependency Injection) и разделять интерфейсы и реализации:</p><p>Теперь OrderProcessor не зависит от конкретной реализации PaymentProcessor. Можно легко подставить другую реализацию, например, PayPalPaymentProcessor или StripePaymentProcessor, без изменений в основном коде.</p><p>Перейдем к<b> когезии (cohesion)</b>. Это степень связанности логики внутри одного модуля. Если модуль выполняет слишком много разрозненных задач, его сложно понимать и поддерживать. Что происходит при низкой когезии?</p><ol><li>Код выглядит хаотично — внутри одного модуля встречается разнородная логика, которая не должна быть связана.</li><li>Повышенный риск багов — разные части модуля зависят от несвязанных данных, что усложняет отладку.</li><li>Сложность изменений — разработчику приходится разбираться в неочевидных взаимосвязях.</li></ol><p>Например:</p><p>Этот класс отвечает за регистрацию, восстановление пароля и маркетинговые email-рассылки, хотя последние никак не связаны с первой парой функций. Как повысить когезию?</p><ul><li>Разделить модули по логическим зонам ответственности;</li><li>Выносить несвязанные задачи в отдельные сервисы.</li></ul><p>Пример высокой когезии:</p><p>Теперь UserManager отвечает только за управление пользователями, а EmailService занимается отправкой писем. Логика каждого модуля цельная и легко расширяется.</p><h4>Как достичь слабой связности и высокой когезии?</h4><ul><li>Используйте интерфейсы и абстракции вместо жёстких зависимостей;</li><li>Делите модули по логическим границам, а не по техническому признаку;</li><li>Изолируйте изменяемые части системы и старайтесь, чтобы модули менялись независимо;</li><li>Разрабатывайте чистые интерфейсы, которые скрывают детали реализации и позволяют легко заменять компоненты.</li></ul><h2>Чистые интерфейсы и контрактное программирование: API модулей должны быть понятными и стабильными</h2><p>Когда модули взаимодействуют между собой, их API должны быть чистыми, стабильными и интуитивно понятными. Если интерфейсы плохо спроектированы, это ведёт к хрупкому коду, сложному рефакторингу и куче неожиданных багов.</p><p><b>Чистый интерфейс </b>— это API модуля, которое:</p><ul><li>Не требует заглядывать в реализацию, чтобы понять, как использовать;</li></ul><ul><li>Не перегружено лишними методами;</li></ul><ul><li>Стабильное — изменения API минимально затрагивают пользователей.</li></ul><p>Плохой пример:</p><p>Этот метод делает слишком много:</p><ul><li>Сохраняет пользователя,</li><li>Отправляет email,</li><li>Логирует активность,</li><li>Обрабатывает override от администратора.</li></ul><p>Такой API трудно использовать: программисту придётся разбираться, какие параметры нужны, а какие — нет.</p><p>Пример чистого API:</p><p>Теперь каждая функция выполняет только одну задачу, а API остаётся предсказуемым и удобным.</p><p><b>Контрактное программирование</b> же означает, что каждый модуль:</p><ul><li>Ясно определяет, какие входные данные он принимает;</li><li>Гарантирует ожидаемый результат;</li><li>Защищается от некорректных данных.</li></ul><p>Пример контракта в коде:</p><p>Здесь чётко определено:</p><ul><li>Если сумма заказа ≤ 0, метод выбросит ошибку.</li></ul><ul><li>Если плата прошла успешно, метод вернёт PaymentResult.Success = true.</li></ul><h4>Как проектировать чистые интерфейсы?</h4><ul><li>API должен быть понятен без чтения документации;</li></ul><ul><li>Чем меньше точек входа, тем проще сопровождать код;</li></ul><ul><li>Если метод принимает bool-флаги, вероятно, его стоит разбить на несколько методов;</li></ul><ul><li>Лучше сделать API чуть менее удобным, но не ломающим обратную совместимость.</li></ul><h3>Простота в тестировании: возможность заменить модули заглушками и писать юнит-тесты</h3><p>Одна из главных причин, почему модульность критически важна — простота тестирования. Хорошо спроектированные модули позволяют легко изолировать отдельные компоненты и тестировать их независимо друг от друга.</p><p>Когда код монолитный и сильно связан, тестирование становится головной болью:</p><ul><li>Один тест может затрагивать десятки зависимостей;</li></ul><ul><li>Невозможно протестировать отдельную функцию без запуска всего приложения;</li></ul><ul><li>Каждый новый баг ломает кучу тестов, потому что код слишком взаимозависимый.</li></ul><p>Но как модульность помогает тестировать код?</p><h4>Можно заменять реальные модули заглушками (моками, стабами, фейками)</h4><p>Если модули слабо связаны, их можно легко подменять тестовыми заглушками. Это позволяет тестировать поведение кода без зависимостей от внешних сервисов или базы данных.</p><p>Пример без модульности:</p><p>Здесь OrderService жёстко завязан на PaymentProcessor, и в тесте мы не сможем подменить его заглушкой.</p><p>Пример с модульностью:</p><p>Теперь мы можем подменять IPaymentProcessor тестовой заглушкой:</p><p>В тесте вместо реального PaymentProcessor подставляем FakePaymentProcessor</p><h4>Легко писать юнит-тесты для отдельных частей кода</h4><p>Когда модули независимы, можно тестировать их по отдельности, не задействуя всю систему.</p><p>Пример юнит-теста с моками:</p><p>Здесь мы проверяем, был ли вызван метод ProcessPayment(), но не запускаем реальную оплату.</p><h4>Можно легко писать интеграционные тесты, используя только нужные связки</h4><p>Модульность позволяет запускать только нужные части системы. Например, можно тестировать API без базы данных, заменяя её на memory-версию.</p><p>Пример тестирования API без реальной базы:</p><p>Здесь TestDbContext — in-memory база, которая не трогает продовые данные.</p><p>Чем лучше организованы модули, тем быстрее можно покрыть код тестами, находить баги и поддерживать систему в рабочем состоянии.</p><h2>Как правильно разбивать код на модули?</h2><p>Окей, мы разобрались, что модульность полезна. Но как её грамотно внедрить? Если просто начать «резать» код на части без продуманной структуры, можно создать хаос вместо удобной системы. В этом разделе разберёмся, как правильно организовать модули, чтобы они реально упростили поддержку проекта.</p><h3>Думайте о модулях с самого начала</h3><p>Ошибку многих разработчиков можно описать так: сначала пишем код как получится, а потом пытаемся нарезать его на модули. Это плохая стратегия — в реальности проще сразу спроектировать систему модульной. Что важно продумать на старте?</p><ul><li>Какие ключевые бизнес-объекты в проекте (например, «Пользователи», «Заказы», «Оплата»);</li><li>Какие у них чёткие границы (UserModule не должен отвечать за Payments);</li><li>Какие взаимодействия между ними (какие API вызывают друг друга).</li></ul><p><b>Пример проектирования модульной системы (возьмем e-commerce):</b></p><p>В интернет-магазине можно выделить такие модули:</p><ul><li>UserModule — управление пользователями;</li><li>CatalogModule — товары и категории;</li><li>CartModule — корзина покупок;</li><li>OrderModule — оформление заказов;</li><li>PaymentModule — платежи.</li></ul><p>Каждый модуль должен иметь своё API и не лезть в чужие данные напрямую.</p><p>Как делать НЕ надо:</p><p>Здесь OrderService вмешивается в чужие модули (работает с UserRepository и PaymentService). Это создаёт жёсткую связанность.</p><p>Как надо:</p><p>Теперь OrderService не лезет внутрь других модулей, а взаимодействует с ними через интерфейсы. Это делает код более гибким и удобным для тестирования.</p><h3>Выделяйте независимые модули по принципу «Один модуль = одна ответственность»</h3><p>Следующий шаг — определить логические единицы, которые можно вынести в модули. Плохая практика — модули по слоям (например, один модуль для всех контроллеров, другой для всех сервисов). Это создаёт горизонтальные зависимости, из-за которых код сложно изменять.</p><p>Хорошая практика — модули по бизнес-областям (например, UserModule, OrderModule, PaymentModule)</p><p>Пример:</p><p>Каждый модуль самодостаточен:</p><ul><li>В user хранятся все файлы, связанные с пользователями;</li><li>В order — всё, что касается заказов;</li><li>В payment — логика работы с платежами.</li></ul><h3>Минимизируйте связи между модулями: слабая связанность и чёткие контракты</h3><p>Главная цель модульности — сделать систему гибкой и расширяемой. Поэтому между модулями должны быть чёткие контракты, а не хаотичные вызовы методов. Как правильно?</p><ul><li>Каждый модуль предоставляет API для взаимодействия;</li><li>Взаимодействие между модулями происходит через интерфейсы или события;</li><li>Модули не лезут друг другу в базы данных.</li></ul><p>Пример с хорошими контрактами:</p><p>Теперь модули работают только через API, а их внутреннюю реализацию можно менять без влияния на другие части системы.</p><h3>Не усложняйте: модульность ≠ миллион мелких файлов</h3><p>Ошибка многих разработчиков: разбить код на слишком много маленьких модулей. В результате каждая задача требует работы с десятками зависимостей, что делает поддержку сложнее.</p><p>Как НЕ надо:</p><p>Зачем так делать? Теперь, чтобы просто добавить новый API-метод, нужно создавать новый файл.</p><p>Как лучше:</p><p>Модуль должен быть логически целостным, а не разрезанным на микросервисы внутри проекта.</p><p>Разбить код на модули — это не просто про удобство. Это про гибкость, тестируемость и возможность развития проекта. Удачи с модульностью!</p>]]></content:encoded>
    </item>
    <item>
      <title>Топовые паттерны для разработки архитектуры ПО</title>
      <link>https://tproger.ru/articles/topovye-patterny-dlya-razrabotki-arhitektury-po</link>
      <comments>https://tproger.ru/articles/topovye-patterny-dlya-razrabotki-arhitektury-po?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Анна Ельцова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/topovye-patterny-dlya-razrabotki-arhitektury-po</guid>
      <description><![CDATA[<p>
Паттерны проектирования архитектуры ПО. Показываем виды паттернов и их особенности. Рассматриваем пошаговую инструкцию и основные нюансы ✔ Tproger</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/topovye-patterny-dlya-razrabotki-arhitektury-po">Топовые паттерны для разработки архитектуры ПО</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Архитектура ПО]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Облачные технологии]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 24 Feb 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Когда речь идет о проектировании системы, важно понимать, что выбор архитектурного паттерна зависит от множества факторов. Универсального решения вы не найдете, но есть проверенные подходы, которые помогают сделать выбор в пользу эффективных инструментов. При этом важно учитывать:</p><ul><li>каких вы придерживаетесь трейдофов;</li><li>какие требования у бизнеса, команды;</li><li>какое техническое окружение;</li><li>насколько система должна быть масштабируемой и отказоустойчивой;</li><li>какая модель данных наиболее эффективная.</li></ul><p>Вместе с <a href="https://solvery.io/ru/mentor/igorwalther?utm_source=article&amp;utm_medium=partner&amp;utm_term=tproger&amp;utm_content=Architecture&amp;utm_campaign=Igor_Panasyuk">Игорем Панасюком</a>, разработчиком в финтехе Яндекса и ментором <a href="https://solvery.io/?utm_source=article&amp;utm_medium=partner&amp;utm_term=tproger&amp;utm_content=cicd&amp;utm_campaign=main_page">Solvery</a>, разбираемся, какие есть антипаттерны в разработке архитектуры, а какие подходы действительно эффективны и для чего нужны.</p><h2>Для начала: антипаттерны и частые ошибки</h2><p>Антипаттерны могут привести к сложному, плохо поддерживаемому или неэффективному коду. Ниже — несколько примеров.</p><h3>Distributed Monolith</h3><blockquote>На мой взгляд, частая проблема в настоящее время — это Distributed Monolith, то есть микросервисы, которые имеют очень сильную связность — в таком случае лучше сделать обычный монолит.</blockquote><p>В результате:</p><ul><li>При деплое одного сервиса нужно обновлять все остальные.</li><li>Сервисы жёстко связаны через API.</li><li>Не получается горизонтально масштабировать.</li></ul><p>Например, у нас есть три микросервиса: заказы, оплата и пользователи. При этом сервис «Заказы» напрямую вызывает остальные сервисы, и наоборот. Так, если в одном сервисе поменяется API, остальные перестанут работать.</p><p>Чтобы исправить, можно использовать, например, асинхронную коммуникацию через Kafka.</p><h3>Микролиты</h3><p>Архитектура по идее микросервисная, но каждый микросервис настолько сложный, что превращается в «маленький монолит». Да, у сервиса есть собственная база данных, но код все равно сложно поддерживать и масштабировать.</p><p>Например, есть сервис «Каталог товаров». По идее, он должен быть простым, но в него добавили еще и данные о всех заказах, пользователях и платежах. Как результат — десятки зависимостей и сложная бизнес-логика.</p><p>Чтобы не было такой путаницы, упрощайте сервисы и следуйте принципу: «один сервис — одна ответственность».</p><h3>Многослойность</h3><p>Архитектура перегружена кучей слоев, например, API → сервис → репозиторий → DAO → DTO → и так далее. Причем каждый слой выполняет какую-то минимальную работу и банально вызывает следующий.</p><p>Каждый слой просто прокидывает вызовы и практически не несет ценности. Здесь важно помнить: если все, что делает слой, — это делегирует вызовы, он вам не нужен.</p><p>А теперь рассказываем, какие паттерны при разработке архитектуры будут эффективными.</p><h2>Паттерны для предоставления данных и управления</h2><p>Наиболее популярные паттерны для предоставления данных — MVC, MVVM и MVP. Рассказываем, чем они отличаются.</p><h3>MVC (Model-View-Controller)</h3><p>Этот паттерн делит приложение на три компонента: Model — хранит бизнес-логику, View — отображает UI, и Controller — обрабатывает ввод пользователя, следит за Model и View. Работает это так:</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-02-21/788cc440-7188-4617-b4f9-2c11f64654a9.png" alt="" /></figure><p>Пример — пользователь хочет авторизоваться на сайте:</p><ol><li>Юзер вводит логин и пароль окно входа — через View.</li><li>View отправляет данные в Controller.</li><li>Controller передает логин и пароль в Model, которая проверяет их в базе данных.</li><li>Model возвращает результат (успешная или неуспешная аутентификация).</li><li>Controller обновляет View — он выводит либо сообщение, что все успешно, либо ошибку, например, «Неверный логин или пароль».</li></ol><h3>MVVM (Model-View-ViewModel)</h3><p>В этом паттерне тоже три компонента, но немного другие: Model — тоже отвечает за логику, View — UI, который поддерживает привязку данных (data binding), ViewModel — преобразует данные Model для View, содержит команды для обработки действий. Вот схема:</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-02-21/b4c9d430-4fb4-4989-a7e6-8e5c4ceed127.png" alt="" /></figure><p>Пример — пользователь хочет добавить новую задачу в список.</p><ol><li>Пользователь вводит новую задачу в поле ввода через View.</li><li>View автоматически передает данные в ViewModel через двустороннюю привязку.</li><li>ViewModel обновляет Model, например, заносит новую задачу в базу данных.</li><li>Model говорит ViewModel, что данные изменились.</li><li>ViewModel обновляет View, и на экране появляется новая задача, но без явного вызова апдейта интерфейса.</li></ol><h3>MVP (Model-View-Presenter)</h3><p>В этом паттерне лежат: Model, View — здесь это пассивный UI, Presenter — посредник между View и Model, плюс в нем есть логика отображения. Работает это вот так:</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-02-21/fb3613d5-574d-4a65-bb78-6be35440b3d3.png" alt="" /></figure><p>Пример — приложение, где есть чат.</p><ol><li>Пользователь набирает сообщение и нажимает «Отправить» или просто кнопку через View.</li><li>View передает этот текст в Presenter, и он вызывает Model, который отправляет сообщение на сервер.</li><li>Когда сообщение отправлено, сервер возвращает подтверждение Model, а он говорит об этом Presenter.</li><li>Presenter обновляет View, добавляя это сообщение в интерфейс.</li><li>Когда приходит новое сообщение от друга/коллеги, Model получает его из сети и передает Presenter.</li><li>Presenter обновляет View и отображает новое сообщение в чате.</li></ol><blockquote>Мы используем MVC при разработке бэкенда, MVVM — при кодинге на Angular и Vue, а MVP — для разработки UI на Android.</blockquote><p>А для управления данными можно использовать:</p><ul><li>Repository — абстрагирует доступ к данным и минимизирует зависимость от конкретной базы данных.</li></ul><blockquote>Важно разделять Repository на несколько интерфейсов (interface segregation). Для транзакций в распределенных системах можно использовать Saga или outbox + event bus.</blockquote><ul><li>Unit of Work — контролирует транзакции на уровне логики.</li><li>Active Record — связывает объекты с таблицами баз данных и просто упрощает работу.</li></ul><h2>Паттерны распределительных систем</h2><p>Микросервисы, Event-driven архитектура и CQRS помогают создавать масштабируемые и отказоустойчивые приложения. Рассмотрим их подробнее.</p><h3>Микросервисы</h3><p>В микросервисах приложение разбивается на небольшие, независимые сервисы, каждый из которых отвечает за конкретную бизнес-логику. Сервисы взаимодействуют друг с другом через API (обычно это HTTP или gRPC).</p><p>Микросервисы позволяют развертывать и масштабировать каждый сервис по отдельности. Плюс они могут разрабатываться на разных технологиях, например, языках и базах данных.</p><h4>Пример</h4><p>В приложении онлайн-магазина могут быть такие сервисы — User/Client Service, Product Order Service и Payment Service. Очевидно, что такой паттерн подойдет только большим приложениям, поэтому использовать микросервисы ради того, чтобы использовать — бессмысленно. В таком случае лучше остановиться на монолите.</p><blockquote>На мой взгляд, самая частая проблема — согласованность данных. В монолите гораздо проще её обеспечить средствами единого адресного пространства. Если мы говорим про подходы к декомпозиции, обычно используют декомпозицию по данным или доменной логике.</blockquote><p>Чтобы микросервисы работали четко, нужно грамотно организовать мониторинг, логирование и управление конфигами. Плюс нужен Kubernetes и API-шлюзы.</p><h3>Event-driven архитектура</h3><p>Это один из главных трендов последних лет. Подробнее о этой архитектуре можно почитать в нашей <a href="https://tproger.ru/articles/event-driven-arhitektura--principy-i-primery-ispolzovaniya">статье</a>.</p><p>Event-driven архитектура — это подход, при котором компоненты системы взаимодействуют через события. Сами события генерируются при изменении состояния системы и обрабатываются нужными компонентами.</p><p>Другими словами, все работает ассинхронно, то есть компоненты не блокируют друг друга, ожидая ответа — они буквально не знают друг о друге, а только реагируют на события. Плюс можно легко масштабировать и добавлять новые обработчики событий.</p><h4>Пример</h4><p>Тот же самый интернет-магазин:</p><ol><li>Пользователь создает заказ (создается событие).</li><li>Сервис уведомлений отправляет, например, пуш или письмо юзеру.</li><li>Сервис склада бронирует товары.</li><li>Сервис оплаты проводит транзакцию.</li></ol><h3>CQRS (Command Query Responsibility Segregation)</h3><p>CQRS — это паттерн, который разделяет логику команд и запросов. Для чтения (Query) и записи (Command) используются разные модели данных — так можно оптимизировать каждую операцию.</p><p>Архитектура здесь будет непростая, поэтому использовать CQRS нужно в приложениях, где будет высокая нагрузка на чтение.</p><h4>Пример</h4><p>Это может быть большой блог или медиа. Работать будет так:</p><ul><li>Через Command будут добавляться новые статьи или обновляться предыдущие.</li><li>Через Query будет, например, происходить поиск по ключевым словам или собираться список статей по тегам.</li></ul><p>Эти паттерны часто используются вместе. Например, в микросервисной архитектуре можно применять Event-driven подход, чтобы взаимодействовать между сервсами, а CQRS — для оптимизации операций чтения и записи.</p><h2>Паттерны для масштабируемости</h2><p>Если у вас падает один компонент, он не должен тянуть за собой всю систему и влиять на пользователей. Для этого есть паттерны, которые повышают надежность приложения.</p><h3>Circuit Breaker</h3><p>Этот паттерн работает как электрический предохранитель: если в одном из сервисов вылезла ошибка, например, он медленно отвечает, Circuit Breaker разрывает соединение и предотвращает перегрузку всей системы и каскадные сбои. Так, система не продолжает отправлять неудачные запросы, а переключается в режим ожидания, и затем периодически проверяет, работает ли сервис. Подходит для распределенных систем, где один упавший сервис может повлиять на всю цепочку вызовов.</p><p>Например, вы делаете покупку на маркетплейсе, и у в нем упал платежный сервис. В таком случае Circuit Breaker временно блокирует запросы и говорит пользователю, что нужно попробовать оплатить позже.</p><h3>Load Balancer</h3><p>Этот паттерн помогает равномерно распределять нагрузку и логический роутинг, предотвращая перегрузку отдельных узлов. Он следит за доступностью сервисов и отправляет запросы только к работающим компонентам. Особенно подходит облачным средах, где количество активных серверов может динамически изменяться.</p><p>Например, в стриминговом сервисе Load Balancer распределяет пользователей между разными серверами, чтобы не было перегрузки и они могли спокойно смотреть контент без задержек.</p><h3>Retry (exponential backoff with jitter)</h3><p>Паттерн нужен для повторения идемпотентного действия, которое завершилось безуспешно. Так, некоторые ошибки бывают кратковременными, и вместо немедленной блокировки запроса, Retry позволяет повторить запрос, но с увеличенным интервалом между попытками (экспоненциальная задержка). А добавление случайного разброса времени (jitter) помогает избежать ситуации, когда все запросы повторяются одновременно, вызывая новую перегрузку.</p><p>Например, вы пытаетесь купить билеты в театр на большую премьеру, но вместе с вами на сайте сидят еще 10 000 человек. Сервер временно перегружен, но система не сразу выдаст ошибку, а будет пытаться найти вам хотя бы какое-то место (где-то на последнем ряду балкона).</p><h2>Паттерны безопасности</h2><ul><li><b>OAuth 2.0</b> — стандартное решение. Он позволяет пользователям предоставлять доступ к своим данным сторонним сервисам без передачи пароля. Например, зарегистрироваться на сайте через Google, Яндекс или VK.</li><li><b>TLS (Transport Layer Security)</b>, криптографический протокол, шифрует данные при передаче.</li><li><b>AES</b> один из самых надежных алгоритмов симметричного шифрования. Его часто используют в базах данных или кеше.</li><li><b>Token-based Security</b> — безопасная аутентификация с JWT. В основе лежит цифровая подпись (обычно HMAC или RSA) — она гарантирует подлинность данных.</li><li>В финтехе используют <b>HSM</b> для генерации и защиты криптографических ключей на аппаратном уровне.</li></ul><p>Выбор паттерна — компромисс между гибкостью, производительностью и надежностью. Главное — учитывать требования бизнеса и технические ограничения. Плюс сейчас практически везде есть искусственный интеллект и облачные технологии, которые позволяют автоматизировать инфраструктуру, например, с помощью Terraform — о них тоже не нужно забывать.</p><p>И поскольку даже опытные разработчики сталкиваются с дилеммами при выборе подходящей модели, <a href="https://solvery.io/?utm_source=article&amp;utm_medium=partner&amp;utm_term=tproger&amp;utm_content=patterny_razrabotki&amp;utm_campaign=main_page">на Solvery</a> вы можете разобрать ваш проект и получить обратную связь от архитекторов и разработчиков уровня Яндекса, Авито и Т-Банка.</p><p>Если хотите сохранить короткую версию статьи — <a href="https://vk.com/wall-30666517_1857999">у нас есть она в ВК.</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Go-разработчик 2025: что нужно знать на каждом грейде</title>
      <link>https://tproger.ru/articles/go-razrabotchik-2025--chto-nuzhno-znat-na-kazhdom-grejde</link>
      <comments>https://tproger.ru/articles/go-razrabotchik-2025--chto-nuzhno-znat-na-kazhdom-grejde?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Danil Dinko]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/go-razrabotchik-2025--chto-nuzhno-znat-na-kazhdom-grejde</guid>
      <description><![CDATA[<p>Даниил Динько, тимлид в компании-лидере в международном кибербезе и эксперт Эйч Навыки, собрал стартер-паки для Go-разработчика каждого уровня.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/go-razrabotchik-2025--chto-nuzhno-znat-na-kazhdom-grejde">Go-разработчик 2025: что нужно знать на каждом грейде</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Golang]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 19 Feb 2025 10:00:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Грейды — штука абстрактная, поскольку у каждой компании есть свое мнение на этот счет. Для одних ты можешь быть джуном+, а для других — сильным сеньором. Тем не менее, можно однозначно наметить общие тренды в требованиях по индустрии.</p><p>Я — <a href="https://h.careers/curators/daniil-dinko?utm_source=tg_bot&amp;utm_medium=rassilka&amp;utm_campaign=161024">Даниил Динько</a>, веду свой личный <a href="https://t.me/thestrikemch">телеграм-канал</a>, где рассказываю о себе, об IT и о Golang. Также являюсь экспертом и спикером в компании <a href="https://h.careers/skills?utm_source=site_tproger&amp;utm_medium=article">Эйч Навыки</a>, TeamLeadом в компании-лидере в международном кибербезе, ex. старшим разработчиком в Ozon Tech. Вместе разбираемся, что объединяет Go-разрабов каждого грейда.</p><p>А почитать о том, как сейчас стать Go-разрабом, можно в предыдущей <a href="https://tproger.ru/articles/kak-sejchas-stat-go-razrabotchikom-s-nulya--vse-puti">статье</a>.</p><h2>Навык собеседований vs. навык работы</h2><p>Для начала важно разделять два понятия: навык прохождения собеседований и навык работы. Интервью длится 3-4 часа — этого невероятно мало, чтобы прочувствовать весь ваш кругозор в бою, поэтому индустрия использует стандартные задачи-заглушки. У большинства компаний такие задачи примерно про одно и то же, поэтому сейчас не редка ситуация, когда на собеседовании ваш реальный грейд на единицу или полторы выше реального — как раз потому, что такие заглушки отскакивают от зубов.</p><ul><li><b>Что это значит для кандидата:</b> в такой ситуации можно быстрее вырасти в реальном навыке работы, потому что через навык собеседований вы получаете грейд. Эти задачи не даются просто так на позиции, которая соответствует навыку реальной работы. Так, в стрессовой ситуации вы максимально выравниваетесь за короткий срок.</li><li><b>Что это значит для компании:</b> для работодателя это плохо, поскольку  определить грейд —  еще сложнее. И есть шанс нанять кандидата, на которого потратят больше денег, чем он теоретически может принести.</li></ul><p>Теперь разберем, что требуется от Go-разработчиков на каждом уровне.</p><h2>Что нужно с точки зрения навыка собеседований</h2><p>Сейчас интервью стали гораздо жестче: конкуренция растет, а требования к кандидатам повышаются.</p><p>Дисклеймер: не обязательно знать все из списка ниже — в нем представлено максимальное количество навыков и верхняя граница знаний по грейду. Поэтому если вы что-то не знаете, это отличный способ понять, что наверстывать.</p><h3>Грейд: Junior</h3><p>Сейчас на рынке Go очень много джунов — он перегрет, и попасть в компанию без коммерческого опыта будет крайне сложно. Более того, от начинающих разработчиков ждут немало знаний и навыков. О них — ниже.</p><h4>Углубленное знание Go</h4><ul><li>Уметь абстрактно рассказать про очереди в планировщике.</li><li>Знать про мапу под капотом: как устроено хеширование, коллизии и разрешение конфликтов.</li><li>Уметь решать задачи по concurrency на относительно базовом уровне (воркер пул) и на слайсы</li><li>Понимать принципы работы горутин и каналов.</li></ul><h4>Базы данных</h4><ul><li>Знать виды баз данных и рассказать про максимальное количество юзкейсов из опыта с разными типами данных.</li><li>Знать индексы и ACID и уметь их базово  писать.</li><li>Знать SQL, уметь составлять схемы и идейно понимать, как работают самые известные базы —  PostgreSQL, ClickHouse.</li><li>Понимать репликацию и шардирование</li></ul><h4>Системный дизайн</h4><p>Да-да, теперь даже джуну нужно иметь абстрактное понимание сисдиза:</p><ul><li>Монолит vs. микросервисы: знать плюсы и минусы каждой архитектуры.</li><li>Знать варианты коммуникаций между сервисами (брокеры сообщений, REST API, gRPC).</li></ul><h4>Алгосы и Computer Science</h4><ul><li>Уметь решать медиум-задачки на LeetCode. Фокус при этом на задачах со слайсами, деревьями и графами.</li><li>В Computer Science — знать про устройство Linux, планировщик, потоки/процессы, а еще про устройство сети — OSI, TCP/IP, протоколы и т.д.</li></ul><p>Также  в некоторых компаниях сейчас ко всему этому требуют еще и знание Kubernetes.</p><p>Вот <a href="https://miro.com/app/board/uXjVLGihxYs=/">здесь</a> собрал дорожную карту, как влиться в IT на примере Go. Из полезных ссылок:</p><ol><li><a href="https://www.youtube.com/watch?v=eQPfHdiz_KI">Один из лучших курсов по Go на Youtube</a></li><li><a href="https://www.youtube.com/watch?v=d6BtxBKhQoc&amp;t=3178s">Крутой урок по системному дизайну</a></li><li><a href="https://www.youtube.com/watch?v=ZTJcaP4G4JM">Все про каналы в Go</a></li></ol><p>А <a href="https://miro.com/app/board/uXjVLIldoLE=/">здесь</a> можно посмотреть, как джуну стать мидлом.</p><h3>Грейд: Middle</h3><p>Схема примерно такая же, как и с джунами, правда, знать все нужно гораздо глубже.</p><h4>Go</h4><ul><li>Знать планировщик на уровне того, какая структура данных используется в локальных очередях.</li><li>В слайсах — уметь решать задачи со срезом по capacity, плюс более уверенное решение кейсов по concurrency.</li></ul><h4>Базы данных</h4><ul><li>MVCC,</li><li>Проблема разбухания индексов,</li><li>Селективность,</li><li>Шардирование на уровне реальных решений основной проблемы решардинга — Consistent Hash,</li><li>Реприликация и паттерн Raft.</li></ul><p>А еще важно уметь писать нормальные индексы и эффективные SQL запросы. Плюс ожидается, что у вас будет больше юзкейсов работы с разными типами баз данных.</p><h4>Сисдиз</h4><p>Нужно знать про паттерны межсервисного взаимодействия: Saga, Transactional Outbox, Circuit Breaker. На мидла могут уже спокойно давать практические задачи на внедрение каких-то идейных дизайнерских штук, например, идемпотентности.</p><h4>Алгосы и Computer Science</h4><p>Здесь они играют меньшую роль. Главное — показать коммерческий опыт, рассказать о кейсах и блеснуть знаниями в Go, базах и проектировании.</p><h3>Грейд: Senior</h3><p>Сеньоры — моя любимая тема, самый абстрактный и спорный грейд. Здесь требуется все то же, что и на мидла, но знания должны быть еще более глубокие. Вот примерный список:</p><h4>Go</h4><p>Нужно знать библиотеку Reflection со всякими приколами, которые могут ускорить concurrency. Также разбираться в аренах памяти и планировщике.</p><h4>Сисдиз</h4><p>В паттернах межсетевого взаимодействия история с обычным рассказом не пройдет — юзкейсы здесь must-have. Поэтому важно уметь проходить System Design-интервью — собирать функциональные и нефункциональные требования, считать нагрузку, проектировать на разных уровнях абстракции, углубляться и решать проблемы в своей же архитектуре. Это сложно, и без хотя бы косвенного соприкосновения с проектированием, будет непросто. Поэтому в качестве совета — стремитесь максимально участвовать на архитектурных сессиях и грумингах, будучи мидлом.</p><h4>Базы данных</h4><p>Будет круто знать, как под капотом реализован, например, PostgreSQL: как он поднимает что-то в буфер, как хранит данные на диске, что такое чекпоинты и бэкапы и как реализована MVCC.</p><p>В случае с ClickHouse лучше верхнеуровнево понимать LSM-дерево, а с ElasticSearch — инвертированные индексы.</p><h4>Алгосы и Computer Science</h4><p>Алгоритмы уже почти не играют роли в большинстве компаний, а Computer Science требуется примерно на том же уровне, что и на джуна. Единственное — в Linux могут чуть капнуть.</p><p>Также в зависимости от компании могут требовать углубленные знания в DevOps, но мы про это говорить не будем — не самый частый кейс. Однако базовое понимание того, как что развернуть, какие могут быть проблемы и как их решить идейно, должно быть.</p><p>Мне часто на трансляциях говорят: «Зачем мне знать планировщик или уметь решать сложные задачи по concurrency? Когда мне это пригодится в работе?». Действительно, на эффективность в решении рабочих задач это влияет незначительно, но все же это особенность собеседований (подробнее можно посмотреть <a href="https://t.me/thestrikemch/68">здесь</a>):</p><ul><li><b>Собес ≠ работа. </b>Принято считать, что знания, требуемые на собеседовании, пригодятся в работе — это не так. За несколько часов невозможно полностью оценить кандидата, поэтому интервью строятся на проверке общих знаний и концепций.</li><li><b>Почему спрашивают про планировщик?</b> Банально узнают софты.</li><li><b>Жесткая конкуренция. </b>Все просто: знание — сила.</li></ul><h2>Что нужно с точки зрения реальной работы</h2><p>На мой взгляд, самое важное, помимо знания технологий — прокаченные софт-скиллы. И наработать их можно только с опытом.</p><ul><li><b>Грейд Junior.</b> Нужно уметь делать максимально базовые задачи. Например, добавить поле или прокинуть фича-флаг. Или же при курировании и ревью быть мотивированными. Этого достаточно. Да, как бы грустно это ни звучало, здесь по классике предполагается, что тебе нельзя доверить что-то серьезное без сторонней помощи.</li><li><b>Грейд Middle.</b> Относительно безболезненно брать на себя полноценные части продукта в зону ответственности, фича-лидить. Здесь предполагается, что ты можешь действовать относительно самостоятельно, приходя с вопросами лишь иногда. Тут уже желательно участвовать в каких-либо технических обсуждениях.</li><li><b>Грейд Senior.</b> Здесь нужно разрабатывать фичи любого уровня сложности под ключ. Тебе достаточно предоставить бизнес-требования, сходить с ними по командам с экспертизой. Затем спроектировать качественную архитектуру, которая развалится с минимальной вероятностью, самому реализовать и принести лиду  таску в Done. Здесь также важно менторить сотрудников, активнейшим образом участвовать на грумингах и любых других технических созвонах.</li></ul><p>Конкуренция растет, требования становятся все жестче, поэтому самое главное — постоянное развитие. Учитесь, ходите на собеседования, участвуйте в грумингах и обсуждениях. И помните, что навык проходить интервью и реальная работа — разные вещи, но без них никуда.</p>]]></content:encoded>
    </item>
    <item>
      <title>Pub/Sub — когда нужно масштабировать приложения</title>
      <link>https://tproger.ru/articles/pub-sub---kogda-nuzhno-maswtabirovat-prilozheniya</link>
      <comments>https://tproger.ru/articles/pub-sub---kogda-nuzhno-maswtabirovat-prilozheniya?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Сергей Лалетин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/pub-sub---kogda-nuzhno-maswtabirovat-prilozheniya</guid>
      <description><![CDATA[<p>Узнайте, как работает архитектура Pub/Sub для масштабирования приложений, организации обмена данными между микросервисами и создания надёжных систем. Примеры с Apache Kafka, RabbitMQ и Redis.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/pub-sub---kogda-nuzhno-maswtabirovat-prilozheniya">Pub/Sub — когда нужно масштабировать приложения</a>»</p>]]></description>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Асинхронное программирование]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sat, 28 Dec 2024 09:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Когда нужно создать приложение, которое будет справляться с большим количеством пользователей и данных, разработчики используют подход Pub/Sub (сокращение от англ. Publisher/Subscriber, то есть Издатель/Подписчик). Проще всего сравнить эту модель с рассылкой новостей:</p><ul><li><b>Издатель </b>— это тот, кто отправляет информацию. Например, новостной сайт.</li><li><b>Подписчик</b> — это тот, кто подписался и хочет получать информацию. Например, читатель новостного сайта, — он будет получать уведомления о новых статьях.</li></ul><p>Pub/Sub помогает создавать надёжные и быстрые приложения, даже если пользователей много. О том, как это работает, читайте ниже.</p><h2>Что внутри Pub/Sub</h2><p>Чтобы было проще понять, как устроена архитектура Pub/Sub, приведём простую аналогию. Представьте, что у вас есть канал в Telegram. Автор канала (Publisher) пишет сообщение, а все участники (Subscribers) его получают. Если один из подписчиков покидает канал или кто-то, наоборот, присоединяется, автору ничего не нужно менять — он, как и раньше, публикует посты, уведомления о которых приходят всем, кто подписан на этот канал.</p><p>Большие приложения состоят из множества независимых частей — микросервисов. Чтобы приложение работало правильно, микросервисы должны быстро обмениваться данными. И как раз для этого разработчики и используют подход Pub/Sub.</p><p>Мы уже рассказали об издателях и подписчиках, но в этой архитектуре также участвуют и брокеры (или посредники) — именно они отвечают за доставку сообщений.</p><p>Забегая вперёд скажем, что именно брокер обеспечивает масштабируемость в системе. Он организует передачу сообщений и не блокирует выполнение других операций, даже если участников становится очень много. Код брокера обычно пишут на Python или Java, используя при этом дополнительные библиотеки.</p><p>Главная идея такая: издатель не знает, кто получит его сообщения, а подписчики не запрашивают эти сообщения напрямую. Всё происходит через посредника. Это работает следующим образом:</p><ol><li>Издатель отправляет сообщение (например, текст или видео) в определённый канал — он называется темой (Topic).</li><li>Получатели подписываются на нужную тему, чтобы принимать эти сообщения.</li><li>Как только сообщение отправлено в тему, все подписчики его получают.</li></ol><p>Этот процесс проиллюстрирован на следующей схеме:</p><figure><img src="https://media.tproger.ru/user-uploads/100503/2024-12-19/d0de5fc7-4786-41fa-a1d5-881e7f3a7cfb.png" alt="" /><figcaption>Помимо всех действующих лиц на схеме вы можете увидеть каналы. Input channel — это место, куда издатель отправляет сообщения, а output channel — место, откуда подписчики получают эти сообщения.</figcaption></figure><p>Обмен сообщениями происходит асинхронно. Это значит, что отправитель (или издатель) не ждёт, когда получатель (или подписчик) обработает сообщение. Поэтому компоненты приложения могут работать независимо друг от друга, но при этом обмениваться данными.</p><p>Паттерн Pub/Sub тем и отличается от стандартных алгоритмов, в которых очередь из сообщений продолжает формироваться, пока пользователи либо службы не сделают запрос и не извлекут их.</p><p>Итак, почему же эта архитектура так удобна?</p><p>Суть в том, что разработчикам не нужно вручную прописывать, кто кому и что отправляет. Например, если издатель опубликовал событие «пользователь сделал заказ», система сама оповестит все нужные сервисы: склад получит команду проверить товар, доставка начнёт планировать маршрут, а клиент получит соответствующее уведомление. И всё это будет происходить параллельно.</p><p>Сообщение обязательно дойдёт до всех подписчиков, если они не настроили фильтры, чтобы его игнорировать. Например, если один сервис подписан только на сообщения «заказы», он не будет получать данные из темы «новые пользователи».</p><p>Теперь для наглядности приведём пример простого кода брокера.</p><h2>Пример кода брокера на Python</h2><p>Код можно написать на разных языках, но для примера мы возьмем Python — просто потому, что его легче понять. Мы используем популярную библиотеку для работы с очередями — asyncio. А чтобы продемонстрировать случайную задержку при обработке сообщений, используем библиотеку random.</p><p>В коде реализовано всё то, о чём мы говорили выше: когда издатель публикует сообщение, оно мгновенно передаётся всем подписчикам, которые подписаны на соответствующую тему. Далее каждый подписчик асинхронно обрабатывает сообщение (с задержкой, чтобы имитировать реальную работу приложения).</p><p>Этот код — очень простой пример реализации брокера. Для более сложных систем, например, с постоянным хранением сообщений, обработкой ошибок и масштабированием, нужна инфраструктура серьёзнее. Для её создания используют внешние брокеры сообщений — те же <b>RabbitMQ</b> или <b>Apache Kafka</b>. Об этом мы рассказываем ниже.</p><h2>Как выбрать инструменты для реализации Pub/Sub</h2><p>Как мы уже сказали, брокера для Pub/Sub можно написать на разных языках с использованием дополнительных библиотек. Выбор зависит от масштаба проекта, специфики, количества пользователей.</p><p>Рассмотрим наиболее популярные инструменты.</p><h3>Apache Kafka</h3><p>Это платформа для обмена данными между приложениями в реальном времени. Она позволяет передавать большие объёмы информации быстро и надёжно — можно не переживать, что данные будут потеряны.</p><p>Например, если приложение A хочет отправить данные приложению B, оно не делает это напрямую, а отправляет сообщение в Kafka. Kafka сохраняет эти сообщения и передает их всем заинтересованным приложениям, которые подписались на получение этой информации.</p><p>Kafka особенно полезен там, где нужно работать с большими объёмами данных в реальном времени — например, в системах стриминга видео или аналитики. Она может обрабатывать миллионы событий в секунду и гарантирует, что данные не потеряются.</p><p>Вот где используют Apache Kafka:</p><ul><li><b>LinkedIn</b> использует Kafka для передачи сообщений между микросервисами.</li><li>Netflix применяет Kafka для контроля количества событий, обрабатываемых одновременно, и передачи данных из нескольких потоков.</li><li>The New York Times использует Kafka для публикации новостей в режиме реального времени.</li></ul><p>Приведём пример простой публикации и получения сообщений (учитывайте, что у вас должна быть установлена соответствующая библиотека и запущен Apache Kafka на локальном сервере или в облаке):</p><p>Producer отправляет сообщения в Kafka в определённую тему (в нашем случае — test_topic). Consumer подписывается на эту тему и получает сообщения.</p><p>В реальных системах таких издателей и подписчиков может быть много, и Kafka помогает координировать их работу.</p><h3>RabbitMQ</h3><p>Это брокер сообщений или посредник, который помогает разным приложениям обмениваться данными. Его разработали в 2007 году на Erlang — языке, который отлично подходит для создания устойчивых к сбоям систем.</p><p>RabbitMQ поддерживает несколько протоколов обмена данными, поэтому его можно использовать в разных проектах. Например, он может связывать микросервисы, обрабатывать фоновую информацию и управлять большими объёмами сообщений.</p><p>RabbitMQ работает как почтовая служба:</p><ol><li>Одно приложение отправляет сообщение (письмо).</li><li>RabbitMQ принимает это сообщение и сохраняет его в очереди.</li><li>Другое приложение (подписчик) получает сообщение из этой очереди.</li></ol><p>Особенность RabbitMQ — push-модель. Брокер сам отправляет сообщения получателю сразу, как только они появляются. Получателю не нужно запрашивать данные постоянно — он просто ждёт, пока RabbitMQ пришлёт новые сообщения.</p><p>Эта особенность полезна, когда нужно быстро информировать участников системы о важных событиях. Например, отправлять уведомления о статусе заказа, оповещать системы мониторинга о проблемах или обновлять данные в реальном времени.</p><p>Покажем пример (RabbitMQ можно подключить к Python с помощью библиотеки pika):</p><p>Вот как это работает:</p><p>Сначала Producer отправляет сообщение в очередь test_queue. Затем Consumer подписывается на эту очередь и получает сообщения. RabbitMQ принимает сообщение и доставляет его получателю сразу после появления в очереди (та самая push-модель).</p><h3>Redis</h3><p>Система управления данными, которая поддерживает не только стандартную очередь сообщений, но и паттерн Pub/Sub. Этот инструмент используют для организации обмена сообщениями, при этом он хранит промежуточный контент (например, набранный, но не отправленный текст), управляет базами данных небольших приложений и одностраничных сайтов.</p><p>Redis — идеальный выбор для проектов, где важна скорость доставки информации, в том числе в биржевых и финансовых сервисах. Его применяют также для реализации механизма подписок. Вот пример кода:</p><p>В примере издатель отправляет 5 сообщений с небольшой паузой, а подписчик сразу их получает.</p><h2>Примеры реализации Pub/Sub</h2><p>Паттерн используют в сферах, где нужно организовать быстрый обмен информацией между распределёнными компонентами системы. Автоматизация процессов — ключевое направление реализации Pub/Sub.</p><p>Рассмотрим наиболее актуальные области применения шаблона.</p><h3>Мониторинг системы и мгновенная отправка уведомлений</h3><p>Те самые темы, о которых мы рассказали раньше, создаются для различных категорий данных — например, загрузка процессора, состояние серверов, журналы ошибок. Каждая служба может публиковать свои метрики в топиках, а подписчики (системы визуализации, алерты и дашборды) получают эти данные для обработки.</p><p>Вот пример сценария:</p><ol><li>В крупномасштабной системе мониторинга серверов сообщения о сбоях отправляются в специальный канал.</li><li>Система визуализации Grafana или Prometheus подписана на этот канал и сразу обновляет дашборды.</li><li>В случае критического сбоя на основной системе резервный сервер автоматически включается через подписку на ту же тему.</li></ol><p>Pub/Sub позволяет внедрить автоматические реакции на определенные события. Например, если загруженность сервера превышает 90%, система может отправить сообщение об аварийном переключении нагрузки или даже автоматически включить дополнительные вычислительные узлы.</p><h3>IoT (Интернет вещей)</h3><p>Смарт-устройств становится все больше, и для каждого из них необходимо организовать надёжный метод сбора и передачи информации. Здесь также на помощь приходит Pub/Sub.</p><p>Гаджеты могут выступать издателями: они отправляют показания сенсоров, данные о температуре, движении, состоянии и других параметрах на центральный сервер или в облако.</p><p>Для лучшего понимания приведём пример:</p><ol><li>Датчики движения отправляют сообщения в тему «Безопасность».</li><li>Подписчик — система управления домом — принимает эти сообщения и отправляет уведомления на мобильное приложение пользователя.</li><li>Тем временем умная лампа подписана на другой канал и автоматически включается по сигналу о движении.</li></ol><p>Pub/Sub обеспечивает масштабируемость IoT-систем — новые устройства можно легко подключать к существующим темам, не нарушая работу всей архитектуры.</p><h3>Резервное копирование</h3><p>Многим компаниям важно не только хранить информацию, но и организовать надёжное резервное копирование, чтобы уменьшить риски потери данных. Pub/Sub помогает и здесь: можно автоматически собирать и передавать резервные копии данных в облачные хранилища или на резервные серверы. Вот как это может работать:</p><ol><li>Каждую ночь системы баз данных отправляют уведомление в тему «Резервное копирование».</li><li>Подписчик (облачный сервис хранения) получает это сообщение и инициирует процесс копирования данных.</li><li>Если основной сервер недоступен, сообщение передаётся на резервный сервер, который берёт на себя задачу сохранения.</li></ol><p>Также Pub/Sub позволяет настроить многоуровневое резервирование: копии данных могут одновременно отправляться на несколько хранилищ, что и позволяет минимизировать риски потери информации.</p><h2>Преимущества и недостатки использования Pub/Sub</h2><p>Давайте кратко пройдёмся по основным плюсам этого паттерна:</p><ul><li>Систему легко адаптировать под любое количество пользователей. Новых издателей и подписчиков можно добавлять без потери производительности, а архитектуру тем и посредников менять без затрагивания базовых компонентов.</li><li>Издатели и подписчики работают независимо друг от друга. Это позволяет создавать безопасные, модульные системы, где компоненты не зависят от прямых связей и могут развиваться отдельно.</li><li>Pub/Sub можно использовать с разными языками программирования (например, Python или Java) и интегрировать с различными брокерами сообщений.</li><li>Сообщения доставляются мгновенно, что делает Pub/Sub идеальным решением для сервисов реального времени.</li><li>Сообщения дублируются в хранилищах для гарантированной доставки. Дополнительно обеспечивается проверка подлинности издателей и шифрование данных для защиты информации.</li></ul><p>У паттерна есть и недостатки. Он слишком сложен для использования в небольших приложениях, требует грамотной настройки и сопровождения. Если продукт не нуждается в масштабировании, то применение Pub/Sub — неоправданная трата ресурсов. Не всем системам требуется такой уровень сложности и надёжности.</p><p>Для потоковой передачи медиафайлов Pub/Sub — не лучший выбор, поскольку работает в асинхронном режиме. Для конференций в формате видео, голосовых коммуникаций по протоколу IP технология не подойдёт.</p><h2>Итоги</h2><p>Pub/Sub — это эффективный и сравнительно простой способ организовать обмен данными между компонентами системы. Он лежит в основе работы распределённых приложений с микросервисной архитектурой и обеспечивает передачу информации в реальном времени.</p><p>Технология работает асинхронно, что позволяет системе легко масштабироваться и разделять её на независимые модули. Благодаря брокерам сообщений, которые обрабатывают и распределяют данные, приложения не перегружаются, а обмен информацией становится быстрым и безопасным.</p>]]></content:encoded>
    </item>
    <item>
      <title>Монолит или микросервисы: какую архитектуру выбрать для нового проекта</title>
      <link>https://tproger.ru/articles/monolit-ili-mikroservisy--kak-vybrat-arhitekturu-dlya-novogo-proekta</link>
      <comments>https://tproger.ru/articles/monolit-ili-mikroservisy--kak-vybrat-arhitekturu-dlya-novogo-proekta?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/monolit-ili-mikroservisy--kak-vybrat-arhitekturu-dlya-novogo-proekta</guid>
      <description><![CDATA[<p>Монолит или микросервисы. Показываем основные критерии выбора архитектуры нового проекта. Рассматриваем плюсы и минусы ✔ Tproger
</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/monolit-ili-mikroservisy--kak-vybrat-arhitekturu-dlya-novogo-proekta">Монолит или микросервисы: какую архитектуру выбрать для нового проекта</a>»</p>]]></description>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Архитектура ПО]]></category>
      <category><![CDATA[Архитектура приложений]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 02 Dec 2024 15:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>При создании нового проекта выбрать правильную архитектуру необходимо, ведь это влияет на скорость разработки, масштабируемость и долгосрочную поддержку системы. Монолитная архитектура обеспечивает простоту и целостность, но может быть сложной в масштабировании. Микросервисы обеспечивают гибкость и независимость компонентов, но требуют продуманного подхода к интеграции и управлению. Сегодня рассмотрим разницу между монолитом и микросервисами, ключевые особенности каждой архитектуры и поможем вам сделать осознанный выбор.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2024-11-27/499fddb7-3212-4a4f-ab60-a65d318ffd08.png" alt="" /></figure><h2>Определение и особенности монолитной архитектуры</h2><h3>Что такое монолитная архитектура и какие у неё основные характеристики</h3><p>Монолитная архитектура представляет собой единую программную систему, в которой все модули и компоненты приложения тесно связаны и работают как единое целое. Вся логика приложения — от пользовательского интерфейса до базы данных — включена в единое приложение, которое развертывается и управляется как единое целое.</p><p><b>Основные характеристики:</b></p><ul><li>Единое хранилище кода и структур данных.</li><li>Тесная взаимосвязь компонентов: изменения в одном модуле часто требуют обновлений в других.</li><li>Унифицированное развертывание: приложение разворачивается в одном контейнере или среде.</li></ul><h3>Плюсы монолита</h3><ul><li><b>Простота разработки.</b> Все компоненты находятся в одном репозитории, что упрощает работу команды. Так, разработчики могут сосредоточиться на функциональности, а не на взаимодействии между сервисами. Плюс разработчики быстрее ориентируются в архитектуре.</li><li><b>Единое развертывание. </b>Нет необходимости управлять множеством сервисов, а обновление системы требует лишь одной операции деплоя.</li><li><b>Легкость тестирования. </b>Общее тестирование всех компонентов можно проводить в одной среде. А еще проще реализовать интеграционные и функциональные тесты.</li><li><b>Удобство в небольших командах</b>. Подходит для стартапов или проектов с ограниченными ресурсами, где важно быстро приступить к работе.</li></ul><h3>Минусы монолита</h3><ul><li><b>Сложность масштабирования.</b> Масштабирование требует копирования всего приложения, даже если нужно повысить производительность только одной его части. Плюс если высокую нагрузку испытывает лишь одна часть приложения, увеличивать производительность приходится для всей системы.</li><li><b>Зависимость компонентов.</b> Любое изменение в одном модуле может привести к непредсказуемым последствиям в других частях системы. К тому же трудно изолировать ошибки и снижать взаимные влияния между частями приложения.</li><li><b>Долгосрочная поддержка. </b>Переход на новые технологии требует переработки всей системы. Например, если монолитная архитектура построена на устаревшей версии фреймворка, переход на более современный инструмент требует изменений во всех связанных модулях, включая базу данных, пользовательский интерфейс и API.</li><li><b>Риск единой точки отказа.</b> Ошибка в одном компоненте может привести к полной остановке всего приложения.</li></ul><p>Монолитная архитектура подходит для небольших и средних проектов с ограниченными требованиями к масштабированию, где важны скорость разработки и простота управления. Однако для крупных динамично развивающихся систем она может стать сдерживающим фактором.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2024-11-27/fb74667c-b881-4215-98fa-d22b2d4b83e4.jpg" alt="" /></figure><h2>Определение и особенности микросервисной архитектуры</h2><h3>Что такое микросервисная архитектура и её ключевые аспекты</h3><p>Микросервисы как архитектура представляет собой подход, при котором приложение разбивается на независимые модули (микросервисы). Каждый микросервис выполняет определённую бизнес-функцию, имеет собственную базу данных (или доступ к её сегменту) и взаимодействует с другими через API.</p><p><b>Ключевые аспекты:</b></p><ul><li>Микросервисы разрабатываются, развёртываются и масштабируются отдельно.</li><li>Каждый микросервис отвечает за конкретную бизнес-логику.</li><li>Микросервисы могут использовать различные языки программирования, базы данных и фреймворки, что позволяет выбрать оптимальный инструмент для каждой задачи.</li></ul><h3>Плюсы микросервисов</h3><ul><li><b>Гибкость. </b>Микросервисы можно развивать независимо друг от друга. Так, в музыкальные стриминги (по типу Яндекс.музыки) новый функционал приложения можно добавлять без изменения сервиса, отвечающего за управление библиотекой треков.</li><li><b>Масштабируемость.</b> Каждый микросервис масштабируется отдельно в зависимости от нагрузки. Не нужно тратить время и мощности но прокачку одних и тех же функций одновременно, а сосредоточиться на приоритетных.</li><li><b>Независимое развертывание.</b> Обновление одного микросервиса не требует остановки всей системы. Например, если в приложении нужно обновить модуль расчёта стоимости (если мы разрабатываем Ozon или WB), это не повлияет на работу модуля оформления заказов.</li></ul><h3>Минусы микросервисов</h3><ul><li><b>Сложность в настройке.</b> Организация микросервисной архитектуры требует грамотной настройки инфраструктуры. Например, необходимо настроить API-шлюз для управления запросами, систему контейнеризации (например, Docker) и оркестрацию (Kubernetes).</li><li><b>Необходимость управления сетью. </b>Микросервисы взаимодействуют через сеть, что может приводить к задержкам и ошибкам. Например, если сервис обработки платежей не отвечает из-за проблем с сетью, процесс оформления заказа на том же Озоне может быть временно недоступен.</li><li><b>Сложности в тестировании.</b> Интеграционное тестирование требует симуляции взаимодействия между десятками или сотнями сервисов.</li></ul><p>Микросервисная архитектура идеально подходит для крупных проектов или систем, которым требуется гибкость и масштабируемость. Она позволяет разделить приложение на независимые компоненты, что упрощает развитие и обновление системы, особенно в условиях изменяющихся бизнес-требований.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2024-11-27/990eee10-701c-4b1c-805a-4e8e3a9d5e32.webp" alt="" /></figure><h2>Сравнение монолита и микросервисов</h2><p>При выборе архитектуры важно учитывать ключевые аспекты, которые влияют на производительность, масштабируемость, удобство поддержки и организацию командной работы. Поговорим об отличиях монолитов от микросервисов.</p><p>Производительность: какая архитектура быстрее и почему</p><p><b>Монолит</b></p><p>Монолитные приложения выигрывают в производительности благодаря отсутствию сетевых вызовов между компонентами. Например, если в приложении есть функция расчёта скидки и оформления заказа, в монолите эти операции выполняются быстрее, так как всё обрабатывается в едином контексте без дополнительных задержек.</p><p><b>Микросервисы</b></p><p>Микросервисы могут быть медленнее из-за сетевых взаимодействий между компонентами. В приложении с такой архитектурой расчёт скидки может быть отдельным сервисом, и каждый запрос к нему потребует сетевого соединения. Однако микросервисы позволяют распределять нагрузку, обеспечивая высокую производительность при большом количестве пользователей.</p><p>Масштабируемость: вертикальное и горизонтальное масштабирование</p><p><b>Монолит</b></p><p>Плюс монолита в том, что его масштабирование осуществляется вертикально (больше оперативной памяти —&gt; мощнее процессор). Это быстро, но дорого, и есть физические ограничения на увеличение ресурсов.</p><p><b>Микросервисы</b></p><p>Поддерживают горизонтальное масштабирование, позволяя увеличивать производительность за счёт запуска дополнительных копий только нужных сервисов. Например, если нагрузка растёт на модуль обработки платежей, администратор может увеличить количество инстансов только этого сервиса, не затрагивая остальные части приложения.</p><p>Поддержка и обновление: как быстро можно добавлять новые функции</p><p><b>Монолит</b></p><p>В монолите изменения требуют работы с общей кодовой базой. Так, добавление нового фильтра в поисковую систему потребует изменений в коде и обязательного тестирования всего приложения. Это может замедлить внедрение обновлений, особенно в сложных системах.</p><p><b>Микросервисы</b></p><p>Каждый микросервис разрабатывается и обновляется независимо. Например, добавление нового фильтра в ту же поисковую систему можно реализовать как отдельный сервис, что не затронет работу других компонентов. Это позволяет быстрее развивать функциональность приложения.</p><p>Командная работа: как архитектура влияет на распределение задач в команде</p><p><b>Монолит</b></p><p>Подходит для небольших команд, так как вся разработка сосредоточена в одной кодовой базе. Однако в крупных командах может возникать путаница: одновременно работать над различными функциями сложно из-за пересечения задач и конфликтов.</p><p><b>Микросервисы</b></p><p>Позволяют разделить задачи между командами, так как каждая  отвечает за свой микросервис. Например, одна команда может работать над модулем аналитики, а другая — над модулем рекомендаций, не мешая друг другу. Это делает микросервисы идеальными для крупных проектов с распределёнными командами.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2024-11-27/a1c18a40-2d4e-4718-9690-a9d23d3f962e.png" alt="" /></figure><h2>Факторы, которые влияют на выбор архитектуры</h2><p>Выбор между монолитной и микросервисной архитектурой зависит от множества факторов, например, особенностей команды, масштаба проекта, технических требований и доступных ресурсов. Так что же выбрать?</p><h3>Размер и опыт команды разработчиков</h3><p><b>Маленькая команда</b></p><p>Если команда небольшая и состоит из 3–5 человек, лучше начать с монолитной архитектуры. Например, для стартапа с ограниченным бюджетом разработка единой кодовой базы будет быстрее и эффективнее, так как все участники смогут работать в одном контексте без разделения на сервисы.</p><p><b>Большая команда</b></p><p>В случае крупной команды, где каждая группа имеет узкую специализацию (например, фронтенд, бэкенд, аналитика), микросервисы становятся более подходящим решением. Так, отдельная команда может заниматься разработкой API для управления пользователями, не мешая работе команды, отвечающей за обработку платежей.</p><p><b>Уровень опыта</b></p><p>Новичкам проще начать с монолита, где всё сосредоточено в одном месте. Микросервисы требуют знания работы с сетями, управления контейнерами и настройки взаимодействия сервисов, что может быть сложно для начинающих.</p><h3>Сложность и масштаб проекта</h3><p><b>Простые проекты</b></p><p>Для небольших приложений монолитная архитектура подходит идеально.</p><p><b>Сложные и крупные проекты</b></p><p>Если проект включает множество связанных функций, типа интернет-магазина с рекомендациями, платежной системой, логистикой и аналитикой, микросервисы становятся более предпочтительными. Разделение функционала на отдельные сервисы позволяет легче масштабировать и обновлять отдельные части системы.</p><h3>Требования к производительности и масштабируемости</h3><p><b>Низкие требования</b></p><p>Если приложение обслуживает ограниченное количество пользователей, например, внутренний инструмент для команды из 50 человек, монолитная архитектура будет более эффективной. Она обеспечит стабильную производительность без сложных настроек.</p><p><b>Высокие требования</b></p><p>Для приложений с миллионами пользователей микросервисы обеспечивают гибкость и возможность горизонтального масштабирования. Например, если растёт нагрузка на видео-хостинг, можно увеличить количество экземпляров только сервиса трансляции.</p><h3>Планы на будущее и возможность роста проекта</h3><p><b>Краткосрочные проекты</b></p><p>Для приложений с коротким жизненным циклом лучше выбрать монолит. Например, MVP для тестирования идеи легче разработать именно так, поскольку это позволяет быстрее выйти на рынок.</p><p><b>Долгосрочные проекты</b></p><p>Если приложение предполагается развивать на протяжении многих лет с добавлением новых функций, микросервисы могут быть более удобны. Например, в крупной ERP-системе с постоянным расширением функционала проще добавлять новые сервисы, не нарушая работу существующих.</p><h3>Инфраструктура и доступные ресурсы</h3><p><b>Ограниченная инфраструктура</b></p><p>Монолитные приложения не требуют сложной инфраструктуры. Их можно развернуть на одном сервере и минимизировать затраты на администрирование.</p><p><b>Развитая инфраструктура</b></p><p>Вам нужно настроить архитектуру, и микросервисы в этом случае потребуют контейнеризации (Docker), оркестрации (Kubernetes) и мощных инструментов мониторинга.</p><p>Выбор архитектуры зависит от целей и условий проекта. Для небольших приложений с ограниченными ресурсами и командами монолит — быстрый и эффективный выбор. Для крупных систем с перспективой роста и распределёнными командами микросервисы предлагают гибкость, масштабируемость и независимость в разработке. Важно учитывать баланс между текущими потребностями и будущими планами, чтобы архитектура оставалась жизнеспособной на протяжении всего жизненного цикла проекта.</p><h2>Кейсы, или практические советы по выбору архитектуры</h2><p>Попробуем подобрать подходящую архитектуру на конкретных кейсах. Для примера возьмем сферу электронной коммерции (раз уж мы много говорили про маркетплейсы).</p><h3>Когда стоит использовать монолит</h3><ul><li><b>Простые проекты.</b> Локальный магазин для продажи органической продукции, где пользователь может оформить заказ через простую корзину, а администратор получает уведомление на почту.</li><li><b>Стартапы с ограниченными ресурсами.</b> Новый бренд, продающий уникальные дизайнерские украшения, быстро запускает MVP с базовыми функциями: каталог, корзина, оплата и личный кабинет.</li><li><b>Приложения без высоких требований к масштабируемости.</b> Интернет-магазин для корпоративных клиентов, где покупки совершаются нерегулярно, и основная нагрузка на сервер минимальна.</li></ul><h3>Когда подходят микросервисы</h3><ul><li><b>Крупные проекты.</b> Большой интернет-магазин с тысячами товаров, сложной структурой категорий и разными модулями (каталог, поиск, рекомендации, платежи).</li><li><b>Распределённые команды.</b> Когда команда в одной стране разрабатывает сервис логистики, а команда в другой — систему интеграции с локальными платёжными провайдерами.</li><li><b>Приложения с высокой нагрузкой. </b>Маркетплейс, который обрабатывает миллионы запросов в секунду, поддерживает сложные фильтры, рекомендации и динамическое ценообразование.</li></ul><h2>Как перейти с монолита на микросервисы</h2><figure><img src="https://media.tproger.ru/user-uploads/102593/2024-11-27/1c2f47e4-31df-4ffa-9833-57beff3954f0.png" alt="" /></figure><h4>1. Оцениваем текущую архитектуру</h4><p>Для начала выявляем модули с наибольшей нагрузкой. Так, если монолитный интернет-магазин испытывает перебои из-за частых запросов к каталогу товаров, начинаем с выделения поиска в отдельный микросервис.</p><h4>2. Разрабатываем стратегию миграции</h4><p>Постепенно выносим модули, сохраняя функциональность. То есть сначала выносим модуль обработки платежей в отдельный сервис, затем переходим к модулям рекомендаций и аналитики.</p><h4>3. Обеспечиваем инфраструктуру</h4><p>Настраиваем контейнеризацию для запуска микросервисов (например, Docker для микросервисов каталога и управления заказами с общей базой данных).</p><h4>4. Используем очередь сообщений</h4><p>Реализуем асинхронное взаимодействие сервисов. Можем настроить очередь RabbitMQ для передачи данных о новых заказах от фронтэнда к микросервису логистики.</p><h4>5. Тестируем взаимодействие сервисов</h4><p>Постоянно проверяем корректность обмена данными. Так, тестируем модуль интеграции с внешними складами, чтобы убедиться в правильной обработке информации о наличии товаров.</p><h2>Примеры реальных проектов и их архитектурных решений</h2><h3>Примеры компаний, которые используют монолит и преуспели в этом</h3><h4>Basecamp</h4><p><a href="https://vizologi.com/basecamp-business-model-how-basecamp-works-makes-money/">Basecamp</a> —  популярный инструмент для управления проектами. Он известен своей монолитной архитектурой. Для команды Basecamp это решение значительно облегчает внедрение новых функций и упрощает развертывание, так как все компоненты находятся в одной кодовой базе.</p><h4>Shopify</h4><p><a href="https://mehmetozkaya.medium.com/shopifys-modular-monolithic-architecture-a-deep-dive-%EF%B8%8F-a2f88c172797">Shopify</a>, одна из крупнейших платформ для создания интернет-магазинов, на ранних этапах своего роста использовала монолитную архитектуру. В отличие от многих других компаний, которые переходят на микросервисы, Shopify создала гибкую систему в рамках монолита, которая поддерживает стабильность и масштабируемость, не перегружая инфраструктуру. Несмотря на это, они также внедряли элементы модульности в свой монолит, что позволяло сохранять производительность при росте компании​.</p><h4>GitHub</h4><p><a href="https://www.infoq.com/articles/github-monolith-microservices/">GitHub</a>, крупнейшая платформа для хостинга и совместной разработки ПО, также начинала с монолитной архитектуры. Этот подход позволил поддерживать высокую скорость разработки и эффективность работы небольшой команды. В дальнейшем GitHub внедрил стратегию масштабирования внутри своего монолита, что позволило им эффективно справляться с растущими требованиями без перехода на микросервисы на первых этапах​.</p><h3>Примеры компаний, которые выбрали микросервисную архитектуру</h3><h4>Netflix</h4><p><a href="https://netflixtechblog.com/">Для масштабируемости и высокой доступности</a> Netflix перешел от монолитной архитектуры к микросервисам. Это позволило им эффективно обрабатывать большое количество запросов пользователей и улучшить управление различными компонентами системы.</p><h4>Amazon</h4><p><a href="https://aws.amazon.com/ru/microservices/">Amazon</a>, особенно его платформа Amazon Web Services (AWS), также широко использует микросервисы. Переход к такой архитектуре позволил Amazon улучшить управление масштабируемостью, изоляцию сбоев и гибкость развертывания. Каждый сервис отвечает за отдельную задачу, что делает платформу более гибкой и облегчает масштабирование отдельных компонентов.</p><h2>Ошибки, которых стоит избегать при выборе и реализации архитектуры</h2><h4>1. Вы не понимаете требования</h4><p>Ошибки могут возникать, если архитектура выбирается без детального анализа потребностей проекта. Это может привести к излишней сложности и необходимости управления множеством сервисов, которые не нужны на первых этапах.</p><p><i>Совет: </i>Тщательно анализируйте требования к масштабируемости, безопасности, производительности и возможностям роста, прежде чем принимать решение о типе архитектуры.</p><h4>2. Вы не учитываете долгосрочные последствия</h4><p>При использовании монолитной архитектуры может быть сложно адаптировать систему под новые требования по мере роста. В то же время излишняя фрагментация в микросервисах приводит к значительным затратам на управление и координацию, особенно если проект не хочет масштабироваться.</p><p><i>Совет:</i> Планируйте архитектуру с учётом будущих потребностей и возможности масштабирования, но не усложняйте проект без реальной необходимости.</p><h4>3. Вы игнорируете опыт и возможности команды</h4><p>Выбор архитектуры должен учитывать не только требования проекта, но и опыт вашей команды. Чтобы развернуть микросервисы, в тиме должны быть опытные DevOps-специалисты. И в целом все сотрудники должны обладать сильными навыками для настройки, управления и мониторинга такой архитектуры.</p><p><i>Совет</i>: Оцените техническую зрелость и возможности вашей команды, чтобы понять, будет ли она в состоянии поддерживать сложную архитектуру.</p><h4>4. У вас проблемы с тестированием</h4><p>При использовании микросервисной архитектуры сложнее поддерживать тестирование, так как необходимо чекать не только отдельные сервисы, но и взаимодействие между ними. В монолитной архитектуре тестирование проще, но с увеличением объема кода и сложности системы это может стать проблемой.</p><p><i>Совет:</i> Убедитесь, что для выбранной архитектуры предусмотрены необходимые стратегии тестирования, чтобы минимизировать риски ошибок при развертывании.</p><h4>5. Вы не уделяете внимание безопасности</h4><p>Независимо от выбранной архитектуры, безопасность всегда должна быть приоритетом. Микросервисы, в свою очередь, увеличивают поверхность атаки из-за множества сервисов, а монолит может быть уязвимым, если не принято должное внимание к его изоляции и защите данных.</p><p><i>Совет</i>: Включите в архитектурное проектирование практики безопасности с самого начала, независимо от того, выбрали вы монолит или микросервисы.</p><p>Эти ошибки можно избежать, тщательно планируя архитектуру, принимая во внимание как текущие потребности, так и потенциальные вызовы в будущем.</p>]]></content:encoded>
    </item>
    <item>
      <title>Event-Driven архитектура: принципы и примеры использования</title>
      <link>https://tproger.ru/articles/event-driven-arhitektura--principy-i-primery-ispolzovaniya</link>
      <comments>https://tproger.ru/articles/event-driven-arhitektura--principy-i-primery-ispolzovaniya?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Денис Кудерин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/event-driven-arhitektura--principy-i-primery-ispolzovaniya</guid>
      <description><![CDATA[<p>Event-Driven архитектура. Показываем принципы и примеры использования EDA. Рассматриваем возможные варианты и пошаговую инструкцию ✔ Tproger</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/event-driven-arhitektura--principy-i-primery-ispolzovaniya">Event-Driven архитектура: принципы и примеры использования</a>»</p>]]></description>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Архитектура приложений]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 04 Oct 2024 11:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>В сфере ИТ под архитектурой понимают технологическую базу, структуру и принципы взаимодействия компонентов программного обеспечения. То есть речь идет о совокупности элементов, необходимых для решения поставленных задач. Без архитектурного проектирования написание кода будет лишено структуры — это своего рода каркас, на который опираются исполнители при реализации проекта.</p><p>В современных приложениях и других программных продуктах распространена событийно-ориентированная архитектура. Для запуска и обмена информацией в таких проектах используются события, то есть значимые изменения состояния кода.</p><p>Узнаем, каковы принципы и основы событийной архитектуры ПО, каковы преимущества и недостатки такой структуры, как работает EDA на конкретных примерах.</p><h2>Принципы событийной архитектуры и ее компоненты</h2><p>Event-Driven Architecture — это распространенный асинхронный шаблон, в котором основной для системных действий становится реакция на какое-либо событие. Здесь событием называют сообщение в разных точках исполняемого кода, возникающее при выполнении ряда условий. Паттерн EDA используется при разработке приложений с высокой масштабируемостью, а также при создании более простых программных продуктов.</p><p>Такой архитектурный подход базируется на асинхронном взаимодействии между частями системы. EDA распределяет системные компоненты, что способствует масштабируемости и ускоренной работе приложений и программ, задействованных в самых разных отраслях.</p><h2>Как работает EDA</h2><p>В системе, которая управляется событиями, компоненты отвечают на изменения статуса кода, что минимизирует потребность в их непосредственной связи друг с другом. Такая архитектура более рациональна и обеспечивает высокую адаптируемость всей системы к изменяющейся среде. Обнаружение и обработка событий происходят в реальном времени.</p><p>В качестве типичного примера работы событийно-ориентированной архитектуры можно привести видеоигру, компоненты которой откликаются на движение мыши или нажатие пунктов меню.</p><p>Событийная архитектура состоит из ключевых компонентов:</p><ul><li><b>Продюсеры (производители).</b> Это компоненты, отвечающие за отправку сообщений. Как только состояние изменяется либо происходит действие в системе, производитель отправляет данные об этом заинтересованной стороне. Продюсером может быть любое фактическое действие, влияющее на состояние кода.</li><li><b>События.</b> Это сообщения либо пакеты данных, фиксирующие изменения состояние или какое-либо действие внутри компонентов большой системы. В событиях содержатся метаданные, маркирующие источник изменения, метки времени, информация о действии. Например, если клиент в приложении сделал покупку, все данные об этом будут отражены в событии.</li><li><b>Каналы. </b>Все события доставляются до адресатов (потребителей) по специальным каналам. Первичные каналы событий — это TCP/IP-соединения или файлы различного формата (XML, JSON и т.д.). Возможно одновременное открытие сразу нескольких каналов. Поскольку читаются события асинхронно, их обработка происходит практически в реальном времени.</li><li><b>Маршрутизатор.</b> Этот компонент идентифицирует первичные события и действия, которые содержатся в сообщении. В ряде источников каналы и маршрутизаторы объединяют в компонент, который называется брокером — именно брокер запускает утверждения, которые становятся ответом на действие. При этом сам маршрутизатор не обрабатывает события, а лишь выдает соответствующие инструкции получателю.</li><li><b>Потребители (получатели).</b> Эти компоненты отвечают на сообщение соответствующим образом. Это может быть обновление данных, инициация новых процессов в приложении, вызов удаленных служб. Потребители — это наиболее автономные элементы архитектуры, выполняющие конкретные задачи. Уровень потребителей детализации варьируется от элементарного к сложнейшему в соответствии с особенностями ПО.</li></ul><p>В EDA производители и потребители сообщений не связаны напрямую. То есть продюсеры не знают, какие получатели принимают события, и наоборот — пользователям неизвестно, кто генерирует сообщения. Благодаря разделению можно автономно обновлять, масштабировать и всячески развивать проект.</p><p>Путь сообщений от точки приема до получателей бывает довольно извилистым — возможно, событию потребуется взаимодействовать с компонентами, написанными на другом языке, использующими другие интерфейсы и протоколы передачи. Используется два распространенных способа доставки данных — pub/sub и стандартная потоковая передача. В первом случае инфраструктура такова, что сообщения получает каждый подписчик, во втором события заносятся в лог, после чего потребители могут воспринимать их из любого участка потока.</p><p>Для современного ПО со сложными и разветвленными рабочими процессами принцип Event-Driven обеспечивает необходимую масштабируемость и гибкость. Полноценная обработка здесь и сейчас — это быстродействие и надежность, то есть основные требования, которые предъявляют пользователи к современному ПО.</p><h2>Преимущества</h2><p>Шаблон EDA имеет большой список плюсов:</p><ul><li><b>Высокая масштабируемость.</b> Отсутствие связанности компонентов обеспечивает масштабируемость системы при необходимости. Например, если в онлайн-магазине значительно повышается спрос на товары, архитектура легко справится с обработкой, не задействуя другие службы.</li><li><b>Асинхронная связь.</b> Архитектура работает по принципу асинхронной связи компонентов — то есть части системы включаются, не дожидаясь взаимных ответов. Параллельная обработка существенно повышает эффективность программных продуктов.</li><li><b>Надежность (отказоустойчивость). </b>В EDA системах минимум зависимостей между элементами, что повышает отказоустойчивость. Если с одним из элементов случится сбой, система продолжит работать с минимальными нарушениями. Брокеры позаботятся о том, чтобы события не были потеряны в процессе сбоя. Событийно-ориентированная коммутация позволяет хранить сообщения в специальном хранилище, где ошибки будут обработаны.</li><li><b>Быстродействие приложений.</b> Поскольку события обрабатываются асинхронно и в режиме онлайн, это обеспечивает высокую скорость реагирования на сообщения. В EDA-структурах компоненты отвечают на изменение статуса кода сразу, что максимально сокращает время между действиями и их обработкой. По этой причине событийная архитектура — идеальный вариант для ПО, где мгновенная обработка данных и оперативное реагирование критично важны, например, на финансовых платформах.</li><li><b>Бесшовная интеграция.</b> Программы с архитектурой EDA легко интегрируются с другими приложениями для обмена сведениями и прочих взаимодействий. События потребляются и создаются независимо от задействованных языков программирования и технологических решений.</li><li><b>Гибкость. </b>Event-Driven предполагает модульный подход к разработке системы. Это значит, что изменение отдельных компонентов практически не влияет на статус всей системы. Повышается скорость реагирования на новые задачи и потребности, улучшается адаптивность, что сокращает период разработки и программные ресурсы.</li></ul><p>Таким образом, продукты с EDA высокопроизводительны и способны параллельно выполнять операции с минимальными затратами.</p><h2>Примеры использования Event-Driven архитектуры</h2><p>Существует множество знакомых нам систем, которые работают по принципу событийной архитектуры. Рассмотрим наиболее типичные направления.</p><h3>Электронная коммерция</h3><p>По принципу EDA устроена обработка заказов в интернет-магазинах. Когда пользователь размещает карточку товара, мгновенно запускается событие, которые инициирует работу системы с запасами на складах, обработку покупок и координацию доставки. Все эти события и действия обрабатываются асинхронно, поэтому площадка продолжает работать с высокой скоростью независимо от количества обращений.</p><h3>Интернет вещей</h3><p>Устройства, которые относятся к классу IoT, инициируют события и передают их получателям. Это могут быть разные платформы, но независимо от системы, обработка сообщений происходит в реальном времени.</p><h3>Регистрация и верификация пользователей</h3><p>Любые сервисы, в которых требуется зарегистрировать или идентифицировать пользователя, запускается цепь событий по проверке учетной информации, обновлению личных данных и предоставлению пользователям доступа согласно его текущему статусу.</p><h3>Системы оповещения</h3><p>В таких программных продуктах запуск событий происходит при конкретных условиях — рассылка сообщений, назначение задач в рабочих пространствах, почтовые и push уведомления.</p><h3>Аналитика</h3><p>События инициируются в системах при получении непрерывного потока информации, что позволяет потребителям анализировать сообщения в реальном времени. К таким задачам относится, например, мониторинг трафика на сайте с целью выявления мошеннической активности.</p><h3>Управление рабочими процессами</h3><p>При достижении контрольной точки или полного выполнения задачи запускается событие. Таким образом, происходит мониторинг рабочих процессов с целью повышения эффективности или обеспечения непрерывности выполняемой работы.</p><h3>Микросервисы</h3><p>Архитектура Event-Driven применяется для взаимодействия множества микросервисов в разных направлениях, что позволяет создавать при необходимости слабосвязанные и при этом быстро масштабируемые системы.</p><h2>Реальные примеры</h2><p>Многие компании с международным статусом внедрили в свои ресурсы системы архитектуры EDA, чтобы обеспечить масштабируемость и гибкость программных продуктов.</p><p>Среди таких организаций Netflix — один из наиболее популярных стриминговых сервисов. Вся инфраструктура этой платформы управляется событиями: система одновременно контролирует множество потоков и обеспечивает клиентам высококачественный сервис.</p><p>Еще один пример EDA — платформа для заказа автомобильных поездок Uber. События в этой системе представлены изменениями геолокации, что позволяет операторам отслеживать местоположение тысяч водителей одновременно.</p><h2>Технологии для реализации EDA</h2><p>Для реализации EDA применяется несколько технологий. Обозначим наиболее значимые из них.</p><h3>Event Sourcing</h3><p>В переводе с английского — «поиск событий». Этот шаблон документирует все изменения статуса системы в виде набора упорядоченных событий. Взамен обновления статуса данных система фиксирует изменения как определенные события.</p><p>Такая схема позволяет реконструировать статус объекта и обладает внушительным списком достоинств — это улучшенные возможности аудита, тщательной диагностики и беспроблемной интеграции с другими платформами.</p><h3>CQRS</h3><p>Распределение ответственности между запросами и командами. При использовании такого шаблона система разделяет процессы чтения данных и их записи. Часть, отвечающая за запись, генерирует события, представляющие изменения состояний. Часть, ответственная за чтение, считывает эти сообщения, после чего на их основе делает запросы и выстраивает модели.</p><p>Разделение ответственности позволяет сторонам действовать автономно, при необходимости масштабироваться и оптимально использовать ресурсы в зависимости от текущей ситуации и требований к производительности.</p><h3>Message Broker</h3><p>Брокер сообщений — это эффективный архитектурный шаблон, используемый в разветвленных системах. Такая технология предполагает наличие посредника, которые преобразует сообщения, сделанные в разных протоколах, в однотипный формат.</p><p>Брокеры реализуют асинхронный обмен сообщениями между разными сервисами с процессом буферизации. Пользователь может регулировать нагрузку и при необходимости ускорять обработку информации.</p><h2>Вызовы и недостатки EDA</h2><p>Поскольку в ИТ-сфере (как и в других отраслях) нет ничего совершенного, у EDA есть свои недостатки и подводные камни. Рассмотрим их подробно.</p><h3>Сложная структура</h3><p>Высокий уровень сложности архитектуры и ее распределенный характер могут быть лишними в ситуациях, когда достаточно традиционной монолитной структуры. Сложность Event-Driven предполагает подробное планирование и затратное проектирование системы. Нужны передовые методы для корректного управления системами с таким уровнем сложности.</p><h3>Согласованность событий</h3><p>Если система распределена на несколько сервисов или иных автономных компонентов, реализовать согласованность событий в структуре будет довольно сложно. Проблемы могут возникнуть и при обеспечении целостности информации, а также ее своевременного обновления в ответ на определенные сообщения.</p><h3>Порядок событий</h3><p>В ряде систем, включая финансовые и бизнес-направления, сохранение нужного порядка событий имеет критическое значение. Стратегия упорядоченной нумерации допустима, но при этом сама система станет еще более сложной.</p><h3>Управление и мониторинг</h3><p>Контролирование потоков событий в асинхронных системах часто становится сложной и затратной задачей. Чтобы справиться с ней, потребуется полноценный мониторинг производительности системы. Это поможет выявить узкие места и улучшить архитектуру.</p><h2>Итоги</h2><p>Событийная архитектура — востребованный шаблон, по которому работают современные приложения, онлайн-платформы и другие системы. Ключевая особенность EDA — реакция компонентов архитектуры на определенные события. Такая архитектура легко масштабируется, ажатируется под разные задачи и отличается высокой производительностью и безопасностью  благодаря асинхронной природе. Минусом шаблона считается сложность разработки и тестирования. При этом многие крупные компании реализуют свои программные ресурсы именно с применением событийной архитектуры.</p><p>И обязательно рассказывайте в комментариях, где применяете event-driven архитектуру.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как снизить нагрузку на CRM-систему</title>
      <link>https://tproger.ru/articles/kak-snizit-nagruzku-na-crm-sistemu</link>
      <comments>https://tproger.ru/articles/kak-snizit-nagruzku-na-crm-sistemu?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Сергей Лалетин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-snizit-nagruzku-na-crm-sistemu</guid>
      <description><![CDATA[<p>Рассказали, как справляемся с нагрузкой внутренней CRM-системы: какие технологии и практики используем и почему.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-snizit-nagruzku-na-crm-sistemu">Как снизить нагрузку на CRM-систему</a>»</p>]]></description>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[NoSQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 14 Jun 2024 10:19:35 GMT</pubDate>
      <content:encoded><![CDATA[<blockquote>Я занимаюсь разработкой CRM-системы, которая собирает, связывает и анализирует информацию о клиентах. Благодаря ей мы можем создавать рекламные предложения и предоставлять важную для банка информацию таргетированно — и быть уверены, что клиент видит в ленте именно то, что нужно (или что-то, что настолько понравится, что станет нужным). В этом тексте расскажу, как мы снижаем нагрузку на CRM-систему, и разберу тонкости разработки.</blockquote><h2>Как выглядит наша CRM-система</h2><p>Мы используем микросервисную архитектуру, микросервисы в основном написаны на Java. Маршрутизатором трафика работает Traefik: он собирает в себя все запросы и определяет, в какой микросервис, в какой API, отправлять реквест. Схема работы выглядит так:</p><p>Клиент —&gt; Traefik —&gt; (mcp-api-cleaner, mcp-reseration, mcp-proressing)</p><p>Микросервисы взаимодействуют с NoSQL и Redis, из которой информация попадает в топики Kafka и дальше в mySQL. Данные хранятся до 90 дней и после удаляются.</p><p>Благодаря такой логике клиенты получают ответ более быстрый, чем при работе с SQL базами данных .</p><h2>Redis взяли по нескольким причинам</h2><p>Первая: в банковском секторе нужна скорость. Вторая — у Redis быстрое и удобное взаимодействие с Java. Третья — это очень популярная система управления базами данных и применяется во многих компаниях.</p><p>Но у работы с ней есть нюансы. Погнавшись за скоростью, можно не рассчитать нагрузку, что фатально повлияет на работу приложения.</p><h2>Мы тоже столкнулись со сложностями</h2><p>При экспоненциальном росте нагрузки на CRM-систему Redis переполнялся и падал с неопределенной периодичностью. Изучив проблему, мы поняли, что в базе копятся записи с одинаковым ключом.</p><p>Например, мы провели тренинг, на котором сотрудники выполняли одни и те же действия: зашли в профиль, выполнили задачи А и Б и так далее. Система проанализировала контакты и объединила пользователей по интересам. В результате мы получили дерево из тысяч записей с одинаковым ключом. Мало того что это увеличило нагрузку на аналитическую систему и замедлило работу приложения, так еще и подвергло риску отказоустойчивость внутри контура банка.</p><p>Первое, что пришло в голову — создать отдельный стенд для обучения, но глобально проблему это бы не решило, потому что заранее узнать, на каком аккаунте возникнет рост, мы не сможем. Да и создание такого демостенда — накладно и не очень честно по отношению к обучаемым, потому что учеба должна проходить на реальным платформе с реальными примерами.</p><p>Также думали и ограничить коммуникацию с одним пользователем в рамках какого-то времени, но это доставило бы неудобства реальным пользователям: мы могли заафектить реальных клиентов, к тому же при каждой записи получать COUNT по ID было бы очень дорого.</p><p>Последняя идея, пришедшая к нам, была такой: искать высоконагруженные ID в mySQL и уже потом удалять их из Redis. Но это бы тоже не сработало, потому что постоянно сканировать счетчик ID долго и дорого.</p><h2>Не найдя комфортного решения на текущей архитектуре, мы начали и тестировать другие инструменты</h2><p>Взяли MongoDB, это тоже NoSQL база данных, которая хранит информацию не в кэше, а в формате BSON, в виде документов, содержащих пары ключ-значение. Мы сравнили скорость работы с Redis и выяснили, что MongoDB работает медленнее. Поэтому остановились на компиляции Redis и MongoDb с помощью паттерна Cache aside. На тестирование ушло несколько месяцев.</p><p>Схема простая: данные попадают в Redis и сразу же записываются в MongoDB. Так мы получаем дублированный кэш с разным временем жизни. На стороне Redis данные хранятся ограниченное время, пару дней. При частых запросах мы не теряем в перформансе и не перегружаем Redis, потому что при нагрузке мы уже смело можем очищать данные по определенному ID.</p><p>Клиент в это время получает информацию из MongoDB (да, информация придет чуть позже, это медленнее процентов на 15, но решает проблему с нагрузкой).</p><p>На перформансе, при частых запросах, потерь в скорости почти нет: даже если данные успели стереться из Redis, они не превышают 10%. В дальнейшем данные уже попадают в Redis, и скорость возвращается.</p><h2>Так мы решили проблемы с нагрузкой</h2><p>Было приятно поделиться этой информацией, если хотите погрузиться в тему детальнее, пишите вопросы в комментариях.</p>]]></content:encoded>
    </item>
    <item>
      <title>История создания API для курса валют</title>
      <link>https://tproger.ru/articles/istoriya-sozdaniya-api-dlya-kursa-valyut-250449</link>
      <comments>https://tproger.ru/articles/istoriya-sozdaniya-api-dlya-kursa-valyut-250449?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[gogochikago]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/istoriya-sozdaniya-api-dlya-kursa-valyut-250449</guid>
      <description><![CDATA[<p>В этой статье рассказываю, что побудило меня создать свой API для конвертации валют и получения актуального курса от различных источников. Начиная от анализа потребностей в онлайн-платежах и заканчивая разработкой гибкого и эффективного микросервиса.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/istoriya-sozdaniya-api-dlya-kursa-valyut-250449">История создания API для курса валют</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 09 Jun 2024 11:20:02 GMT</pubDate>
      <content:encoded><![CDATA[<h2>Вводные данные</h2><p>В сфере онлайн-платежей, включая банки и платежные системы, возникла необходимость в получении курсов валют для конвертации суммы платежей, особенно в случаях, когда провайдер не поддерживает валюту платежа. Для этой задачи требуются следующие функциональные возможности от потенциального сервиса:</p><ol><li>Быстрая обработка большого объема запросов для получения курсов валют и готовых результатов конвертации.</li><li>Возможность создания собственных стратегий конвертации, учитывая различные особенности, например, принятие оплаты в одной валюте и конвертацию в другую.</li></ol><p>Пример конкретной задачи: Банк А принимает оплату только в PLN (польский злотый), но покупатель готов оплатить это только картой с валютой EUR. Нам необходимо определить сумму в PLN для отправки запроса к банку-эквайру. Какие есть варианты решения этой задачи?</p><ol><li>Использование среднего курса валют с небольшим процентом наценки для нивелирования недополучения дохода нашему мерчанту.</li><li>Отказ от принятия оплаты в неподдерживаемой валюте (неоптимальный вариант для бизнеса, но идеальный для разработчика).</li><li>Попросить банк добавить поддержку нужной валюты (часто невозможно).</li></ol><p>Изначально выбрал первый вариант, который казался успешным, пока не стали поступать жалобы о том, что суммы списания превышают заявленные. Дальнейший анализ показал, что средний курс валют сильно отличается от фактического и зависит от многих факторов, таких как провайдер, который выпустил карту, правила конвертации у банка, который принимает платеж.</p><figure><img src="https://media.tproger.ru/user-uploads/100995/2024-05-09/86c9789a-0553-4417-b02b-d27d1da6eb60.webp" alt="" /></figure><blockquote>Пример 1: У вас карта в евро. Вы совершаете покупки в отпуске в Италии тоже в евро. Сумма покупки — 50 евро, итого с вашего счёта спишется 50 евро.<br />Пример 2: У вас карта в евро. Вы совершаете покупку в Польше в польских злотых. В этом случае схема пересчёта следующая: польские злотые (PLN) → пересчитываются в USD по курсу Mastercard, далее USD → пересчитываются в CNY по курсу Mastercard, затем CNY → пересчитываются в евро по курсу банка.</blockquote><p>Для точного расчета суммы после всех конвертаций нам нужна информация о курсах валют от следующих источников:</p><ol><li><i>“Mastercard”</i> <b>PLN</b> -&gt; <b>USD</b></li><li><i>“Mastercard”</i> <b>USD</b> -&gt; <b>CNY</b></li><li><i>“Альфа-Банк Беларусь”</i> <b>CNY</b> -&gt; <b>EUR</b></li></ol><p>С такими вводными приступаем к анализу рынка…</p><h2>Анализ рынка</h2><p>Напомню, мы выделили основные критерии поиска:</p><blockquote>1)Быстрая обработка большого объема запросов для получения курсов валют и готовых результатов конвертации.<br />2)Возможность создания собственных стратегий конвертации, учитывая различные особенности, например, принятие оплаты в одной валюте и конвертацию в другую.</blockquote><figure><img src="https://media.tproger.ru/user-uploads/100995/2024-05-10/808ca336-bfbe-44d0-8a4c-a2062ca47d99.jpeg" alt="" /></figure><p><a href="https://www.xe.com/">Xe</a>:</p><p>+ быстрый и удобный API</p><p>+ есть возможность выбора источника курса валют (но на данный момент только центральные банки нескольких стран, что недостаточно для моего кейса)</p><p>+ есть курсы криптовалюты</p><p>– дорого</p><p>– нет возможности создания собственных стратегий для конвертации</p><p><a href="https://openexchangerates.org/">Openexchangerates</a>:</p><p>+ быстрый и удобный API</p><p>+ приятная цена</p><p>– нет возможности создания собственных стратегий для конвертации</p><p>– нет возможности выбрать источник курса</p><p><a href="https://currencylayer.com/">Currencylayer</a>:</p><p>+ быстрый и удобный API</p><p>+ приятная цена</p><p>– нет возможности создания собственных стратегий для конвертации</p><p>– нет возможности выбрать источник курса</p><p><a href="https://coinlayer.com/">Coinlayer</a>:</p><p>+ быстрый и удобный API</p><p>+ приятная цена</p><p>+ есть курсы криптовалюты</p><p>– нет возможности создания собственных стратегий для конвертации</p><p>– нет возможности выбрать источник курса</p><p><a href="https://fixer.io/">Fixer</a>:</p><p>+ быстрый и удобный API</p><p>+ приятная цена</p><p>– нет возможности создания собственных стратегий для конвертации</p><p>– нет возможности выбрать источник курса</p><p>Изначально выбрал <a href="https://openexchangerates.org/">https://openexchangerates.org</a> и использовал именно его, но достаточно быстро появились новые бизнес-кейсы, такие как пример с <i>“Альфа-Банк Беларусь”</i> и покупкой в PLN, когда этого функционала перестало хватать. Об этом упоминалось выше.</p><p>Все сервисы имели почти одинаковый набор плюсов и минусов, но главное, что ни один из них не имел того, что требовалось мне. С этого момента произошло разочарование из-за отсутствия нужного инструмента, но с другой стороны появилось вдохновение от возможности создать то, что будет работать именно под мою конкретную задачу. Благодаря этому анализу у меня возникла некоторая насмотренность на то, как крупные игроки рынка делают свои API. Поэтому в моей голове уже начала складываться база того, как это должно выглядеть: <b>source_currency</b>, <b>target_currency</b>, <b>amount</b>, <b>base_currency</b>, и поехали, думал я. Но как я ошибался, что этим все ограничится.</p><h2>Разработка</h2><p>Ванильное представление о своем микросервисе быстро столкнулось с жесткой реальностью, так как оказалось, что все гораздо сложнее. Набор параметров на вход стал больше, также увеличилось количество логики в коде и интеграций с источниками курсов. В конечном итоге, получился минимальный набор для активно используемых эндпоинтов (не учитывая эндпоинты для получения информации о источниках, созданных конвертациях и т.д.).</p><ul><li><b>/api/v1/rates</b> – эндпоинт, который позволяет получать курсы валют, указывая необходимые параметры.</li></ul><ul><li><b>/api/v1/conversions</b> – этот эндпоинт выполнит конвертацию в соответствии с указанной стратегией, учитывая все соответствующие правила и параметры конвертации.</li></ul><ul><li><b>/api/v1/conversion_strategies</b> – для создания стратегии конвертации валют.</li></ul><p>Как только все было запущено в продакшн и протестировано, я почувствовал облегчение. Однако, спустя некоторое время осознал, что получился микросервис, который по своей функциональности объединяет все доступные на рынке API-сервисы для конвертации валют и получения курсов. Кроме того, он добавляет такие возможности, как:</p><ol><li>Получение курсов из любых источников: банков, платежных систем, бирж и т.д. (ограничивается лишь вашим набором интеграций).</li><li>Создание собственных стратегий для конвертации, которые позволяют решать самые сложные кейсы.</li><li>Использование точной конвертации осуществляется по определенным параметрам, таким как источник курса, его тип обмена и категория. Альтернативно, можно использовать средний курс из всех источников, доступных в базе данных, с учетом фильтрации по категории источника валют.</li></ol><p>Обсуждение в комментариях может привести к ценным идеям и обмену опытом. Если у вас возникали аналогичные сценарии или есть желание использовать более широкий функционал сервисов курсов валют, я бы с интересом прочитал ваши мысли и опыт.</p><p>Какие функции или возможности вам кажутся наиболее важными или полезными для улучшения этого сервиса? Я открыт к обсуждению и готов рассмотреть любые предложения по его улучшению.</p><p>P.S. Сам микросервис я трансформировал в отдельное API, к которому теперь есть доступ не только у меня. Если кто-то захочет использовать его или просто “потыкать палкой”, то велкоме: <a href="https://irates.io">https://irates.io</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Что такое OpenTelemetry и как она может улучшить качество ваших сервисов</title>
      <link>https://tproger.ru/articles/chto-takoe-opentelemetry-i-kak-ona-mozhet-uluchwit-kachestvo-vawih-servisov</link>
      <comments>https://tproger.ru/articles/chto-takoe-opentelemetry-i-kak-ona-mozhet-uluchwit-kachestvo-vawih-servisov?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Dmitrii “Ymatigoosa”]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/chto-takoe-opentelemetry-i-kak-ona-mozhet-uluchwit-kachestvo-vawih-servisov</guid>
      <description><![CDATA[<p>Разбираем OpenTelemetry: трассировка, логи, метрики и Baggage в микросервисах. Узнайте, как настроить наблюдаемость и повысить надёжность бэкенда.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/chto-takoe-opentelemetry-i-kak-ona-mozhet-uluchwit-kachestvo-vawih-servisov">Что такое OpenTelemetry и как она может улучшить качество ваших сервисов</a>»</p>]]></description>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[OpenTelemetry]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 05 Jun 2024 13:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Раньше, когда мы говорили "backend", мы скорее всего имели в виду одно большое приложение с одной большой базой данных, для мониторинга которого было достаточно простого логирования. Теперь, благодаря технологиям вроде Kubernetes, микросервисы стали стандартом, приложений становится больше, приложения становятся распределенными и традиционного логирования уже недостаточно для отладки и диагностики проблем.</p><p>Отличным решением для организации мониторинга является OpenTelemetry - современный инструментарий, который можно применять для отладки и анализа производительности распределенных систем.</p><p>Эта статья предназначена для профессионалов в сфере IT, стремящихся расширить свои знания в области оптимизации работы бэкенда. Ниже мы в деталях рассмотрим, что такое OpenTelemetry, из каких ключевых концептов она состоит, и какие проблемы помогает решить. Если вам интересно, как OpenTelemetry может изменить подход к мониторингу и отладке ваших бэкенд-систем, повысив их надежность и эффективность – читайте дальше!</p><p>OpenTelemetry — важный слой наблюдаемости, но не вся картина целиком. Если нужен полный маршрут DevOps-инженера и место observability в нём, посмотрите <a href="https://tproger.ru/articles/roadmap-devops-inzhenera-v-2026-godu--chto-uchit-i-v-kakom-poryadke">Roadmap DevOps-инженера в 2026 году: что учить и в каком порядке</a>.</p><h2>Коротко об истории OpenTelemetry</h2><p>Первыми с проблемой распределенного логирования и трейсинга столкнулись крупные технологические компании еще в конце 2000-х годов. В 2010 году Google опубликовал статью "<a href="https://research.google/pubs/pub36356/">Dapper, a Large-Scale Distributed Systems Tracing Infrastructure</a>", послужившую основой для разработки компанией Twitter инструмента трейсинга - Zipkin, который был выпущен в 2012 году.</p><p>Затем, в 2014 году, появился Kubernetes, который значительно упростил разработку микросервисов и других облачных распределенных систем. Это привело к тому, что все большее количество компаний начало сталкиваться с проблемой распределенного логирования и трейсинга в микросервисах. Для стандартизации распределенного трейсинга был создан стандарт OpenTracing, принятый <a href="https://www.cncf.io/">CNCF</a>, а также проект OpenCensus от Google, решающий ту же задачу.</p><p>В 2019 году проекты OpenTracing и OpenCensus объявили об объединении под названием OpenTelemetry. Полученная платформа объединяет лучшие практики, накопленные за много лет, и позволяет с минимальными усилиями интегрировать трассировку, логирование и метрику в любые системы, независимо от их сложности.</p><p>Сегодня OpenTelemetry – это не просто проект, это по сути отраслевой стандарт сбора и передачи телеметрических данных. Его разработку и поддержку осуществляет сообщество специалистов и компаний – лидеров рынка, таких как Google, и Microsoft. Проект непрерывно развивается, получая все новые возможности с целью еще большего упрощения процесса интеграции и использования.</p><figure><img src="https://media.tproger.ru/user-uploads/100037/2024-04-14/4c6789c8-4d1f-4332-a672-0aabb31f594c.png" alt="" /></figure><h2>А что внутри?</h2><p>OpenTelemetry - это целый набор практик и инструментов, определяющих, какие <b>сигналы </b>может генерировать приложение для взаимодействия с внешним миром, а также как эти сигналы можно собирать и визуализировать для наблюдения за состоянием приложений и системы в целом. Три основных типа сигналов: трассировка, логирование и сбор метрик. Давайте рассмотрим составляющие части подробнее.</p><figure><img src="https://media.tproger.ru/user-uploads/100037/2024-04-14/af81be8e-6831-4bef-b6a9-50d9d192cb0a.jpg" alt="" /></figure><h3>Контексты</h3><p>OpenTelemetry вводит понятие контекста операции. Контекст в первую очередь включает в себя атрибуты trace_id (идентификатор текущей операции) и span_id (идентификатор подзапроса, при ретраях каждый подзапрос, например, должен иметь уникальный span_id). Кроме того, контекст может содержать статическую информацию, такую как название ноды, на которой развернуто приложение, или название окружения (prod/qa). Такие поля в терминологии OpenTelemetry называются resource и прикрепляются к каждому логу, метрике или трассировке для более удобного поиска. Дополнительно в контексте могут содержаться динамические данные, например, идентификатор текущего эндпоинта ("http_path": "GET /user/:id/info"), которые могут быть выборочно прикреплены к группе логов, метрик или трассировок.</p><p>Контексты OpenTelemetry могут передаваться между различными приложениями с использованием протоколов context propagation. Эти протоколы представляют собой наборы заголовков, которые добавляются в каждый HTTP- или gRPC-запрос, или же в заголовки сообщений для очередей. Это позволяет нижестоящему приложению восстановить контекст операций из этих заголовков.</p><p>Можно выделить следующие виды передачи контекста:</p><ul><li>B3-Propagation: Это набор заголовков вида x-b3-*, изначально разработанный для системы трассировки Zipkin. Он был адаптирован в OpenTracing и использовался многими инструментами и библиотеками. B3-Propagation обеспечивает передачу trace_id/span_id, а также флага, указывающего на необходимость семплирования;</li><li>На смену ему пришел стандарт W3C Trace Context: Разработанный рабочей группой W3C. Он объединяет в себе практики различных подходов к контекстному распространению в единый стандарт и этот подход является стандартным в OpenTelemetry.</li></ul><h3>Tracing</h3><p>Трейсинг - это процесс записи и последующей визуализации таймлайна пути запроса через несколько приложений.</p><figure><img src="https://media.tproger.ru/user-uploads/100037/2024-04-14/0dbcda7c-dc83-489c-9d85-6124408a06a5.png" alt="" /><figcaption>Источник: https://opentelemetry.io/docs/demo/screenshots/</figcaption></figure><p>На визуализации каждая полоска называется "span" и имеет идентификатор "span_id". Корневой span называется "trace" и имеет идентификатор "trace_id", который служит идентификатором всего запроса.</p><p>Такая визуализация позволяет:</p><ul><li>Анализировать время исполнения запроса на каждой из систем и баз данных и выявлять узкие места, требующие оптимизации</li><li>Выявлять циклические зависимости между сервисами</li><li>Находить дублирующие запросы</li></ul><p>Используя данные трейсинга, можно также строить дополнительные аналитики, такие как построение карты микросервисов или распределение времени между разными системами при обработке операций.</p><p>Важно отметить, что даже если не используется выгрузка трейсов для визуализации таймлайнов, OpenTelemetry все равно генерирует trace_id и span_id для использования в других сигналах.</p><h3>Logs</h3><p>Логирование, несмотря на свою кажущуюся тривиальность, остается одним из наиболее мощных инструментов для диагностики проблем. OpenTelemetry расширяет возможности традиционного логирования, добавляя контекстную информацию. В частности, при наличии открытого трейса к логам автоматически добавляются атрибуты trace_id и span_id, позволяющие связать логи с таймлайном операций. Кроме того, в качестве атрибутов лога можно использовать как статическую информацию из контекста OpenTelemetry – например, идентификатор ноды, так и динамическую информацию – например, идентификатор текущего HTTP-эндпоинта ("http_path": "GET /user/:id").</p><p>Используя идентификатор trace_id, можно найти логи всех микросервисов, связанных с текущим запросом, в то время как span_id позволяет разделять подзапросы. Например, в случае ретраев логи от разных попыток будут иметь разные span_id. Использование этих идентификаторов позволяет быстро анализировать поведение всей системы в реальном времени и быстрее диагностировать проблемы, что способствует повышению стабильности и надежности.</p><h3>Metrics</h3><p>Сбор метрик предоставляет количественные данные о работе системы, такие как задержки, количество ошибок, использование ресурсов и т.д. Мониторинг метрик в реальном времени позволяет оперативно реагировать на изменения в производительности системы и предотвращать сбои и перегрузки, гарантируя высокий уровень доступности и надежности приложения для пользователей. А интеграция с хорошо известными инструментами, такими как Prometheus и Grafana,  позволяет визуализировать эти данные, что существенно упрощает мониторинг.</p><figure><img src="https://media.tproger.ru/user-uploads/100037/2024-04-14/6df10692-e64c-45a1-b445-540820e1465c.png" alt="" /><figcaption>Источник: https://grafana.com/blog/2021/06/22/grafana-dashboard-showcase-visualizations-for-prometheus-home-energy-usage-github-and-more/</figcaption></figure><p>Коллекторы метрик OpenTelemetry совместимы со стандартами выгрузки метрик Prometheus и OpenMetrics, что обеспечивает возможность легкого перехода на решения OpenTelemetry без необходимости внесения значительных изменений. SDK OpenTelemetry позволяет вместе с метриками выгружать примеры trace_id, чтобы была возможность связывать метрики с примерами логов и трейсами.</p><h3>Связь между сигналами</h3><p>Вместе логи, метрики и трейсинг создают комплексную картину состояния системы: логи предоставляют информацию о событиях в системе, позволяя быстро находить и исправлять ошибки; метрики отражают качественные и количественные показатели работы системы, например, время отклика или процент ошибок; трейсинг дополняет эту картину, отображая путь выполнения запросов через различные компоненты системы, что помогает понять взаимосвязи между ними. Однозначная связь логов, трейсов и метрик – одна из отличительных особенностей OpenTelemetry.</p><p>Grafana, к примеру, позволяет пользователю, открывшему лог, увидеть соответствующий трейс и метрики запроса, что существенно повышает удобство и эффективность использования платформы.</p><figure><img src="https://media.tproger.ru/user-uploads/100037/2024-04-14/9193fdd5-f59a-400e-9201-9fa7b3102fd9.jpg" alt="" /><figcaption>Источник: https://grafana.com/blog/2020/03/31/how-to-successfully-correlate-metrics-logs-and-traces-in-grafana/</figcaption></figure><p>Помимо этих трех компонентов, OpenTelemetry включает в себя концепции Sampling, Baggage и управления контекстом операций.</p><h3>Sampling</h3><p>В высоконагруженных системах трафик выгружаемых логов и трейсов может достигать огромных значений, требуя невероятных расходов на инфраструктуру и хранение данных. Для решения этой проблемы стандарты OpenTelemetry включают в себя возможность семплирования сигналов – возможность выгружать не все трейсы и логи, а только их часть. Например, можно подробно выгружать только сигналы от некоторого процента запросов или выбрать для выгрузки только сигналы от долгих запросов или только сигналы от запросов, завершившихся с ошибкой. Это позволяет получить достаточную выборку для построения статистики и сэкономить значительные ресурсы.</p><p>Однако, если каждая система самостоятельно принимает решения о том, какие запросы мониторить подробно, а какие – нет, мы столкнемся с тем, что будем всегда видеть фрагментированную картину по каждому запросу – некоторые системы будут выгружать подробные данные, в то время как другие могут решить, выгружать данные частично или вовсе не выгружать их.</p><p>Для решения этой проблемы механизмы распространения контекста OpenTelemetry передают флаг семплирования вместе с trace_id/span_id. Это необходимо для того, чтобы, если сервис, первый принявший запрос от пользователя, решит, что запрос должен быть выгружен подробно, все остальные системы также должны следовать этому решению и также выгружать данные подробно. В противном случае все системы должны выгружать сигналы частично или не выгружать вовсе, чтобы сэкономить ресурсы. Такой подход называется "Head Sampling" - решение принимается в начале обработки запроса случайно или на основе каких-то входных атрибутов.</p><p>Кроме этого, OpenTelemetry поддерживает режим "Tail Sampling", при котором все приложения всегда выгружают все сигналы подробно, но существует некоторый промежуточный буфер. После получения всех данных этот буфер принимает решение о том, стоит ли сохранить данные полностью или оставить лишь частичную выборку. Такой подход позволяет сохранить более репрезентативную выборку по каждой категории запросов (успешные/долгие/ошибочные), но требует настройки дополнительной инфраструктуры.</p><h3>Baggage</h3><p>Механизм Baggage позволяет вместе с trace_id/span_id передавать произвольный набор пар ключ-значение, который автоматически будет передаваться между всеми микросервисами по ходу обработки запроса. Этот механизм полезен для передачи дополнительной информации, которая необходима на протяжении всего пути запроса – например, для передачи информации о пользователе или настройках среды выполнения.</p><p>Пример заголовка для передачи baggage по стандарту w3c</p><p>tracestate: rojo=00f067aa0ba902b7,congo=t61rcWkgMzE,userId=1c30032h5</p><p>Вот несколько примеров использования Baggage:</p><ul><li>Передача бизнес контекста операции, такого как userId, productId, deviceId, через все микросервисы. Такую информацию приложения могут автоматически логировать, чтобы получить возможность искать логи любого приложения по контексту юзера, совершившего оригинальный запрос;</li><li>Специфичные настройки параметры для SDK или инфраструктуры;</li><li>Флаги, по который балансировщики могут принимать решение о роутинге запроса – такой подход можно использовать, чтобы автоматически роутить некоторые запросы на mock бекенды во время тестирования. Т.к. baggage передается автоматически – не надо придумывать дополнительных протоколов, достаточно настроить правило на балансировщике.</li></ul><p>Важный момент: хотя влияние Baggage на производительность само по себе минимально, чрезмерное его использование может существенно увеличить нагрузку на сеть и сервисы. Тщательно выбирайте, какие данные вам действительно необходимо передавать через Baggage, если хотите избежать проблем с производительностью.</p><h2>Имплементация</h2><h3>С точки зрения инфраструктуры</h3><p>Имплементация OpenTelemetry на уровне инфраструктуры требует интеграции бекендов OpenTelemetry в архитектуру приложений и настройки инфраструктуры для агрегации данных и состоит из четырех этапов:</p><ol><li><b>Интеграция с приложениями.</b> На первом этапе SDK или агенты OpenTelemetry интегрируются непосредственно в приложения для сбора метрик, логов и трассировок. Это обеспечивает непрерывный поток данных о работе каждого компонента системы.</li><li><b>Конфигурация экспортеров.</b> Собранные данные направляются из приложений через экспортеры во внешние системы для дальнейшей обработки. Это могут быть системы логирования, мониторинга, трассировки или аналитики, в зависимости от ваших потребностей.</li><li><b>Агрегация и хранение.</b> На этом этапе может происходить нормализация данных, обогащение их дополнительной информацией и слияние данных из разных источников для создания единого представления о состоянии системы.</li><li><b>Визуализация данных.</b> Наконец, обработанные данные представляются в виде дашбордов в таких системах, как Grafana (для метрик и трассировок) или Kibana (для логов). Это позволяет командам быстро оценивать состояние системы, выявлять проблемы и тенденции, а также создавать алерты на основе созданных сигналов.<br /></li></ol><h3>С точки зрения приложения</h3><p>Для интеграции с приложением необходимо подключить SDK OpenTelemetry для соответствующего языка или использовать библиотеки и фреймворки, имеющие прямую поддержку OpenTelemetry. OpenTelemetry часто предоставляет свои реализации широко используемых интерфейсов известных библиотек, что позволяет осуществить drop-in замену. Например, в мире Java для сбора метрик часто используется библиотека Micrometer. SDK OpenTelemetry предоставляет свои реализации интерфейсов Micrometer, что позволяет заменить выгрузку метрик без изменения основного кода приложения. Кроме того, OpenTelemetry предоставляет реализации старых интерфейсов OpenTracing и OpenCensus, что позволяет максимально безболезненно мигрировать на OpenTelemetry.</p><h2>В заключение</h2><p>В условиях постоянного развития и усложнения IT-систем OpenTelemetry – ключ к двери в будущее надежных и эффективных бэкендов. Этот инструмент не просто упрощает отладку и мониторинг; он открывает возможности для глубокого понимания работы приложений и оптимизации их производительности на новом уровне. Присоединяйтесь к сообществу OpenTelemetry, чтобы вместе приближать будущее, где каждый из нас может сделать разработку бэкендов проще и эффективнее!</p>]]></content:encoded>
    </item>
    <item>
      <title>5 архитектурных ошибок, которые мы совершаем на старте проектов</title>
      <link>https://tproger.ru/articles/5-arhitekturnyh-owibok--kotorye-my-soverwaem-pri-starte-proektov</link>
      <comments>https://tproger.ru/articles/5-arhitekturnyh-owibok--kotorye-my-soverwaem-pri-starte-proektov?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/5-arhitekturnyh-owibok--kotorye-my-soverwaem-pri-starte-proektov</guid>
      <description><![CDATA[<p>Какие архитектурные ошибки чаще всего совершают разработчики при запуске проектов и как их избежать? Разбираем пять критичных промахов, которые мешают продукту масштабироваться и усложняют поддержку.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/5-arhitekturnyh-owibok--kotorye-my-soverwaem-pri-starte-proektov">5 архитектурных ошибок, которые мы совершаем на старте проектов</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Django]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Redux]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Маркетинг]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Vue]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 14 Jul 2023 12:10:24 GMT</pubDate>
      <content:encoded><![CDATA[<p>Можно запустить MVP за пару недель, но потом годами разгребать архитектурные долги. Ошибки на старте проекта легко не заметить: код вроде бы работает, фичи выкатываются, пользователи приходят. Но когда продукт растёт, каждая непродуманная деталь в архитектуре оборачивается багами. Разбираем пять ключевых ошибок, которые разработчики совершают чаще всего, и объясняем, как их избежать.</p><h2>Ошибка 1. Нет четких границ между слоями приложения</h2><p>На старте проекта код часто пишется «в лоб»: контроллеры ходят в базу напрямую, внутри функций появляются бизнес-правила и расчёты, а валидация размазывается по коду. Это кажется удобным, пока приложение небольшое. Но при росте команды и количества фич изменения начинают ломать соседние части кода, баги растут, а скорость разработки падает.</p><p>Можно выделить три базовых уровня:</p><ul><li>Контроллеры (или хэндлеры) принимают запросы, проводят базовую валидацию (например, через pydantic-схемы) и передают данные дальше.</li><li>Слой бизнес-логики реализует правила работы приложения: транзакции, расчёты скидок, проверку лимитов, работу с несколькими сервисами.</li><li>Слой доступа к данным отвечает за запросы к базе и возвращает данные в удобной для бизнес-логики форме.</li></ul><p>Например, в FastAPI проще начать с хэндлеров, которые сразу ходят в SQLAlchemy-модель. Но если сразу заложить сервисный слой, расчёты комиссий и проверку бизнес-правил можно будет тестировать изолированно, не поднимая всю API. Слой репозиториев позволяет в будущем легко заменить Postgres на другую базу или добавить кэш, не переписывая логику приложения.</p><p>Чёткое разделение позволяет быстро находить, где живёт бизнес-логика, где происходит доступ к данным и куда добавлять новые фичи. Продукт растёт, а код остается предсказуемым, удобным для изменений и масштабирования.</p><h2>Ошибка 2. Игнор масштабирования с первого дня</h2><p>Когда проект только запускается, кажется, что про масштабирование можно подумать потом. Приложение обслуживает сотню пользователей, запросы проходят быстро, всё работает. Но как только запускается маркетинг или приходит первый крупный клиент, внезапно всё начинает тормозить, а в коде нет ни одной зацепки, куда безопасно вставить кэш или вынести тяжёлые операции в фон.</p><p>Важно сразу закладывать в архитектуру точки роста, даже если пока они не нужны на каждый день.</p><p>Например:</p><ul><li>Добавить очереди и фоновые задачи через Celery или RQ, если есть риск появления тяжёлых операций (генерация отчётов, массовая рассылка).</li><li>Разносить чтение и запись: даже простое разделение на эндпоинты, где читающие операции не блокируются длительными транзакциями, уже помогает при росте нагрузки.</li><li>Придумать, как кэшировать самые тяжелые запросы: например, использовать Redis, чтобы хранить агрегированные данные, а не считать их каждый раз.</li><li>Закладывать возможность горизонтального масштабирования: не привязывать логику к локальному состоянию приложения, использовать хранилище с возможностью разделения нагрузки, не писать монолит, который нельзя будет разбить на части при росте.</li></ul><p>На практике проект растёт быстрее, чем кажется. Сначала в API добавляется массовая выгрузка CSV, потом приходят интеграции с другими сервисами, а затем накатывается нагрузка от новых пользователей. Если архитектура не подготовлена, команде приходится ставить костыли, переписывать эндпоинты под фоновые задачи или внедрять кэш в экстренном порядке, исправляя баги в проде.</p><p>Закладывая масштабирование в архитектуру с первого дня,  команда экономит себе месяцы переработок и спасается от бесконечных хотфиксов. Это инвестиция, которая позволяет команде развивать продукт спокойно.</p><h2>Ошибка 3. Преждевременное усложнение архитектуры</h2><p>Многие разработчики боятся, что проект не выдержит нагрузку, поэтому с самого старта закладывают сложные паттерны, микросервисы, брокеры событий и сразу три уровня кэширования. Но пока в системе нет ни пользователей, ни подтверждённой бизнес-модели, такие решения снижают скорость разработки и приводят к куче багов.</p><p>Рядовой пример — проект сразу запускается на Kubernetes с несколькими сервисами, которые обмениваются сообщениями через Kafka. В реальности такие проекты вначале требуют десятков часов на поддержание инфраструктуры, а баги приходится искать сразу в нескольких сервисах, между которыми гуляют события. При этом единственная реальная задача в начале — быстро проверить гипотезы и получить первых пользователей.</p><p>Упрощённая архитектура на старте позволяет команде сосредоточиться на продукте: монолит с чёткими слоями (контроллеры, сервисы, репозитории) куда быстрее дорабатывается и легче деплоится, чем микросервисы с отдельными контурами.</p><p>Что можно делать:</p><ul><li>Запускать монолит на FastAPI или Django, а не дробить на микросервисы до появления реальных узких мест.</li><li>Использовать Postgres без брокеров событий, пока не появятся требования к масштабированию.</li><li>Добавлять кэш Redis точечно, когда видна реальная нагрузка, а не вслепую кэшировать каждый запрос.</li></ul><p>Сложные архитектуры требуют времени на поддержку и экспертизу, чтобы не допустить критичных ошибок (например, потерю событий в брокере или гонки данных между сервисами). Поэтому вложения в сложную архитектуру оправданы, когда проект достигает уровня, где без этого уже не обойтись.</p><p>Если команда делает стартап или MVP, преждевременное усложнение архитектуры только тормозит развитие продукта. Гораздо эффективнее заложить возможности для масштабирования (очереди, фоновые задачи, кэш), но держать архитектуру простой до тех пор, пока проект не начнёт расти и не появятся реальные вещи, требующие изменений.</p><h2>Ошибка 4. Непродуманная работа с зависимостями</h2><p>В начале проекта обычно кажется, что зависимости — это просто. Но со временем проект разрастается, зависимости множатся, версии начинают конфликтовать, а обновление одной библиотеки ломает другую.</p><p>Эта ошибка обычно проявляется в нескольких местах. Например, в проект могут без разбора ставиться зависимости про запас или ради одной строчки удобной функции, хотя можно обойтись стандартной библиотекой. Ещё одна частая проблема — зависимости фиксируются слишком жестко, что не дает обновляться безопасно, или наоборот, версии не фиксируются вовсе, и проект начинает падать после автоматического обновления библиотек.</p><p>Чтобы избежать проблем, важно с самого начала заложить порядок в работе с зависимостями:</p><ul><li>Использовать инструмент управления зависимостями, который позволяет контролировать версии и изолировать окружения.</li><li>Разделять зависимости для разработки и продакшена.</li><li>Периодически обновлять зависимости, чтобы не закапываться в старые версии, но делать это контролируемо и с прогоном тестов.</li></ul><p>Например, при работе с Python удобным подходом будет использование Poetry: можно зафиксировать версии зависимостей в pyproject.toml, автоматически создавать lock-файл, следить за актуальностью библиотек и легко пересоздавать окружение. Если проект запускается на CI/CD, можно установить точные версии и сразу выявить, где обновление ломает тесты.</p><p>В длинных проектах непродуманная работа с зависимостями множится в геометрической прогрессии. Любой новый разработчик тратит время на настройку окружения, зависимости конфликтуют, часть библиотек остаётся неиспользованной. Порядок с зависимостями экономит часы и дни, снижает риск падений в проде и влияет на развитие проекта.</p><h2>Ошибка 5. Нет стратегии управления состоянием</h2><p>Состояние — это данные, которые хранятся между запросами или действиями пользователя: корзина, прогресс пользователя, кэшированные результаты запроса, состояние WebSocket-подключений. Если не продумать, как эти данные хранятся, обновляются и синхронизируются, приложение быстро начинает вести себя непредсказуемо.</p><p>На старте часто используют облегченный подход: данные передаются по цепочке вызовов, хранятся в сессии или глобальных переменных, кэшируются в памяти процесса. Это удобно, пока пользователей мало и сервер один. Но при росте нагрузки и масштабировании начинаются проблемы: сессии теряются между инстансами, кэш расходится, данные теряются при перезапуске приложения.</p><p>Чтобы избежать хаоса, управление состоянием нужно продумать заранее:</p><ul><li>Выяснить, какие данные должны храниться между запросами и как долго.</li><li>Решить, где хранить состояние: в базе данных, Redis, сторонних сервисах.</li><li>Сразу заложить сериализацию и валидацию состояния, чтобы избежать рассинхронизации форматов.</li></ul><p>Например, хранение кэша в памяти может подойти для небольших проектов, но если приложение начинает горизонтально масштабироваться, лучше вынести кэш в Redis, чтобы все инстансы работали с единым источником. Для сессий пользователей можно использовать JWT, если нужно масштабирование без общего состояния, или централизованное хранилище сессий, если требуется возможность их отзыва.</p><p>При работе с фронтендом стратегия управления состоянием не менее важна. Например, при использовании React или Vue проект может сначала обходиться локальным состоянием компонентов, но при росте сложности приложение начинает сыпаться из-за рассинхрона между компонентами. Важно заранее заложить подход с централизованным состоянием, а также понять, какие данные держать в состоянии клиента, а какие запрашивать заново.</p><p>Без стратегии управления состоянием проект становится сложным в отладке и поддержке. Грамотное управление состоянием ускоряет разработку и снижает количество багов в будущем.</p><p>А какие ошибки допускаете вы? Делитесь в комментариях или в тг-канале <a href="https://t.me/+a1v-IRDDUqI0MDhi">Веб-страница</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Поднимаем Full Spring стенд микросервисов из монорепозитория в Kubernetes</title>
      <link>https://tproger.ru/articles/podnimaem-full-spring-stend-mikroservisov-iz-monorepozitoriya-v-kubernetes</link>
      <comments>https://tproger.ru/articles/podnimaem-full-spring-stend-mikroservisov-iz-monorepozitoriya-v-kubernetes?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Юлия Волощенко]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/podnimaem-full-spring-stend-mikroservisov-iz-monorepozitoriya-v-kubernetes</guid>
      <description><![CDATA[<p>Как поднять стенд микросервисов в Kunernetes из монорепозитория, чтобы быстрее зарелизить микросервисы на стенд для экспериментов.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/podnimaem-full-spring-stend-mikroservisov-iz-monorepozitoriya-v-kubernetes">Поднимаем Full Spring стенд микросервисов из монорепозитория в Kubernetes</a>»</p>]]></description>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 29 Jun 2023 10:35:10 GMT</pubDate>
      <content:encoded><![CDATA[<p>Статья ориентирована на тех разработчиков, кто разбил рабочий монолит на микросервисы и теперь думает, как быстрее зарелизить микросервисы на стенд для экспериментов.</p><p>В статье основной упор делается на приготовление одного из рецептов CI в монорепозитории, прохождение по стадиям настройки Spring Cloud Gateway, в конце добавлена щепотка мониторинга — подключение Sentry к микросервисам.</p><p>Данная статья является продолжением статьи:</p><p>Код статьи размещён в монорепозитории:</p><p><b>Автор:</b> Александр Леонов, руководитель группы разработки одной из распределенных команд Usetech.</p><p><b>Дисклеймер:</b></p><p>Данная статья рассчитана на разработчиков, которые волей судьбы или желания работают с деплоем приложений на стенд. Решения, предложенные в статье, не претендуют на использование в работе, они предназначены для экспериментов и общего понимания картины переноса монолита на микросервисы.</p><p>Итак, у нас есть проект какого-то абстрактного магазина, например, мы продавали книги. Раньше он из себя представлял обычный Spring бэкенд, который крутился на 8080 порту. Однако, со временем пришёл заказ на размещение эксклюзива, который будет иметь при релизе у читателей ажиотаж. В таком случае, мы начинаем бояться, а не завалит ли это одно произведение весь магазин? Нужно его как-то масштабировать в случае нагрузки. Причём полностью масштабировать мы его не хотим, т. к. знаем, что только часть оформления заказов будет под высокой нагрузкой. Поэтому из всех идей, нам приходит в голову перевести монолит на микросервисы.</p><p>Для начала проведём подготовку со стороны кода, выделив в отдельные модули важные части (будем дробить по бизнес-ценности), затем изолируем модули друг от друга и сделаем их самостоятельными. Spring Boot приложениями. В итоге, проект будет выглядеть так:</p><figure><img src="https://media.tproger.ru/uploads/2023/06/158ff409-1d33-4c0f-922d-e34d835cf57e-autoconverted.jpeg" alt="" /></figure><p>Отлично, теперь у нас есть 4 отдельных разрозненных микросервиса, которые разные и под которые нужно переделывать фронт. Но нам, по возможности, этого бы не хотелось, поэтому пришла идея использовать Spring Cloud Gateway. Но не стоит сразу с места в карьер. В теории, если успех магазина по продаже книжек зайдёт, то его можно будет развести до целой платформы и потом продавать другим разработчикам сертификаты о её знании. Для того, чтобы безболезненно внедрять микросервисы, нам нужно хранить их конфигурации в одном месте, всё равно уже в монорепозитории делаем. Так как проект учебный, то почему бы не использовать стандартный Spring Config Service. Добавим к нашим разрозненным сервисам config-service и вынесем в специальную папку config все отличающиеся части application.yml файлов сервисов, унифицировав оставшиеся к одному стандартному виду, который будет тянуть всё содержимое из сервиса конфигурации.</p><p><b>В итоге получается вот такая структура:</b></p><figure><img src="https://media.tproger.ru/uploads/2023/06/2aa1e71c-dcad-4e0c-be93-5c9ffe4f5f48-autoconverted.jpeg" alt="" /></figure><p>Новый сервис по коду — обычный spring boot application, но с особенностями:</p><p>1) В помнике присутствуют две зависимости:</p><p>2) Над стартером приложения размещена аннотация @EnableConfigServer</p><p>Рассмотрим application.yml нового config-service:</p><p>Рассмотрим конфигурацию order-service, которую мы будем подгружать из конфиг сервиса config/order-service.yml:</p><p>А теперь увидим изменённый application.yml внутри сервиса order-service:</p><p>Всё, теперь order-service будет подгружать конфигурацию из config-service. Помимо плюсов, стоит отметить, что будут минусы при написании тестов, т. к. нам нужно будет или поднимать config-service или копировать содержимое части order-service.yml в application-test.yml. Но мы пока о тестах не думали, поэтому вывели все конфигурации сервисов в наш config-service.</p><p>Отлично, теперь у нас есть одна точка отказа, правда вероятность этого крайне мала, т. к. менять конфигурацию мы будем редко и в случае проблемы сразу же это обнаружим.</p><p>Отлично, унифицировав наши микросервисы, давайте избавимся от необходимости вносить правки на фронте, применяя один API Gateway для взаимодействия со всеми сервисами. Для этого создадим новый сервис — gateway-service, который будет использовать Spring Cloud Gateway и крутится на 8080 порту, как наш старый монолит.</p><p>Из особенностей gateway-service можно выделить только:</p><p>1) наличие необходимых зависимостей</p><p>2) наличие в конфиге application.yml необходимых перенаправлений на сервисы:</p><p>Отлично, теперь наши сервисы работают внешне как один бэкенд, фронт переделывать не нужно. Но, как теперь из монорепозитория собирать артефакты по сервисам отдельно, чтобы полностью не собирать проект?</p><p>Нам поможет сборка отдельных модулей maven + одна из стратегий CI в монорепозитории через деплой по коммиту в отдельную ветку, созданную под отдельный сервис. Это проще для понимания, нежели чем стратегия определения изменений в конкретных директориях модулей.</p><p>Итак, напишем наш ci файл. Как и раньше будем использовать github-ci. В итоге, получим такой конфиг сборки артефактов наших сервисов и упаковки их в образы, в docker-hub:</p><p>.github/workflows/maven.yml (по стандартному шаблону github):</p><p>Ура, мы сделали CI из монорепозитория только тех сервисов, которые будем править. Но есть одно но: сервисы за нашим Spring Cloud Gateway не будут масштабироваться автоматически, т. к. выше мы их завязали на порты, т. е. Нам нужно будет править ещё и Spring Cloud Gateway. Давайте поднимем свой service discovery и подружим его со Spring Cloud Gateway. В свободном доступе все предлагают использовать Eureka, её и будем использовать.</p><p>Добавим ещё один сервис discovery-service, который будет ничем иным, как Eureka Server со следующими приметами:</p><p>1) Над стартером используется аннотация @EnableEurekaServer</p><p>2)</p><p>3) во все существующие сервисы добавим над стартером аннотацию: @EnableDiscoveryClient</p><p>и зависимость в помники:</p><p>Теперь переделаем наш конфиг gateway-service:</p><p>Ура, вот теперь мы можем не трогать Spring Cloud Gateway при масштабировании наших сервисов. Работа через Eureka это, конечно, хорошо, но мы бы хотели стенд на kubernetes (т. к. монолит деплоился раньше туда). К тому же, там просто чудесные средства масштабирования приложений из коробки. В таком случае, давайте переведем наши сервисы в k8s:</p><p>Создадим пространство имён:</p><p>В принципе на этом этапе, можно забыть про  Eureka, т. к. далее мы всё равно переделаем наш gateway-service для работу с Kubernetes абстракцией под. Если бы не было Kubernetes, то Eureka была бы незаменимой вещью, но тут она может отдохнуть и остаться в конфигах, в памяти о былых заслугах.</p><p>Обновленный gateway-service.yml:</p><p>Готово, давайте задеплоим наши поды, отмасштабируем payment-service и проверим, что всё работает, как мы задумывали:</p><figure><img src="https://media.tproger.ru/uploads/2023/06/1c1f4c0a-931e-4df5-9925-e5c65c88ad85-autoconverted.jpeg" alt="" /></figure><p>Т.к. у нас ещё жива Eureka давайте проверим, что она видит 2 поды:</p><figure><img src="https://media.tproger.ru/uploads/2023/06/fd1dbedd-84ad-4583-9d8e-674c862a0480-autoconverted.jpeg" alt="" /></figure><p>Постучимся через API Gateway к нашему сервису:</p><figure><img src="https://media.tproger.ru/uploads/2023/06/517860ab-1775-4f2f-88ac-419833aab89c-autoconverted.jpeg" alt="" /></figure><p>Супер, а теперь постучимся за детализацией несуществующих платежей и проверим, что балансер Kubernetes распределяет трафик по двум подам:</p><figure><img src="https://media.tproger.ru/uploads/2023/06/72f0e2b8-64b4-4b58-8ebe-4a6c1a7b6dc6-autoconverted.jpeg" alt="" /></figure><figure><img src="https://media.tproger.ru/uploads/2023/06/144746a5-2284-497d-a347-2e8f20164de0-autoconverted.jpeg" alt="" /></figure><p>Итого, из 6 минус идентификаторов — 2 ушли в ошибку на одной поде, 4 на второй (основная).</p><p>Мы достигли цели, осталось накрутить мониторинг Sentry, для наработки навыка работы с фоном ошибок в домашних условиях.</p><p>1) Зарегистрируемся в https://sentry.io/</p><p>2) Создадим своё пространство, в нём создадим Spring Boot проект:</p><figure><img src="https://media.tproger.ru/uploads/2023/06/603bd39e-79f5-43ee-83ab-aeed7a5e1617-autoconverted.jpeg" alt="" /></figure><p>3) Добавим нужные зависимости в pom.xml по инструкции и dsn путь для отправки ивентов в payment-service.yml (см. код проекта по ссылке) + сделаем выставление значений через переменные среды в deployment файле payment-service.yaml k8s, для замены значений на лету.</p><p>Всё, теперь посмотрим как выглядит фон ошибок по нашим двум подам payment-service:</p><figure><img src="https://media.tproger.ru/uploads/2023/06/a624b186-8ec2-44c6-ac05-896a96d439d1-autoconverted.jpeg" alt="" /></figure><p>Отлично, мы подняли свой стенд микросервисов из дробленого монолита с деплоем из монорепозитория и мониторингом Sentry. Конечно, можно продолжить улучшать то, что уже есть: пирамида тестов, безопасность через sso, зеркалирование трафика kubernetes, внедрение Vault конфигов, но это потом.</p><p>Надеюсь, статья была полезной и интересной. Спасибо за уделенное время!</p>]]></content:encoded>
    </item>
    <item>
      <title>Поднимаем стенд Spring микросервисов в Kubernetes</title>
      <link>https://tproger.ru/articles/podnimaem-stend-spring-mikroservisov-v-kubernetes</link>
      <comments>https://tproger.ru/articles/podnimaem-stend-spring-mikroservisov-v-kubernetes?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Юлия Волощенко]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/podnimaem-stend-spring-mikroservisov-v-kubernetes</guid>
      <description><![CDATA[<p>Гайд для начинающих по поднятию домашнего стенда для экспериментов c k8s c базовым CI/CD для микросервисов Spring.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/podnimaem-stend-spring-mikroservisov-v-kubernetes">Поднимаем стенд Spring микросервисов в Kubernetes</a>»</p>]]></description>
      <category><![CDATA[Обучение программированию]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 24 Jan 2023 12:13:29 GMT</pubDate>
      <content:encoded><![CDATA[<p>В статье будет описан процесс поднятия домашнего стенда для экспериментов c k8s, c базовым CI/CD для микросервисов Spring.</p><p>Автор: Александр Леонов, руководитель группы разработки одной из распределённых команд Usetech.</p><p>Дисклеймер Эта статья ориентирована на тех, кто не имеет полной картины разворачивания сервиса на инфраструктуре или является готовым шаблоном для быстрого поднятия своего стенда.</p><p>Код статьи c инструкцией установки доступен в репозиториях:</p><ol><li><a href="https://github.com/alexandr-leonov/eda-configuration">https://github.com/alexandr-leonov/eda-configuration</a></li><li><a href="https://github.com/alexandr-leonov/eda-order-service">https://github.com/alexandr-leonov/eda-order-service</a></li></ol><p>Итак, вам понадобилось обкатать какое-то решение на практике, но на работе это делать не разрешено/опасно/коллеги не поймут… Тогда самое время развернуть свой стенд для испытаний и экспериментами с инфраструктурой и сервисами.</p><p>Дано:</p><ul><li>Кластер на Kubernetes;</li><li>Пару сервисов на Spring с PostgresSQL базой, кешом Redis и взаимодействием по Kafka и REST API;</li><li>Аккаунт на Github (конечно, ближе к настоящей системе поднять свой Gitlab, но т. к. экспериментируем для себя и в одиночку, то Github достаточно);</li><li>Аккаунт на DockerHub.</li></ul><p>Найти:</p><p>Поднять у себя на локальной машине кластер k8s, который бы по пушу в Github деплоил на стенд необходимый сервис.</p><p>Решение:</p><p>Для начала поднимем свой кластер k8s. Для домашнего использования и экспериментов достаточно одного миникуба. Для этого установим его и запустим из терминала, с тем количеством памяти, которое вы можете позволить, но желательно не меньше 2‑х гигов.</p><figure><img src="https://media.tproger.ru/uploads/2023/01/87909a16-3fcf-46f3-b1e3-a17a42c91c32.png" alt="" /></figure><p>Отлично, кластер мы подняли и запустили. Теперь создадим неймспейс наших сервисов. Пускай это будет Event Driven Architecture Develop — слишком долго, поэтому укоротим до eda-dev.</p><p>Создадим namespace.yaml с неймспейсом:</p><p>Применяем конфиг в k8s c помощью команды:</p><p>Теперь попробуем установить Postgress, но перед тем как искать нужный yml в документации, необходимо озаботиться тем, где будем хранить секреты. В этой статье не будем затрагивать тему Vault. Для начала используем стандартный механизм k8s для хранения секретов.</p><p>Оформим secret.yaml:</p><p>Запускаем той же командой:</p><p>Теперь найдём эталонный конфиг k8s для Postgres и модифицируем его под себя.</p><p>Итоговый файл postgres-cluster.yaml:</p><p>Здесь конфиг состоит из двух частей — самого сервиса и плана развёртывания этого сервиса, с указанием секретов и докер образа постгреса. Для экономии ресурсов выделим 1 реплику на БД.</p><p>Далее применяем yaml.</p><ol><li>zookeeper-cluster.yaml, устанавливающий zookeeper (если используете не самую последнюю версию Kafka);</li><li>kafka-broker.yaml, устанавливает Kafka.</li></ol><p>Исходный код:</p><ol><li><a href="https://github.com/alexandr-leonov/eda-configuration/blob/master/dev/kafka/zookeeper-cluster.yaml">https://github.com/alexandr-leonov/eda-configuration/blob/master/dev/kafka/zookeeper-cluster.yaml</a></li><li><a href="https://github.com/alexandr-leonov/eda-configuration/blob/master/dev/kafka/kafka-broker.yaml">https://github.com/alexandr-leonov/eda-configuration/blob/master/dev/kafka/kafka-broker.yaml</a></li></ol><p>После применим наши конфиги по очереди — сначала zookeeper, потом Kafka.</p><p>Помимо установки стандартным путём, можно пойти другим путём, воспользовавшись helm чартами, готовыми сборками компонент, которые можно развернуть одной командой как есть или же переопределить какую-то часть пропертей в values.yaml.</p><p>Установим Redis через helm.</p><p>Для начала установим сам helm, в терминале Ubuntu это делается установкой snap пакета:</p><p>Далее добавим репозиторий с компонентами. Довольно распространены сборки компонент от компании Bitnami.</p><p>А теперь установим полноценный Redis, как есть с указанием неймспейса:</p><p>Готово! Установка helm с переопределением некоторых переменных на примере Mongo DB выглядит так:</p><p>Пример <a href="https://github.com/alexandr-leonov/eda-configuration/blob/master/dev/mongodb/values.yaml">конфига переопределённых переменных</a>.</p><p>Отлично, теперь напишем один из пары микросервисов. Пускай это будет сервис заказов, написанный с использованием Kotlin, Spring Boot, Webflux, Gradle. Так как написание такого сервиса не является целью этой статьи, то можно воспользоваться <a href="https://github.com/alexandr-leonov/eda-order-service">готовым кодом</a>.</p><p>Теперь, когда код сервиса написан, осталось настроить его CI/CD в кластер Kubernetes. Для CI части будем использовать Github Actions, в то время как для CD части обычно используют Webhook. Однако представим, что у нас не белый ip и мы вообще не хотим предоставлять какие-то данные наружу и готовы пожертвовать частью удобств, дабы не увлечься и не сожрать лимиты бесплатного использования service registry, в качестве, которого будем использовать Docker Hub, настроим крон джобу, которая периодически будет обновлять стенд самыми новыми образами сервисов.</p><p>Итак, CI делаем на стороне order-service, сначала подготовим Dockerfile для образа приложения:</p><p>Затем, модифицируя стандартный github-ci конфиг, а также используя стандартные секреты Github для хранения логинов и паролей, получим:</p><p>Данный конфиг будет собирать образ и публиковать его Docker Hub при каждом пуше в мастер.</p><p>Настало время CD части.</p><p>Создадим order-service.yaml, который будет разворачивать наше приложение в k8s с заданными настройками:</p><p>Так как конфиги лежат в отдельной Github репе, то креды Docker Hub скрыты подобным образом. Однако при локальной работе их нужно будет заменить настоящими значениями. Значения вида $(POSTGRES_SERVICE_HOST) стандартные, их можно не менять.</p><p>Применим конфиг:</p><p>Готово, сервис пошёл тянуть образ из Docker Hub. Смотрим поды:</p><figure><img src="https://media.tproger.ru/uploads/2023/01/d3552c47-3be8-4ca7-8a56-a2ed4a060795.png" alt="" /></figure><p>Ждём, когда сервис стартанёт.</p><figure><img src="https://media.tproger.ru/uploads/2023/01/3c266c10-4dc1-4565-8f29-e9413cc9bd83.png" alt="" /></figure><p>Готово, сервис поднят, теперь можно стучаться к сваггеру. Для этого определим какой ip адрес у ноды k8s, а затем найдём порт, по которому доступно приложение:</p><figure><img src="https://media.tproger.ru/uploads/2023/01/90e04ef6-2d47-446b-bfa7-7e95445dd6da.png" alt="" /></figure><p>Открываем сваггер:</p><figure><img src="https://media.tproger.ru/uploads/2023/01/dd1d2d8c-c4da-423e-99cf-bd99af8c6be3.png" alt="" /></figure><p>В целом можно остановиться. Но, не каждый же раз руками вызывать деплой сервиса! Поэтому автоматизируем и этот процесс так, как договорились ранее.</p><p>Перед тем как создавать шедуллер джобу, надо отметить, что она должна выполняться, как системный процесс, а значит её необходимо наделить соответствующими правами, используя политику RBAC k8s.</p><p>Создадим конфиг прав для плана order-service-deployment — rights.yaml:</p><p>Теперь создадим джобу scheduler.yaml, которая будет каждые 4 часа обновлять order-service в кластере, если в Docker Hub появились новые образы.</p><p>Применим данные конфиги:</p><p>Ура! Мы развернули кластер с микросервисом Spring, с полноценным CI/CD процессом, познакомились с некоторыми сущностями k8s, helm и подняли тестовый стенд для экспериментов.</p><p>Если вам понравилась эта статья, то скоро выйдет продолжение, где мы рассмотрим более сложную работу микросервисов в Kubernetes с балансировкой через Spring Cloud Gateway, хранением конфигураций приложений в Spring Config Service, фиксированием инцидентов через Sentry.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как разработать веб-приложение уровня Enterprise Application с нуля</title>
      <link>https://tproger.ru/articles/kak-razrabotat-veb-prilozhenie-urovnja-enterprise-application-s-nulja</link>
      <comments>https://tproger.ru/articles/kak-razrabotat-veb-prilozhenie-urovnja-enterprise-application-s-nulja?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Philipp Ple]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-razrabotat-veb-prilozhenie-urovnja-enterprise-application-s-nulja</guid>
      <description><![CDATA[<p>Авторы подписки «Огонь» поделились личным опытом и рассказали, как разработать Enterprise Application с нуля. Код — внутри.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-razrabotat-veb-prilozhenie-urovnja-enterprise-application-s-nulja">Как разработать веб-приложение уровня Enterprise Application с нуля</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Golang]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 26 May 2022 08:13:28 GMT</pubDate>
      <content:encoded><![CDATA[<h2>План</h2><ol><li><a href="https://tproger.ru/#part1">Вводная</a></li><li><a href="https://tproger.ru/#part2">Бизнес-требования</a></li><li><a href="https://tproger.ru/#part3">Требования к архитектуре</a></li><li><a href="https://tproger.ru/#part4">Требования к веб-фреймворку</a></li><li><a href="https://tproger.ru/#part5">Выбор веб-фреймворка</a></li><li><a href="https://tproger.ru/#part6">Начало работы над проектом</a></li></ol><h2>Вводная</h2><p>Всем привет, сегодня мы начинаем серию статей о том, как разработать коммерческое веб-приложение с нуля. В этом материале будут продемонстрированы решения, используемые командой разработки подписки «Огонь» <a href="https://ogon.ru/">Ogon.ru</a>.</p><p>Прежде чем начать писать код, давайте поймем, что мы хотим получить в итоге. Для этого составим бизнес-требования и технические требования.</p><h2>Бизнес-требования</h2><p>В рамках серии статей мы разработаем интернет-магазин. Давайте разложим функционал магазина на несколько простых пользовательских историй. Я, как пользователь сайта интернет-магазина, могу:</p><ol><li>Зарегистрироваться на сайте.</li><li>Авторизоваться на сайте.</li><li>Посмотреть список товаров.</li><li>Посмотреть карточку товара.</li><li>Положить товар в корзину.</li><li>Управлять товарами в корзине.</li><li>Оплатить товары в корзине.</li><li>Получить чек на почту.</li></ol><h2>Требования к архитектуре</h2><p>Как мы видим, весь функционал раскладывается на три предметные области или домена:</p><ol><li>Пользователи.</li><li>Товары.</li><li>Заказы.</li></ol><p>Разделение всего функционала на домены является одним из принципов <a href="https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B5%D0%B4%D0%BC%D0%B5%D1%82%D0%BD%D0%BE-%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5">DDD</a>. Разделять проект на домены хорошо, потому что:</p><ol><li>Домен описывается набором сущностей, характерных для него.</li><li>Домен имеет набор сервисов, которые управляют этими сущностями.</li><li>Домены общаются между собой через сервисы.</li></ol><p>Архитектура, разработанная на принципах DDD, имеет очевидные преимущества:</p><ol><li>Бизнес-логика пишется один раз внутри домена и переиспользуется другими. Значит изменение логики либо не затронет остальные части проекта, либо будут дешевле с точки зрения времени и денег.</li><li>Все домены имеют схожую структуру, значит разработчикам будет легче переключаться между доменами и разбираться, что там происходит.</li></ol><p>Таким образом, мы получаем проект, который проще разрабатывать и тестировать потому, что каждый домен является центром силы, раз он делает только свою часть работы. Исходя из того, что мы выделили три домена, нам необходимо реализовать три микросервиса:</p><ol><li>Пользователи.</li><li>Товары.</li><li>Заказы.</li></ol><p>Команда разработки <a href="https://ogon.ru/">Ogon.ru</a> начинает новую фичу с проектирования API и схемы СУБД, т.к. готовая фича — это работающая и серверная, и клиентская часть. Кроме того, фича должна соответствовать критериям приемки, значит и тестировщики должны быть сразу вовлечены в процесс. Другими словами, надо организовать работу N человек, а для этого надо с чего-то начать. Давайте начнем с API, но сначала поймем, что мы хотим от веб-фреймворка.</p><h2>Требования к веб-фреймворку</h2><p>Во время разработки API <a href="https://ogon.ru/">Ogon.ru</a> мы использовали свой положительный опыт из прошлых проектов и рекомендации <a href="https://restfulapi.net/">REST API Tutorial</a>. Таким образом, веб-фреймворк должен поддерживать:</p><ol><li>Маршрутизацию запросов по схеме.</li><li>Маршрутизацию запросов по заголовкам.</li><li>Маршрутизацию по URL-пути.</li><li>Переменные в URL-пути.</li><li>HTTP-методы.</li><li>Контекст запроса.</li><li>Middleware.</li><li>Получение запросов в JSON, XML и т. д.</li><li>Встроенную десериализацию запросов и ответов.</li><li>Генерацию документации для фронтэндщиков, тестировщиков и наших партнеров.</li><li>Минимизацию трафика между микросервисами.</li></ol><h2>Выбор веб-фреймворка</h2><p>Проведя несложный поиск, можно легко убедиться, что:</p><ol><li>Веб-фреймворков <a href="https://github.com/mingrammer/go-web-framework-stars">много</a>.</li><li>Все они в той или иной степени реализуют все наши требования, кроме документации и минимизации трафика.</li></ol><p>Как уже говорилось ранее, над фичей работают много человек, с фичей могут работать партнеры, значит документирование API становится важной задачей. Для документирования API можно воспользоваться:</p><ol><li><a href="https://raml.org/">RAML</a></li><li><a href="https://apiblueprint.org/">API Blueprint</a></li><li><a href="https://www.openapis.org/">OpenAPI</a> (<a href="https://swagger.io/specification/">Swagger</a>)</li></ol><p>На наш взгляд <a href="https://github.com/search?l=Go&amp;o=desc&amp;q=raml&amp;s=stars&amp;type=Repositories">RAML</a> и <a href="https://github.com/search?l=Go&amp;o=desc&amp;q=api+blueprint&amp;s=stars&amp;type=Repositories">API Blueprint</a> слабо представлены в golang, т.к. количество проектов, использующих эти технологии, невелико по сравнению с <a href="https://github.com/search?l=Go&amp;o=desc&amp;q=swagger&amp;s=stars&amp;type=Repositories">OpenAPI</a>. Строить коммерческое веб-приложение на непопулярных технологиях — это риски для компании и для команды разработки, т.к. при самом плохом раскладе придется поддерживать выбранную технологию. Мы остановили свой выбор на OpenAPI, и тут на помощь нам пришел <a href="https://grpc.io/">GRPC</a> в реализации <a href="https://github.com/golang/protobuf">Go Protobuf</a> и <a href="https://github.com/grpc-ecosystem/grpc-gateway">GRPC-Gateway</a>.</p><p>GRPC используется в ситуациях, когда микросервисы общаются между собой внутри сети. GRPC-Gateway оборачивает GRPC-методы в красивое REST API. В качестве альтернативы можно было взять:</p><ol><li><a href="https://github.com/go-swagger/go-swagger">Go Swagger</a>, но сам swagger более многословный, чем protobuf, вдобавок не хочется гонять JSON внутри сети, поэтому он нам не подошел.</li><li><a href="https://github.com/swaggo/swag">Swag</a>, но этот проект выглядит костыльным решением для команд, которым потребовалось документировать свое API через полгода разработки на своем любимом фреймворке. Есть риски, что документация API на основе комментариев в коде и сама реализация разойдутся, потому что разработчик забыл их актуализировать, при этом нет никаких инструментов валидации этой ситуации.</li></ol><h2>Начало работы над проектом</h2><p>Теперь давайте потрогаем технологии руками и для начала:</p><ol><li>Установим зависимости:<br />a. <a href="https://grpc.io/docs/protoc-installation/">protoc</a><br />b. <a href="https://www.docker.com/">docker</a><br />c. <a href="https://go.dev/">golang</a><br />d. <a href="http://buf.build/">buf</a>, после 24 февраля введена блокировка для России, решается установкой VPN<br />e. <a href="https://ru.wikipedia.org/wiki/Make">make</a></li><li>Создадим <a href="https://github.com/byorty/enterprise-application">структуру проекта</a> на <a href="https://github.com/golang-standards/project-layout">основании популярного решения</a>.</li><li>Настроим генерацию сервисов и сущностей из protobuf.</li></ol><h3>Генерация сервисов и сущностей из protobuf</h3><p>Установим зависимости для GRPC и GRPC-Gateway:</p><h3>Настроим buf</h3><ol><li>Создадим enterprise-application/buf.yaml</li><li>Создадим enterprise-application/buf.gen.yaml</li><li>Выполним buf mod update</li></ol><p>Теперь мы готовы описывать сервисы, используя <a href="https://docs.buf.build/best-practices/style-guide">рекомендации buf</a> и <a href="https://github.com/alta/protopatch">дополнительные опции protopatch</a>, которые сделают генерацию кода более лаконичной.</p><p>Давайте опишем сервисы и сущности корзины enterprise-application/api/proto/v1/order.proto:</p><p>enterprise-application/api/proto/v1/order_service.proto:</p><h3>По аналогии с сервисом корзины описываем:</h3><ol><li>Микросервис продуктов и его сущности.</li><li>Микросервис пользователей и его сущности.</li></ol><p>Генерируем golang-код:</p><p>buf generate </p><p>В результате мы должны получить сгенерированный код.</p><p>Теперь давайте приступим к реализации бизнес-логики, начиная с микросервиса продуктов, как самого простого.</p><p>Внутренняя архитектура микросервиса будет основана <a href="https://docs.microsoft.com/ru-ru/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/ddd-oriented-microservice">на принципах DDD</a>:</p><ol><li>Доменный слой — описание сущностей, интерфейсов сервисов и репозиториев.</li><li>Инфраструктурный слой — реализация интерфейсов репозиториев и сервисов.</li><li>Слой приложения — реализация GRPC-сервиса.</li></ol><h3>Доменный слой</h3><p>В рамках этой статьи мы опустим описание сущностей и репозиториев, т.к. на текущий момент не работаем с каким-либо постоянных хранилищем. Опишем сервис для управления продуктами.</p><p>pkg/product/domain/service/product.go:</p><p>Обратите внимание, что имя пакета отличается от имени папки из-за того, что в каждом домене будут свои сервисы, соответственно будут конфликты при импорте между order/domain/service и product/domain/service. С помощью такого простого трюка современные IDE будут импортировать пакеты и сразу вешать на него алиас.</p><p>Микросервисы заказов и пользователей реализуются и собираются аналогичным способом.</p><p>Теперь необходимо собрать все воедино и проверить работоспособность, для этого соберем docker-compose.yml.</p><p>deployments/docker-compose.yml:</p><h3>Поднимаем наш проект</h3><p>docker-compose -p enterprise_application -f deployments/docker-compose.yml up -d --build --force-recreate</p><p>Пропишем 127.0.0.1 enterprise.application.local в /etc/hosts.</p><p>Введем в адресную строку браузера http://enterprise.application.local и увидим нашу документацию в виде swagger-файла:</p><figure><img src="https://media.tproger.ru/uploads/2022/05/pic1-autoconverted.jpeg" alt="" /></figure><p>Swagger-файл — это не только наглядный, но и рабочий документ, который позволяет провалиться в конкретный метод, выполнить запрос и получить ответ:</p><figure><img src="https://media.tproger.ru/uploads/2022/05/pic2-autoconverted.jpeg" alt="" /></figure><figure><img src="https://media.tproger.ru/uploads/2022/05/pic3-autoconverted.jpeg" alt="" /></figure><h3>Итак, в рамках данной статьи нам удалось</h3><ol><li>Получить бизнес-требования.</li><li>На их основании выработать требования к архитектуре.</li><li>Подобрать веб-фреймворк.</li><li>Реализовать микросервисы.</li><li>Собрать и развернуть микросервисы на локальном стенде.</li><li>Подготовить документацию по API.</li></ol><p>Код проекта представлен в <a href="https://github.com/byorty/enterprise-application">репозитории</a>.</p><p>В следующей статье мы научимся:</p><ol><li>Работать с middleware.</li><li>Настраивать приложения с помощью конфигурационного файла и переменных окружения.</li><li>Автоматически внедрять зависимости.</li><li>Мокать и тестировать код.</li></ol>]]></content:encoded>
    </item>
    <item>
      <title>Как распилить монолит: о микросервисной архитектуре веб-приложений</title>
      <link>https://tproger.ru/articles/kak-raspilit-monolit-o-mikroservisnoj-arhitekture-veb-prilozhenij</link>
      <comments>https://tproger.ru/articles/kak-raspilit-monolit-o-mikroservisnoj-arhitekture-veb-prilozhenij?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Дарья Кушнир]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-raspilit-monolit-o-mikroservisnoj-arhitekture-veb-prilozhenij</guid>
      <description><![CDATA[<p>Разберёмся, на что обратить внимание при проектировании микросервисов, и выясним, стоит ли вам пилить монолит проекта.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-raspilit-monolit-o-mikroservisnoj-arhitekture-veb-prilozhenij">Как распилить монолит: о микросервисной архитектуре веб-приложений</a>»</p>]]></description>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Гостевая публикация]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 15 Feb 2022 14:08:23 GMT</pubDate>
      <content:encoded><![CDATA[<p>В этой статье мы рассмотрим микросервисную архитектуру бэкенда, разберёмся, на что обратить внимание при проектировании микросервисов, и выясним, стоит ли вам пилить монолит вашего проекта.</p><h2>Что такое микросервисная архитектура</h2><p>Представьте себе интернет-магазин, бэкенд которого не обновлялся много лет. За такой срок магазин успел обрасти не только внушительной базой клиентов, но и устаревшими технологиями, ошибками в коде и багами. Такое веб-приложение с трудом выдерживает наплыв клиентов, что не только негативно отражается на лояльности, но и ставит под сомнение безопасность сервиса. Новые сотрудники тратят слишком много времени на погружение, рефакторинг проходит медленно, что и говорить о введении новых фич и технологий.</p><p>Да, монолитная архитектура веб-приложений имеет свои плюсы, среди которых относительная простота разработки и скорость запуска. С другой стороны, такие системы не всегда отвечают меняющимся требованиям бизнеса, и тогда на помощь приходят микросервисы.</p><p>Микросервисная архитектура — это такой способ проектирования системы, при котором бизнес-логика поделена на несколько частей и реализована в виде независимых приложений. Эти приложения взаимодействуют между собой по определённому протоколу для достижения конкретного результата.</p><p>Если у вас растущий бизнес, и вы планируете масштабирование в перспективе, использование микросервисной архитектуры позволит вам создать устойчивую к нагрузкам систему. Вы сможете выбирать актуальные технологии под ваши нужды и оперативно доставлять новые фичи в продакшн.</p><h2>Проектирование микросервисов</h2><p>При проектировании микросервисов необходимо отталкиваться от их основных характеристик. Каждый микросервис должен быть небольшим, сфокусированным, и независимым настолько, насколько это возможно. Разберём подробнее.</p><p>В фокусе одного микросервиса должна быть одна задача. Это не только позволит сделать его максимально компактным, но и обеспечит «самостоятельность» микросервиса, исключив лишние связи.</p><p>Если вы спроектировали систему, где имеются микросервисы с плотным взаимодействием и один не может существовать без другого, это повод задуматься над тем, чтобы объединить эти приложения в одно.</p><p>Также стоит определиться с тем в каком формате будут взаимодействовать ваши микросервисы (JSON, XML, GraphQL, gRPC). Данный шаг очень важен, так как впоследствии с ростом микросервисов будет сложно перестроиться на новый формат</p><p>Все микросервисы могут и должны взаимодействовать друг с другом, осуществляя синхронные и асинхронные операции.</p><p>Представим, что пользователь изменил фамилию у себя в личном кабинете. Эта информация должна также меняться в email-рассылке, в чате, словом, везде, где используются контактные данные пользователя. Это и будет асинхронной операцией, для осуществления которой создается сообщение, которое затем отправляется в сервер очередей. Информацию об изменении получают те микросервисы, которые подписаны на обновления. При получении этой информации происходит событие — в нашем случае изменение данных пользователя.</p><h2>Инструменты для работы с МС: создание, логирование, мониторинг</h2><p>Вы могли заметить, что микросервисная архитектура — достаточно сложная система, которая требует правильного обращения. Ниже мы собрали инструменты для работы с микросервисами, а также описали основные правила работы.</p><p>Почётное место в списке занимает Docker – платформа для разработки и эксплуатации программных продуктов. Docker стал технологией, которая пришла на замену виртуализации серверов и дала буст микросервисной архитектуре. Docker позволяет завернуть каждый микросервис в отдельный контейнер и поднимать, когда это необходимо.</p><p>Со временем, когда приложение обрастет достаточным количеством микросервисов, потребуется приложение-менеджер для оркестрации. Самый популярный такой менеджер на сегодняшний день — Kubernetes, который позволяет автоматизировать их развёртывание, масштабирование и координацию.</p><p>При этом мы не можем оставить микросервисы без должного наблюдения, поэтому мы подключаем процессы логирования и мониторинга. Логировать необходимо следующие моменты: критические и фатальные ошибки, входящие и исходящие сообщения для поиска места бага, а также недоступность микросервиса, чтобы затем системы мониторинга смогли оповестить, если один из элементов вышел из строя.</p><p>Как можно догадаться, объём логов может выходить за границы чувственного восприятия человека. На помощь приходит ELK-схема — набор из трёх инструментов для генерации, обработки и индексации лога. Микросервис генерирует файлы лога, которые в дальнейшем проходят три этапа обработки. Logstash собирает логи приложений по заданным правилам и направляет их в ElasticSearch, который хранит и индексирует все логи. Затем информация визуализируется в Kibana, где мы можем с ней работать.</p><p>Помимо логирования, необходимо вести мониторинг определенных параметров, чтобы быть в курсе текущего состояния микросервисов. Среди важных параметров:</p><ul><li>нагрузка на сервер — чтобы понять, сколько приложение задействует памяти процессора, оперативной памяти, сколько свободного места остается;</li><li>состояние web-сервера — для отслеживания спама запросов от микросервиса и предотвращения падения приложения;</li><li>сквозной мониторинг запросов позволит понять, через какие микросервисы и как долго проходит тот или иной запрос;</li><li>мониторинг БД — чтобы следить за нагрузкой на распределенные базы данных.</li></ul><p>Для мониторинга можно использовать популярные Zabbix или Prometheus. Выбор зависит от ваших потребностей.</p><p>Напоследок упомянем CI/CD — практику continuous integration и continuous delivery. Так как микросервисов достаточно много, процесс интеграции вручную не представляется возможным. CI/CD позволяет автоматизировать выкладку на разные ландшафты и обладает следующими преимуществами: автоматизация сборки проекта, автоматическое тестирование, экономия времени при доставке фич на разные ландшафты. Для реализации CI/CD используют: Gitlab CI, Bitbucket Pipelines, Jenkins, Gitlab Actions.</p><h2>Работа в команде</h2><p>Чтобы микросервисы не превратились в распределённый монолит, команде также нужно придерживаться некоторых правил работы.</p><p>Исходя из количества микросервисов вся команда делится на группы. В каждой группе назначается ответственный, который обладает наиболее полной информацией о состоянии микросервиса.</p><p>До начала разработки необходимо составить точки входа, согласовать их между командами, создать скрипты для типовых операций, регламент по наименованию идентичных параметров, чтобы не возникало рассогласованности.</p><p>И добавляем самое важное правило: разработал блок — написал документацию.</p><p>Документация при корректном использовании позволяет избежать ошибок и «костылей». К примеру, вашим разработчикам будет проще погрузиться в проект, если у вас есть задокументированная архитектура с описанием взаимодействий, схем и инструментов и бизнес-логика. Для таких целей существуют различные вики-системы, например, Confluence, Bookstack.</p><p>Но если без документации по проекту разобраться ещё получится, хоть и с большим трудом, то без документации API работать невозможно. Фиксировать необходимо публичный API, который вы даете фронтендерам для взаимодействия и микросервисный API. Для этого предлагаем воспользоваться Postman или Swagger.</p><h2>Стоит ли вам перейти на микросервисы?</h2><p>Вам определенно стоит рассмотреть переход на микросервисную архитектуру, если у вас интенсивно развивающаяся система, и у вас есть потребность в создании высоконагруженной, масштабируемой системы. Небольшой совет: если ваш монолит достаточно большой, проводите рефакторинг итерационно, по очереди прорабатывая определенные области.</p><p>При этом нецелесообразно применять микросервисную архитектуру, если у вас небольшой проект, например, блог или промо-сайт, если у вашего веб-приложения стабильно низкая нагрузка, или крайне горят сроки запуска. Возможно, это не лучший момент в корне менять архитектуру.</p><p>Да, микросервисы — это сложно. Они требуют ответственного подхода к проектированию, но затраченные усилия оправданы. С помощью микросервисной архитектуры реально создать отказоустойчивую систему, которую легко совершенствовать и масштабировать.</p><p>Вы также можете посмотреть выступление тимлида Hawking Bros, Ильи Малиновского, о микросервисной архитектуре веб-приложений на конференции Mind Bros Conf</p>]]></content:encoded>
    </item>
    <item>
      <title>Как микросервисы помогают бизнесу</title>
      <link>https://tproger.ru/articles/kak-mikroservisy-pomogajut-biznesu</link>
      <comments>https://tproger.ru/articles/kak-mikroservisy-pomogajut-biznesu?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Мария Кривоченко]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-mikroservisy-pomogajut-biznesu</guid>
      <description><![CDATA[<p>Микросервисы в России применяют для разных задач бизнеса; сравнение двух типов архитектур показывает их преимущества и особенности использования.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-mikroservisy-pomogajut-biznesu">Как микросервисы помогают бизнесу</a>»</p>]]></description>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Гостевая публикация]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 17 Dec 2021 14:40:31 GMT</pubDate>
      <content:encoded><![CDATA[<p>Когда увеличивается конкуренция, на первый план выходит параметр time-to-market. Под ним имеется в виду скорость выпуска на рынок любых доработок клиентских сервисов и продуктов. Это может быть в том числе «фича», которая ускоряет скорость загрузки контента, повышает юзабилити сайта и приложения, способствует кросс-продажам.</p><p>Яркий пример — супераппы в банках, где дополнительной функциональностью можно считать интегрированных голосовых помощников, чаты с другими пользователями, возможность не только оплатить счета из приложения, но и заказать в нём же товары и услуги из смежных сервисов.</p><p>Из-за цифровизации и пандемии, которая подтолкнула многие компании к онлайну, time-to-market новой клиентской функциональности стал одной из метрик эффективности бизнеса. Считается, что низкий параметр TTM снижает жизнеспособность продукта на 20% (данные Gartner).</p><p>В погоне за скоростью компании начинают пересматривать подходы к построению и развитию ИТ-архитектуры, которая лежит в основе сервисов. Пришло понимание, что классическая инфраструктура (её ещё называют монолитной) плохо справляется с актуальными вызовами. Взамен ей всё чаще обращаются к микросервисам — особому подходу, позволяющему ускорить ИТ-разработку и выход конечных продуктов на рынок.</p><p>В активной фазе микросервисы в России стали применять около пяти лет назад, хотя первые упоминания этого подхода в мире датируются началом 2000-х. По мнению аналитиков Allied Market Research, объём рынка микросервисов к 2026 году превысит $8 миллиардов, демонстрируя ежегодный прирост на уровне 18%. Это одна из точек роста глобального ИТ-рынка, включая нашу страну. Из 500 клиентов КРОК Облачные сервисы не менее 65% уже используют у себя микросервисную архитектуру, а примерно 18% планируют «распилить свой монолит» в ближайшие годы.</p><h2>В чём преимущества микросервисов?</h2><p>Рассмотрим на примере двух типов архитектур.</p><h3>Монолитные архитектуры</h3><p>Характеризуются жёсткой иерархией и связностью. В них всё подчинено бизнес-логике. Если мы говорим про интернет-магазин, на бизнес-уровне находятся сервис оплаты, корзина, личный кабинет и другие функциональные блоки для клиентов. Изменение одного из компонентов влияет на остальные, корректируя бизнес-логику. При этом все сервисы обращаются к единой базе данных — основному хранилищу ассортимента товаров, стоимости, скидок и так далее.</p><h4>Минусы:</h4><ul><li>Сложность внесения изменений. Чтобы поменять что-то, пусть и незначительное, в структуре, например, e-commerce платформы (предположим, код модуля, отвечающий за каталог товаров), надо вручную отследить и скорректировать большое количество других зависимостей. Это не только увеличивает время доработки онлайн-ресурса, но и требует вовлечения большого количества инженеров.</li><li>Трудности масштабирования. В монолитных архитектурах не всегда возможно нарастить вычислительные мощности для какого-то одного из сервисов, например, только лишь основной витрины товаров или модуля, отвечающего за оплату. Можно нарастить потребление ресурсов для всего сайта, а это часто бывает избыточно.</li><li>Риски сбоев. Из-за связности компонентов сбой на уровне ПО одного из сервисов с большой долей вероятности негативно повлияет на всю платформу.</li><li>Сложность внедрения новых технологий. Если платформа была написана, предположим, на Python, перейти на что-то другое фактически нереально. В ИТ-отрасли это ещё зовется legacy — унаследованной инфраструктурой, которая в статичном виде может функционировать годами.</li><li>Большие трудозатраты на поддержку. Когда сервисов становится много, нужен супер-квалифицированный специалист, который сможет видеть верхнеуровневую картину. Скорее всего, найти такого на рынке не получится, либо он будет стоить слишком дорого для компании. Единственный путь — вырастить его изнутри.</li></ul><h3>Микросервисы</h3><p>На пользовательский интерфейс никак не влияет, однако внутри она строится по принципиально иным правилам. Каждый сервис — это изолированная сущность, имеющая собственное хранилище и полный набор файлов, библиотек так далее для создания приложения. Каждый сервис, как чаще всего бывает, развивает такая же обособленная команда из продакт-менеджера, DevOps-специалиста, архитектора, инженера.</p><h4>Плюсы:</h4><ul><li>Простота и скорость развёртывания. Благодаря отсутствию зависимости от других сервисов внести изменения можно гораздо быстрее — недели вместо месяцев в монолитной архитектуре.</li><li>Оптимальность масштабирования. Повышение производительности касается только тех сервисов, которым это действительно необходимо. За счёт этого достигается экономия на инфраструктуре.</li><li>Большой выбор технологического стека. Язык программирования можно менять в зависимости от предпочтений ИТ-разработчика или релевантности для конкретной бизнес-задачи. Это важно, так как позволяет привлечь с рынка специалистов, которые не хотят ограничивать себя той или иной технологией.</li><li>Многократное использование. Однажды написав микросервис, его можно использовать многократно в похожих задачах. Благодаря этому уменьшаются трудозатраты и количество рутинных операций, совершаемых ИТ-специалистом.</li></ul><p>Однако не стоит думать, что микросервисы – это панацея. Многие компании не спешат переходить к ним, так как боятся потерять вложенные ранее инвестиции в инфраструктуру. К тому же, объективно, не для каждого приложения и типа бизнеса переход на микросервисы даст ощутимую ценность.</p><p>Кроме того, сам «распил монолита» не кажется такой уж простой задачей. Дополнительный барьер — это всё те же высокие затраты на сопровождение инфраструктуры — бич для российского рынка ближайших лет (уже сейчас дефицит ИТ-специалистов составляет 1 миллион человек в год). Если количество сервисов в инфраструктуре превышает сотню, нужна помощь дополнительных архитекторов и DevOps-специалистов, которые будут разрабатывать API-интерфейсы для согласованности приложений.</p>]]></content:encoded>
    </item>
    <item>
      <title>Система заметок с нуля. Часть 5: знакомство с объектным хранилищем MinIO и разработка микросервиса на Golang</title>
      <link>https://tproger.ru/video/sistema-zametok-s-nulja-chast-5-znakomstvo-s-obektnym-hranilishhem-minio-i-razrabotka-mikroservisa-na-golang</link>
      <comments>https://tproger.ru/video/sistema-zametok-s-nulja-chast-5-znakomstvo-s-obektnym-hranilishhem-minio-i-razrabotka-mikroservisa-na-golang?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[theartofdevel]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/video/sistema-zametok-s-nulja-chast-5-znakomstvo-s-obektnym-hranilishhem-minio-i-razrabotka-mikroservisa-na-golang</guid>
      <description><![CDATA[<p>Знакомство с объектным хранилищем MinIO, его первый запуск и настройка через docker-compose, а также разработка File Service на Golang.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/video/sistema-zametok-s-nulja-chast-5-znakomstvo-s-obektnym-hranilishhem-minio-i-razrabotka-mikroservisa-na-golang">Система заметок с нуля. Часть 5: знакомство с объектным хранилищем MinIO и разработка микросервиса на Golang</a>»</p>]]></description>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Форматы хранения данных]]></category>
      <category><![CDATA[Пост пользователя]]></category>
      <category><![CDATA[Видео]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 30 Apr 2021 11:36:24 GMT</pubDate>
      <content:encoded><![CDATA[<p>Мы продолжаем создание системы заметок. На этот раз посмотрим на разработанный File Service, который работает с хранилищем MinIO. Но сначала разберёмся с самим хранилищем и его настройкой.</p><p>Содержание:</p><p>0:17  Знакомство с MinIO</p><p>3:54  MinIO docker-compose.yml</p><p>5:43 Разработка микросервиса на Golang</p><p>28:08  Текущее состояние системы заметок</p><h2>Знакомство с хранилищем MinIO</h2><p>MinIO создано для размещения неструктурированных данных, таких как фотографии, видеозаписи, файлы журналов, резервные копии, а также образы виртуальных машин и контейнеров. Небольшой размер позволяет включать его в состав стека приложений. В MinIO также поддерживается распределённый режим (Distributed mode), который предоставляет возможность подключения к одному серверу хранения объектов множества дисков, в том числе расположенных на разных машинах.</p><p>MinIO крайне минималистичо, у него нет красивого и функционального UI. Но по части использования ресурсов оно крайне жадное — оперативную память и процессор кушает достаточно много. Также хочу отметить, что такие известные решения, как FreeNAS и TrueNAS под капотом используют именно MinIO.</p><p>В MinIO используется внутренний механизм избыточного кодирования (Erasure coding), обеспечивающий системе достаточную устойчивость, чтобы она оставалась работоспособной даже при отказе половины дисков. Также хранилище управляет целостностью и безопасностью данных, используя собственное хеширование и шифрование на стороне сервера.</p><p>Производительность MinIO сильно зависит от конфигурации операционной системы и файловой системы, на которой будут храниться файлы. По сути, этот инструмент даёт лишь метод хранения объектов поверх файловой системы и никак не влияет на саму файловую систему. Если у вас есть задача хранить и оперировать миллиардами объектов, необходимо подумать в первую очередь о файловой системе, которая будет использоваться под MinIO.</p><h2>Использование MinIO Erasure Coding</h2><p>Erasure Coding — это программная защита данных от повреждения и потери. Как рейд, только намного надёжней. Если классический RAID 6 может позволить себе потерять 2 диска, то MinIO спокойно переживает потерю половины.</p><p>Вся информация хранится в виде блоков данных, к которым есть блоки чётности. И вроде это всё уже было сделано много раз, только есть важное «но»: мы можем явно указывать соотношение блоков чётности к блокам данных для хранимых объектов.</p><p>Хотите 1:1? Пожалуйста! Хотите 5:2? Без проблем! Очень важная функция, если вы используете сразу несколько нод и хотите найти свой собственный баланс между максимальной безопасностью данных и количеством затраченных ресурсов.</p><p>Из коробки MinIO использует формулу N/2 (где N — общее количество дисков), т.е. делит ваши данные между N/2 дисками данных и N/2 дисками чётности. Перевожу на человеческий: можно потерять половину дисков и восстановить данные. Это соотношение задаётся через Storage Class, позволяя вам самостоятельно выбрать, что важнее — надёжность или ёмкость.</p><p>Предположим, что у вас инсталляция на 16 дисков и вам надо сохранить файл размером 100 Мб. Если используются настройки по умолчанию (8 дисков под данные, 8 под блоки чётности), то файл в итоге займёт практически двойной объём т.е. 200 Мб. Если отношение дисков будет 10/6, то понадобится 160 Мб. 14/2 — 114 Мб.</p><h2>Настройка и запуск MinIO</h2><p>Cкачиваем файлы docker-compose.yml и nginx.conf, после чего можно запускать.</p><p>Давайте поближе посмотрим docker-compose файл.</p><p>По дефолту здесь 4 сервиса MinIO. Их количество можно увеличить до 16, но мы уменьшим до 2, чтобы сохранить кластер. Большее количество узлов для нас сейчас избыточно. Также здесь описан сервис NGINX, для которого мы скачивали конфигурацию. Он нужен для балансировки запросов между узлами кластера.</p><p>Описание сервисов MinIO по сути одинаковое. Давайте посмотрим на minio1:</p><ul><li>image с тегом релиза от определенной даты;</li><li>два volume, их можно распределить по разным физическим дискам, чтобы обеспечить отказоустойчивость;</li><li>наружу выставляется 9000 порт для обращения к API;</li><li>указываются переменные среды с логином и паролем доступа к MinIO;</li><li>команда для запуска сервера MinIO в URL  которой используется синтаксис указания множества серверов: [http://minio{1…2}](http://minio{1…2})/data{1…2} раскрывается как массив http://minio1/data1 и http://minio2/data2;</li></ul><p>Далее описан healthcheck, который позволяет мониторить здоровье сервиса. У него есть параметр test. Это Shell-команда, которая вызывает Curl и передает ему URL для проверки того, живёт ли сервис. Делать такую проверку мы будем каждые 30 секунд. Если за 20 секунд сервис не ответит, он будет помечен как нездоровый.</p><p>Запустив compose-файл, открываем интерфейс в браузере. Слева в сайдбаре отображены бакеты — корзины, в которых хранятся файлы, справа — список файлов в бакете. Функционал здесь минимален: можно загрузить, расшарить или удалить файл и создать или удалить бакет.</p><p>На этом знакомство с MinIO завершено, далее — продолжение разработки системы заметок с нуля. В предыдущих частях мы:</p><ul><li><a href="https://tproger.ru/articles/razrabotka-sistemy-zametok-s-nulja-chast-1-proektirovanie-mikroservisnoj-arhitektury/">спроектировали микросервисную архитектуру</a>;</li><li><a href="https://tproger.ru/articles/razrabotka-sistemy-zametok-s-nulja-chast-2-rest-api-dlja-restful-api-service-jwt-swagger/">разработали RESTful API Service на Golang cо Swagger и авторизацией</a>;</li><li><a href="https://tproger.ru/articles/razrabotka-sistemy-zametok-s-nulja-chast-3-znakomstvo-s-neo4j-rabota-nad-mikroservisami-categoryservice-i-apiservice/">познакомились с графовой БД Neo4j и работали над микросервисами CategoryService и APIService</a>;</li><li><a href="https://tproger.ru/articles/sistema-zametok-s-nulja-chast-4-razrabotka-mikroservisov-noteservice-tagservice-i-userservice/">разработали микросервисы NoteService, TagService и UserService</a>.</li></ul><p><a href="https://github.com/theartofdevel/notes_system">Исходный код проекта на GitHub</a></p><p>Какая текущая ситуация? Мы разработали все сервисы. Осталось реализовать веб-клиент в виде приложения на Vue.js, а также заняться инфраструктурой системы, такой как Service Discovering и OpenTracing, упаковать все сервисы в docker-контейнеры и настроить CI/CD.</p>]]></content:encoded>
    </item>
    <item>
      <title>Разработка приложений в среде Kubernetes: преимущества и нюансы</title>
      <link>https://tproger.ru/articles/razrabotka-prilozhenij-v-srede-kubernetes-preimushhestva-i-njuansy</link>
      <comments>https://tproger.ru/articles/razrabotka-prilozhenij-v-srede-kubernetes-preimushhestva-i-njuansy?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Анастасия Жигач]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/razrabotka-prilozhenij-v-srede-kubernetes-preimushhestva-i-njuansy</guid>
      <description><![CDATA[<p>Дмитрий Лазаренко из Mail.ru Cloud Solutions объясняет, кому платформа становится стандартом и в чём особенность Kubernetes-as-a-Service.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/razrabotka-prilozhenij-v-srede-kubernetes-preimushhestva-i-njuansy">Разработка приложений в среде Kubernetes: преимущества и нюансы</a>»</p>]]></description>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[Гостевая публикация]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 29 Apr 2021 12:20:04 GMT</pubDate>
      <content:encoded><![CDATA[<p>Систему оркестрации Kubernetes всё чаще называют более продвинутым уровнем разработки приложений на основе микросервисной архитектуры. Опенсорсная платформа управления контейнерами действительно позволяет быстрее разрабатывать и выводить на рынок ИТ-продукты и сервисы. А также обновлять их и обеспечивать доступность во время пиковых нагрузок.</p><p>Но и нюансов у технологии достаточно. Для кого среда Kubernetes становится стандартом? Кому лучше воспользоваться другими инструментами? И в чём особенность облачного Kubernetes-as-a-Service? Рассказывает Дмитрий Лазаренко, директор по продукту Mail.ru Cloud Solutions.</p><h2>О контейнерах и микросервисах</h2><p>Разговор о Kubernetes нужно начать с определения контейнеров и микросервисной архитектуры. Контейнеры — это изолированная среда для приложений. В них «‎упаковывают» приложения, которые чаще всего работают по принципу микросервисов вместе со средой запуска, кодом, настройками, библиотеками и системными инструментами.</p><p>Обычно код пишут в определённой среде, которая может быть связана с другими составляющими проекта. Контейнер — автономен, поэтому на его работу не влияют внешние факторы. В нём есть всё необходимое для разработки, доставки и развёртывания приложения. К тому же у него небольшой объём и его легко перенести на любую платформу.</p><p>Основное преимущество — это обособленность контейнера от реальной среды, в которой работает приложение. Он несёт с собой операционную систему. Так что можно одновременно запускать несколько контейнеров с приложениями, требующими разные дистрибутивы.</p><p>Именно контейнеры позволяют наиболее эффективно использовать микросервисную архитектуру разработки, которая предполагает отказ от монолитного решения в пользу комплекса автономных сервисов. В рамках одного приложения они взаимодействуют между собой не в единой среде, а через API. И если при монолитной архитектуре «‎ломается» всё приложение, когда из строя выходит какой-то компонент, то при использовании микросервисов, «‎потеря» одного компонента не влияет на приложение в целом. Оно продолжит работу без одной функции. А критичные функции можно дублировать в нескольких экземплярах контейнеров.</p><h2>Kubernetes — инструмент для масштабных разработок</h2><p>В производстве приложения можно задействовать сотни и даже тысячи контейнеров. Управлять ими вручную сложно и ресурсозатратно. Именно поэтому разработчикам необходимы такие сервисы, как Kubernetes.</p><p>Это инструмент с открытым исходным кодом предназначенный для оркестрации множества контейнеров. Координация взаимодействия происходит в течение их жизненного цикла: подготовки, резервирования, мониторинга здоровья, распределения ресурсов, масштабирования, балансировки нагрузки, перемещения между серверами. А также перезапуска в случае сбоев.</p><p>Таким образом, система Kubernetes ускоряет разработку контейнерных приложений и выкатку обновлений. А ведь максимально быстрый Time-To-Market — это именно та задача, которые сегодня пытаются решить крупные игроки в ритейле и логистике, в финансовой сфере, в телекоме и других высококонкурентных направлениях бизнеса.</p><p>Почему в первую очередь именно крупные? Для перехода на среду Kubernetes компании нужны квалифицированные специалисты и серьёзные преобразования ИТ-подразделения. Кластеры Kubernetes — это сложная система. Она требует точной настройки и постоянной поддержки, создания отдельной экосистемы и подключения отдельных Open Source инструментов для мониторинга, балансировки нагрузки и тому подобного. И перед внедрением платформы стоит оценить, действительно ли эта технология необходима.</p><h3>Основные преимущества Kubernetes:</h3><ul><li>Программное управление релизами на серверах. В том числе моментальное внедрение и откатывание релиза, a/b тестирование и другие процессы.</li><li>Автоскейлинг — автоматическое увеличение или уменьшение количества копий приложения или размера кластера (добавление или удаление нод в зависимости от нагрузки).</li><li>Автоматическая регулировка отказоустойчивости — распределение приложений по серверам с учётом нагрузки и в случае сбоя одного из них.</li><li>Автоматизация тестирования и выкатки приложений — без участия администраторов.</li></ul><h3>Есть смысл внедрять Kubernetes, если:</h3><ul><li>ИТ-подразделение постоянно занимается разработкой и поддержкой высоконагруженных приложений, например, интернет-магазина, платёжной системы или мобильного приложения. А также выкатывает новые релизы.</li><li>Компании нужно постоянно обновлять и дорабатывать приложения.</li><li>Используется много контейнеров, и их невозможно контролировать вручную.</li></ul><p>Даже в рамках одной организации на Kubernetes стоит переводить только те проекты, которые соответствуют этим критериям. Для разработки обычных приложений, с оркестрацией небольшого количества контейнеров, достаточно более простых систем.</p><h2>Самостоятельное развёртывание vs KaaS</h2><p>Самостоятельное развёртывание (self-hosted) Kubernetes на собственных серверах «из коробки» не единственный вариант внедрения технологии. Ту же функциональность можно реализовать в облаке проще, используя готовый сервис: KaaS или Managed Kubernetes.</p><p>Если вы используете среду Kubernetes как сервис, провайдер сам обновляет и поддерживает систему. А также занимается вопросами отказоустойчивости кластера. Клиенту для эксплуатации системы потребуется только DevOps-инженер, а не целое подразделение. KaaS хорошо подходит для быстрого первоначального развёртывания кластера. Так, процесс, который в варианте self-hosted занимает от нескольких часов до нескольких дней, в облаке сокращается до десяти минут.</p><p>Дополнительные open source решения в облачном сервисе предоставляются по умолчанию или легко подключаются. Пользователю не нужно вручную настраивать систему мониторинга, балансировку нагрузки, сбор и хранение логов, настройки безопасности, авторизацию пользователей и другие параметры. То же касается хранилищ постоянных данных приложений (так называемых постоянных томов, или Persistent Volumes), которые приходится держать вне часто обновляющихся контейнеров. Хранилище также можно приобрести у провайдера и достаточно просто интегрировать со средой Kubernetes через API.</p><p>KaaS делает технологию доступной не только крупным игрокам, но и небольшим компаниям. Однако даже при использовании облачного Managed Kubernetes не стоит полагаться только на провайдера. Например, чтобы сделать бизнес-критичные приложения максимально доступными, важно помнить о балансировке нагрузки на кластер и возможности его репликации.</p>]]></content:encoded>
    </item>
    <item>
      <title>Видео: разработка микросервиса на Go на примере реального проекта</title>
      <link>https://tproger.ru/video/video-razrabotka-mikroservisa-na-go-na-primere-realnogo-proekta</link>
      <comments>https://tproger.ru/video/video-razrabotka-mikroservisa-na-go-na-primere-realnogo-proekta?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[theartofdevel]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/video/video-razrabotka-mikroservisa-na-go-na-primere-realnogo-proekta</guid>
      <description><![CDATA[<p>Разбор API Gateway на Golang: структура проекта, авторизация через JSON Web Token, система ошибок и паттерны разработки, исходный код лежит на GitHub.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/video/video-razrabotka-mikroservisa-na-go-na-primere-realnogo-proekta">Видео: разработка микросервиса на Go на примере реального проекта</a>»</p>]]></description>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Организация разработки]]></category>
      <category><![CDATA[Golang]]></category>
      <category><![CDATA[Пост пользователя]]></category>
      <category><![CDATA[Видео]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 23 Apr 2021 07:38:08 GMT</pubDate>
      <content:encoded><![CDATA[<p>В этом видео мы рассмотрим готовый проект на Go, являющийся API Gateway для микросервисной архитектуры. Он используется в рамках системы заметок, которую мы <a href="https://tproger.ru/articles/razrabotka-sistemy-zametok-s-nulja-chast-1-proektirovanie-mikroservisnoj-arhitektury/">разрабатываем в отдельной серии материалов.</a></p><p>Мы разберём реализацию JSON Web Token авторизации и систему ошибок. Посмотрим на программную архитектуру проекта, изучим программные паттерны разработки и посмотрим, как использовать в проекте язык программирования Golang.</p><p>Исходный код проекта <a href="https://github.com/theartofdevel/notes_system">доступен на GitHub</a>.</p><p>0:33 Обзор структуры проекта, функции main в файле main.go — точке входа в приложении.</p><p>2:42 Обзор обёртки над логером logrus. Логирование в разные файлы с разным уровнем логирования.</p><p>12:34 Создание объекта конфигурации из YAML-файла при помощи библиотеки cleanenv.</p><p>16:30 Разбираем обёртку над кэшем в Golang и реализацию кэша с использованием библиотеки freecache.</p><p>21:40 Реализация JSON Web Token.</p><p>32:05 Смотрим на хендлеры — обработчики запросов к сервису, разбираем паттерн Data Transfer Object в Golang.</p><p>41:13 Система обработки ошибок и определения статуса HTTP кода возврата по ошибке.</p><p>1:00:10 Общий REST Client для взаимодействия с RESTful сервисами.</p><p>1:09:00 Разбираемся с сервисами бизнес-логики и контекстом в Golang.</p><p>1:23:10 Функции старта приложения по порту и на сокете, Graceful Shutdown с закрытием ресурсов.</p><p>1:26:40 Разбираемся с особенностью Golang: nil != nil.</p>]]></content:encoded>
    </item>
  </channel>
</rss>