<?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>DeFi</title>
    <description>DeFi (Decentralized Finance) — это движение в финансовом секторе, основанное на использовании блокчейн-технологий для создания децентрализованных финансовых услуг, которые не зависят от традиционных банков и финансовых учреждений.

С помощью DeFi пользователи могут зарабатывать на криптовалютах, брать займы, обменивать активы и участвовать в инвестиционных проектах, используя смарт-контракты и децентрализованные приложения (dApps). DeFi открывает новые возможности для прозрачности, доступности и независимости в финансовых операциях.</description>
    <link>https://tproger.ru/tag/defi</link>
    <atom:link href="https://tproger.ru/tag/defi/feed" rel="self" type="application/rss+xml"/>
    <lastBuildDate>Tue, 06 Oct 2026 16:15:06 GMT</lastBuildDate>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>12</sy:updateFrequency>
    <image>
      <title>DeFi</title>
      <link>https://tproger.ru</link>
      <url>https://tproger.ru/apple-touch-icon.png</url>
    </image>
    <item>
      <title>Своя self-hosted двухсерверная VPN-архитектура. Подробный путь разработки и ошибки, с которыми вы можете столкнуться</title>
      <link>https://tproger.ru/articles/svoya-self-hosted-dvuhservernaya-vpn-arhitektura-podrobnyj-put-r</link>
      <comments>https://tproger.ru/articles/svoya-self-hosted-dvuhservernaya-vpn-arhitektura-podrobnyj-put-r?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Роман Фролов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/svoya-self-hosted-dvuhservernaya-vpn-arhitektura-podrobnyj-put-r</guid>
      <description><![CDATA[<p>Проект представляет из себя быстрый способ воссоздать архитектуру состоящую из 2 серверов (локальный + удаленный) с определенными сервисами, которые решают специфические задачи. Проект сделан прежде всего для меня, а также для людей которые хотят свой готовый self-hosted сервер из коробки с полной системой обслуживания</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/svoya-self-hosted-dvuhservernaya-vpn-arhitektura-podrobnyj-put-r">Своя self-hosted двухсерверная VPN-архитектура. Подробный путь разработки и ошибки, с которыми вы можете столкнуться</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[unix]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[Музыка]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[DIY]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[VPN]]></category>
      <category><![CDATA[Telegram]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Cloudflare]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Мессенджер]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[NFT]]></category>
      <category><![CDATA[Машин]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Grafana]]></category>
      <category><![CDATA[VPS]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 26 Jul 2026 15:46:26 GMT</pubDate>
      <content:encoded><![CDATA[<p>Всё
 началось с того, что меня перестал устраивать мой подход к 
развертыванию личных сервисов. Я решил переписать всё с нуля. К тому же 
это был отличный повод получить новые навыки и попробовать инструменты, 
до которых давно не доходили руки.</p><p>Арендовать мощные VPS под 
ресурсоемкие задачи в текущих реалиях выходит неоправданно дорого. При 
этом дома у меня уже был выделенный неттоп (мини-ПК) с 16 ГБ оперативной
 памяти на базе энергоэффективного процессора Intel N95.</p><p>Пройдя 
путь от простых Bash-скриптов и сторонних туннелей до полностью 
автоматизированной инфраструктуры, я создал проект ServeHub-2. В этой 
статье я подробно разберу, как эволюционировала сеть проекта, почему 
декларативный подход победил императивный и с какими неочевидными багами
 пришлось столкнуться в процессе автоматизации.</p><h2>История настройки сетевой архитектуры</h2><h3>Использование Tuna</h3><p>В
 самом начале проекта я еще не думал о VPN как о способе пробития NAT и 
основе, на которой будет строиться вся система. Первое, к чему я пришел —
 сервис Tuna. Если кратко, это аналог Cloudflare Tunnel за условные 300 
рублей. У него очень приятный веб-интерфейс и невероятно простая 
настройка. Однако для полноценной независимой архитектуры он не подошел 
по двум причинам:</p><ul><li>Сервера Tuna находятся вне контроля пользователя.</li><li>На удаленном сервере нельзя развернуть свои сопутствующие сервисы.</li></ul><p>В целом сервис действительно удобный, но для моих задач он оказался слишком ограничивающим.</p><p>Вот
 пример конфига для tuna (все максимально просто, создаем контейнеры для
 ssh туннеля, чтобы был доступ ssh, а также основной http туннель с 
привязкой к nginx или любому другому прокси если такой есть):</p><h3>В поисках гибкости: тесты Pangolin и переход к FRP</h3><p>После Tuna я решил двигаться в сторону собственного контроля и попробовал Pangolin.
 Однако решение быстро отвалилось: для дешёвого сервера оно оказалось 
слишком «тяжёлым» и избыточным. Главные минусы — ощутимый оверхед по 
ресурсам и лишний слой принудительной веб-аутентификации перед самими 
сервисами. Это ломало нормальное взаимодействие с родными мобильными 
клиентами (вроде Element для Matrix или Bitwarden для паролей), где 
повторная авторизация в браузере просто не нужна.</p><p>На смену пришел FRP (Fast Reverse Proxy).
 Он выполнял ту же функцию проброса, но хостил я его уже на собственном 
арендованном VPS в режиме Layer 4 (TCP). Это дало абсолютную гибкость: 
внешний VPS не заглядывал внутрь пакетов и ничего не расшифровывал, а 
просто пересылал сырой поток домой. Кроме того, это отлично 
оптимизировало расходы: вместо 300 рублей за Tuna и ещё 300 рублей за 
отдельный VPN, я стал платить всего 500 рублей за один стойкий VPS, 
который мог настраивать как хочу. (к тому же можно было обойтись даже 
дешевле, так как VPS с 4 гб оперативки загружен всего лишь на 40%, 
процессор всего на 20%-40%)</p><p>FRP состоит из 2 конфигурационных 
файлов (один на удаленном сервере frp server, другой на локальном frp 
client), все также довольно просто, однако его можно использовать на 
разных слоях. У меня он брал трафик за стандартный TCP и передавал его 
на локальный сервер.</p><p>Также доп. фишка в том что основная 
конфигурация происходит именно в frpc, который, в свою очередь, передает
 часть настроек на frp на удаленном сервере.</p><p>frpc.toml:</p><p>frps.toml:</p><h3>Полноценный переезд на WireGuard (AmneziaWG) и 8 часов отладки</h3><p>Со временем архитектура эволюционировала в сторону полноценной VPN-сети на базе WireGuard, а точнее — его модификации AmneziaWG. Причин для этого шага было несколько:</p><ul><li>Безопасность: FRP всё же открывал внутренние ресурсы в публичный интернет, оставляя их доступными для сканеров портов.</li><li>Удобство маршрутизации:
 Все участники сети стали равноправными узлами в одной виртуальной 
локальной подсети. Больше не нужно было настраивать постоянные 
односторонние пробросы.</li><li>Дополнительный бонус:
 Поскольку удаленный VPS был куплен в Нидерландах, через этот же VPN я 
автоматически получил безопасный доступ ко всем зарубежным ресурсам.</li></ul><p>Для реализации схемы на удаленном VPS был развернут контейнер wg-easy с поддержкой AmneziaWG, а на домашнем мини-ПК — клиентский контейнер Amnezia (сборка из Dockerfile с использованием amnezia-tools  и модулем ядра хоста).</p><p>И
 именно здесь я поймал самый изнурительный баг проекта. После 
развертывания трафик упорно шёл только в одну сторону. Часов 8 ушло на 
диагностику iptables, маршрутов и чтение зарубежных форумов (что 
бесполезно, учитывая специфику наших блокировок). Оказалось, провайдер 
просто дропал обратный трафик стандартного WireGuard, так как пакеты шли
 без маскировки. Причина крылась в docker-compose.yml: у меня было прописано image: ghcr.io/wg-easy/wg-easy:latest. Как выяснилось, тег latest  на Docker Hub намертво прилип к старой 14-й версии, а поддержка параметров AmneziaWG появилась только в ветке 15.x. Изменение тега на конкретную версию (15.3) решило проблему за секунду.</p><p>Благодаря
 переходу конфигурация получилась максимально простой, основные отличия 
от стандартной документации выделил в коде: (в основном то, на что 
пришлось долго рыть информацию)</p><h3>Настройка Nginx</h3><p>Чтобы
 сервисы были доступны исключительно внутри подсети VPN, я задействовал 
Nginx. Доступ к приложениям был жестко ограничен на уровне конфигурации —
 веб-сервер принимает запросы только из диапазона IP-адресов 10.8.0.0/24. Любые попытки постучаться на сервер из внешнего интернета без активного VPN-туннеля автоматически сбрасываются Nginx.</p><p>Логика
 распределения завязана на proxy-протоколе: Nginx на удаленном VPS 
выступает основным входным узлом, принимает зашифрованный трафик, 
заворачивает его в заголовки с реальным IP-адресом клиента и через 
туннель перекидывает на локальный Nginx домашнего сервера. Локальный 
веб-сервер уже сам расшифровывает SSL и распределяет трафик по конечным 
Docker-контейнерам, сохраняя реальные IP в логах безопасности.</p><p>Вставлю
 один кусок кода из nginx на удаленной машине для примера, так все 
остальное примерно похоже (конфиги использовались в виде .template):</p><h3>SSL-сертификаты</h3><p>Для получения валидных SSL-сертификатов я настроил работу через автоматический Certbot по challenge-валидации DNS-01 c API Webnames. Сам домен привязан к внутреннему IP-адресу 10.8.0.1.
 Проверка через DNS позволила выпустить единый wildcard-сертификат на 
весь домен и его поддомены без необходимости держать открытым 80-й порт 
веб-сервера наружу.</p><p>Уточню, что certbot запускается автоматически 
во время выполнения Ansible плейбука, поэтому самому кроме указания 
переменных ничего делать не нужно.</p><p>В
 итоге получилась схема, при которой все сервисы доступны по красивым 
доменным именам с HTTPS, но абсолютно невидимы для внешнего интернета.</p><p>Вот настройка certbot:</p><h2>История софта</h2><p>Параллельно
 с сетевой структурой развивался и сам набор приложений. Изначально я 
хотел собрать в одном месте утилиты, которыми пользуюсь каждый день, но в
 процессе селфхостинга быстро понимаешь: нельзя просто накидать 
контейнеров и надеяться, что мини-ПК справится, а конфигурационные файлы
 не превратятся в кашу.</p><h3>Первый стек и оптимизация</h3><p>Первыми на домашнем сервере прижились медиа-сервисы: Navidrome для стриминга музыки и Audiobookshelf
 для аудиокниг и подкастов. Они легковесные, имеют отличные мобильные 
клиенты с синхронизацией прогресса и полностью закрывают мои 
потребности. Позже к ним добавился Nextcloud как единое независимое облако для файлов, контактов и семейных документов.</p><p>Затем встал вопрос безопасного хранения паролей. Сначала я смотрел в сторону оригинального Bitwarden, но в итоге я выбрал Vaultwarden
 — альтернативный сервер на Rust, полностью совместимый с API Bitwarden.
 Он потребляет считанные мегабайты оперативной памяти и работает 
идеально. Дополнительно для удобства управления всей этой распределенной
 Docker-инфраструктурой в локальный стек был добавлен Portainer. (+ Portainer Agent на удаленный сервер)</p><p>Из интересных моментов, где мне пришлось немного больше возиться, чем с остальными сервисами это nextcloud настройка:</p><h3>Ошибки проектирования: почему я удалил Matrix (Synapse)</h3><p>Не все решения прошли проверку временем. На этапе использования Tuna и FRP я развернул сервер Matrix (Synapse)
 для защищенного обмена сообщениями. Мне казалось это крутой идеей, но 
когда я окончательно перешел на AmneziaWG, целесообразность мессенджера 
внутри закрытого туннеля сошла на нет.</p><p>Synapse требовал слишком 
много ресурсов, впустую расходовал оперативку домашнего ПК и усложнял 
конфиг Nginx. При этом реальной пользы для семьи он не приносил. Для 
критических алертов инфраструктуры и повседневного общения проще и 
эффективнее оказалось использовать Telegram. (плюс алертинг настроен 
именно через него) В итоге я полностью выпилил Synapse из стека, 
освободив ресурсы.</p><p>Вместо него я добавил в связку к wg-easy локальный AdGuard Home.
 Теперь он работает прямо внутри VPN-сети: очищает весь трафик от 
рекламы и трекеров на лету, кэширует DNS-запросы и не дает истории 
веб-серфинга улетать внешним провайдерам.</p><p>Основной проблемой с 
которой я столкнулся при использовании AdGuard Home, так это то что я 
так и не понял как заставить использовать AmneziaVPN клиент AdGuard как 
основной DNS, при этом AmneziaWG работает прекрасно. Как я понимаю дело в
 том что AmneziaWG работает намного проще на уровне ip и у него нету 
никаких доп фильтров, настроек и подобного, поэтому он просто берет 
данные из конфига.</p><h3>От костылей на Bash к декларативному Ansible</h3><p>Весь
 стек на обоих серверах разворачивался через bash скрипты, что было уж 
очень плохо с точки зрения идемпотентности. Во первых из-за bash мне 
постоянно приходилось очищать сервера, так как нормальных проверок у 
меня не было и писать я их не хотел, а также было много костылей с 
импортом переменных, записями в файлы и подобным.</p><p>Так я пришел к декларативному подходу и Ansible.
 Теперь вся конфигурация описывается в виде плейбуков и ролей, 
отражающих конечное желаемое состояние серверов. Конфиденциальные данные
 перенесены в файл secrets.yml, а хрупкие конструкции 
автоматизированы через шаблоны Jinja2. Проект стал идемпотентным: если 
шаги уже выполнены, Ansible их просто пропускает.</p><p>В итоге 
получилось несколько yaml файлов для стандартной настройки системы 
(bootstrap_os.yml) и для настройки каждого из хостов (setup_local.yml и 
setup_remote.yml). В итоге теперь все что нужно чтобы полностью с нуля 
развернуть проект - скачать Ansible, несколько других зависимостей на 
свой рабочий пк и запустить один manage_deploy.sh, в котором можно будет
 выбрать сценарий как будет вести себя Ansible и спокойно дождаться 
разворачивания сервисов.</p><p>Также благодаря Ansible я удобно 
реализовал переносимость проекта. Так как я решил не использовать тома 
docker, и вместо этого храню все в папках, чтобы перенести старые данные
 проекта нужно просто скопировать папку apps-data и положить ее в нужное
 место и все само заработает после повторного развертывания проекта. В 
Ansible выделяется отдельная пауза для этого.</p><p>Вот пример основного плейбука deploy.yml:</p><h3>Тестирование мультидистрибутивности с помощью Vagrant</h3><p>Проект
 изначально затачивался под работу на трех дистрибутивах: Ubuntu, Debian
 и Arch Linux. Тестировать Ansible-плейбуки прямо на рабочей локальной 
машине (в моем случае — EndeavourOS) слишком рискованно, а создавать 
виртуальные машины руками — долго и неудобно.</p><p>Решением стал Vagrant,
 позволяющий за пару минут развернуть чистые ОС в VirtualBox из готовых 
образов. Но в процессе настройки мультивендорного стенда в режиме 
сетевого моста (public_network) всплыли две критические проблемы:</p><ol><li>Конфликт DNS:
 По умолчанию Vagrant создает NAT-интерфейс для управления нодой. При 
включении второго (публичного) интерфейса для локальной сети ломался 
дефолтный DNS-резолвер. Проблему пришлось решать принудительной очисткой
 и перезаписью файла /etc/resolv.conf через inline-скрипт автоматизации Vagrant.</li><li>Проблема с GRUB на Debian: В используемом базовом образе generic/debian12
 конфигурация GRUB сохраняла жесткую привязку к конкретному имени диска 
из окружения сборщика. При повторном развертывании плейбуков на тестовом
 стенде это приводило к сбоям загрузчика. Чтобы автоматизировать 
очистку, пришлось внедрить скрипт, который на лету определяет имя 
системного диска через lsblk и автоматически передает правильные параметры в загрузчик через утилиту debconf-set-selections.</li></ol><p>Вот код Vagrantfile: (в node.vm.provision происходит основное решение ошибок)</p><p>Надежная система бэкапов на базе BorgmaticДля создания резервных копий я внедрил Borgmatic
 (удобную надстройку над дедуплицирующим инструментом Borg Backup). Весь
 процесс автоматизирован с помощью связки системных юнитов borgmatic.service и borgmatic.timer. В бэкап уходят две ключевые директории: apps-data (конфигурации приложений и баз данных) и PersonalData (медиатека: музыка, книги, подкасты, файлы Nextcloud).</p><p>Развертывание
 системы бэкапов полностью берет на себя Ansible. Мне достаточно указать
 UUID внешнего жесткого диска — скрипт сам проверит его наличие в 
системе, примонтирует в нужную директорию, создаст зашифрованный 
репозиторий и настроит политику ротации (хранение 7 ежедневных, 4 
еженедельных и 6 ежемесячных копий). Также в Prometheus выведен 
мониторинг самого репозитория .borg для отслеживания его размера и статуса успешности архивации.</p><p>Главная
 проблема при бэкапе работающих Docker-контейнеров — риск скопировать 
базу данных в «битом» или неконсистентном состоянии, если в момент 
создания архива в нее шла активная запись. Чтобы решить эту проблему, я 
задействовал механизм хуков в конфигурации Borgmatic.</p><p>Перед началом резервного копирования автоматически срабатывает команда остановки контейнеров проекта (docker-compose down),
 а после успешного завершения (или в случае возникновения непредвиденной
 ошибки) контейнеры автоматически поднимаются обратно в фоновом режиме. 
Для удобного просмотра архивов и быстрого восстановления файлов я 
развернул веб-интерфейс Borg UI.</p><p>Конфигурация borgmatic: (использую как Jinja2 шаблон, чтобы Ansible в плейбуках сам подставил переменные)</p><h2>Наблюдаемость (Observability) уровня Enterprise</h2><p>В последних релизах (v1.2.0 и v1.3.0) фокус проекта сместился на мониторинг и работу с логами.</p><h3>Эволюция алертинга и переход на Gatus</h3><p>Изначально для мониторинга доступности я смотрел на Uptime Kuma, но отказался из-за отсутствия удобной декларативной настройки через конфиги. Затем я развернул связку Blackbox Exporter и Alertmanager
 с уведомлениями в Matrix. Но тут крылась логическая несостыковка: весь 
алертинг был завязан на локальном ПК, и в случае его аппаратного отказа я
 бы просто лишился уведомлений.</p><p>Тогда я решил вернуть Uptime Kuma,
 но развернуть его на удаленном VPS в качестве внешнего «сторожа» и 
автоматизировать его настройку через Python-скрипт с библиотекой uptime-kuma-api. Но и тут ждали «грабли» — библиотека не обновлялась три года и намертво ломалась на свежих версиях Kuma.</p><p>В итоге идеальным решением стал Gatus.
 Он изначально проектировался под управление через YAML-конфиги и 
поддерживает отправку алертов, если сервер не отвечает. Из-за специфики 
фронтенда Gatus (он не умеет работать из подкаталога типа /gatus), мне пришлось перенести его и wg-easy на полноценные субдомены gatus. и wireguard.</p><p>Для Gatus получился простой конфиг:</p><p>Для мониторинга аппаратных ресурсов удаленного и локального серверов была развернута связка node-exporter + cAdvisor. Все уведомления теперь приходят мгновенно в Telegram-бота. Чтобы 
избежать лавины одинаковых сообщений (например, при перезагрузке хоста),
 в Alertmanager настроена жесткая группировка и дедупликация событий. 
Также добавлен экспортер для AdGuard Home, выводящий статистику 
заблокированных запросов в Grafana.</p><h3>Централизованные логи: Loki + Grafana Alloy</h3><p>В релизе v1.3.0 в стек была добавлена централизованная система сбора логов Loki. Вместо устаревшего Promtail в качестве агента сбора я применил Grafana Alloy.</p><p>Он
 эффективно собирает логи со всех запущенных Docker-контейнеров, парсит 
их и передает в Loki. Теперь вся история событий, ошибок веб-сервера 
Nginx или падений внутренних приложений доступна в едином интерфейсе 
Grafana с возможностью удобной фильтрации через LogQL, что значительно 
упрощает отладку.</p><p>Конфиг Loki:</p><p>Конфиг Grafana Alloy: (локальный конфиг)</p><h2>Интерфейс: переход на Homepage</h2><p>Изначально для 
домашней страницы я написал кастомную минималистичную HTML-панель с 
Glassmorphism-дизайном. Выглядело это красиво, но добавлять новые 
сервисы вручную через постоянную правку исходного кода было крайне 
неудобно.</p><figure><img src="https://media.tproger.ru/user-uploads/139471/2026-07-15/8a8f2752-8aac-4aa5-898e-98affd01cdff.webp" alt="" /><figcaption>HTML + CSS</figcaption></figure><p>В итоге я заменил самописную страницу на полноценный комьюнити-проект Homepage.
 Это дало некоторую гибкость: вся панель настраивается через простые 
YAML-файлы и поддерживает встроенные виджеты интеграции. Пока что она 
простенькая, но возможно в будущем сделаю что-то более продвинутое.</p><figure><img src="https://media.tproger.ru/user-uploads/139471/2026-07-15/90c65d4a-1310-4a30-b1ad-9e4d3083959d.webp" alt="" /><figcaption>Homepage</figcaption></figure><h2>Заключение</h2><p>Постарался
 подробно рассказать о структуре проекта и как я к этому пришел, очень 
много я не добавил, если пост зайдет, то я обязательно более подробно 
пройдусь по некоторым моментам: как я настраивал Matrix и на каком 
моменте я решил его убрать, как собирал локальный amnezia 
контейнер-клиент, что нового я добавил в релизе 1.4.0 и другое.</p><p>Также
 я перешел с manage_deploy.sh на отдельный GUI клиент, который 
будет полностью автоматизировать процесс подготовки к deploy. (написан на Go Wails). Про это тоже возможно сделаю статью.</p><p>Вся кодовая база проекта, подробная документация, инструкции по развертыванию открыты и доступны для сообщества:</p><p>🔗 GitHub-репозиторий: <a href="https://github.com/canntstand/ServeHub-2" rel="noopener noreferrer nofollow">https://github.com/canntstand/ServeHub-2</a></p><p>Это
 моя первая статья на этом сайте и в то же время первый личный проект, которому я 
отдал так много времени (3 месяца). Буду рад вашему фидбеку в 
комментариях!</p>]]></content:encoded>
    </item>
    <item>
      <title>Как приручить legacy-код: безопасная модернизация без заморозки фич</title>
      <link>https://tproger.ru/articles/kak-priruchit-legacy-kod-bezopasnaya-modernizaciya-bez-zamorozki</link>
      <comments>https://tproger.ru/articles/kak-priruchit-legacy-kod-bezopasnaya-modernizaciya-bez-zamorozki?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[KODE]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-priruchit-legacy-kod-bezopasnaya-modernizaciya-bez-zamorozki</guid>
      <description><![CDATA[<p>Как модернизировать legacy-код без остановки продукта: Strangler Fig Pattern, feature flags, shadow testing и безопасная миграция данных. Практика и антипаттерны.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-priruchit-legacy-kod-bezopasnaya-modernizaciya-bez-zamorozki">Как приручить legacy-код: безопасная модернизация без заморозки фич</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Рефакторинг]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[MIT]]></category>
      <category><![CDATA[Финтех]]></category>
      <category><![CDATA[ICO]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Twitter]]></category>
      <category><![CDATA[Игра]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[OpenTelemetry]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Grafana]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Legacy]]></category>
      <category><![CDATA[Техника]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 23 Jun 2026 06:16:57 GMT</pubDate>
      <content:encoded><![CDATA[<p>Legacy-код — одна из самых болезненных тем в инженерных командах. Обычно все понимают, что система устарела: архитектура мешает быстро выпускать изменения, новые фичи приходится встраивать через обходные пути, тесты либо неполные, либо отсутствуют, а любое изменение в одном модуле неожиданно ломает другой.</p><p>Но при этом к такому коду часто боятся прикасаться. И не без причины. В старых системах редко бывает понятная карта зависимостей. Документация устарела, часть знаний живет только в головах нескольких разработчиков, а бизнес при этом продолжает ждать новых релизов, интеграций и продуктовых экспериментов.</p><p>Так появляется классическая ловушка legacy: систему надо модернизировать, но остановить развитие нельзя. Переписать всё с нуля страшно, поддерживать как есть — всё дороже. В результате продукт обрастает временными решениями, скорость разработки падает, а стоимость каждого следующего изменения растет.</p><p>Хорошая новость в том, что модернизация legacy-кода не обязана быть большим взрывом. Старую систему можно менять постепенно, сохраняя рабочий продукт, не замораживая фичи и не устраивая один критический релиз, от которого зависит всё.</p><h2>Почему Big Bang-переписывание чаще всего заканчивается плохо</h2><p>Когда команда долго живет с устаревшей системой, идея переписать всё с нуля выглядит очень соблазнительно. Кажется, что можно наконец избавиться от технического долга, выбрать нормальную архитектуру, перепроектировать модули, покрыть всё тестами и начать «правильно».</p><p>На старте такой план часто звучит логично. Особенно если текущая система действительно мешает развитию. Например, мобильное приложение растет, у него уже миллионы пользователей, бэкенд написан несколько лет назад как монолит, а каждая новая фича требует изменений в десятке мест. Команда устала чинить регрессии, бизнес устал ждать, и всем хочется «один раз нормально переписать».</p><p>Проблема не в самой идее переписывания, а в условиях, при которых оно проваливается. Большой риск возникает, когда совпадают четыре фактора: переписывание занимает много месяцев, в это время бизнес продолжает развивать старую систему, новая версия покрывает сразу большую часть функциональности, а откат связан с миграцией данных. Если все четыре пункта присутствуют, Big Bang почти гарантированно превратится в долгий и дорогой проект.</p><p>Допустим, команда решила переписать модуль заказов в e-commerce-продукте. В старой версии есть корзина, промокоды, доставка и оплата. Команда планирует за полгода сделать новый сервис заказов. Но за эти полгода бизнес добавляет подписки, подарочные сертификаты, частичную оплату бонусами и новую логику возвратов. В итоге новая система, которую проектировали под старые требования, к моменту релиза уже нуждается в доработке.</p><p>Есть и другая проблема: большой релиз почти всегда несет максимальный риск. Если вы заменяете крупный кусок системы целиком, ошибка влияет сразу на большую часть пользователей. Откат тоже становится сложным, потому что новая логика уже связана с новыми данными, контрактами и интеграциями.</p><p>Big Bang всё-таки бывает оправдан — но в узких условиях. Если кодовая база молодая (год-два), пользователей мало, у системы нет критичного состояния в БД и продукт можно временно заморозить или вести в обоих контурах параллельно, полное переписывание может оказаться дешевле постепенной миграции. Это редкая ситуация, и она быстро исчезает по мере роста продукта. В зрелых системах безопаснее работает другой подход — постепенная архитектурная эволюция.</p><h2>Пример: как команда переписала сервис документов и потеряла полгода</h2><p>Команда сопровождала сервис — старый модуль на aiohttp с Pydantic v1, через который проходила вся обработка путевых листов и актов осмотра транспорта. Сервис существовал шесть лет, был покрыт тестами фрагментарно, а его API использовали мобильное приложение водителей, диспетчерская веб-панель и пакетный импорт.</p><p>Команда решила переписать сервис целиком: перейти на FastAPI, обновить Pydantic до v2, заодно почистить контракты и заменить внутреннее хранилище документов с MongoDB на PostgreSQL. План был рассчитан на четыре месяца.</p><p>Через восемь месяцев проект всё ещё не был готов к выкатке, а к десятому месяцу команда откатила миграцию полностью. Причин было несколько.</p><p>Во-первых, переписывание шло параллельно с продуктовой разработкой. За время миграции бизнес добавил два новых типа документов и изменил правила подписи актов. Новая система проектировалась под старые требования и к моменту готовности уже не соответствовала продукту.</p><p>Во-вторых, команда не написала характеристических тестов. Поведение «как есть» нигде не было зафиксировано, и расхождения находились только в продакшене после переключения.</p><p>В-третьих, у старого сервиса были скрытые побочные эффекты, о которых никто не помнил. При смене статуса документа публиковал событие в Kafka, которое читал биллинг и сервис аналитики. В новой реализации это поведение не было воспроизведено, потому что в коде оно выглядело как «лишний» вызов. После переключения биллинг перестал получать события, и расхождение обнаружили только через две недели — по жалобе финансового отдела.</p><p>В-четвёртых, переключение было сделано «в лоб»: маршрут в API Gateway просто перенаправили на новый сервис. Фича-флага не было, теневого запуска не было, плана отката не было. Когда выяснилось, что новый сервис строже валидирует исторические форматы документов и отклоняет часть старых записей, быстро вернуться на старую реализацию не получилось — её к тому моменту уже отключили на стенде, а в БД успели уйти записи в новом формате.</p><p>В итоге миграцию свернули, потратив около десяти человеко-месяцев и потеряв доверие бизнеса. Сервис до сих пор работает в исходной реализации, а команда переходит к плану, описанному ниже.</p><h2>Strangler Fig Pattern: как заменить систему по частям</h2><p>Один из самых практичных подходов к модернизации legacy-кода — Strangler Fig Pattern. В софтверном виде паттерн был сформулирован Мартином Фаулером в 2004 году под названием StranglerFigApplication. Идея проста: не переписывать систему целиком, а постепенно выносить отдельные части в новую реализацию.</p><p>Название пришло из биологии. Фикус-душитель растет вокруг дерева-хозяина и постепенно вытесняет его. В архитектуре принцип похожий: старая система продолжает работать, новая функциональность появляется рядом, а затем отдельные потоки постепенно переводятся на новую реализацию.</p><p>Представим старый монолит интернет-магазина. Внутри него есть каталог, корзина, заказы, платежи, скидки, личный кабинет и уведомления. Переписать всё сразу — рискованно. Но можно начать с относительно изолированного участка, например с уведомлений.</p><p>Сначала команда описывает текущий контракт: какие события приходят в модуль уведомлений, какие каналы используются, какие шаблоны отправляются, какие ошибки считаются допустимыми. Затем рядом создается новый сервис уведомлений, который реализует тот же контракт. На первом этапе он может даже не отправлять реальные сообщения, а только принимать события и логировать результат. После проверки часть трафика переводится на новую реализацию. Когда сервис стабилизируется, старый код уведомлений удаляется из монолита.</p><p>Strangler Fig хорошо работает там, где между старым и новым кодом есть сетевая граница: HTTP, message bus, RPC. Если такой границы нет — например, нужно постепенно заменить функцию или класс внутри одного процесса — используется родственный паттерн Branch by Abstraction: над старой реализацией создается абстракция, рядом пишется новая реализация, переключение происходит через конфигурацию или фича-флаг, после стабилизации старая ветка удаляется. Снаружи это выглядит как Strangler Fig, но без сетевого прокси.</p><p>Такой подход снижает риск. В системе нет одного большого релиза, где всё меняется сразу. Есть серия небольших контролируемых изменений. Каждое можно протестировать, измерить и откатить.</p><h2>Главное правило: сначала повторить поведение, потом улучшать</h2><p>Одна из частых ошибок при модернизации legacy-кода — попытка одновременно переписать систему и улучшить бизнес-логику. Команда смотрит на старый модуль и думает: «Раз уж мы его трогаем, давайте сразу сделаем нормальную архитектуру, изменим контракты, уберем странные кейсы и перепишем поведение».</p><p>Это опасный путь. В legacy-системах странное поведение часто существует не случайно. За ним может стоять неочевидное бизнес-правило, старый клиент, интеграция с внешней системой или исторический баг, на который уже кто-то завязался.</p><p>Например, в системе расчета налогов может быть правило: для контрактов, заключенных до 2018 года, НДС округляется в меньшую сторону до целого рубля, а для всех остальных — по математическим правилам. Новый разработчик может решить, что это ошибка, и «исправить» округление. Но потом выяснится, что часть крупных клиентов держит это поведение в своих сверках, а смена правила приведет к расхождениям в актах и претензиям.</p><p>Прежде чем менять поведение, его нужно зафиксировать. Для этого пишут характеристические тесты (characterization tests, иногда называемые golden master или approval tests). Идея простая: на реальных данных или их обезличенных копиях прогоняется старая реализация, её ответы сохраняются как эталон, и любые будущие изменения, отклоняющиеся от эталона, отлавливаются автоматически. Тесты пишутся не для красоты, а для того, чтобы зафиксировать существующее поведение — даже странное — перед тем, как его трогать. Подробно эта техника описана у Майкла Физерса в книге Working Effectively with Legacy Code; на практике её удобно реализовать через библиотеки семейства approval-tests (approvaltests-python, approvaltests-java и аналоги).</p><p>Поэтому первый этап модернизации — не улучшение, а воспроизведение текущего поведения. Новая реализация должна вести себя так же, как старая. Даже если старое поведение кажется странным. Только после стабилизации можно отдельно обсуждать, что именно стоит менять.</p><h2>Feature toggles: как включать новую логику без риска</h2><p>Feature toggles, или фича-флаги, — один из главных инструментов безопасной миграции. Они позволяют включать и выключать новую логику без деплоя.</p><p>В обычной разработке релиз часто выглядит бинарно: код либо выкатили, либо нет. При миграции legacy это неудобно. Гораздо безопаснее иметь возможность включить новую реализацию для 1% пользователей, затем для 10%, потом для половины аудитории и только после этого для всех.</p><p>Например, команда переносит расчет стоимости доставки из монолита в новый сервис. С помощью фича-флага это выглядит так:</p><p>user_id передается явно, чтобы решение «попал ли пользователь в новый сегмент» было стабильным от запроса к запросу. Иначе один и тот же клиент будет получать разные ответы при обновлении страницы, и поведение системы станет непредсказуемым.</p><p>На первом этапе флаг включают только для внутренней команды. Потом для тестового сегмента пользователей. Затем для небольшой доли реального трафика. Если метрики стабильны, долю увеличивают. Если появляются ошибки, флаг выключают, и пользователи снова идут в старую реализацию.</p><p>Важно различать два разных типа флагов. Флаг постепенной выкатки (rollout flag) меняется редко и контролирует, какой процент пользователей видит новую логику. Kill switch — отдельный флаг, единственная задача которого — мгновенно выключить новую реализацию при инциденте. Kill switch должен опрашиваться на каждом запросе, его кэширование должно жить секунды, а не минуты, и он принципиально не должен зависеть от той системы, которую он выключает. Иначе в момент аварии может оказаться, что выключатель сам недоступен.</p><p>В качестве инфраструктуры для флагов команды обычно берут одну из платформ: LaunchDarkly, Unleash, Flagsmith, GrowthBook, либо собирают собственную поверх Redis или конфигурационного сервиса. Для миграции важны три свойства: быстрое распространение изменений (секунды, а не минуты), поддержка таргетинга по пользователю/сегменту и аудит — кто и когда менял флаг.</p><p>Важно, что фича-флаг — это не просто if в коде. Для серьезной миграции нужны правила: кто может включать флаг, как быстро его можно отключить, какие метрики отслеживаются, когда флаг должен быть удален.</p><p>Последний пункт особенно важен. Если флаги не удалять, система быстро превращается в набор ветвлений, где никто уже не понимает, какая логика актуальна.</p><h2>Shadow testing: как проверить новую систему на реальном трафике</h2><p>Feature toggles помогают безопасно переключать пользователей. Но перед этим хорошо бы понять, совпадает ли новая логика со старой. Для этого используют shadow testing.</p><p>Shadow testing — это запуск новой реализации параллельно старой, но без влияния на пользователя. Пользовательский запрос по-прежнему обрабатывает старая система, а новая получает копию запроса и считает результат «в тени». Пользователю этот результат не показывается. Команда только сравнивает ответы.</p><p>Например, есть старый модуль расчета скидок. Он учитывает промокоды, сегмент пользователя, историю покупок, регион и партнерские условия. Команда пишет новый сервис скидок. Чтобы не переключать пользователей сразу, можно запустить теневой режим:</p><p>Два момента, на которые стоит обратить внимание в этом коде. Теневой вызов запускается через asyncio.create_task — корутина сразу планируется в event loop и начнёт выполняться, как только функция вернёт управление. И весь блок завернут в try/except: исключение в новой логике не должно ронять основной запрос. Без этих двух свойств shadow testing рискует ухудшить продакшен вместо того, чтобы безопасно его проверить.</p><p>Небольшая оговорка для продакшена: event loop держит на task только слабую ссылку, и без сохранённой ссылки задача может быть собрана сборщиком мусора прямо во время выполнения. В реальном коде Task имеет смысл класть в set фоновых задач и удалять оттуда через add_done_callback. В примере выше эта обвязка опущена для читаемости.</p><p>Для критичной доменной логики — платежей, биллинга, расчета тарифов — допустимый уровень расхождения должен быть около нуля: цель в shadow-режиме не «как можно меньше различий», а «понимаем каждое расхождение». Для менее чувствительных доменов (рекомендации, ранжирование результатов поиска) можно жить с расхождением в долях процента, но и там расхождения нужно классифицировать, а не игнорировать. Возможно, это баги новой реализации. А возможно, старая система содержит устаревшую логику, которую нужно отдельно обсудить с бизнесом.</p><p>Shadow testing особенно полезен для критичных доменных частей: платежей, биллинга, расчета тарифов, персональных предложений, транзакций. Там нельзя просто «попробовать на пользователях» и посмотреть, что будет.</p><p>При этом важно отличать теневую проверку чтения от теневой проверки записи. Чтение проверить относительно дёшево: запрос идёт в обе системы, ответы сравниваются, никаких внешних эффектов нет. С записью всё сложнее. Если новая реализация в shadow-режиме действительно создаст заказ, спишет деньги или отправит письмо, у пользователя возникнут двойные эффекты. Поэтому для writes либо вводят идемпотентные ключи и shadow-режим без реальных побочных действий (внешние вызовы заменены no-op-стабами, БД — отдельной shadow-копией), либо вообще отказываются от теневой проверки записи в пользу постепенной выкатки за фича-флагом.</p><p>Сравнение ответов в реальной системе тоже не сводится к одной функции compare. Нужно отдельно решать, как игнорировать «нормальный» шум (метки времени, идентификаторы, порядок коллекций), как сэмплировать трафик, чтобы не утопить хранилище расхождений, и как организовать триаж — кто и в каком ритме разбирает накопившиеся диффы. Готовые решения этого класса — GitHub Scientist (Ruby и его порты в другие языки), Twitter Diffy, либо собственный лёгкий регистратор поверх Kafka и таблицы расхождений.</p><h2>С чего начинать модернизацию</h2><p>Начинать лучше не с самого больного и не с самого центрального модуля. Это звучит контринтуитивно, потому что обычно хочется сразу взяться за главный источник проблем. Но если начать с ядра системы, команда быстро упрется в максимальное количество зависимостей и рисков.</p><p>Удобный способ выбрать первый кусок — оценить кандидатов по двум осям: насколько модуль критичен для бизнеса (low / high) и насколько сильно он связан с остальной системой (low / high). Начинать стоит с квадранта low-criticality + low-coupling: ошибки в нем не уронят бизнес-показатели, а малое количество зависимостей позволит провести миграцию полностью, не утянув за собой смежные модули. Высоко-критичные и сильно связанные части (платежи, ядро авторизации) трогают в последнюю очередь — на этот момент команда уже наберёт опыт безопасной миграции.</p><p>Хорошие точки входа обычно: уведомления, генерация отчетов, поиск, история операций, профиль пользователя, отдельная часть каталога. Важно, чтобы у команды была возможность описать контракт: какие данные входят, какие выходят, какие ошибки возможны, какие внешние системы участвуют.</p><p>Допустим, в банковском приложении есть старый модуль истории операций. Он медленный, сложно расширяется, но при этом не выполняет сами транзакции. Это хороший кандидат для первой миграции. Ошибка в истории операций неприятна, но обычно менее критична, чем ошибка в списании денег.</p><p>Команда может вынести чтение истории в отдельный сервис, сначала запустить его в shadow-режиме, потом включить для части пользователей, затем полностью перевести чтение на новую реализацию. При этом критичная транзакционная логика останется в старой системе до тех пор, пока команда не наберет опыт безопасной миграции.</p><h2>Миграция данных: самая сложная часть</h2><p>Большая часть статьи говорит о маршрутизации запросов и переключении трафика. Но в реальных проектах основная сложность лежит ниже — в данных. Старая и новая реализации почти всегда работают с общим состоянием: одной БД, одним хранилищем документов, одним набором очередей. Переехать туда «одним коммитом» нельзя.</p><p>Базовый рабочий приём — Expand-Contract (он же Parallel Change). Изменение схемы делается в три такта. На этапе expand в БД добавляются новые поля, таблицы или индексы, при этом старое поведение полностью сохраняется. Затем — migrate: обе реализации начинают писать и в старое, и в новое место (dual writes), а отдельный фоновый процесс делает backfill — заполняет новые поля историческими данными. После этого читатели по одному переключаются на новую схему. Только когда никто из читателей не использует старую структуру, наступает contract — удаление лишних колонок и таблиц.</p><p>Несколько практических деталей, которые часто упускают:</p><p>·         Dual writes — это не бесплатная операция. Две записи означают две точки отказа. Если одна из них упала, нужно решать, что делать: продолжать ли работу, ставить ли событие в очередь на повтор, помечать ли запись как несогласованную. Простое «сначала пишем туда, потом сюда» в продакшене на нагрузке приводит к расхождениям.</p><p>·         Backfill часто длиннее, чем кажется. На большой таблице миграция в одном UPDATE блокирует продакшен. Поэтому backfill делают батчами по N тысяч строк с паузами, отслеживают прогресс и предусматривают возможность остановить и продолжить.</p><p>·         Онлайн-изменения схемы на крупных таблицах делаются не штатным ALTER TABLE, а специализированными инструментами: gh-ost или pt-online-schema-change для MySQL, встроенные онлайн-механизмы PostgreSQL для индексов и колонок, Liquibase/Flyway — для управления версионированием изменений в репозитории.</p><p>·         Shadow testing данные не покрывает. Можно сравнить, что новая реализация возвращает то же, что и старая, но если за этим стоит другая схема в БД, проверка корректности самой миграции данных — это отдельная работа: сверки, контрольные суммы, выборочный аудит исторических записей.</p><p>Без этих шагов любая красивая фасадная архитектура наталкивается на разъезжающиеся данные — и тогда даже идеальный Strangler Fig снаружи не спасает.</p><h2>Прокси-слой как точка контроля</h2><p>Чтобы постепенно заменять legacy-код, нужно управлять маршрутизацией запросов. Для этого часто создают прокси-слой, API Gateway или фасад, через который проходит обращение к старой и новой логике. В терминах Domain-Driven Design такой слой часто называют Anti-Corruption Layer: он защищает новую реализацию от старых контрактов и наоборот, позволяя двум моделям сосуществовать без взаимного «загрязнения».</p><p>Без такой точки контроля миграция становится хаотичной. Часть клиентов ходит напрямую в старый модуль, часть — в новый, часть использует обходные пути, а команда теряет возможность централизованно переключать трафик.</p><p>Прокси-слой решает несколько задач. Он скрывает детали реализации от клиентов, позволяет направлять часть запросов в новую систему, поддерживает фича-флаги, собирает метрики и упрощает откат.</p><p>В качестве технической основы команды обычно берут один из трех вариантов: классический API gateway (Kong, AWS API Gateway), service mesh (Envoy, Istio) или более простой reverse proxy (NGINX, HAProxy). Service mesh особенно удобен, когда трафик уже идёт внутри Kubernetes-кластера: маршрутизацию можно менять конфигурацией, без правок кода клиентов и сервисов.</p><p>Например, мобильное приложение обращается к endpoint /orders/history. Раньше этот endpoint напрямую обслуживал монолит. После введения API Gateway приложение продолжает ходить по тому же контракту, но внутри gateway может решать, куда направить запрос: в legacy-модуль или новый сервис истории заказов.</p><p>Управление маршрутизацией обычно делается не «всё или ничего», а на основании атрибутов запроса: значения заголовка (X-Migration-Cohort: new), куки, хэша от user-id (стабильное разбиение пользователей на сегменты) или географического региона. Это позволяет выкатывать новую реализацию сначала на одну страну, на сотрудников самой компании или на тестовый сегмент — и только потом расширять охват.</p><p>Для клиента ничего не меняется. Для команды появляется управляемость.</p><h2>Наблюдаемость: без метрик миграция превращается в гадание</h2><p>Постепенная модернизация невозможна без нормальной наблюдаемости. Если команда не видит, что происходит внутри системы, она не сможет безопасно переключать трафик.</p><p>Минимальный набор — это логи, метрики и распределенная трассировка (distributed tracing). Нужно понимать, сколько запросов идет в старую и новую реализацию, сколько ошибок возникает, как меняется latency, где появляются таймауты, какие статусы возвращаются, какие бизнес-метрики проседают.</p><p>Технические метрики стоит формулировать не как «средний ответ» и «процент ошибок», а в терминах SLI и SLO: целевые показатели вида «99.9% запросов на /orders/history отвечают быстрее 300 ms за 30 дней» с явным error budget. Latency измеряется по перцентилям (p50, p95, p99) — среднее значение почти всегда обманчиво, а хвосты распределения говорят о реальном опыте пользователя. На время миграции имеет смысл выставить отдельные SLO для нового и старого пути и сравнивать их.</p><p>В качестве инструментов де-факто стандартом стал OpenTelemetry для трассировок, метрик и логов — единый протокол, который пишет в практически любое хранилище. Дальше — Prometheus и Grafana для метрик, Jaeger или Tempo для traces, Sentry или аналог для ошибок. Для миграции важна возможность фильтровать метрики по «варианту» — отдельно по старому и новому пути — иначе все цифры смешаются и реальную динамику будет не видно.</p><p>Технических метрик недостаточно. Если команда переносит оформление заказа, важно смотреть не только на 500 ошибки и время ответа, но и на конверсию в оплату, количество брошенных корзин, повторы запросов, обращения в поддержку.</p><p>Пример: новая система формально отвечает быстрее старой и не дает ошибок. Но после включения на 10% пользователей падает конверсия в оплату. Причина может быть не в серверной ошибке, а в изменении порядка полей, другом тексте сообщения или потере какого-то edge-case. Без бизнес-метрик команда может решить, что миграция успешна, хотя для продукта она уже создает проблему.</p><h2>Практическая последовательность миграции</h2><p>Рабочая последовательность обычно выглядит так.</p><p>Сначала команда выбирает ограниченный участок системы. На этом этапе важно не просто назвать модуль, а описать его границы. Какие сценарии он закрывает? Кто его вызывает? Какие данные он читает и пишет? Какие внешние интеграции использует? Какие неочевидные бизнес-правила в нем есть?</p><p>Затем поверх legacy-логики создается стабильный контракт. Это может быть API, фасад, gateway или отдельный слой внутри приложения. Главная задача — сделать так, чтобы клиенты зависели не от внутренней реализации, а от понятного интерфейса. На этом этапе полезно вспомнить про contract testing (Pact, Spring Cloud Contract): автотесты со стороны потребителей фиксируют, что именно они ожидают от API, и предупреждают о ломающих изменениях до того, как они доедут до продакшена.</p><p>После этого рядом пишется новая реализация. Она должна повторять текущее поведение, а не сразу становиться «идеальной версией будущего». На этом этапе полезно фиксировать все расхождения: где старая система работает странно, где требования не описаны, где бизнес-правила требуют уточнения.</p><p>Следующий этап — shadow testing. Новая система получает копии реальных запросов, считает результат, но пользователю по-прежнему возвращается ответ legacy. Команда сравнивает результаты и устраняет расхождения.</p><p>Когда новая реализация достаточно стабильна, начинается постепенное переключение через feature toggles. Сначала внутренние пользователи, потом 1% реального трафика, затем 5–10%, затем 50% и только после этого 100%.</p><p>На каждом этапе команда смотрит на метрики. Если всё стабильно, движение продолжается. Если появляются проблемы, флаг выключается, трафик возвращается в legacy, а команда разбирает причины.</p><p>Последний этап — удаление старого кода. Это не формальность, а обязательная часть миграции. И «удалить старый код» — это не один коммит, а явный Definition of Done: вырезана старая ветка кода, удалён фича-флаг, обновлена документация и схемы архитектуры, переименованы или удалены устаревшие дашборды и алерты, обновлены runbook’и для on-call и проведено короткое внутреннее обучение. Если этого не сделать, через полгода никто уже не вспомнит, какой путь актуален, и легаси-ветвление останется в коде навсегда.</p><h2>Откат миграций: дешёвый только пока не пошли записи</h2><p>Откатить миграцию, в которой ещё не было записи в БД, легко: достаточно переключить фича-флаг, и трафик снова идёт через старую реализацию. Откатить миграцию, в которой новая система уже неделю писала данные в новые таблицы, — отдельный, гораздо более тяжёлый разговор.</p><p>Поэтому ещё на этапе проектирования каждое изменение должно сопровождаться явным планом отката. Удобно различать три типа шагов.</p><p>Полностью обратимые шаги. Чтение через новый сервис, расчёт «в тени», новые метрики. Откат — выключить флаг. Это самый комфортный режим, и в нём стоит держать миграцию как можно дольше.</p><p>Обратимые с компенсацией. Новая реализация пишет дополнительные данные (например, дублирует операции в новую таблицу), но старый источник тоже обновляется. Откат возможен, но требует решить, что делать с уже записанными данными: оставить, очистить, синхронизировать. План этих действий должен быть написан до выкатки, не во время инцидента.</p><p>Forward-only. После некоторой точки откат становится невозможен — например, после того, как старая схема удалена или внешние интеграции перенастроены на новый сервис. Такие шаги допустимы, но к ним нужно приходить отдельно, осознанно, с особенно строгими SLO в предыдущем этапе. До forward-only-перехода имеет смысл подержать систему в режиме параллельной работы дольше, чем по графику.</p><p>Базовое правило: ни один шаг миграции не должен уходить в продакшен, если у команды нет письменного ответа на вопрос «как мы откатываемся в случае проблемы». Иначе при инциденте откатываться будут на ходу — и не факт, что успешно.</p><h2>Пример: как тот же сервис мигрировали со второй попытки</h2><p>После неудачного опыта команда взялась за тот же сервис заново, но изменила подход.</p><p>На первом шаге они зафиксировали поведение существующего сервиса. На самые часто используемые сценарии (создание путевого листа, подпись акта осмотра, выгрузка пакета документов за период) написали характеристические тесты на реальных продакшен-данных, обезличенных и сохранённых как фикстуры. Любое будущее изменение поведения теперь падало в CI как явное расхождение.</p><p>Параллельно команда провела инвентаризацию побочных эффектов. Из исходного кода и логов выяснилось, что сервис не только хранит документы, но и: публикует событие в Kafka при смене статуса, инкрементирует счётчик в Redis для рейтинга водителей, отправляет webhook во внешнюю систему партнёра, пишет в таблицу аудита. Каждый из этих эффектов попал в отдельный пункт чек-листа «что должно остаться» в новой реализации.</p><p>Затем команда выбрала первый кусок для выноса — не весь сервис, а только чтение документов (GET /documents/{id} и GET /documents/by-driver/{driver_id}). Это была наименее рискованная часть: ошибки в чтении неприятны, но не ломают финансовые потоки.</p><p>Новый сервис написали на FastAPI рядом со старым. На уровне API Gateway появилось правило маршрутизации: запросы на чтение шли в старый сервис, но в фоне дублировались в новый. Ответ пользователю всегда возвращал legacy, а ответ нового сервиса сравнивался с эталоном и записывался в отдельную таблицу для разбора. Использовали обёртку поверх asyncio.create_task — на ответ пользователя теневой вызов не влиял.</p><p>За три недели shadow-режима команда нашла четыре расхождения. Два оказались багами новой реализации (округление времени, неправильная сортировка вложений). Два — давно забытыми особенностями старого сервиса (одно поле возвращалось в UTC, другое — в локальной зоне; так было исторически, бизнес не возражал, но в новой реализации захотели единый формат). Все четыре зафиксировали явно: баги — починили, особенности — согласовали с продуктовой командой как осознанное изменение.</p><p>Когда расхождений не осталось, включили фича-флаг на сотрудников самой компании. Через неделю — на 1% реальных водителей. Дальше шаг по 5%, 25%, 50%, 100% с паузой в несколько дней между этапами. На каждом шаге следили не только за HTTP-ошибками и latency, но и за продуктовыми метриками: количество подписанных актов, время от открытия документа до подписи, доля повторных запросов. Один раз пришлось откатиться с 25% на 5% — в одном из регионов выросло время отклика из-за неэффективного запроса. Исправили, выкатили снова.</p><p>Через два месяца чтение полностью перешло в новый сервис. Старый код чтения и фича-флаг удалили в том же релизе. После этого по той же схеме мигрировали запись документов, потом публикацию событий, потом импорт из внешних систем. Полная миграция заняла девять месяцев — почти столько же, сколько провалившийся Big Bang, — но продукт всё это время продолжал развиваться, инцидентов не было, и в конце команда осталась с системой, которую понимает.</p><h2>Типичные ошибки при работе с legacy</h2><p>Первая ошибка — пытаться улучшить всё сразу. Команда одновременно меняет архитектуру, бизнес-логику, контракты и инфраструктуру. В результате становится невозможно понять, какая именно часть вызвала проблему. Правильнее сначала воспроизвести поведение, стабилизировать новую реализацию и только потом улучшать.</p><p>Вторая ошибка — недооценивать скрытые зависимости и побочные эффекты. Legacy-код часто делает больше, чем кажется. На один и тот же вызов могут быть навешаны: запись в таблицу аудита, инкремент счётчика в кэше, публикация события в очередь, обновление статуса связанной сущности, инвалидация кэша, дёрганье webhook’а во внешнюю систему. Если в новой реализации воспроизвести только явный путь, скрытые потребители молча перестанут получать данные — и узнают об этом через жалобу бизнеса, а не через ошибку в логах. Поэтому перед выносом любого модуля имеет смысл составить инвентаризацию побочных эффектов: пройтись по коду и логам и выписать каждое нелогичное действие отдельным пунктом чек-листа.</p><p>Третья ошибка — отсутствие наблюдаемости. Без логов, метрик и трассировки команда не управляет миграцией, а угадывает. Особенно опасно смотреть только на технические ошибки и игнорировать бизнес-показатели.</p><p>Четвертая ошибка — не договариваться с бизнесом. Модернизация не должна быть невидимой «инженерной активностью в стол». Её нужно встраивать в roadmap, объяснять эффект и договариваться о приоритетах. Если бизнес не понимает, зачем команда тратит время на миграцию, работа будет постоянно проигрывать новым фичам.</p><p>Пятая ошибка — не удалять старый код. Временное сосуществование старой и новой логики нормально. Вечное сосуществование — нет. Если legacy не удаляется, технический долг не уменьшается, а просто меняет форму.</p><p>Шестая ошибка — не удалять фича-флаги после миграции. Флаг, который сыграл свою роль и больше никогда не выключается, превращается в постоянное ветвление в коде. Через год команда не помнит, можно ли удалить такую ветку или там сидит важный edge-case. Через два — кода с такими «мёртвыми» флагами становится больше, чем основной логики. Поэтому каждый флаг должен заводиться с условием удаления («после полной выкатки и двух недель стабильной работы») и иметь ответственного, кто этим удалением займётся.</p><p>Отдельно стоит упомянуть организационную сторону. Закон Конвея работает и в обратную сторону: если новый и старый код владеются разными командами с разными приоритетами, миграция будет тормозиться независимо от выбранного паттерна. На время миграции имеет смысл явно проговорить, кто отвечает за переход, и не разделять старую и новую реализации между несовместимыми roadmap’ами.</p><h2>Компромиссы, к которым нужно быть готовыми</h2><p>Постепенная модернизация безопаснее Big Bang-переписывания, но она не бесплатна. Некоторое время система будет сложнее, чем раньше. В ней появятся старый и новый код, прокси-слой, фича-флаги, дублирование логики, дополнительные метрики.</p><p>Shadow testing увеличит нагрузку на инфраструктуру, потому что часть запросов будет обрабатываться дважды. Команде придется поддерживать дисциплину: документировать контракты, отслеживать флаги, удалять старую реализацию после миграции, поддерживать contract-тесты в актуальном состоянии.</p><p>Но это контролируемая сложность. Она распределена во времени и управляется инженерными практиками. В отличие от Big Bang-риска, где команда долго работает с минимальной обратной связью, а потом выкатывает один большой релиз с максимальной неопределенностью.</p><h2>Когда Strangler Fig особенно оправдан</h2><p>Постепенная миграция особенно хорошо подходит для систем, где downtime невозможен или слишком дорог. Это финтех, e-commerce, биллинг, мобильные бэкенды с большой аудиторией, высоконагруженные продукты, старые монолиты и системы с большим количеством интеграций.</p><p>Если продуктом ежедневно пользуются сотни тысяч или миллионы людей, нельзя позволить себе «переписать и посмотреть, что будет». Нужно менять архитектуру так, чтобы пользователь не замечал процесса миграции.</p><p>Этот подход также полезен там, где бизнес продолжает активно развивать продукт. Если фичи нельзя заморозить на полгода, модернизация должна идти параллельно с продуктовой разработкой.</p><h2>Когда модернизацию лучше не делать</h2><p>Постепенная миграция — мощный инструмент, но у неё тоже есть стоимость, и иногда правильный ответ — оставить систему как есть. Несколько сценариев, в которых модернизация плохо окупается.</p><p>Продукт, который уходит из эксплуатации. Если через год сервис будет выключен или заменён на покупное решение, тратить квартал на его рефакторинг бессмысленно. Достаточно стабилизировать то, что есть.</p><p>Модуль, который никто не трогает. Если код десятилетней давности продолжает работать, не падает, не требует изменений и не вызывает инцидентов, его «уродливость» — не повод его переписывать. Цель модернизации — упростить будущие изменения; если будущих изменений нет, цели тоже нет.</p><p>Регулируемые системы с тяжёлой ресертификацией. В банковских, медицинских и государственных контурах любое изменение в критичной системе может потребовать повторной сертификации, перепрохождения аудитов, обновления договорной обвязки. В таких условиях стоимость модернизации может на порядок превышать стоимость поддержки текущей реализации, и решение нужно принимать вместе с владельцем продукта и юристами, а не только инженерным составом.</p><p>Простой тест: если на вопрос «какой бизнес-сценарий мы откроем после миграции» нет внятного ответа — модернизацию имеет смысл отложить и заняться чем-то другим.</p><h2>Что получает команда</h2><p>Главный результат постепенной модернизации — управляемость. Команда начинает лучше понимать систему, контролировать изменения и снижать риск инцидентов.</p><p>Появляются понятные контракты, наблюдаемость, практика безопасных релизов, культура удаления старого кода. Разработчики перестают бояться legacy, потому что у них появляется метод, а не только желание «когда-нибудь всё переписать».</p><p>Для бизнеса это тоже выгодно. Продукт продолжает развиваться, сроки становятся более прогнозируемыми, риски крупных сбоев снижаются, а технический долг постепенно уменьшается.</p><h2>Модернизация — это процесс, а не проект</h2><p>Legacy нельзя «починить за квартал». Если система развивалась годами, она не станет простой после одного рефакторинга. Но её можно системно улучшать.</p><p>Strangler Fig Pattern, Branch by Abstraction, feature toggles, shadow testing и аккуратная миграция данных дают рабочую модель: выбрать ограниченный участок, описать контракт, реализовать новую версию, проверить её на реальном трафике, постепенно переключить пользователей и удалить старый код.</p><p>Это не самый быстрый путь. Зато он управляемый. А в зрелых продуктах управляемость важнее скорости.</p><p>Потому что цель модернизации — не написать красивую новую систему. Цель — сделать так, чтобы продукт продолжал развиваться, команда могла безопасно вносить изменения, а пользователи не становились участниками инженерного эксперимента.</p>]]></content:encoded>
    </item>
    <item>
      <title>Северокорейские хакеры украли $2 млрд в криптовалюте — и это ещё не конец года</title>
      <link>https://tproger.ru/news/severokorejskie-hakery-ukrali--2-mlrd-v-kriptovalyute---i-eto-eshhyo-ne-konec-goda</link>
      <comments>https://tproger.ru/news/severokorejskie-hakery-ukrali--2-mlrd-v-kriptovalyute---i-eto-eshhyo-ne-konec-goda?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/severokorejskie-hakery-ukrali--2-mlrd-v-kriptovalyute---i-eto-eshhyo-ne-konec-goda</guid>
      <description><![CDATA[<p>Северокорейские хакеры установили новый рекорд: $2 млрд украденной криптовалюты за 2025 год. Lazarus Group меняет тактику — от взлома DeFi к атакам на людей. Аналитики предупреждают: слабым звеном безопасности снова стал человек.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/severokorejskie-hakery-ukrali--2-mlrd-v-kriptovalyute---i-eto-eshhyo-ne-konec-goda">Северокорейские хакеры украли $2 млрд в криптовалюте — и это ещё не конец года</a>»</p>]]></description>
      <category><![CDATA[Блокчейн]]></category>
      <category><![CDATA[Криптовалюты]]></category>
      <category><![CDATA[Хакеры]]></category>
      <category><![CDATA[Взлом]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 09 Oct 2025 15:32:35 GMT</pubDate>
      <content:encoded><![CDATA[<p>2025 год уже стал рекордным по объёму криптовалют, похищенных группировками, связанными с КНДР. По данным <a href="https://www.techspot.com/news/109780-north-korean-hackers-stole-2-billion-crypto-year.html">аналитиков</a>, эти атаки становятся всё агрессивнее — и всё чаще бьют не по смарт-контрактам, а по людям.</p><p>Северокорейские хакерские группы украли более $2 млрд в криптовалюте с начала 2025 года — это рекорд, который превысил все предыдущие показатели, сообщает Elliptic. Исследователи проанализировали паттерны отмывания средств, транзакционные цепочки и разведданные и пришли к выводу, что кибероперации Пхеньяна стали одной из ключевых статей госфинансирования. Значительная часть украденных активов, по данным аналитиков, уходит на программы вооружений и ракетные разработки.</p><p>Большая часть суммы пришлась на взлом криптобиржи Bybit в феврале — $1,46 млрд. Это один из крупнейших инцидентов в истории цифровых активов. Трассировка средств показала знакомые методы Lazarus Group — подразделения, которое США и их союзники напрямую связывают с правительством КНДР. Остальные атаки были распределены по более чем 30 инцидентам, включая взломы LND.fi, WOO X и Seedify.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-10-09/875654b0-dfc8-4c0e-86c7-210585f7edfe.png" alt="" /></figure><p>Для сравнения: в 2022 году КНДР похитила около $1,35 млрд, в 2024-м — $660 млн. Эксперты отмечают, что нынешний всплеск связан с сменой тактики. Если раньше упор был на уязвимости в DeFi и мостах, то теперь — на социальную инженерию. Хакеры целенаправленно охотятся на держателей крупных кошельков, добывая приватные ключи через фишинг, поддельные предложения о работе и другие схемы обмана.</p><p>Эксперты считают, что слабым звеном криптобезопасности снова стал человек. Пока инфраструктура крупных платформ усиливает мониторинг и защиту мостов, личные аккаунты топ-менеджеров и трейдеров остаются куда менее защищёнными.</p><p>Параллельно эволюционирует и отмывание средств. Lazarus Group всё активнее использует многоступенчатые кроссчейн-переводы, миксеры и малопопулярные блокчейны, чтобы запутать следы. Несмотря на это, аналитические инструменты становятся точнее: правоохранительные органы всё чаще успевают отследить и заморозить часть средств — но окно возможностей крайне короткое.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как Web3 меняет разработку веб-приложений: от серверов к блокчейну</title>
      <link>https://tproger.ru/articles/kak-web3-menyaet-razrabotku-veb-prilozhenij--ot-serverov-k-blokchejnu</link>
      <comments>https://tproger.ru/articles/kak-web3-menyaet-razrabotku-veb-prilozhenij--ot-serverov-k-blokchejnu?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Диана Тажетдинова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-web3-menyaet-razrabotku-veb-prilozhenij--ot-serverov-k-blokchejnu</guid>
      <description><![CDATA[<p>Поговорили с экспертом и узнали, где Web3 даёт практическую пользу разработчикам: сравниваем подходы, исследуем рынок вакансий и особенности новой реальности.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-web3-menyaet-razrabotku-veb-prilozhenij--ot-serverov-k-blokchejnu">Как Web3 меняет разработку веб-приложений: от серверов к блокчейну</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Блокчейн]]></category>
      <category><![CDATA[Ethereum]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[смарт-контракты]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 22 Sep 2025 12:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Раньше, чтобы запустить приложение, приходилось настраивать сервер и базу данных. В Web3 всё по-другому: вместо серверов — смарт-контракты, вместо базы — блокчейн. <a href="https://www.esparkinfo.com/web3/statistics">По прогнозам</a>, объём рынка Web3‑разработки вырастет с $4,43 млрд в 2024 году до $6,15 млрд в 2025. Кейсы<a href="https://ru.wikipedia.org/wiki/Plume_Network_%E2%80%93_The_Future_of_Real-World_Assets_on_Web3_%F0%9F%8C%90?utm_source=chatgpt.com"> Plume Network</a> и<a href="https://en.wikipedia.org/wiki/The_Graph?utm_source=chatgpt.com"> The Graph</a> показывают, что Web3 уже работает в реальных продуктах. Что, если нас уже сегодня ждет backend в виде блокчейна? Давайте разберём, как меняются инструменты, архитектуры и карьерные треки.</p><h2>Главные отличия Web3 от Web2</h2><p>Перед тем как углубиться в код и практику, полезно увидеть основные различия между привычной Web2-разработкой и новой логикой Web3.</p><figure><img src="https://media.tproger.ru/user-uploads/114509/2025-09-22/3fa1cc2a-0755-4b71-af24-9b8a6f9d22ea.png" alt="" /></figure><p>Представим себе простой сервис для задач. В классическом Web2 его работа привычна: сервер обрабатывает запросы, база данных хранит задачи, а пользователь авторизуется через почту и пароль. Всё централизовано и зависит от владельца сервера.</p><p>В Web3 логика сильно меняется. Пользователь входит в систему с помощью криптокошелька, например, MetaMask. Каждая задача создаётся транзакцией и записывается в смарт‑контракт, а значит становится частью блокчейна. Удалить её уже нельзя — только отметить статус выполнения. Такой подход даёт прозрачность: любой участник сети может проверить, что задача действительно существует, и её статус изменён честно.</p><h2>Стек Web3: что понадобится на практике</h2><p>Чтобы построить работающий DApp, важно понимать, чем он отличается от обычного приложения. DApp — это децентрализованное приложение, в котором логика хранится в смарт-контрактах на блокчейне, а данные — в распределённых хранилищах, а не на сервере компании. Поэтому одного знания блокчейна мало: нужен полный набор инструментов — от языков и фреймворков до кошельков и сервисов подключения.</p><ul><li>Блокчейн: Ethereum, Layer‑2 (Arbitrum, Optimism, Base, Polygon), Solana.</li><li>Языки: Solidity (EVM), Rust (Solana), Go (инфраструктура и сервисы).</li><li>Библиотеки: ethers.js, wagmi.</li><li>Фреймворки: Hardhat, Foundry, Truffle.</li><li>Хранилища: IPFS/Arweave для файлов и метаданных.</li><li>Кошельки/подключение: MetaMask, WalletConnect (v2/WalletConnect Network), Web3Auth.</li></ul><blockquote>Точка входа для новичка — Alchemy, а также ethers.js.</blockquote><p><b>Пример.</b> Быстрое подключение кошелька (ethers.js).</p><h2>Архитектура DApp: из чего состоит современное Web3‑приложение</h2><p>Любое Web3‑приложение строится из нескольких слоёв, каждый со своей ролью. Фронтенд остаётся привычным SPA, но работает не с сервером, а напрямую с кошельком и смарт-контрактами. Контракты содержат бизнес‑логику и хранят ссылки на данные в децентрализованных хранилищах. Оракулы обеспечивают связь с внешним миром, например, передают цены или сообщения между разными блокчейнами. Важную часть играет off‑chain слой — сервисы вне блокчейна (индексаторы, аналитика), которые помогают быстрее искать и обрабатывать данные, при этом не перегружать сеть.</p><p><b>Пример.</b> Возьмём DeFi‑приложение. Пользователь открывает фронтенд и инициирует операцию swap(). В ответ фронтенд обращается к смарт‑контракту, который выполняет обмен токенов. Чтобы определить курс, контракт тянет актуальные данные через оракул. При этом тяжёлые артефакты, изображения или отчёты не хранятся в блокчейне напрямую — они лежат в IPFS. Сам контракт содержит только контент‑идентификаторы CID. Таким образом, получаем баланс: блокчейн отвечает за логику и безопасность, а децентрализованное хранилище — за данные.</p><h2>Практика: ваш первый DApp за вечер</h2><p>Давайте попробуем собрать простейшее приложение своими руками.</p><p><b>Шаг 0. Подготовка</b></p><p>Сначала убедитесь, что у вас стоит Node.js LTS и Git. Также нужен браузер с установленным MetaMask, где можно создать тестовый аккаунт. Чтобы оплачивать транзакции в тестовой сети, заранее возьмите немного тестовых монет через faucet — например, для Sepolia или Polygon Amoy.</p><p><b>Шаг 1. Проект</b></p><p>Создадим новый проект и установим Hardhat вместе с тулзами. Эта среда нужна для компиляции и деплоя контрактов.</p><p><b>Шаг 2. Контракт</b></p><p>В папке contracts/ создаём файл TaskTracker.sol и копируем туда код смарт-контракта из первого раздела. Это и будет бизнес-логика нашего приложения.</p><p><b>Шаг 3. Сценарий деплоя</b></p><p>Пишем скрипт, который разворачивает контракт в сети. Это простой скрипт на JavaScript, который вызывает методы Hardhat.</p><p><b>Шаг 4. Конфиг сети</b></p><p>В файле hardhat.config.js добавляем настройки для подключения к тестовой сети. Используем RPC-URL от Alchemy или Infura и приватный ключ от тестового аккаунта — его можно экспортировать из MetaMask, но использовать только для тестовой сети.</p><p><b>Шаг 5. Деплой в тестнет</b></p><p>Теперь запускаем скрипт деплоя. После выполнения увидите адрес контракта — он понадобится для фронтенда.</p><p><b>Шаг 6. Фронтенд (React + ethers.js + wagmi)</b></p><p>Собираем простое SPA: форма, чтобы добавить задачи, и кнопка «complete». Здесь мы используем ethers.js для обращения к контракту. Сделайте вызовы addTask и completeTask.</p><h2>Подводные камни Web3-разработки и что с ними делать</h2><p><b>Комиссии (gas): </b>любая запись в блокчейн стоит денег и иногда комиссия выше ценности операции — например, $10 за простую задачу.</p><ul><li>Что делать: использовать Layer-2 (Arbitrum/Optimism/Base/Polygon), выбирать сети с низкими комиссиями (Solana, Avalanche), оптимизировать контракты и батчи транзакций.</li></ul><p><b>Скорость: </b>подтверждение транзакции занимает секунды или десятки секунд, что заметно медленнее обычного сервера.</p><ul><li>Что делать: показывать «оптимистичный UI», кешировать данные, переносить часть логики off-chain, использовать быстрые сети (Solana, Near, Aptos).</li></ul><p><b>Безопасность:</b> код контракта неизменяем, и одна ошибка может стоить миллионов.</p><ul><li>Что делать: проходить аудит (CertiK, Trail of Bits), использовать проверенные библиотеки (OpenZeppelin), писать тесты в тестовых сетях (Goerli, Sepolia), внедрять баг-баунти и ролевую модель доступа.</li><li>Ресурс:<a href="https://consensys.io/diligence/smart-contract-security-best-practices/"> ConsenSys Diligence — Smart Contract Security Best Practices</a>.</li></ul><p><b>UX:</b> вход через кошелёк сложнее привычного логина/пароля. Нужно ставить расширение, пополнять баланс и подтверждать каждую транзакцию.</p><ul><li>Что делать: использовать аккаунт-абстракцию (ERC-4337), социальный логин, gasless транзакции через Paymaster, улучшать UI (подсказки, авто-фокус на MetaMask).</li></ul><p><b>Регуляция: </b>законы о Web3 пока разные в каждой стране. Легальное в одной юрисдикции может быть запрещено в другой (например, токенизация акций без лицензии).</p><ul><li>Что делать: консультироваться с юристами, следить за изменениями. Например, MiCA в ЕС — “Markets in Crypto-Assets Regulation” —  это единый регламент по криптоактивам в Евросоюзе.</li></ul><blockquote>Безопасность всегда должна быть на первом месте, потому что в Web3 есть риск потерять реальные деньги пользователей.</blockquote><h2>Карьерные возможности и перспективы</h2><p>Web3‑разработчиков уже активно ищут: <a href="https://web3.career/learn-web3/web3-intelligence-report">зарплаты в среднем предлагают выше</a>, чем у Web2‑коллег. Кроме программистов, востребованы смежные роли: аудиторы смарт‑контрактов, специалисты по безопасности, а также продакт‑менеджеры и аналитики, которые понимают специфику блокчейна.</p><p>Чтобы войти в профессию, начните с изучения Solidity и базовых паттернов смарт‑контрактов. Сделайте пару пет‑проектов и выложите код в GitHub. Отличный вариант прокачки — участвовать в хакатонах и грантовых программах от Ethereum Foundation или Solana Grants. Это даёт и опыт, и контакты, и иногда финансирование.</p><blockquote>Пара пет‑проектов + понимание блокчейна — хороший старт в Web3‑команду.</blockquote><h2>Будущее Web3</h2><p>Web3 не вытеснит Web2 полностью, но поменяет привычный подход к разработке. Разработчику это открывает новые вызовы: комиссии, безопасность и UX, но одновременно и новые возможности — прозрачные данные, токенизация, децентрализованные бизнес‑модели.</p><p>Для тех, кто только входит в сферу, это шанс попасть в индустрию на раннем этапе и быстро нарастить экспертизу. Простые пет‑проекты, хакатоны и знакомство с инструментами дают ощутимый старт.</p><p>Web3 будет развиваться параллельно с Web2, усиливая те области, где важны децентрализация, доверие и контроль за данными. Попробуйте задеплоить первый контракт — и вы сами почувствуете, что это не просто мода, а новый уровень возможностей.</p>]]></content:encoded>
    </item>
    <item>
      <title>n8n: установка, настройка и интеграция с Python, Node.JS и PHP</title>
      <link>https://tproger.ru/articles/n8n--ustanovka--nastrojka-i-integraciya-s-python--node-js-i-php</link>
      <comments>https://tproger.ru/articles/n8n--ustanovka--nastrojka-i-integraciya-s-python--node-js-i-php?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Кирилл Косолапов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/n8n--ustanovka--nastrojka-i-integraciya-s-python--node-js-i-php</guid>
      <description><![CDATA[<p>Подробный туториал по установке и настройки n8n. Примеры интеграции с Python, Node.JS и PHP и взаимодействия с LLM Mistral AI.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/n8n--ustanovka--nastrojka-i-integraciya-s-python--node-js-i-php">n8n: установка, настройка и интеграция с Python, Node.JS и PHP</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[C#]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Microsoft]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Opera]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Telegram]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[OpenAI]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 29 Jun 2025 09:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>n8n — open-source платформа для автоматизации рабочих процессов (workflow), позволяющая создавать сложные цепочки задач без глубоких знаний программирования.</p><p><b>В статье рассмотрим:</b></p><p>- Установку локально и в облаке;</p><p>- Интеграцию с Python, Node.js и PHP;</p><p>- Примеры автоматизаций;</p><p>- Интеграцию с AI Mistral.</p><h2>Установка n8n</h2><h3>Локальная установка</h3><p>Нам потребуется Docker, проверьте установку:</p><p><b>Шаги установки:</b></p><p>1. Создайте том данных:</p><p>2. Запустите контейнер:</p><p>После запуска откройте: `http://localhost:5678`</p><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/32713acd-811d-40dc-8141-4fb625cd4216.png" alt="" /></figure><h3>Установка на удаленном сервере</h3><p>Развертывание мы произведем в облаке <a href="https://amvera.ru/n8n">Amvera</a>, так как в нем n8n предоставляется как преднастроенный сервис с бесплатным доменом (он нам нужен), настроенными переменными и проксированием до заблокированных в РФ LLM (OpenAI, Gemini, Claude и др.).</p><p>1. Регистрируемся на <a href="https://amvera.ru/n8n">Amvera</a>;</p><p>2. Выбираем n8n в плитке на главной странице;</p><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/e74d96ee-5f96-4c61-bf7a-562a38edc703.png" alt="" /></figure><p>3. Вводим название для проекта и выбираем тариф.</p><p><b>Готово, через 30 секунд запустится n8n с выделенным доменом и настроенными основными переменными.</b></p><h2>Настройка n8n</h2><h3>Первоначальная настройка</h3><p>1. Откройте n8n (локально: `localhost:5678`, в облаке: ваш домен)</p><p>2. Заполните данные администратора:</p><ul><li>Email</li></ul><ul><li>Имя/Фамилия</li></ul><ul><li>Пароль</li></ul><p>3. По желанию вы можете получить бесплатный лицензионный ключ:</p><ul><li>Введите email → "Send me a free license key"</li></ul><ul><li>Активируйте в разделе Settings → Usage</li></ul><h3>Настройка для HTTP</h3><p>1. Создайте новый <b>workflow</b> → Start from scratc</p><p>2. Добавьте триггер: <b>Webhook</b> - <b>On webhook call</b></p><p>3. Настройте:</p><ul><li>HTTP Method: POST</li></ul><ul><li>Path: `/n8n` (пример)</li></ul><ul><li>Respond Mode: Using 'Respond to Webhook' node</li></ul><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/6e51fb08-a901-408c-833e-eb27c3ab1f17.png" alt="" /></figure><p>4. Добавьте обработчик: <b>Core</b> → <b>Respond to Webhook</b></p><p>5. Настройте ответ:</p><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/37a5add7-0873-42e1-9004-d33a228d828b.png" alt="" /></figure><h2>Примеры использования</h2><h3>Пример на Python</h3><p>В примере на Python мы сделаем калькулятор. Суть: отправляем выражение через POST,  n8n делает вычисление, возвращаем результат.</p><p><b>Workflow</b>:</p><p>1. Добавьте <b>Core</b> → <b>Code node</b> между Webhook и Respons:</p><p><b>Клиент (Python):</b></p><p>Запустим код и посмотрим результат:</p><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/c9a2bd14-0a7e-4c6f-8544-e4a098a5cd5e.png" alt="" /></figure><h3>Пример на PHP</h3><p>В примере на PHP мы сделаем валидацию данных. Суть: отправляем данные через POST, n8n проверяет данные, возвращает результат.</p><p><b>Workflow (Code node):</b></p><p><b>Клиент (PHP):</b></p><p>Можем зайти на нашу страницу, все работает нормально:</p><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/722241bc-9794-41eb-9d32-8d73d7147800.png" alt="" /></figure><h3>Пример на Node.js</h3><p>Примером на node.js будет фильтр запрещенных слов. Суть: отправляем текст, n8n проверяет на наличие плохих слов, возвращает результат.</p><p><b>Workflow (Code node):</b></p><p><b>Клиент (Node.js):</b></p><p>Перед запуском установим библиотеку командой `npm install axios`</p><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/c56f275a-8c74-49bf-80e5-22d5becd222a.png" alt="" /></figure><h3>Интеграция n8n с Mistral AI</h3><p>Мы интегрируем нейросеть Mistral в телеграмм-бота на C# с помощью n8n. Перед тем как начать, нам нужно получить токен.</p><p>1. Зарегистрируйтесь на <a href="https://mistral.ai/">Mistral</a></p><p>2. Создайте агента <b>Сreate an agent</b></p><p>3. Перейдите в раздел <b>API Keys</b></p><p>4. Создайте и скопируйте API-ключ (звездочки наложены):</p><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/7bb95f2e-0ebe-47af-9089-5e10ee2822cf.png" alt="" /></figure><p>Теперь нужно создать credentials для работы с созданной моделью. Для этого в правом верхнем углу нажмите <b>Create credentials</b>. В списке найдите <b>Mistral Cloud API</b>. В открывшемся окне вставьте скопированный ключ и сохраните.</p><p>Осталось настроить workflow.</p><p>1. Добавляем <b>Webhook</b>:</p><ul><li>Method: POST</li></ul><ul><li>PATH: n8n</li></ul><ul><li>Respond: Using 'Respond to Webhook' Node</li></ul><p>2. Добавляем <b>AI Agent</b>:</p><ul><li>Source for Prompt: Define below</li></ul><ul><li>Prompt: `{{ $json.body.text }}`</li></ul><p>3. Подключаем <b>Chat Model </b>к созданному агенту:</p><ul><li>Credential to connect with: Mistral Cloud API</li></ul><ul><li>Model: mistral-large-2411</li></ul><p>4. Добавляем <b>Respond to Webhook</b></p><p>Вот так выглядит готовый workflow:</p><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/b2618a94-f3eb-4055-9061-ab185aca9d9d.png" alt="" /></figure><p>Можем приступить к созданию бота. Для начала введите эти команды по очередности:</p><p>Переходим в папку с кодом и редактируем файл `Program.cs`:</p><p>Запустите бота с помощью команды `dotnet run`.</p><h3>Автоматизируем с помощью n8n</h3><p>В примере автоматизации мы сделаем бота, который будет отправлять уведомления при заполнении формы, полностью без кода.</p><p>Для работы с <b>Telegram Node</b> понадобиться создать credentials <b>Telegram API</b>. Туда вставляем токен бота, полученный в @BotFater. Сохраняем и переходим к настройке workflow.</p><p><b>Создаем новый workflow. </b></p><p>1. Добавляем <b>On form submission</b>. В качестве примера я создам самую простую форму:</p><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/3bd6f188-16bd-4fa4-bde2-f7a88855bdad.png" alt="" /></figure><p>Перейдите по ссылке в <b>Producrion URL</b> чтобы заполнить форму.</p><p>2. Добавляем <b>Telegram Node</b>:</p><ul><li>Credential to connect with: Telegram account</li></ul><ul><li>Resource: Message</li></ul><ul><li>Operation: Send message</li></ul><ul><li>Chat ID: вставьте свой telegram id</li></ul><p>Text:</p><p>Готово! При новых заявках бот будет присылать уведомления.</p><h3>Деплой бота в Amvera Cloud</h3><p>Перед тем как начать деплой, мы должны создать конфигуационнный файл `amvera.yml`. Для этого создаем его в рабочем каталоге с ботом и вводим следующее:</p><p>Строго говоря, этот файл проще создать в конфигураторе в интерфейсе.</p><p>2. Структура проекта будет такой:</p><p>tg-bot/</p><p>├── Program.cs</p><p>├── tg-bot.csproj</p><p>├── amvera.yml</p><p>├── bin/</p><p>└── obj/</p><p>Идем В Amvera Cloud и создаем приложение <b>Приложения</b> — <b>Создать приложение</b>. Вводим название и выбираем тариф.</p><p>Далее загружаем все файлы, что есть у нас в каталоге, с ботом. В конце будет окно с настройкой конфигуцрации, выглядит оно так:</p><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/7806bf2f-38e5-4aa4-ade2-6c12d3f6c214.png" alt="" /></figure><p>Нажимаем <b>Завершить</b> и ждем когда приложение будет запущено.</p><h2>Заключение</h2><p>n8n — мощный инструмент для создания интеграций и автоматизаций. Надеюсь, статья была вам полезна и буду рад обсудить в комментариях любые вопросы!</p>]]></content:encoded>
    </item>
    <item>
      <title>Комментарии в коде: зло или спасение ?</title>
      <link>https://tproger.ru/articles/kommentarii-v-kode--zlo-ili-spasenie--</link>
      <comments>https://tproger.ru/articles/kommentarii-v-kode--zlo-ili-spasenie--?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Baskon]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kommentarii-v-kode--zlo-ili-spasenie--</guid>
      <description><![CDATA[<p>Когда нужны комментарии в коде, а когда без них лучше. Объясняем на примерах, как писать понятные и полезные комментарии</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kommentarii-v-kode--zlo-ili-spasenie--">Комментарии в коде: зло или спасение ?</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[C#]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[MIT]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Игра]]></category>
      <category><![CDATA[Safari]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Машин]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[XML]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 23 Jun 2025 10:39:48 GMT</pubDate>
      <content:encoded><![CDATA[<p>Что делать с комментариями в коде — писать или не писать? Одни уверены: чистый код говорит сам за себя, другие не представляют работу без пояснений. Истина, как обычно, посередине. Комментарии — это инструмент, умелый программист применяет их с пользой, неумелый — только усложняет жизнь себе, коллегам, начальству, пользователям и вообщем всем сопричастным. Разберемся, когда комментарии действительно нужны, а когда от них больше вреда и приведем примеры в коде</p><h2>Зачем вообще писать комментарии в коде?</h2><p>Комментарии — это кусочки текста в программе, которые компилятор пропускает, а человек читает. Они не влияют на работу программы, зато сильно влияют на мозг того, кто будет с этой программой разбираться.</p><h3>Какие задачи они решают ?</h3><h4>1. Пояснить неочевидное</h4><p>Код показывает «что» делает программа, а комментарий — «зачем».</p><p>Такой комментарий не просто поясняет логику — он экономит десятки минут будущего чтения.</p><h3>2. Предупредить</h3><p>В коде бывает странное поведение. Иногда это не баг, а фича. И если не предупредить, другой разработчик обязательно «поправит» и всё сломает. Комментарий защитит от этого:</p><h3>3. Пометить незавершёнку</h3><p>TODO, FIXME, HACK — это специальные маячки. Их ставят туда, где нужно что-то доделать, починить или переписать по-человечески.</p><p>Бонусом, IDE умеют обрабатывать такие заметки, каждая по-своему.</p><h3>4. Временно отключить код</h3><p>Иногда нужно что-то закомментировать, чтобы проверить гипотезу. Но такой код нельзя оставлять надолго. Если от него нет пользы — в мусор. Историю всё равно сохранит git.</p><h3>5. Объяснить архитектуру</h3><p>Иногда важно не только «как» сделано, но и «почему так». Особенно это касается паттернов, нестандартных решений или компромиссов.</p><h3>6. Генерация документации</h3><p>Многие языки и фреймворки поддерживают специальные форматированные комментарии для генерации документации. Например, JavaDoc в Java, docstring в Python, XML в C# – предназначены для описания интерфейсов: что делает функция или класс, какие имеют входные параметры и какой результат дают. Такие Комментарии выполняют роль пользовательской документации прямо в коде и могут автоматически собираться в справочник по API.</p><h3>7. Пошутить</h3><p>Программисты – тоже люди, и иногда оставляют в коде шуточные либо эмоциональные комментарии, чтобы снять стресс. В открытых исходниках можно встретить комментарии с шутками, сарказмом или даже ругательствами, адресованными сложному коду или «костылям».</p><p>Как видно, диапазон применения комментариев очень широк. Но одинаково ли хорошо все эти виды влияют на качество кода? Рассмотрим случаи, когда комментарии приносят пользу, а когда создают проблемы.</p><h2>Когда комментарии помогают</h2><p>А часто без комментариев в коде сложно разобраться, особенно когда  код чужой.</p><h3>1. Когда логика не лежит на поверхности</h3><p>Есть участки кода, где без контекста трудно разобраться, даже если код написан довольно читабельно. Например, сложная формула, нетривиальный алгоритм или необычная структура данных – всё, что выбивается из обыденного опыта разработчиков. В таких случаях пара строк комментария, резюмирующих подход, или объясняющих, что происходит, сэкономят часы на анализ. Это особенно важно для командной работы: коллегам, незнакомым с модулем, не придётся разбираться «с нуля».</p><h3>2. Когда нужно документировать контракты и условия</h3><p>Комментарии могут  использоваться для обозначения контрактов – предусловий и постусловий функций, инвариантов и т.д. (подход Design by Contract). Хотя современные языки позволяют выразить многое (например, через assert или декораторы), комментарии могут дополнять код уточнениями вроде:</p><p>Также текстовые пометки в коде полезны для фиксации граничных условий и особых случаев, таких как обработка пустных массивов в бинарном поиске,  другой пример:</p><p>Да, можно это выразить через assert, но комментарий дает сразу и контекст, и предупреждение. Особенно если логика непростая.</p><h3>3. Когда нужно предоставить контекст и ссылки</h3><p>Иногда кусок кода существует благодаря внешнему источнику, например, когда решение просто скопировано из ответа на форуме или из книги по теме. Просто так его не понять — нужна ссылка на источник:</p><h3>4. Когда нужно облегчить ревью</h3><p>Когда код содержит много пояснений к его работе  новому участнику команды проще входить в проект – по сути, комментарии выполняют роль встроенной документации. Кроме того, код-ревью проходит эффективнее, если автор сразу помечает неочевидные места комментариями. Например:</p><p>В PEP 8 (стиле кодирования Python) прямо приводится пример: комментарий “Compensate for border” – полезный, в отличие от банального “Increment x”, который не даёт новой информации.</p><h3>5. Когда нужна поддержка самодокументируемости через структуру</h3><p>Иногда хочется написать: # Этап 1: авторизация пользователя, и в этот момент приходит мысль — а почему бы не вынести это в функцию authorize_user()? И комментарий уже не нужен. То есть сам порыв объяснить словами часто указывает, что код пора расчленить и упростить.</p><h3>6. Когда нужно кого-то обучить программированию или корпоративным стандартам оформления кода</h3><p>Когда человек обучается программированию или только пришел в компанию, где есть свои стандарты, комментарии в коде можно использовать, чтобы дать ему обучающий материал с примерами из практики, пример:</p><p>Комментарий — это инструмент. Если комментарий в коде дает информацию, которую нельзя вытащить из кода напрямую, — значит, работает как надо. Но бывает и обратное — когда комментарии мешают. Об этом — в следующей части.</p><h2>Когда комментарии вредят</h2><p>Худшее, что может случиться с комментариями – когда они вводят в заблуждение или засоряют код впустую. Рассмотрим подробнее:</p><h3>Дублируют очевидное</h3><p>Комментарий, который просто повторяет код своими словами, не несёт никакой пользы:</p><p>А вот так — лучше вообще без пояснений:</p><p>Комментарий должен объяснять, зачем что-то делается, а не что именно:</p><h3>Врут и вводят в заблуждение</h3><p>Классика: код переписали, а про комментарий забыли.</p><p>Спустя некоторое время код могли переписать, и old_api_call() заменили на new_api_call(), но комментарий остался от прежней версии и стал источником дезинформации: разработчик, читающий код, может принять заведомо неверное решение, доверившись устаревшей заметке. По этой причине крайне важно понимать: если уж пишете комментарий, держите его в актуальном состоянии вместе с кодом.</p><h3>Показывают, что код плохой</h3><p>Когда код плохо читается, и его пытаются «объяснить» словами, вместо того чтобы переписать:</p><p>Вместо этого — понятный код:</p><h3>Плодятся бесконтрольно</h3><p>Иногда встречается код, где каждое действие сопровождается избыточными пояснениями:</p><p>Здесь нет ни одной неочевидной строки. Лучше оставить так:</p><h3>Представляют собой мёртвый код</h3><p>Когда в коде остаются большие мёртвые блоки, которые просто закомментированы:</p><p>Может быть, раньше это что-то значило, но сейчас — просто мертвый груз. Если код не нужен — удаляй. История останется в git.</p><h3>Запутывают и размывают смысл</h3><p>Что значит «временное»? Когда переделывать? Почему не постоянное?</p><p>Лучше так:</p><p>Теперь ясно, почему так сделано, и можно отследить, когда это поведение закончится.</p><p>Итак, комментарии становятся злом, когда они не выполняют своей информативной роли, а лишь создают шум или дезинформируют. В худшем случае они могут привести к багам (если программист доверится неверному комментарию) и точно приведут к потере времени на их чтение и разбор. Единственный способ избежать этого зла —  писать комментарии ответственно: убедиться, что они нужны, правдивы и своевременны.</p><h2>Самодокументируемый код vs комментарии</h2><p>Есть мечта у программистов — писать код, который объясняет сам себя. Без сносок, без подсказок, без комментариев. Такой код читается как инструкция: открыл — понял. Это и называется самодокументируемым стилем.</p><p>Как его достигают?</p><ul><li>Говорящие имена. Не x и a, а temperature, retryLimit, userProfile. Лучше сразу по имени понять, что перед тобой — массив с ID или словарь с настройками.</li><li>Функции с характером. У функции должно быть имя-глагол, в котором есть ответ на вопрос “что делает этот код?”. Например: parseInvoice(), sendEmailReminder(), fetchUserByToken().</li><li>Использовать названия для константных значений. Вместо if (status == 4) — if (status == ORDER_CONFIRMED). Вместо 3000 — RETRY_TIMEOUT_MS.</li><li>Структура — как абзацы в тексте. Пустые строки, логические блоки, отступы — чтобы этапы выделялись сами собой.</li></ul><p>Посмотрим например, где простой код поясняется ненужным комментарием:</p><p>Другой пример:</p><p>Комментарий уже не нужен. Из имён всё понятно: считаем среднюю температуру. Здесь самое интересное — само документируемость имеет границы. Потому что:</p><ul><li>Код объясняет «что», но не всегда «почему».</li></ul><p>Вот есть строка:</p><p>А почему 5? Почему не 3, не 10? Если причина — ограничение API, бизнес-логика или чья-то странная прихоть — код не расскажет. А вот комментарий может:</p><p><b>Неочевидные решения и компромиссы</b></p><p>Иногда приходится делать что-то нестандартное. Например:</p><p>Такой кусок кода без пояснений вызовет недоумение: А почему не сортируем?</p><p>Старайтесь писать код так, чтобы его поняли без подсказок. Как будто у вас нет возможности что-то дополнительно объяснить. А если видите, что читателю будет трудно — помогите: добавьте комментарий, который действительно нужен.</p><h2>Влияние ИИ и новых инструментов на подход к комментариям</h2><p>В последние годы в распоряжении разработчиков появились мощные ассистенты на базе искусственного интеллекта — такие как GitHub Copilot (автодополнение кода на основе ИИ) и большие языковые модели вроде ChatGPT. Эти технологии начинают влиять и на практики комментирования кода.</p><p>Во-первых, автогенерация кода по комментариям стала реальностью.</p><p>Инструмент Copilot способен на лету написать фрагмент кода, ориентируясь на описания на естественном языке. Например:</p><p>Copilot тут же может подставить реализацию:</p><p>Такой подход превращает комментарий в своего рода промпт — описание задачи для ИИ. Это приучает писать коротко и по делу. Хотя такие комментарии потом часто удаляют, их роль в генерации кода становится всё важнее.</p><p>Во-вторых, ИИ сам пишет комментарии.</p><p>Можно просто показать код:</p><p>…и попросить ИИ: прокомментируй. В ответ он выдаст:</p><p>Или даже более детальный:</p><p>Такие автокомментарии могут быть полезны, но всё равно требуют проверки: всезнающий ИИ не всегда понимает скрытые нюансы логики, а часто просто галлюцинирует, поэтому доверять полностью не стоит, но, как черновик, вполне годится.</p><p>В-третьих, стало проще понимать чужой код без комментариев.</p><p>Раньше приходилось часами вчитываться, сегодня — можно просто спросить:</p><p>Запрос в ChatGPT: что делает эта функция?</p><p>Ответ: Она возвращает новый список, содержащий удвоенные значения тех элементов исходного списка, которые делятся на 3.</p><p>ИИ не волшебник, но в 90% случаев — удобный переводчик с машинного на человеческий. Это снимает часть нагрузки с необходимости документировать тривиальные вещи.</p><p>В-четвертых, новый тип комментариев: инструкции для ИИ</p><p>Может возникнуть ситуация, когда комментарий пишется не столько для человека, сколько как команда:</p><p>Если вы используете Cursor или Replit, это может очень полезным.</p><h2>Заключение</h2><p>Так всё-таки, комментарии – зло или спасение?</p><p>Это не абсолютное благо и не абсолютное зло, это просто инструмент. Всё зависит от того, в чьих он руках и зачем используется. Комментарии способны помочь понять неочевидные решения, разобраться в сложных структурах, подсказать направление для размышления. Но, как и любой инструмент, в неумелых руках это способ случайно (или не очень) испортить кровь себе и окружающим.</p><p>Но всё-таки чаще наличие комментариев делает жизнь лучше, ведь иногда формулирование мысли разговорным текстом, а не кодом, позволяет понять свою идею лучше, взглянуть на нее с другой стороны.</p>]]></content:encoded>
    </item>
    <item>
      <title>Зачем нам свои сети, если ими никто не пользуется? Насколько все плохо с российскими SDN</title>
      <link>https://tproger.ru/articles/zachem-nam-svoi-seti--esli-imi-nikto-ne-polzuetsya--naskolko-vse-ploho-s-rossijskimi-sdn</link>
      <comments>https://tproger.ru/articles/zachem-nam-svoi-seti--esli-imi-nikto-ne-polzuetsya--naskolko-vse-ploho-s-rossijskimi-sdn?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Денис Кудерин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/zachem-nam-svoi-seti--esli-imi-nikto-ne-polzuetsya--naskolko-vse-ploho-s-rossijskimi-sdn</guid>
      <description><![CDATA[<p>Российские сети SDN — что с ними не так и почему инфраструктура так медленно развивается. Экспертный обзор ситуации на рынке</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/zachem-nam-svoi-seti--esli-imi-nikto-ne-polzuetsya--naskolko-vse-ploho-s-rossijskimi-sdn">Зачем нам свои сети, если ими никто не пользуется? Насколько все плохо с российскими SDN</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Образование]]></category>
      <category><![CDATA[Россия]]></category>
      <category><![CDATA[VMware]]></category>
      <category><![CDATA[Дата-центр]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 20 Jun 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>В 2025 году программно-определяемые сети (SDN) — это не тренд, а жизненная необходимость. Мировой рынок SDN растет на 13–22% в год, а в России его объем уже превысил 15 млрд рублей. Но вот в чем подвох: пока мир переходит на «сети из кода», российские компании до сих пор настраивают VLAN вручную или цепляются за устаревшие решения VMware, американского разработчика ПО для виртуализации.</p><p>Почему так? В 2024–2025 годах США ужесточили ограничения: VMware NSX и Cisco ACI официально заблокированы. Казалось бы, идеальный момент для отечественных решений вроде Basis SDN от «Базиса». Но сегодня их доля на рынке — не выше 3%.</p><p>Выясним, почему российские SDN, несмотря на импортозамещение, пока так и не стали массовыми, и что мешает бизнесу переходить на отечественные продукты — от дефицита специалистов до проблем с legacy-инфраструктурой. Только факты, кейсы внедрений и прогнозы на 2026–2030 годы с опорой на отчеты Ростелекома, аналитику <a href="https://www.6wresearch.com/industry-report/russia-software-defined-anything-market">6Wresearch</a> и документы <a href="https://www.archivemarketresearch.com/reports/sdn-system-43385">OFAC</a>.</p><h2>SDN в России-2025: почему мир перешел на «сети из кода», а мы настраиваем маршрутизаторы вручную</h2><p>SDN (Software-defined networking) — это когда сетью управляют не железки, а код. Представьте, что вместо того, чтобы вручную прописывать правила на каждом коммутаторе, вы просто пишете скрипт, и сеть мгновенно перестраивается под ваши задачи. Контроллер SDN решает, куда направить трафик, как распределить нагрузку и какие политики безопасности применить. Все это — без манипуляций с командной строкой и конфигурационных файлов.</p><h3>Мировой контекст: SDN как новая норма</h3><p>Глобальный рынок SDN к 2025 году оценивается в $12+ млрд, а темпы роста превышают 18% в год. Причины просты:</p><ul><li>Облака и гибридные инфраструктуры требуют гибкости, которую традиционные сети дать не могут.</li><li>Киберугрозы теперь атакуют не отдельные устройства, а всю сеть. SDN позволяет изолировать зараженные сегменты за секунды — например, отрезать атакованный филиал до того, как он заразит головной офис.</li><li>5G и IoT без SDN просто не работают. Виртуальные срезы сети (network slicing) — единственный способ гарантировать приоритет критичному трафику, будь то телемедицина или беспилотники.</li></ul><p>Но главный драйвер — экономика. <a href="https://www.tadviser.ru/index.php/%D0%A1%D1%82%D0%B0%D1%82%D1%8C%D1%8F:%D0%93%D0%BB%D0%B0%D0%B2%D0%BD%D1%8B%D0%B5_%D1%82%D0%B5%D0%BD%D0%B4%D0%B5%D0%BD%D1%86%D0%B8%D0%B8_%D0%BD%D0%B0_%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%BE%D0%BC_%D1%80%D1%8B%D0%BD%D0%BA%D0%B5_%D0%B4%D0%B0%D1%82%D0%B0-%D1%86%D0%B5%D0%BD%D1%82%D1%80%D0%BE%D0%B2">Компании устали переплачивать за «умное» железо</a> Cisco и Juniper, когда всю логику можно перенести в софт. К 2025 году 70% корпоративных сетей в ЕС и США управляются через SDN-контроллеры — просто потому, что это дешевле и быстрее.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-06-12/45a4e2ba-6d0d-4766-9673-120dca5836f6.png" alt="" /></figure><h3>Россия: технологический суверенитет vs. реальность</h3><p>В 2024–2025 годах санкции добили то, что не успели в 2022-м:</p><ul><li>VMware NSX официально заблокирован для российских компаний.</li><li>Cisco ACI и Huawei CloudFabric доступны только через «серые» схемы, но их поддержка практически не работает.</li><li>Оборудование попало под прямые ограничения: даже нейтральные производители вроде Arista отказываются поставлять коммутаторы из-за риска вторичных санкций.</li></ul><p>Казалось бы, идеальный момент для российских SDN-решений. Но доля отечественных продуктов на рынке — единицы. Причины такой ситуации вполне объективны:</p><ul><li>«Железная» зависимость. Большинство российских SDN работают только с оборудованием конкретных вендоров — YADRO, Aquarius, «Бифорком». Если у компании инфраструктура на старых Cisco или Huawei, миграция потребует полной замены «железа».</li><li>Функциональные пробелы. Тот же Basis SDN декларирует 80% функционала VMware NSX, но ключевые фичи вроде автоматического восстановления после сбоев (self-healing) или глубокой аналитики трафика через ИИ пока в разработке.</li><li>Дефицит экспертов. В России менее 1000 сертифицированных специалистов по SDN — против 25 000 в США и ЕС. Обучение нового инженера с нуля занимает 1.5–2 года — бизнес не готов ждать.</li></ul><h3>Спрос есть, но внедрять некому</h3><p>Опросы специализированных изданий показали, что более трети крупных отечественных компаний хотели бы перейти на отечественные SDN, но многие из них не верят в стабильность российских решений, не готовы инвестировать в замену инфраструктуры, не могут найти подрядчика с нужной экспертизой.</p><p>При этом Basis SDN — единственное решение, которое хоть как-то закрывает дыру. Его пилоты запустили Ростелеком, СберТех и несколько госструктур. Но даже они признают: продукту не хватает открытости API и поддержки мультивендорных сред.</p><p>Вывод: мир уже живет в эпоху «сетей как кода», а Россия только учится настраивать контроллеры. Без массовых инвестиций в R&amp;D (Research and Development, научные исследования и разработки) и образование разрыв будет расти. К 2030 году мы рискуем остаться с SDN «на бумаге», пока глобальные игроки перейдут на следующую ступень — IBN (intent-based networking) — сеть, основанную на намерениях с полной автономией ИИ.</p><h2>Свои SDN: роскошь или необходимость?</h2><p>Блокировки лишили российские компании доступа к обновлениям и техподдержке. Санкции против YADRO и других производителей сетевого оборудования усугубили проблему: даже если «железо» физически есть, его нельзя масштабировать без лицензий. Сложность в том, что технологический суверенитет нельзя купить — его нужно строить.</p><h3>Технологический суверенитет — не лозунг, а вынужденная мера</h3><p>В 2025 году термин «импортозамещение» уже не вызывает иронии. Сегодня российский бизнес столкнулся с простым фактом: зарубежные SDN-решения либо недоступны, либо работают с перебоями.</p><p>Компании, которые в 2024-м надеялись на «серые» поставки VMware NSX, теперь тратят на 40% больше на поддержку устаревших версий.</p><p>Basis SDN — пока единственная рабочая альтернатива. Разработка «Базиса» и Angie Software изначально создавалась под санкционные реалии:</p><ul><li>полная независимость от зарубежного ПО — даже гипервизор работает на KVM;</li><li>поддержка российского «железа» (YADRO, Aquarius) без необходимости доработок;</li><li>цена ниже VMware NSX до его ухода с рынка.</li></ul><p>Но главное — это не просто клон VMware, а адаптация под российские условия. Например, здесь изначально заложена поддержка требований ФСТЭК к шифрованию трафика, что для госсектора критично.</p><h2>Преимущества, которые оценит даже скептик</h2><p>Рассмотрим подробно плюсы перехода на отечественные программно-определяемые сети.</p><h3>Централизованное управление: оптимизация времени и расходов</h3><p>Вместо настройки каждого коммутатора вручную вы управляете всей сетью через одну веб-панель. Нужно изменить политику безопасности для филиала? Все делается элементарно: не надо ехать на место или объяснять по телефону — правила применяются мгновенно.</p><p>Так работает Basis SDN:</p><ul><li>единый контроллер заменяет десятки разрозненных консолей Cisco Prime или Huawei eSight;</li><li>автоматизация рутинных задач — например, выделение VLAN под новый отдел занимает минуты вместо часов;</li><li>мониторинг в реальном времени — аномалии трафика (DDoS, утечки) система обнаруживает сама и предлагает решения.</li></ul><h3>Микросегментация: безопасность без головной боли</h3><p>В 2025 году кибератаки стали точечными: злоумышленники не ломают всю сеть, а ищут слабые звенья — бухгалтерию, базы данных, IoT-устройства.</p><p>SDN позволяет изолировать критичные сегменты без физического разделения:</p><ul><li>финансовые системы можно отрезать от общего трафика, даже если они используют те же коммутаторы;</li><li>доступ к данным регулируется не только логинами, но и контекстными правилами (например, запрет копирования файлов после 18:00);</li><li>в случае атаки зараженный сегмент автоматически блокируется — без остановки всей сети.</li></ul><h2>Совместимость: работает здесь и сейчас</h2><p>Типичная претензия к российскому ПО — «а вот у Cisco…». Но Basis SDN уже сегодня поддерживает:</p><ul><li>Astra Linux и «Альт» — без костылей в виде дополнительных драйверов;</li><li>оборудование YADRO, БСТ, Aquarius — с гарантией обновлений;</li><li>облачные платформы на базе KVM и отечественных гипервизоров.</li></ul><p>При этом система не требует полного отказа от legacy-инфраструктуры. Например, можно оставить старые коммутаторы Cisco, но управлять ими через SDN-контроллер — это вдвое дешевле, чем менять все железо.</p><h2>Рыночные перспективы: куда движется отрасль</h2><p>Объем рынка SDN в России пока относительно невелик, но к 2031-му прогнозируют его рост до 32 млрд.</p><p>Основные драйверы:</p><ul><li>Госсектор: с 2024 года все госкомпании обязаны использовать «третьи ключи шифрования» — без SDN это нереализуемо.</li><li>Телеком: Ростелеком и МТС тестируют SDN для 5G-сетей — ручное управление таким трафиком уже невозможно.</li><li>Средний бизнес: облачные CRM и ERP требуют гибких сетей, а аренда VMware NSX теперь недоступна.</li></ul><h3>Вывод: свои SDN — это про выживание</h3><p>В 2025 году вопрос уже не в том, «зачем свои SDN», а в том, как быстро компании смогут перейти на них. Ожидать возвращения VMware бессмысленно и нерационально.</p><p>При этом:</p><ul><li>Basis SDN — не идеален, но это практически единственное рабочее решение;</li><li>без микросегментации скоро не получится пройти даже базовый аудит ФСТЭК;</li><li>гибридные облака без SDN превращаются в кошмар админа.</li></ul><p>Те, кто внедрит российские SDN сейчас, через 2–3 года получат снижение затрат на 25–40% по сравнению с теми, кто цепляется за «серые» Cisco и Huawei. Остальные рискуют остаться с сетью, которую некому и нечем администрировать.</p><h2>Проблемы отечественных SDN: почему российские «сети из кода» пока не взлетели</h2><p>Однако в 2025 году российские SDN-решения пока далеки от совершенства. Basis SDN от «Базиса» и аналоги от VK Tech («Спрут») — первые ласточки, но их внедрение сталкивается с тремя группами проблем: технологическими, экономическими и рыночными. Разберем каждую.</p><h3>Технологические вызовы: когда железа много, а экспертов нет</h3><p>Эта  группа проблем наиболее показательна для отечественных решений.</p><p><b>Дефицит экспертизы.</b> Для разработки конкурентоспособного SDN нужны специалисты высшего уровня, которых в РФ катастрофически не хватает.</p><p><b>Функциональные пробелы.</b> Basis SDN декларирует 80% функционала VMware NSX, но критичные фичи вроде автономного восстановления после сбоев или глубокой аналитики трафика через ИИ появятся <a href="https://ict-online.ru/news/Basis-SDN-pervoye-setevoye-resheniye-klassa-SDN-sozdannoye-pod-rossiiskikh-zakazchikov-310789">не раньше 2026 года</a>. Для корпоративных клиентов это риск: например, без self-healing атака на один сегмент может парализовать всю сеть.</p><p><b>Совместимость с legacy-инфраструктурой.</b> Большинство российских SDN работают с оборудованием YADRO, Aquarius или «Бифорком». Если у компании стоят старые Cisco или Huawei, миграция потребует полной замены «железа» — а это +30–50% к бюджету проекта.</p><p><i>Пример: В 2024 году Ростелеком-ЦОД пытался интегрировать Basis SDN с унаследованными коммутаторами Juniper. Проект забуксовал — пришлось докупать российские аналоги, что увеличило сроки внедрения на 4 месяца.</i></p><h3>Экономические и регуляторные барьеры: санкции vs. окупаемость</h3><p><b>Высокая стоимость разработки.</b> Создание Basis SDN обошлось в сотни миллионов рублей. Для сравнения: бюджет VMware NSX превышает $1 млрд, но его распределяют на глобальный рынок. Российским вендорам приходится компенсировать затраты за счет узкой локальной аудитории.</p><p><b>Давление санкций.</b> С июня 2024 года США запретили ИТ-консалтинг и облачные услуги для российских компаний. Это ударило по поддержке гибридных инфраструктур. Стало невозможно заказывать аудит сети у зарубежных вендоров, а облачные платформы вроде VMware Cloud Foundation недоступны даже через «серые» схемы.</p><p><b>Долгая окупаемость.</b> По прогнозам «Базиса», Basis SDN окупится за 2–3 года. Но малый бизнес не готов ждать — ему нужны решения здесь и сейчас.</p><h3>Рыночное недоверие: почему бизнес не верит в свои SDN</h3><p>Культ «проверенных» зарубежных решений. Даже санкционные Cisco ACI и VMware NSX остаются в топе запросов у российских интеграторов.</p><p>Причины:</p><ul><li>Документация. У Cisco — 500+ страниц детальных мануалов, у Basis SDN — 80, и половина на уровне «как включить контроллер».</li><li>Сообщество. Для VMware NSX есть 1000+ готовых скриптов на GitHub, для Basis SDN — меньше 50.</li></ul><p>Низкая осведомленность малого бизнеса. Опрос бизнес-лаборатории «КРОК» показал: 60% компаний с оборотом до 1 млрд руб. считают SDN «дорогой игрушкой для корпораций». При этом они не знают, что микросегментация в Basis SDN снижает риски утечек на 40% — но об этом не пишут в СМИ.</p><p>Российские SDN не смогут конкурировать с зарубежными, пока:</p><ul><li>не сократится разрыв в экспертизе — нужны образовательные программы уровня Cisco Networking Academy;</li><li>не появятся гарантии долгосрочной поддержки — например, госсубсидий на 5–10 лет;</li><li>не изменится восприятие рынка — тут нужны кейсы уровня «Сбербанк полностью перешел на Basis SDN».</li></ul><p>Сейчас Basis SDN остается нишевым продуктом для госсектора и Ростелекома.</p><h2>Кейсы и перспективы: где российские SDN уже работают и куда движутся</h2><p>В 2025 году российские SDN-решения перестали быть лабораторными проектами — они постепенно внедряются в реальную инфраструктуру. Но масштабы пока несопоставимы с зарубежными аналогами.</p><p>Разберем, где Basis SDN и другие решения уже доказали свою жизнеспособность, какие рынки могут стать для них перспективными и что мешает ускорить развитие.</p><h3>Basis SDN: первый крупный кейс — «Ростелеком-ЦОД»</h3><p>В мае 2025 года «Базис» <a href="https://www.cnews.ru/news/line/2025-05-28_bazis_predstavila_basis_sdn">завершил пилотное внедрение</a> своего SDN-решения в дата-центрах Ростелекома.</p><p>Проект показал:</p><ul><li>Сокращение времени настройки VLAN с 4 часов до 15 минут за счет централизованного управления.</li><li>Микросегментация финансовых сервисов — изоляция платежных систем снизила риски атак на 40% по данным внутреннего аудита.</li><li>Совместимость с оборудованием: 70% старых коммутаторов Cisco удалось интегрировать через шлюзы на базе KVM, хотя изначально Basis SDN разрабатывался для российского «железа» YADRO и Aquarius.</li></ul><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-06-12/d64df88f-43a2-4a51-967e-4e5f3967e1d5.png" alt="" /></figure><h2>Потенциальные рынки: где российские SDN могут закрепиться</h2><p>В июне 2025 года «Базис» анонсировал партнерство с телеком-оператором в ЮАР.</p><p>Причины интереса:</p><ul><li>Цена: $15 000 за контроллер против $30 000 у VMware NSX.</li><li>Санкционная нейтральность: в Африке нет давления на использование российского ПО, а китайские аналоги (например, ZTE SDN) проигрывают в функционале.</li></ul><p>Планируются поставки в Бразилию (интеграция с облачной платформой на базе OpenStack) и Казахстан (совместный проект с «Казтелеком»).</p><p><a href="https://www.moneytimes.ru/news/rynok-sdn-rossiya-2024/56918/#:~:text=%D0%A0%D0%BE%D1%81%D1%81%D0%B8%D0%B9%D1%81%D0%BA%D0%B8%D0%B9%20%D1%80%D1%8B%D0%BD%D0%BE%D0%BA%20SDN%20%D0%BD%D0%B5%20%D1%80%D0%B0%D1%81%D1%82%D0%B5%D1%82%2C%20%D0%BD%D0%BE%20%D0%BE%D1%82%D0%B5%D1%87%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5%20%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F%20%D0%BE%D0%B1%D0%B5%D1%89%D0%B0%D1%8E%D1%82%20%D0%B2%D0%B7%D1%80%D1%8B%D0%B2%D0%BD%D0%BE%D0%B9%20%D1%80%D0%BE%D1%81%D1%82%20%D0%BA%202031%20%D0%B3%D0%BE%D0%B4%D1%83&amp;text=%D0%A0%D0%BE%D1%81%D1%81%D0%B8%D0%B9%D1%81%D0%BA%D0%B8%D0%B9%20%D1%80%D1%8B%D0%BD%D0%BE%D0%BA%20SDN%20%D0%BD%D0%B5%20%D1%80%D0%B0%D1%81%D1%82%D0%B5%D1%82%2C%20%D0%BD%D0%BE%20%D0%BE%D1%82%D0%B5%D1%87%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5%20%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F%20%D0%BE%D0%B1%D0%B5%D1%89%D0%B0%D1%8E%D1%82%20%D0%B2%D0%B7%D1%80%D1%8B%D0%B2%D0%BD%D0%BE%D0%B9%20%D1%80%D0%BE%D1%81%D1%82%20%D0%BA%202031%20%D0%B3%D0%BE%D0%B4%D1%83&amp;text=%D0%9F%D1%80%D0%BE%D0%B3%D0%BD%D0%BE%D0%B7%D1%8B%20iKS%2DConsulting%20%D1%83%D0%BA%D0%B0%D0%B7%D1%8B%D0%B2%D0%B0%D1%8E%D1%82%20%D0%BD%D0%B0%20%D1%82%D0%BE%2C%20%D1%87%D1%82%D0%BE%20%D0%BA,%D1%8D%D1%82%D0%BE%D0%BC%20%D0%B4%D0%BE%D0%BB%D1%8F%20%D0%BE%D1%82%D0%B5%D1%87%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85%20%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D0%B9%20%D0%B4%D0%BE%D1%81%D1%82%D0%B8%D0%B3%D0%BD%D0%B5%D1%82%2044%20%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D0%BD%D1%82%D0%BE%D0%B2.">Согласно прогнозам</a>, к 2031 году объем рынка SDN в РФ вырастет в 2-3 раза, но 80% спроса будет приходиться на госсектор и госкомпании.</p><p>Малый бизнес пока остается в стороне. Проблема в том, что Basis SDN ориентирован на крупные внедрения. Для малого бизнеса нет «облегченных» версий — аналогов Cisco ACI Essentials.</p><h2>Рекомендации: как сделать российские SDN массовыми</h2><p>Российские SDN-решения доказали свою жизнеспособность, но для перехода из нишевого сегмента в массовый нужны системные изменения. Рассмотрим ключевые направления, без которых не обойтись.</p><p>Кадры — основа всего. Чтобы ускорить подготовку специалистов, нужно:</p><ul><li>ввести грантовые программы по типу «Цифровых профессий», но с фокусом на сетевые технологии;</li><li>интегрировать модули по SDN в вузовские программы — пока лишь единицы технических университетов включают их в учебные планы.</li></ul><p>Без этих шагов бизнес будет сталкиваться с той же проблемой, что и сейчас: даже купив Basis SDN, компании не смогут его эффективно использовать из-за нехватки компетенций.</p><p>Госсектор стал основным драйвером спроса на отечественные SDN, но для массового внедрения нужны меры, стимулирующие переход коммерческих компаний. Опыт Китая показывает, что субсидии на 50% затрат при миграции с VMware/Cisco резко увеличивают долю локальных решений.</p><p>Кроме того, стоит рассмотреть налоговые каникулы для стартапов в области сетевой виртуализации и заняться софинансированием пилотных проектов в среднем бизнесе — например, через Фонд развития цифровой экономики.</p><p>Одна из главных претензий к Basis SDN — слабая интеграция со сторонними платформами. Для сравнения: VMware NSX поддерживал свыше 200 приложений, а у российского аналога их на порядки меньше.</p><p>Без этого Basis SDN так и останется «закрытым» продуктом для узкого круга заказчиков. Российские SDN не станут массовыми сами по себе — нужна скоординированная работа бизнеса, образовательных учреждений и регуляторов.</p><h2>Итоги: отечественные SDN требуют долгосрочной стратегии</h2><p>Российские решения вроде Basis SDN доказали, что могут работать в реальных условиях. Но чтобы конкурировать глобально, нужно:</p><ul><li>увеличить долю рынка внутри страны — пока она менее 5%;</li><li>снизить порог входа для малого бизнеса;</li><li>выйти за пределы госзаказов — иначе продукт останется нишевым.</li></ul><p>Жизнеспособность у проекта есть. Basis SDN закрывает 80% базовых потребностей бизнеса: микросегментация, централизованное управление, совместимость с российским «железом». Но критичные функции вроде автономного восстановления сетей появятся только к 2026 году.</p><p>Аналитики предсказывают рост рынка SDN в России, но это произойдет только если появятся новые фичи: например, интеграция с ИИ для прогнозирования сетевых аномалий, снизится порог входа и вырастет число специалистов.</p><p>Что может сделать каждый:</p><ul><li><b>Тестировать.</b> «Базис» активно привлекает IT-комьюнити к доработке Basis SDN. Участие в пилотах — способ повлиять на развитие продукта.</li><li><b>Развивать open-source.</b> Проекты вроде OpenDaylight и OpenStack — основа для российских SDN. Чем больше контрибьюторов, тем быстрее сократится разрыв с зарубежными аналогами.</li><li>Требовать документирования. Одна из главных претензий к Basis SDN — скудные мануалы. Если разработчики увидят запрос от сообщества на детальные гайды, они быстрее их выпустят</li></ul><p>Главный вывод: SDN — не просто технология, а новая сетевая парадигма. Россия может занять в ней свое место, но для этого нужны не точечные успехи, а системные изменения.</p><p>Больше инфоповодов — в нашем <a href="https://t.me/+WYtyV4-XYmdhZTMy">тг-канале.</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Как сделать код-ревью, чтобы тебя не возненавидели?</title>
      <link>https://tproger.ru/articles/kak-sdelat-kod-revyu--chtoby-tebya-ne-voznenavideli-</link>
      <comments>https://tproger.ru/articles/kak-sdelat-kod-revyu--chtoby-tebya-ne-voznenavideli-?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-sdelat-kod-revyu--chtoby-tebya-ne-voznenavideli-</guid>
      <description><![CDATA[<p>Как делать код-ревью без токсичности: что говорить, как формулировать замечания и не разрушать отношения в команде. </p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-sdelat-kod-revyu--chtoby-tebya-ne-voznenavideli-">Как сделать код-ревью, чтобы тебя не возненавидели?</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Тимлид]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 16 Jun 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>«Почему ты так написал?» — если ваш комментарий в код-ревью начинается с таких слов, будьте готовы к тому, что коллеги разочаруются. Жёсткая критика без контекста, замечания о стиле вместо архитектуры и тон преподавателя, а не ментора, превращают ревью в стресс. Но можно иначе: находить реальные баги, а не придираться к неймингу; объяснять, а не указывать; замечать хорошие решения. Рассказываем, как делать код-ревью так, чтобы ваш фидбек ждали, а не проклинали.</p><h2>Почему код-ревью — не про власть, а про заботу</h2><p>Код-ревью — процесс, который помогает проекту и команде расти. И подходить к нему стоит не с позиции «сейчас найду ошибку», а с установки «сделать вместе с разработчиком лучше». На зачем он вообще нужен?</p><ul><li>чтобы заметить ошибки до продакшена, а не после;</li><li>чтобы синхронизировать стиль и подходы в команде;</li><li>чтобы разработчик не оставался наедине с кодом и сомнениями.</li></ul><p>Хорошее ревью по сути — это дополнительная пара глаз. Но часто оно воспринимается как экзамен, особенно у джунов. Почему? Комментарии звучат категорично, без объяснений, а ревью превращается в поиск опечаток, а не обсуждение архитектуры. В итоге весь процесс теряет смысл: вместо совместной работы над улучшением кода получается конфликт интересов. В таком случае оптику нужно менять.</p><h3>Что на самом деле проверяется</h3><p>В код-ревью обычно проверяется:</p><ul><li>Понятность и читаемость — сможет ли через месяц любой член команды понять, что происходит.</li><li>Надёжность — не развалится ли всё, если пойти по нестандартному сценарию.</li><li>Согласованность — насколько код вписывается в архитектуру и договорённости команды.</li><li>Перспектива — насколько удобно будет этот код поддерживать, масштабировать или переписывать через год.</li></ul><p>Задача здесь — дать взгляд со стороны, нащупать правильные вопросы, увидеть то, что автор кода мог не заметить. Но как это сделать правильно?</p><h2>Чек-лист для ревьюера: что смотреть в коде, чтобы все прошло гладко</h2><p>Хороший ревьюер не выискивает опечатки, а помогает сделать код лучше. Рассмотрим, что необходимо проверять.</p><h3>Логика: всё ли понятно и предсказуемо?</h3><p>Проверка логики — про то, чтобы прочитать код и сразу понять, зачем он написан именно так. Без нужды лезть в историю коммитов или в личные сообщения к программисту. Вот на что стоит обратить внимание:</p><h4>Код решает задачу или обходит её?</h4><p>Иногда разработчик может использовать запутанные конструкции, прибегать к костылям и лишним условиям. Здесь стоит спрашивать самого себя:</p><ul><li>«А зачем тут это условие?»</li><li>«Можно ли решить задачу проще?»</li><li>«Это бизнес-логика или побочный эффект бага?»</li></ul><h4>Всё ли предсказуемо?</h4><p>Хорошая логика — это ожидаемое поведение. Когда видишь функцию getUserRoles, и она действительно возвращает роли пользователя, а не делает лишний лог (или хуже, мутирует глобальное состояние).</p><p>Нужно проверить:</p><ul><li>Есть ли неожиданные побочные эффекты?</li><li>Не делает ли функция всё подряд?</li><li>Можно ли использовать этот код повторно?</li></ul><h4>Учитываются ли граничные случаи?</h4><p>Тестировать happy path — это приятно. Но ревью — момент, когда нужно быть немного параноиком и задавать себе вопросы:</p><ul><li>«А что, если в массиве будет null?»</li><li>«Что вернётся, если база пустая?»</li><li>«Что произойдёт, если API не ответит?»</li></ul><p>Если логика ломается при первой же нестандартной ситуации — это нерабочая логика.</p><h4>Видна ли связь между частями?</h4><p>Чем сложнее фича, тем важнее понимать, как всё взаимодействует. Хороший код складывается в историю: ты читаешь файл, и у тебя в голове выстраивается картинка. Если же приходится постоянно прыгать между файлами и держать всё в голове — это тревожный сигнал.</p><h3>Архитектура: насколько код ложится в общую картину?</h3><p>Ревью — про то, как новая часть кода вписывается в уже существующую систему. Даже идеально написанное решение может быть неуместно, если оно идёт вразрез с архитектурой проекта. На что обращать внимание:</p><h4>Живёт ли код в вакууме</h4><p>Каждый новый модуль, компонент или класс должен:</p><ul><li>быть в нужном слое архитектуры (не пишем, например, SQL-запросы в React-компоненте),</li><li>располагаться там, где его логически ожидаешь (не прячем бизнес-логику в утилитах),</li><li>использовать существующие механизмы, а не дублировать их.</li></ul><h4>Следует ли код соглашениям команды</h4><p>Хорошая архитектура держится на дисциплине. Если вы договорились, что у каждого эндпоинта есть слой сервисов — не нужно вызывать репозиторий напрямую из контроллера. Иначе проект превращается в сборную солянку: один разработчик пишет по паттернам, другой — по наитию.</p><p>Нужно проверить:</p><ul><li>используются ли принятые в команде подходы;</li><li>поддерживаются ли слои;</li><li>повторяет ли структура проекта предыдущие решения.</li></ul><h3>Безопасность: нет ли уязвимосей?</h3><p>Код должен не только работать корректно, но и быть защищённым. Даже в небольших задачах могут скрываться уязвимости — особенно там, где данные приходят извне или есть доступ к чувствительной информации. На что обращать внимание:</p><h4>Пользовательский ввод</h4><p>Всё, что приходит от пользователя (формы, параметры URL, тело запроса), требует внимания. Здесь могут возникнуть SQL-инъекции, XSS и т.д. Поэтому стоит проверить:</p><ul><li>Есть ли валидация данных на стороне сервера?</li><li>Используются ли подготовленные запросы или ORM?</li><li>Обрабатываются ли потенциально опасные символы?</li><li>Предусмотрена ли защита от исполнения произвольного кода?</li></ul><h4>Доступ к данным и авторизация</h4><p>Если код взаимодействует с базой, файлами или персональными данными, важно удостовериться, что доступ предоставляется только тем, кому он положен. Проверяем:</p><ul><li>Есть ли проверка прав пользователя перед выполнением запроса?</li><li>Реализована ли проверка не только на фронте, но и на сервере?</li><li>Используются ли идентификаторы, которые нельзя легко перебрать?</li></ul><h3>Тесты: можно ли быть уверенным, что всё работает?</h3><p>Хороший тест — реальная гарантия, что при следующем изменении код не сломается. Здесь важно понять, действительно ли тесты покрывают важные сценарии и защищают от регрессий:</p><h4>Есть ли вообще тесты?</h4><p>Начнём с очевидного. Прежде чем обсуждать качество, стоит выяснить: тесты вообще написаны? Если в задаче меняется логика или добавляется новая функциональность — это почти всегда повод что-то протестировать.</p><p>Проверяем:</p><ul><li>Есть ли новые юнит- или интеграционные тесты?</li><li>Актуальны ли существующие — не остались ли висящими после изменений?</li><li>Упали ли какие-нибудь тесты в CI — и если да, то почему?</li></ul><h4>Тестируется ли то, что нужно?</h4><p>Иногда тесты есть, но проверяют слишком очевидное или не покрывают рисковые места. На что обратить внимание:</p><ul><li>Проверяются ли граничные случаи (например, пустой ввод, null, некорректные данные)?</li><li>Есть ли тесты на негативные сценарии — когда функция должна вернуть ошибку?</li><li>Покрыта ли новая логика?</li></ul><h4>Понятны ли сами тесты?</h4><p>Тесты тоже часть кода, и их читают люди. Если логика проверок неочевидна, тесты будут мешать. При ревью задаем вопросы:</p><ul><li>Говорят ли названия тестов, что именно они проверяют?</li><li>Можно ли по коду теста быстро понять, зачем он нужен?</li><li>Нет ли странных чисел или непонятных моков?</li></ul><p>Так, хороший код-ревьюер фокусируется на смысловых точках риска. Но как указывать на эти точки? Рассмотрим стратегии взаимодейтсвия с разработчиком во время код-ревью (чтобы последний не возненавидел любую возможность писать код и самого ревьюера).</p><h2>Как давать комментарии и не звучать резко</h2><p>Хорошее ревью — это про диалог, в котором оба участника заинтересованы в улучшении кода. Чтобы комментарии воспринимались конструктивно, а не как придирки, важно держать тон и структуру. Разберем четыре простых ориентира.</p><h3>Начните с положительного: что в этом коде уже хорошо</h3><p>Хорошее ревью начинается с признания сильных сторон. Это легальный способ показать, что вы оцениваете работу комплексно. Когда автор видит, что вы заметили не только недочеты, но и удачные решения, он/она с большей вероятностью воспримет все конструктивно.</p><p>К тому же, положительные комментарии помогают закрепить результат: человек будет знать, что именно сработало — и использовать это снова.</p><p>Что можно хвалить:</p><ul><li>чистую и понятную структуру;</li><li>удачные названия переменных или функций;</li><li>хорошую обработку исключений или пограничных случаев;</li><li>то, что код хорошо ложится в текущую архитектуру.</li></ul><p>Примеры фраз:</p><ul><li>«Здорово, что ты вынес логику в отдельный хелпер — теперь это читается в разы легче».</li><li>«Классная идея использовать (вставьте код),а не (вставьте код)— так гораздо понятнее».</li><li>«Круто, что добавил тест на этот кейс — про него часто забывают».</li></ul><h3>Замечания: только по делу и с предложением, как исправить</h3><p>Чтобы код-ревью было конструктивным, нужно не просто указывать на проблему, а помогать найти решение. Комментарии без объяснения или контекста могут звучать как придирки, особенно если ревью получает менее опытный разработчик. А вот если вы объясняете, почему что-то не так, и что можно сделать по-другому — это уже наставничество, а не критика.</p><p>Так НЕ надо:</p><ul><li>«Плохо читается».</li><li>«Переделай»</li><li>«Зачем???»</li></ul><p>Так лучше:</p><ul><li>«Можно упростить, если разделить условие на два блока — сейчас выглядит довольно сложно».</li><li>«Тут, кажется, можно обойтись без цикла: достаточно метода (вставьте метод)— он короче и лучше читается»..</li><li>«В этом месте можно потенциально получить undefined. Может, стоит добавить проверку?»</li></ul><h3>Говорите прямо, без намёков и иронии</h3><p>Код-ревью — не место для недосказанностей и полутонов. Комментарии вроде «Ну, если так РЕАЛЬНО работает — ок» звучат пассивно-агрессивно и только создают напряжение. Получивший такое замечание будет гадать: это одобрение, сарказм или тонкий намёк, что я всё сделал не так?</p><p>Вместо этого — формулируйте замечания ясно и по существу:</p><ul><li>«В этом месте поведение функции может быть неочевидным — можешь уточнить название или добавить комментарий?»</li><li>«Пока непонятно, почему именно такое условие — можешь пояснить, пожалуйста?»</li><li>«Похоже, тут можно упростить: если заменить на (вставьте код) логика станет короче».</li></ul><p>Если вы не уверены, как ваша реплика будет воспринята — переформулируйте. В ревью лучше не пошутить, чем задеть человека, особенно если вы не на 100% уверены в уровне вашей взаимной иронии.</p><h3>Делайте фокус на код, а не на человека</h3><p>Хорошее ревью — это не про то, чтобы указать, что человек сделал плохо, скорее про то, что в этом месте можно улучшить. Разница тонкая, но критически важная. Комментарии не должны звучать как обвинения, даже если баг очевидный.</p><p>Так НЕ надо:</p><ul><li>«Ты опять забыл обработать ошибку».</li><li>«Почему ты так сделал?!»</li><li>«Это неправильно».</li></ul><p>Лучше так:</p><ul><li>«Похоже, здесь не хватает обработки ошибки — может быть сбой».</li><li>«Можешь, пожалуйста, уточнить логику? Кажется, тут может возникнуть исключение».</li><li>«Вот так решение будет стабильнее: предлагаю…»</li></ul><p>Когда мы говорим о коде, а не о человеке, снижается напряжение. Человек не чувствует, что его «проверяют», он чувствует, что с ним вместе улучшают результат.</p><h2>Как сделать код-ревью полезным и для себя</h2><p>Код-ревью часто воспринимается как обязанность: проверил pull request, поставил галочку, пошел дальше. Но на самом деле это отличная возможность прокачиваться не только тому, чью работу вы смотрите, но и вам самим. Даже если задача кажется простой, внимательно просмотрев чужой код, можно узнать что-то новое и лучше понять архитектуру проекта. Рассмотрим, как превратить свой ревьюерский труд в пользу.</p><h3>Учитесь новому: чужой код — тоже учебник</h3><p>Читая чужие решения, можно заметить многое: библиотеку или инструмент, который вы раньше не использовали; необычную структуру функции или способ организации логики; паттерн, который вы обычно не применяете, но он к месту и т.д. Это особенно полезно, если вы работаете в мультистековой команде. Кто-то пишет на Python, вы — на C++, но идеи и архитектурные подходы легко переносятся между языками. Подмечайте, как другие подходят к задачам, даже если в целом всё вам понятно — детали часто дают самые интересные инсайты.</p><p>Заведите привычку задаваться вопросом: «Что здесь сделано хорошо и почему я сам так не пишу?». Или наоборот — «Почему мне этот кусок кажется странным и как бы я сделал иначе?». Такие наблюдения дают гораздо больше, чем кажется на первый взгляд.</p><h3>Задавайте вопросы, даже если всё понятно</h3><p>Иногда вы смотрите код — и вроде всё чисто, логично. Но это как раз повод не просто молча одобрить, а пообщаться с проггером. Почему? Потому что вопросы — не всегда сигнал о проблеме: иногда это инструмент обучения.</p><p>Например:</p><ul><li>«А почему решили использовать именно этот метод?»</li><li>«Это кастомное решение или такой подход у нас принят в проекте?»</li><li>«Я раньше делал по-другому — есть ли причины, почему здесь выбрали такой путь?»</li></ul><p>Такие вопросы помогают вам лучше понять чужой ход мыслей; показывают автору, что вы включены в процесс, а не просто пробежались глазами; создают пространство для обсуждения и обмена опытом.</p><p>Важно: вопросы должны звучать как приглашение к диалогу, а не как скрытая критика. Если вы спрашиваете «Зачем это вообще нужно?», лучше замените на «Помоги разобраться, почему выбрали такой подход — интересно сравнить с тем, как делал раньше».</p><h3>Прокачивайте навык объяснять</h3><p>Хороший разработчик умеет не только писать код, но и объяснять, почему он написал именно так. Код-ревью — отличная тренировка этого навыка.</p><p>Когда вы оставляете комментарий — попробуйте объяснить, в чём именно суть проблемы и почему стоит внести изменения. Это заставит вас сформулировать мысль чётко, логично и по делу — а это критически важный навык для тимлида, ментора и любого разработчика, который находится в команде.</p><p>Например, вместо «Это плохой способ», напишите: «Такой подход может усложнить отладку, потому что данные не логируются. Предлагаю использовать вот такой паттерн (укажите паттерн), он делает поведение функции более прозрачным».</p><p>Почему это работает:</p><ul><li>вы тренируете навык аргументации — полезно и в коммуникации, и на технических собеседованиях;</li><li>автор кода быстрее понимает, что именно стоит изменить, и почему;</li><li>вы сами начинаете глубже понимать, почему какой-то код не совсем правильно написан.</li></ul><p>И ещё один плюс: если ваш комментарий требует объяснения — это повод задуматься, действительно ли замечание по делу. Иногда, пока формулируешь аргументы, понимаешь, что лучше промолчать. И это тоже рост.</p><p>Код-ревью — не ритуал и не повод самоутверждаться. Это способ сделать код лучше, команду сильнее, а продукт стабильнее. Хорошее ревью помогает не только найти баги, но и передать знания, улучшать архитектуру, учиться объяснять мысли и замечать собственные пробелы.</p>]]></content:encoded>
    </item>
    <item>
      <title>Ethereum растёт: что это значит для разработчиков DeFi</title>
      <link>https://tproger.ru/articles/ethereum-rastyot--chto-eto-znachit-dlya-razrabotchikov-defi</link>
      <comments>https://tproger.ru/articles/ethereum-rastyot--chto-eto-znachit-dlya-razrabotchikov-defi?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Григорий Тюрамович]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/ethereum-rastyot--chto-eto-znachit-dlya-razrabotchikov-defi</guid>
      <description><![CDATA[<p>Ethereum снова в плюсе, и это не просто цифры — это новые возможности для разработчиков. Обсуждаем, как меняется DeFi, какие инструменты использовать и что важно учитывать при создании Web3-продуктов.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/ethereum-rastyot--chto-eto-znachit-dlya-razrabotchikov-defi">Ethereum растёт: что это значит для разработчиков DeFi</a>»</p>]]></description>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Блокчейн]]></category>
      <category><![CDATA[Ethereum]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 12 Jun 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Ethereum снова растёт. На момент написания — выше 2700 долларов, и это уже не просто случайный всплеск. На фоне вялого рынка в начале года — выглядит бодро. Причин несколько: крупные игроки вроде BlackRock закупаются, DeFi снова оживился, а обновления сети наконец-то приносят плоды. Но главное — это влияет на нас, разработчиков.</p><p>Если ты когда-нибудь писал что-то под Web3 или просто интересовался, как всё это устроено, сейчас хороший момент снова посмотреть в сторону Ethereum. Дальше по пунктам — что именно стоит иметь в виду.</p><h2>Сеть стала быстрее и дешевле — это уже не шутки</h2><p>Ethereum 2.0 наконец начал работать не просто на бумаге. Транзакции идут быстрее, комиссии стабильнее, нагрузка меньше. Для нас это значит, что можно не закладывать в архитектуру кучу костылей, чтобы обойти медленный отклик или запредельные цены за газ.</p><p>Если раньше ты откладывал идею своего DeFi-продукта на потом — сейчас это самое потом.</p><h2>Больше денег — больше пользователей — больше запросов</h2><p>Когда эфир растёт, люди начинают активнее пользоваться протоколами. Кто-то хочет купить криптовалюту, кто-то — протестить очередной пул, а кто-то просто поиграться с токенами. В любом случае — у тебя на фронте или в бекенде прибавляется трафик.</p><p>И тут важно понимать, как себя поведёт твой код под нагрузкой. Если юзер решит купить Ethereum через твоё приложение, а у тебя всё повиснет — это минус карма и минус юзер.</p><h2>Работать с данными стало важнее, чем когда-либо</h2><p>Показывать актуальный курс, считать доходность, подсказывать пользователю, где выгоднее обменять — это уже не дополнительная фича, а базовая вещь.</p><p>Я для себя давно решил: проще пользоваться агрегаторами, чем пилить миллион обвязок под каждую биржу. Например, <a href="https://exnode.ru/?utm_source=tproger&amp;utm_medium=29.05.2025(g)">Exnode</a> хорошо помогает — глянул в пару кликов, где норм курс, и встроил это в продукт. Не как основа логики, а как ориентир. Удобно и не надо городить огород.</p><h2>DeFi снова жив, и это видно</h2><p>Новые протоколы запускаются почти каждый день. Layer2-сети дышат полной грудью. zkSync, Arbitrum, Base — инструменты уже не просто экспериментальные, с ними можно работать без ощущения, что ты тратишь время впустую.</p><p>Если ты давно хотел сделать что-то на стыке frontend + блокчейн — сейчас тот момент, когда это будет востребовано. Вполне возможно, кто-то через твоё приложение завтра будет покупать криптовалюту, не выходя из Telegram-бота.</p><h2>Вместо вывода</h2><p>Ethereum растёт. Это хороший знак — не только потому, что цифра в CoinMarketCap красивая, а потому что это оживляет экосистему. А значит, оживляет и спрос на наши с тобой скиллы.</p><p>Если давно хотел попробовать себя в Web3 — сейчас, кажется, пора. Даже если начнёшь с чего-то простого: калькулятора доходности, обменника или трекера портфеля — это уже будет полезно.</p><p>Инструменты стали лучше, данные — доступнее, и пользователи опять интересуются. Дальше — дело за нами.</p>]]></content:encoded>
    </item>
    <item>
      <title>React и RTK Query — новый лёгкий путь для redux?</title>
      <link>https://tproger.ru/articles/react-i-rtk-query-novyj-lyogkij-put-dlya-redux-</link>
      <comments>https://tproger.ru/articles/react-i-rtk-query-novyj-lyogkij-put-dlya-redux-?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Alex Shulgin]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/react-i-rtk-query-novyj-lyogkij-put-dlya-redux-</guid>
      <description><![CDATA[<p>Разбираемся, как упростить запросы в react-redux с помощью redux toolkit. Пишем облегченные запросы с RTK query. Подойдет ли для всего?</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/react-i-rtk-query-novyj-lyogkij-put-dlya-redux-">React и RTK Query — новый лёгкий путь для redux?</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Redux]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sat, 12 Apr 2025 09:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Прежде всего, давайте вспомним, как выглядит классический запрос и хранение данные с redux-saga и @reduxjs/toolkit.</p><p>Так выглядит стандартный шаблон запроса с манипулированием статусов и показом данных. Универсально, как швейцарский нож, и может быть полностью кастомизировано. На таком шаблоне мы вправе выполнять запросы любой сложности и контролировать все детали.</p><p>Но что если запросы такие же легкие как в примере выше? Мы просто берем данные и показываем их. Разве нам нужно каждый раз проделывать такую рутину, если можно облегчить себе жизнь?</p><p>Как раз для таких случаев есть инструмент <a href="https://redux-toolkit.js.org/rtk-query/overview">rtk-query</a> (входит в reduxjs/toolkit). Посмотрим как теперь выглядит наш запрос.</p><p>В build.query мы передаем два аргумента, 1 — тип, который вернется и 2 — параметры, которые мы принимаем в хуке в компоненте.</p><p>Далее в компоненте мы вызываем хук и передаем данные для вызова апи и вторым аргументом, параметры для самого хука. Например, свойство refetchOnMountOrArgChange перезапросит данные при unmount компоненте. В документации можно подробнее прочитать о каждом из них.</p><p>Самое главное, что в ответе хука  у нас появляются все статусы/данные/фичи. Каждый из них может быть полезен для конкретной ситуации, но все вместе они покрывает почти все кейсы.</p><p>Теперь компонент выглядит легко и изящно. Тут мы используем isFetching (отличие от isLoading в том, что он активируется при любой загрузке, а isLoading только при начальной). Можно вызывать refetch для перезапроса или проверить isError при ошибке.</p><p>Также мы можем вызывать хук с задержкой. Так называемый lazy query.</p><p>Тут мы делаем запрос из хука. Обычно это нужно, если хотим передать аргумент в хук, который появляется не сразу. Также проверяем isUninitialized, чтоб хук был проинициализирован и далее при загрузке стал false.</p><p>Плюс к этому, rtk дает возможность использовать мутации для обновления данных. Это будет выглядеть примерно так:</p><h2>Для чего не подходит rtk?</h2><p>Для сложных операций, таких как пагинация или хранение переменных между запросами. В подобных кейсах лучше использовать саги и не ставить костыли с ртк. Ведь его главная цель избавить нас от рутинных запросов.</p>]]></content:encoded>
    </item>
    <item>
      <title>Часть 1: Почему стандартное логирование может тормозить .NET-приложения</title>
      <link>https://tproger.ru/articles/pochemu-standartnoe-logirovanie-mozhet-tormozit--net-prilozheniya</link>
      <comments>https://tproger.ru/articles/pochemu-standartnoe-logirovanie-mozhet-tormozit--net-prilozheniya?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Александр Береговой]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/pochemu-standartnoe-logirovanie-mozhet-tormozit--net-prilozheniya</guid>
      <description><![CDATA[<p>Узнайте, как стандартное логирование в .NET может замедлять работу приложения. Разбираем основные проблемы, связанные с записью логов, и их влияние на производительность.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/pochemu-standartnoe-logirovanie-mozhet-tormozit--net-prilozheniya">Часть 1: Почему стандартное логирование может тормозить .NET-приложения</a>»</p>]]></description>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[.NET]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Microsoft]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 11 Feb 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Логирование — один из ключевых инструментов для мониторинга и отладки .NET-приложений. Однако стандартные подходы к сбору и хранению логов могут незаметно снижать производительность системы. Избыточные записи в логах, блокирующие операции ввода-вывода, и неоптимальная работа с хранилищем данных — всё это может привести к задержкам и росту потребления ресурсов. В первой части нашей статьи разберём, какие проблемы могут возникнуть при стандартном логировании в .NET и почему бездумное использование логов способно замедлить работу приложения.</p><h2>Зачем нужно логирование</h2><p>Когда приложение уже в проде, а в нем что-то сломалось, подключиться отладчиком и просто пройтись по коду, чтобы разобраться в ошибке, не выйдет. В этом случае на помощь может прийти логирование — запись событий в журнал. Таким журналом могут быть:</p><ul><li>консоль,</li><li>обычный текстовый файл,</li><li>системный журнал операционной системы,</li><li>реляционная база данных,</li><li>специализированные средства, такие как Elastic.</li></ul><p>В .NET есть встроенная поддержка логирования, доступная в пространстве имен Microsoft.Extensions.Logging. О том, как инициализировать логирование, можно почитать в <a href="https://learn.microsoft.com/en-us/dotnet/core/extensions/logging?tabs=command-line">документации</a>. Скажем лишь, что в результате мы можем получить экземпляр ILogger —  он предоставляет расширения, которые позволяют записывать события с различным уровнем серьезности (severity). Severity — атрибут, который определяет, насколько сильно дефект может повлиять на работу.</p><p>В высоконагруженных приложениях логирование может давать ощутимую нагрузку — как вычислительную, так и в части потребления памяти. Это происходит по следующим причинам:</p><ul><li>Методы расширения ILogger выполняют упаковку (boxing) значимых типов для преобразования их в object. Это верно для bool, int и др.;</li><li>Методы расширения ILogger выполняют разбор (parsing) шаблона сообщения каждый раз, когда вызывается соответствующий метод расширения.</li></ul><h3>Как работает высокопроизводительное логирование</h3><p>Microsoft предлагает другой механизм записи сообщений в журнал — с помощью LoggerMessage. Этот класс позволяет избежать следующих проблем:</p><ul><li><b>Проблема упаковки</b> (boxing). Решается за счет перегруженных методов с обобщенными параметрами.</li><li><b>Проблема разбора шаблона сообщения.</b> Решается так: разбор производится один раз в момент объявления специфического метода для записи сообщения.</li></ul><p>Ниже покажем, как использовать LoggerMessage в приложении, и сравним его производительность с методами расширения ILogger из LoggerExtensions и типизированными методами из LoggerMessageExtensions.</p><p>Для начала создадим новый проект типа Console Application. Будем использовать фреймворк .Net9.</p><p>После создания проекта нам нужно подключить следующие nuget-пакеты:</p><p>Далее инстанцируем в приложении экземпляр ILogger:</p><p>При использовании LoggerMessage для каждого типа события нам нужно создать отдельный метод логирования. Для начала — написать статический класс, который будет выступать хранилищем (реестром сообщений). Добавим LoggerExtensions:</p><p>Добавим метод для логирования старта приложения, сохраняя имя хоста. Метод должен соответствовать следующему делегату:</p><p>Где:</p><ul><li>T1..T6 —  обобщенные типы параметров, которые мы можем передать во время записи сообщения в журнал;</li><li>logLevel — уровень логирования (степень серьезности) события;</li><li>eventid — уникальный идентификатор события;</li><li>formatString — шаблон сообщения.</li></ul><p>В классе LoggerExtensions для каждого лог-сообщения объявляем Action-делегат в приватном статическом поле. Экземпляр этого делегата инициализируем через LoggerMessage.Define в конструкторе — для его вызова нужно определить public-метод. Код для метода LogApplicationStart:</p><h2>Как работает LoggerMessage.Define T</h2><p>Давайте разберемся немного глубже и посмотрим, что же делает метод Define. Код метода для одного обобщенного параметра приведен ниже:</p><p>В первой строке метод CreateLogValuesFormatter разбирает шаблон сообщения и проверяет соответствие количества плейсхолдеров числу обобщённых параметров Define. Если не совпадает — возбуждается исключение.</p><p>Локальная функция Log вызывает ILogger.Log и записывает сообщение в журнал.</p><p>Ниже идет проверка флага SkipEnabledCheck:</p><ul><li>Если true, сообщение записывается без учёта объявленного уровня логирования.</li><li>Если false (или options не предоставлен), сначала проверяется уровень логирования. Если наше событие объявлено с уровнем, подлежащим записи, то будет произведен вызов функции Log.</li></ul><p>Выводы:</p><ol><li>Результат метода, делегат Action, мы сохраняем в приватном статическом поле. То есть Define выполнится лишь один раз за время жизни приложения. То же самое и с разбором шаблона каждого сообщения.</li><li>Делегат проверяет уровень логирования, исключая ненужные вызовы ILogger.Log — это повышает производительность.</li><li>Наличие параметров Define и делегатов Action позволяет избежать упаковки значимых типов — это снижает нагрузку на память и процессор.</li></ol><p>Добавим вызов этого метода в наше приложение:</p><p>Если запустить, то в консоли мы увидим такой вывод:</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-01-30/fdfdb0e8-6e51-4f4d-b721-c3549e2ce59b.png" alt="" /></figure><p>Добавим сообщение, которые говорит об окончании работы приложения. В качестве параметра выводим в лог время выполнения. Вот основные изменения в LoggerExtensions:</p><p>Выше добавили еще одно приватное поле, public-метод и код инициализации делегата.</p><p>Вот обновленный код приложения:</p><p>Вывод будет такой:</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-01-30/09e9b56e-d2bf-4730-bd92-94a0cbb78b59.png" alt="" /></figure><p>Резюмируем, что нужно сделать с LoggerMessage для каждого события:</p><ul><li>Добавить в статический класс приватное поле для сохранения ссылки на делегат.</li><li>Определить публичный метод расширения.</li><li>Добавить инициализацию делегата в конструктор статического класса.</li></ul><p>Это кажется сложнее, чем обычные методы ILogger. К счастью, есть LoggerMessageAttribute, который позволяет уменьшить объем работы.</p><h2>Как упростить переход на высокопроизводительное логирование в .NET</h2><p>С LoggerMessageAttribute, для объявления метода расширения, нужно сделать следующее:</p><ul><li>Пометить класс с методами расширения директивой partial — объявить класс частичным;</li><li>Объявить публичный метод расширения — тоже частичный;</li><li>Декорировать этот метод атрибутом LoggerMessageAttribute.</li></ul><p>Это приведет к тому, что во время компиляции сработает механизм перехватчика, который сгенерирует весь необходимый код за нас. Вот обновленный код класса LoggerExtensions:</p><p>До момента компиляции Visual Studio будет показывать, что в коде есть ошибки — нужно дописать тела объявленных методов. Не пугайтесь: просто выполните сборку проекта и ошибки уйдут.</p><p>Что же делает этот атрибут? Давайте посмотрим на сгенерированный код:</p><p>Для каждого частичного метода будет сгенерировано:</p><ul><li>Приватное поле для хранения ссылки на делегат. Имя поля начинается с двойного символа underscore(_), в этом случае  называется __LogApplicationFinishCallback,</li><li>Код инициализации делегата,</li><li>Тело метода расширения.</li></ul><p>Метод проверяет уровень логирования: если событие уровня Debug, а минимальный уровень — Information, делегат не вызывается. Это улучшает производительность. А LoggerMessageAttribute упрощает создание методов расширения, снижая трудозатраты.</p><p><a href="https://tproger.ru/articles/kak-optimizirovat-logirovanie-v--net--sovety-i-primery">В следующей статье</a> мы сравним производительность стандартного логирования и LoggerMessage на реальных примерах, а также покажем, как легко оптимизировать код с помощью AutoLoggerMessage. Не переключайтесь!</p><p>А если хотите больше узнать про .NET, сразу переходите в наш <a href="https://t.me/+L9Wi95tNHhs1MTIy">Telegram канал</a>, это точно ускорит время ожидания!</p>]]></content:encoded>
    </item>
    <item>
      <title>Что такое децентрализованные финансы и как они работают</title>
      <link>https://tproger.ru/articles/chto-takoe-decentralizovannye-finansy-i-kak-oni-rabotayut</link>
      <comments>https://tproger.ru/articles/chto-takoe-decentralizovannye-finansy-i-kak-oni-rabotayut?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Анна Ельцова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/chto-takoe-decentralizovannye-finansy-i-kak-oni-rabotayut</guid>
      <description><![CDATA[<p>Децентрализованные финансы (DeFi) — специальные сервисы, основанные на смарт-контрактах и блокчейне. Разбираемся, что они из себя представляют и зачем нужны.
</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/chto-takoe-decentralizovannye-finansy-i-kak-oni-rabotayut">Что такое децентрализованные финансы и как они работают</a>»</p>]]></description>
      <category><![CDATA[Ethereum]]></category>
      <category><![CDATA[Криптовалюты]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 11 Jul 2024 08:30:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>В 2024 году объем рынка DeFi <a href="https://www.statista.com/outlook/fmo/digital-assets/defi/worldwide">достигнет</a> $26 млн, а к 2028 вырастет до $37 млн. Тогда же, по прогнозам, DeFi-продуктами будут пользоваться более 22 млн человек по всему миру. Такая популярность децентрализованных финансов — еще одна ступень на пути к повсеместному использованию криптовалюты, учитывая все разговоры о цифровых рублях и других валютах.</p><p>DeFi — это целая экосистема, которая упрощает банкинг, инвестирование, кредитование и другие финансовые операции. И для этого достаточно просто скачать приложение. Ниже разбираемся, как это работает и зачем это нужно.</p><h2>Что такое DeFi</h2><p>DeFi (Decentralized Finance) — это набор финансовых приложений и услуг, которые построены на блокчейнах, преимущественно на Ethereum. Эти приложения включают в себя всё от кредитования и займов до торговли и страхования.</p><p>Основная идея заключается в создании открытой, прозрачной и доступной финансовой системы. При этом не нужно обращаться в банки — сохраняется полная анонимность пользователя.</p><p>Представьте, что вам нужно занять деньги. В традиционной системе вы бы пошли в банк, заполнили кучу документов, прошли проверку кредитной истории, и если банк одобрит ваш запрос, вы получите займ. В децентрализованных финансах (DeFi) все происходит иначе:</p><ol><li>Вы заходите на DeFi-платформу и вместо проверки кредитной истории вы размещаете свои криптовалюты в качестве залога (например, Ethereum или Bitcoin).</li><li>На основе залога вы получаете займ в другой криптовалюте или стабильной монете (например, DAI или USDC).</li></ol><p>Стоимость операций в протоколах DeFi определяют пользователи: чем больше спрос на нужную криптовалюту, тем выше комиссия — с неё продавцы и получают доход. Однако юзеры могут сами занижать процент в отличие от традиционного банкинга, где он устанавливается свыше на все транзакции.</p><h2>Технологии внутри DeFi</h2><p>DeFi завязана на peer-to-peer операциях — все транзакции происходят без посредников (банков) между пользователями на открытом рынке. Децентрализованные финансы используют модель p2p-обмена, но с помощью приложений и смарт-контрактов на блокчейне.</p><h3>Блокчейн</h3><p>Блокчейн (или, если вас очень просят переводить термины на русский язык, «цеповяз») — это распределенная и защищённая база данных. В блокчейне транзакции записываются в блоки и проверяются с помощью автоматизированных процессов. Если транзакция подтверждена, блок шифруется, затем создается другой блок с информацией о предыдущем и новых транзакциях.</p><p>Изменить, кстати, блокчейн невозможно — тогда полетит вся система. В общем, безопасность с большой буквы.</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2024-07-09/7719ed51-00a8-47e2-8d44-374970ff8ca6.png" alt="" /></figure><p>Эта технология позволяет пользователям хранить персональные ключи к виртуальным токенам или крипте, которые работают как пароли. Собственность на токены передаётся другому юзеру через кошелек с таким же закрытым ключом, и за счет блокчейна обратная передача невозможна.</p><p>В DeFi блокчейн нужен, чтобы пользователи могли совершать транзакции, брать займы и торговать на бирже без какого-либо контроля со стороны финансовых институтов. Технология записывает все транзакции и данные смарт-контрактов по сети. И решающую роль здесь играют Etherium и Solana, способные поддерживать смарт-контракты.</p><h3>Смарт-контракты</h3><p>Это база DeFi. Смарт-контракты — аналог обычных контрактов, только цифровых и автоматизированных. Именно они обеспечивают прозрачные транзакции без посредников. Разработчики пишут и развёртывают их на блокчейне, поддерживающем умные-контракты — как мы уже выяснили, это Etherium, Solana и ещё Polka dot. По сути, это как 1С, только круче: с помощью смарт-контрактов можно запланировать ежемесячные платежи или даже запустить свою биржу.</p><p>Вообще, в разработке смарт-контрактов стоит отдать должное девелоперам Etherium. Сначала технология работала по принципу Proof-of-Work (как Биткоин), а потом, чтобы Эфир мог оперативнее обрабатывать огромное количество транзакций, создатели перевели её на Proof-of-Stake. Благодаря этому мы имеем DeFi в современном виде.</p><h3>Децентрализованные приложения (dApps)</h3><p>Их можно скачать на компьютер или телефон и получать финуслуги из любой точки мира (без пятидневного ожидания от европейского банка). Приложения построены на базовом блокчейне — внутри можно брать кредиты, торговать на бирже, дарить подарки и совершать покупки без участия третьих лиц. Только вы, приложение и man in finance (6’5, blue eyes), который успел купить крипту десять лет назад.</p><p>Например, если вам нужен кредит, вы выходите на p2p-рынок и ищете продавца с более выгодными условиями и процентами — он одолжит вам определённое количество криптовалюты.</p><p>Вот несколько таких платформ:</p><ul><li>CriptoKitties</li><li>Uniswap</li><li>Aave</li><li>Alchemix</li><li>Yearn</li><li>MakerDAO</li><li>ENS</li></ul><p>Большинство из них построены на Etherium. Цены меняются в зависимости от спроса и предложения. Но помните: нужно оставаться аккуратными с p2p-кредитованием на DeFi-платформах, торговлей на криптобиржах и в целом с покупкой/продажей криптовалюты — это инвестиционный риск (про Патрики знаем, плавали).</p><h2>Немного подробнее: где используется DeFi</h2><p>Изначально это была история про кредитование и обмен, но сейчас с развитием индустрии количество направлений DeFi увеличилось. Вот некоторые из них:</p><ul><li><b>Провайдеры ликвидности. </b>Ликвидность — это возможность быстро продавать активы. Провайдеры ликвидности, как правило, представляют собой пулы, в которых пользователи размещают средства, чтобы биржи могли предоставлять своим пользователям возможности для продажи.</li><li><b>Децентрализованное страхование.</b> Да, в какой-то момент разработчики поняли, что в смарт-контрактах могут быть ошибки, а криптокошелёк и вовсе могут украсть. Тогда придумали децентрализованное страхование: пользователи дают ликвидность на покрытие ущерба, и получают с этого процент.</li><li><b>NFT.</b> Да, рынок немного «подуспокоился», но энтузиастов, которые коллекционируют обезьян, всё ещё много.</li><li><b>Рынки прогнозов.</b> Можно делать ставки на исход любого события. История рискованная, поэтому всегда делайте ставку на себя.</li><li><b>Стейблкоины.</b> Если переводить на русский — стабильные монеты. Это валюты с фиксированной ценой — она обеспечивается фиатной и децентрализованной криптой (знакомые нам ETH и BTC).</li></ul><h2>Подводные камни есть</h2><p>Несмотря на быстрое развитие DeFi-индустрии и все преимущества — анонимность, круглосуточный и легкий доступ к активам и займам и обход банков — система не выглядит идеальной. Вот несколько возможных проблем:</p><ul><li><b>Хакеры «хакерствуют», закон пока не «законится».</b> Помним, что любая система уязвима (как говорили в фильме «Кто я»). И DeFi-платформы являются одними из самых взламываемых в мире криптовалюты. Кроме того, сфера до сих пор полностью не регулируется с правовой точки зрения (хотя инициативы со стороны американского правительства <a href="https://www.rbc.ru/crypto/news/65c3477a9a79477180bd4a80">есть</a>), поэтому вопросы с расследованиями и скандалами остаются открытыми. Это в определённой степени нормально, учитывая, насколько быстро растет сфера.</li><li><b>Смарт-контракты могут рухнуть.</b> Несмотря на то что они обеспечивают прозрачность и безопасность, они написаны не на бумаге, а в компьютере, и не ручкой, а кодом. А любой код может дать сбой в какой-то момент, что может привести к потере средств.</li><li><b>Могут подняться комиссии.</b> Если валюта нестабильна, пользователям придётся платить больший процент, чтобы быстро закрыть все транзакции — это может привести к резкому увеличению комиссий.</li><li><b>Непостоянные убытки.</b> Они связаны с обеспечением ликвидности в протоколах автоматизированных маркетмейкеров. Когда вы предоставляете ликвидность пулу на этих платформах, вы вносите вклад в оба криптоактива (обычно в соотношении 50/50), чтобы облегчить торговлю, а взамен зарабатываете на комиссии: получаете долю комиссионных за торговлю криптовалютой, генерируемых протоколом. Непостоянные убытки возникают, когда цены на два токена в пуле ликвидности значительно расходятся с течением времени.</li><li><b>Rug Pull.</b> Или «подтасовка». Это тип мошенничества, при котором создатели проекта DeFi намеренно обманывают инвесторов или пользователей, резко выводя ликвидность или средства из проекта, а пользователи остаются с «носом», точнее, с обесценившимися токенами.</li></ul><figure><img src="https://media.tproger.ru/user-uploads/101078/2024-07-09/265f4a19-ccd9-479a-8a9b-539fad75c478.jpeg" alt="" /></figure><p>Децентрализованные финансы — ещё один шаг на пути к миру «Киберпанка» и «Первому игроку приготовиться». Они позволяют совершать операции с криптой быстро, анонимно, прозрачно и без посредников за счет смарт-контрактов. Но всегда нужно помнить, что сфера только начинает зарождаться, а изъяны есть в любой системе.</p>]]></content:encoded>
    </item>
  </channel>
</rss>