Все публикации
Все материалы сайта в обратном хронологическом порядке
Архитектура
Надёжность распределённых систем: карта
Навигатор по надёжности распределённых систем: консенсус, согласованность, атомарность и транзакции, гарантии доставки сообщений и устойчивость под нагрузкой — как это связано и в каком порядке разбираться
Java
Kotlin для backend: null-safety, корутины и Ktor
Kotlin как backend-язык на JVM: null-safety на уровне типов, корутины и structured concurrency, DSL и фреймворк Ktor — где Kotlin реально выигрывает у Java и где это вопрос вкуса
Базы данных
Когда нужен OLAP: ClickHouse против PostgreSQL для аналитики
Чем OLAP-нагрузка отличается от OLTP, как колоночное хранение и векторное исполнение делают ClickHouse быстрым на аналитике, в какой момент PostgreSQL перестаёт тянуть агрегаты по большим таблицам — и где ClickHouse категорически не подходит
Базы данных
Паттерны и антипаттерны индексирования
Что делать и чего избегать с индексами: over-indexing и write-amplification, неиспользуемые и дублирующие индексы, bloat и обслуживание, covering под горячие запросы, online-создание без блокировок, индексы под пагинацию — и антипаттерн «индекс на всё»
Java
Современная Java: records, sealed-классы, pattern matching и virtual threads
Как изменился язык Java к 2026: records и sealed-классы, pattern matching для switch, текстовые блоки и virtual threads (Project Loom) — что из этого реально меняет стиль backend-кода
Базы данных
Мульти-хранилищный стенд: один сценарий по всем БД и карта выбора
Финал серии: единый сценарий (списание с инвариантом «баланс не в минус») реализован поверх PostgreSQL, Redis, MongoDB и ScyllaDB и прогнан одним нагрузчиком. Что каждая система гарантирует из коробки, что ломается под конкуренцией, цена корректности — и итоговая карта выбора
Базы данных
Индексы в разных БД: PostgreSQL, MongoDB, Tarantool
Один принцип, разные реализации: индексы в PostgreSQL (btree/GiN/GiST/BRIN, CONCURRENTLY, partial/expression), MongoDB (compound/multikey/text/2dsphere/TTL/partial/wildcard, правило ESR) и Tarantool (memtx TREE/HASH/BITSET/RTREE и vinyl LSM)
Базы данных
Брокеры и стриминг: транзакции в очереди и логе — RabbitMQ и Kafka
Что значит «транзакция» в брокере: AMQP-транзакции RabbitMQ против publisher confirms, транзакционный producer и exactly-once в Kafka, consume-process-produce и read_committed, границы EOS и outbox-паттерн как мост к БД. Примеры на Go и Java
Базы данных
Как выбирать и использовать индексы
Практика индексов: селективность и кардинальность, покрывающие индексы и index-only scan, составные индексы и порядок колонок, частичные и функциональные, и главное — почему индекс НЕ используется и как это увидеть
Сообщения
Messaging: выбрать и эксплуатировать — карта
Навигатор по messaging: как выбрать брокер (очередь vs лог vs шина), какие гарантии доставки бывают, как эксплуатировать кластер и как обрабатывать потоки данных — с картой всех статей по теме
Performance
Вероятностные структуры: Bloom-фильтры и компания — когда эффективны, когда нет
Bloom-фильтры, Cuckoo, HyperLogLog, Count-Min Sketch и родственники: как они экономят память и время ценой приблизительности, где реально эффективны (LSM-БД, кэш/CDN, дедупликация, аналитика уникальных), а где только вредят — с прикидкой параметров и примерами на Go и Java
Базы данных
KV и документные: «транзакций» почти нет — Redis, MongoDB, ScyllaDB
Что означает «транзакция» там, где нет классического ACID-движка: Redis MULTI/EXEC без rollback и WATCH-CAS, multi-document транзакции MongoDB поверх snapshot, LWT на Paxos в ScyllaDB и почему BATCH — это не транзакция. Примеры на Go и Java
Базы данных
Транзакции в реляционных БД на практике: PostgreSQL, изоляция и нагрузочный стенд
PostgreSQL как эталон управляемой изоляции: уровни в деле, SELECT FOR UPDATE, SERIALIZABLE с retry на 40001, advisory locks. Примеры на Go (pgx) и Java (JDBC) плюс нагрузочный стенд, воспроизводящий lost update и write skew под конкуренцией
Базы данных
Индексы в БД: зачем нужны, какие бывают и как устроены
Фундамент про индексы: зачем они (ускорение поиска ценой записи и места), какие бывают — B-tree, hash, bitmap, инвертированный (GiN), GiST, BRIN, R-tree, LSM — и как каждая структура устроена, что ускоряет и чем платит
Безопасность
Сканирование уязвимых зависимостей (SCA): Dependabot, osv-scanner, govulncheck
SCA на практике: почему Dependabot показывал 0, а osv-scanner нашёл полсотни; чем различаются базы advisory (GitHub Advisory, OSV, Go vuln DB, RustSec) и методы (presence-based против call-graph govulncheck); плейбук починки транзитивных CVE по экосистемам (Go, Maven, Python, Rust) и честная работа с no-fix и ложными срабатываниями
Архитектура
Consensus Landscape: тур по алгоритмам консенсуса через симулятор
Флагманский тур по ландшафту консенсуса: осваиваем Raft, Paxos, Zab и EPaxos, воспроизводя перевыборы, сетевые партиции и цену latency в интерактивном симуляторе.
Безопасность
Bubblewrap: песочница для недоверенного кода без root
Как запускать недоверенный бинарник, скрипт или сборку в песочнице без root с помощью Bubblewrap, что он изолирует, а что нет, и когда bwrap уместнее Docker, Podman или Firejail
Go
Go modules: go.mod, версионирование и управление зависимостями
go.mod, go.sum, семантический импорт версий, minimal version selection, replace/exclude, vendoring и workspaces (go.work). Как Go решает, какие версии зависимостей брать, почему MVS отличается от других менеджеров пакетов, и как этим управлять на практике
Базы данных
Аномалии и уровни изоляции: фундамент транзакций
С чего начинается транзакционность: ACID и BASE, каталог аномалий (dirty read, lost update, phantom, write skew), ANSI-уровни изоляции и их критика, блокировки против MVCC, snapshot isolation и почему это ещё не serializable
Rust
Rust в production: паттерны для надёжного backend
Production-паттерны для Rust backend: конфигурация через env, graceful shutdown, structured logging, OpenTelemetry трейсы, health checks, error handling стратегии
Rust
Rust в Docker: минимальные образы и cross-compilation
Как собирать Rust-сервисы в минимальные Docker-образы: multi-stage builds, musl vs glibc, cross-compilation, оптимизация размера. Практические рецепты для CI/CD
Сообщения
Эксплуатация NATS: nats CLI, мониторинг, backup и обновление кластера
Администрирование NATS: nats CLI и contexts, endpoints /varz /jsz /connz, prometheus-nats-exporter и Grafana, nats-top, backup/restore стримов и rolling upgrade кластера — с продакшн-чеклистом серии
Rust
Rust web-фреймворки: Axum vs Actix и выбор под задачу
Сравнение Axum и Actix-web: архитектура, производительность, ergonomics. Как выбрать фреймворк под конкретный backend-сценарий. Практические примеры: REST API, middleware, error handling
Сообщения
Безопасность и multi-tenancy в NATS: accounts, JWT, nkeys и TLS
Изоляция через accounts (глубже, чем vhost), exports/imports, три модели аутентификации (user/pass, nkeys, децентрализованный JWT через nsc и resolver) и TLS/mTLS — то, чего нет у соседей в таком виде
Базы данных
Подключение к Redis из Go, Java и Rust: что важно кроме простого PING
Практика подключения к Redis из Go, Java и Rust: timeout, pool, multiplexing, reconnect, а главное — как клиенты ведут себя с Sentinel и Cluster при failover и падении отдельных узлов
Rust
Rust async runtime: Tokio изнутри
Как устроен async runtime в Rust на примере Tokio: futures, waker, event loop. Чем отличается от goroutines в Go и virtual threads в Java. Когда async даёт выигрыш, а когда усложняет без пользы
Сообщения
NATS из Java: jnats, Core и JetStream паттерны
Те же паттерны на jnats: Connection и Dispatcher, request/reply, JetStream с pull-consumer через ConsumerContext, ack и redelivery, KV и graceful drain — зеркально к Go-статье серии
Performance
JVM-клиент под нагрузкой: gRPC ManagedChannel и HttpClient на HTTP/2
Клиент на JVM для highload: пул gRPC-каналов и java.net.http HttpClient поверх HTTP/2, deadlines под SLA и идемпотентный retry — параллель к Go-клиенту
Базы данных
Семантический поиск в OpenSearch: k-NN, эмбеддинги и гибридный поиск
Как искать по смыслу, а не по словам: k-NN плагин OpenSearch, векторные эмбеддинги, методы ANN (HNSW/Faiss/Lucene) и гибридный поиск, сочетающий лексику и семантику
Инфраструктура
Бэкапы ценного: фото, эскизы, проекты и готовность к потере
Как защитить необратимые данные — фото, свои эскизы и проекты: правило 3-2-1, проверка дисков и тест восстановления простыми словами, готовые бытовые сценарии без командной строки и облака (зашифрованный диск у близких) и что делать, если облако кажется дорогим
Сообщения
NATS из Go: nats.go, Core и JetStream паттерны
Практика на nats.go: подключение и reconnect, Drain и graceful shutdown, request/reply и queue groups, новый jetstream API с pull-consumer, ack и дедупликацией, KV — с оглядкой на идиомы клиентов Kafka и RabbitMQ
Performance
JVM-сервис под нагрузкой: virtual threads, пулы и reactive для 1000 in-flight
Как JVM держит ~1000 одновременных проверок: platform-пул против virtual threads и reactive (WebFlux), тред-модель и бэкпрешер правильно/неправильно/неоптимально
Наблюдаемость
OpenSearch Dashboards: Discover, визуализации и дашборды
Как работать с данными OpenSearch через Dashboards: index patterns, поиск в Discover, визуализации и дашборды, saved objects и доступ по ролям поверх security plugin
Сообщения
Надёжность и производительность NATS: гарантии, репликация и tuning
Матрица гарантий Core vs JetStream, влияние R3 на latency записи, slow consumer и flow control, storage file/memory, sizing и измерение throughput/latency через nats bench — трейдофф надёжность ↔ скорость
Performance
Go-клиент под нагрузкой: пул HTTP/2-соединений и потоки
Как клиенту на Go эффективно использовать HTTP/2: одно соединение — много streams, пул из 2–8 соединений, таймауты под SLA и идемпотентный retry
Базы данных
Retention в OpenSearch: ISM, rollover и жизненный цикл индексов
Как автоматически управлять жизненным циклом индексов в OpenSearch: политики ISM, переходы hot/warm/snapshot/delete по возрасту и размеру, rollover с write-алиасом и снапшоты перед удалением
Go
slog: структурированное логирование в стандартной библиотеке Go
log/slog (Go 1.21) — структурированное логирование в стандартной библиотеке: уровни, атрибуты, группы, JSON и text-хендлеры, With для контекста и связка с context. Как устроены Handler/Record, как писать свой хендлер и почему slog вытесняет самописные обёртки над log — на живых примерах вывода
Сообщения
Геораспределённый NATS: superclusters, gateways, leaf nodes и mirror-стримы
Особые гео-топологии NATS: gateways и supercluster с interest-propagation, leaf nodes для edge, асинхронная репликация стримов через mirror/source между регионами — и почему RAFT-группу нельзя растягивать через океан
Performance
HAProxy L4 vs L7 и HTTP/2: как масштабировать обработку между серверами
L4 против L7, разбор мифа «1 TCP = 1 backend» для HTTP/2, конфиги HAProxy правильно/неправильно/неоптимально и таймауты с retry под SLA
Базы данных
Полнотекстовый поиск в OpenSearch: запросы, анализаторы и подсветка результатов
Как устроен полнотекстовый поиск в OpenSearch: типы запросов, анализаторы для русского и английского языков, подсветка результатов, оптимизация релевантности и сравнение с полнотекстовым поиском в PostgreSQL и MongoDB
Сообщения
Классический кластер NATS: routes, RAFT и надёжный failover
Два уровня кластеризации NATS: full-mesh routes для Core и RAFT (meta-group + per-stream) для JetStream; кворум, реплики R3, placement и как кластер переживает падение ноды без потери данных
Performance
Бюджет задержки и выбор транспорта: highload под SLA < 300 мс
Из чего складывается бюджет 300 мс, почему Kafka не место в синхронном пути, HTTP/1.1 против HTTP/2 и когда WebSocket не нужен — на сквозном кейсе 2000–5000 rps
Базы данных
Сбор данных в OpenSearch: API, клиенты и bulk-загрузка
Как отправлять данные в OpenSearch из приложений на Go, Java, Rust и Python: REST и bulk, официальные клиенты, обработка ошибок и живой бенчмарк single vs bulk на 3.5.0
Архитектура
Гарантии доставки и идемпотентность: как получить effectively-once
Вся событийная архитектура держится на одной связке, которую редко проговаривают вслух: at-least-once доставка + идемпотентный консьюмер = effectively-once. Разбираем, почему сквозной exactly-once недостижим в принципе, чем at-least-once отличается от at-most-once, как сделать консьюмер идемпотентным (ключи идемпотентности, dedup-хранилище, естественная идемпотентность, окно дедупа) и где эта связка уже работает в серии — в outbox, saga и проекциях
Сообщения
JetStream: как NATS получает persistence, streams и гарантии доставки
Второй уровень NATS: streams и retention policies (limits/interest/workqueue), pull vs push consumers, ack и redelivery, дедупликация, KV и Object store — и чем это отличается от лога Kafka и очередей RabbitMQ
Архитектура
Досрочное погашение и архитектурные решения: почему ранняя коррекция курса обходится дешевле
Аннуитетный кредит как модель технического долга. Интерактивный калькулятор, реальные ставки ЦБ РФ и архитектурная аналогия: чем раньше вы меняете курс – тем дешевле это стоит
Базы данных
OpenSearch: индексы, маппинги и шаблоны
Как устроены индексы и маппинги в OpenSearch: dynamic vs explicit, типы полей и анализаторы, index и component templates, алиасы для ротации — с живой проверкой на 3.5.0
Сообщения
NATS для тех, кто знает Kafka и RabbitMQ: subjects, Core и request/reply
Ментальная модель NATS через знакомые понятия: subjects вместо exchanges и topics, встроенный request/reply, queue groups и почему Core NATS — это at-most-once транспорт без хранения
Архитектура
Что кладём в событие: notification vs event-carried state transfer
Самое базовое решение событийной архитектуры — что положить в событие: тонкое уведомление (просто «заказ изменился», ID) или толстое событие с полным состоянием. Первое слабо связывает, но провоцирует «GET-storm» обратно на источник; второе автономно, но раздувает payload, устаревает и тащит связанность по данным. Разбираем два паттерна из таксономии Фаулера, их компромиссы (связанность ↔ автономность ↔ staleness), версионирование нагрузки, приватность в событии и когда что выбирать
Инфраструктура
OpenSearch: установка кластера через Ansible, авторизация и работа с индексами
Как развернуть 3-нодный кластер OpenSearch официальным Ansible-плейбуком, настроить TLS через Vault PKI и security plugin с ролевым доступом
Go
Профилирование и бенчмаркинг в Go: как измерять без самообмана
Как в Go профилировать и бенчмаркить без самообмана: b.Loop и benchstat для честных замеров, чтение pprof (CPU/heap/allocs), execution trace и PGO, и типичные ошибки «оптимизации по ощущениям»
Архитектура
Хореография vs оркестрация: кто знает бизнес-процесс
Многошаговый процесс между сервисами координируют двумя способами: хореография — сервисы реагируют на события, единого дирижёра нет, поток эмерджентный; оркестрация — центральный координатор явно ведёт шаги и обрабатывает отказы. Разница не в технологии, а в том, ГДЕ живёт знание о процессе: размазано по сервисам или собрано в одном месте. Разбираем компромиссы, антипаттерны (event-спагетти vs god-оркестратор), когда что и почему реальные системы почти всегда гибрид
Архитектура
Ошибки, паники и исключения: как языки обращаются с отказами
Как Go, Rust, C++ и Java проводят границу между ожидаемым отказом и сломанным инвариантом, и как осознанно выбирать между возвратом ошибки, паникой и исключением
Go
sqlc и SQL-builders в Go: генерация кода из SQL vs конструирование запросов
Два подхода к работе с SQL в Go без ORM на одном домене: sqlc генерирует типизированный код из SQL, а SQL-builders (squirrel, goqu) конструируют запросы программно. Где каждый силён, где кусается и как их комбинировать
Сообщения
Streams в RabbitMQ: Kafka-подобный лог и можно ли заменить Kafka
Что такое streams в RabbitMQ — append-only лог с offset-чтением и репликацией, как их объявлять и читать (native stream-протокол и AMQP), super streams для партиционирования, честное сравнение с Kafka и разбор, где RabbitMQ Streams реально заменяет Kafka, а где нет
Go
ORM в Go: где он уместен и что выбрать между GORM и go-jet
ORM в Go: где такой подход оправдан, чем GORM отличается от EF/Hibernate, когда практичнее SQL-first go-jet, и какие есть альтернативы (sqlc, ent, bun)
Архитектура
Temporal: durable workflows вместо самодельных очередей
Что такое Temporal, какие задачи он решает, чем отличается от очередей и saga-оркестраторов и когда стоит его внедрять, а когда достаточно простого решения
Docker
Rootless Docker: стоит ли переходить
Что даёт rootless Docker по безопасности, где он удобен и какие ограничения приносит в реальной эксплуатации — и при чём здесь Podman
Go
PGX в Go: зачем уходить с pq и где проходит граница пользы
Как собрать нормальный data-access слой на pgx: чтение в структуры без sqlx, типы PostgreSQL (jsonb/array/nullable/timestamptz), транзакции, batch и CopyFrom, настройка pgxpool, режимы за pgbouncer и типичные сложности эксплуатации
Архитектура
Saga: распределённые транзакции без двухфазного коммита
Как паттерн Saga решает проблему распределённых транзакций, чем оркестрация отличается от хореографии и когда saga создаёт больше проблем, чем решает
Безопасность
HTTP/2 Bomb: как склейка двух старых приёмов кладёт веб-сервер
Разбор атаки HTTP/2 Bomb: HPACK-бомба и удержание через нулевое flow-control окно по отдельности известны десять лет, но вместе кладут nginx, Apache, IIS, Envoy и Pingora за секунды. Как устроен механизм на уровне фреймов, кто уязвим и что пропатчено, почему Angie (и khorost.tech) не тронут, как проверить свой сервер — и почему эту склейку первым увидел ИИ
Инфраструктура
Terraform для Docker-хостов и сетей: где проходит граница пользы
Где Terraform реально помогает в Docker-инфраструктуре — хост, firewall, генерация Ansible inventory, — а где только добавляет слой абстракции: lifecycle контейнеров и docker-сети. С рабочим примером стыка Terraform → Ansible из digital-cookbook
Go
Когда env уже мало: layered configuration в Go с confita
Когда env-only уже мало: как выстроить layered configuration в Go с confita — сквозной Config с группами, time.Duration/срезы/nested, приоритет слоёв, post-load валидация и где confita кусается
Архитектура
Контракты событий: schema evolution без боли
Событие как публичный контракт: naming, обратная и прямая совместимость, безопасные и ломающие изменения схемы, JSON против Avro/Protobuf, schema registry, consumer-driven contracts и upcasting
Инфраструктура
Ansible и Docker Compose: раскатываем сервисы без ручной магии
Как использовать Ansible для управления Docker Compose стеками: inventory, group_vars для нескольких окружений, шаблоны compose и .env, секреты через ansible-vault и модуль community.docker.docker_compose_v2 — с рабочим примером из digital-cookbook
Архитектура
Transactional Outbox/Inbox: события без распределённой транзакции
Как надёжно публиковать события при изменении данных без распределённой транзакции: outbox, relay/poller, inbox и дедупликация, idempotency key, ordering, poison messages и почему exactly-once — это иллюзия
Инфраструктура
Proxmox + Terraform: автоматизируем создание VM и контейнеров в домашней лаборатории
Как использовать Terraform для автоматического создания и управления виртуальными машинами и LXC-контейнерами в Proxmox VE: провайдер bpg/proxmox, cloud-init шаблоны, примеры VM и CT, типичные ошибки
Архитектура
CQRS: разделяем чтение и запись без лишнего пафоса
Что такое CQRS, зачем разделять модели чтения и записи, как это связано с event sourcing и где этот паттерн создаёт больше проблем, чем решает
Kubernetes
Kubernetes Gateway API: чем он лучше Ingress и когда переходить
Gateway API — новый стандарт управления входящим трафиком в Kubernetes. Чем он отличается от Ingress, какие задачи решает лучше, как оценивать готовность реализаций к production и когда переход действительно оправдан.
Архитектура
Event Sourcing: когда история важнее текущего состояния
Что такое event sourcing, какие задачи он решает лучше классического CRUD, где усложняет без пользы и на что смотреть перед внедрением
Архитектура
Архитекторы в IT: кто чем занимается и кому это нужно
Какие виды архитектуры бывают в IT, чем отличаются роли архитекторов, и почему архитектурные решения на практике принимают не только люди с «архитектор» в должности
Архитектура
Событийная архитектура без магии: карта понятий
Карта понятий событийной архитектуры: чем команда отличается от события, domain event от integration event, где брокер, где event store, где workflow engine — и как читать остальную серию
Архитектура
Распределённые конфигурации: etcd, Consul, Vault и когда они действительно нужны
Когда конфигурация через env и файлы перестаёт работать, какие задачи решают etcd, Consul и Vault, чем они отличаются и как не усложнить систему раньше времени
Архитектура
Сквозной итоговый кейс: собираем рабочую систему лунной базы
Финальная статья архитектурно-аналитической серии: один сценарий лунной базы, пройденный целиком — от problem statement и требований через доменную модель, C4, взаимодействия и согласованность до эксплуатации, чтобы увидеть, как все решения складываются в одну систему
Сообщения
Эксплуатация RabbitMQ: мониторинг и продакшн-чеклист
Что наблюдать в RabbitMQ через Prometheus и Grafana, как читать метрики во время failover и финальный продакшн-чеклист настроек отказоустойчивого кластера
Архитектура
Эксплуатация в архитектуре: как инженеры возвращают схему в реальность
Статья архитектурно-аналитической серии на примере лунной базы: почему эксплуатация — не этап после архитектуры, а её часть, и как наблюдаемость, деградация и восстановление должны проектироваться вместе с системой
Сообщения
Связываем кластеры RabbitMQ: Federation и Shovel
Асинхронная маршрутизация между кластерами RabbitMQ: чем federation отличается от shovel, как строить geo-распределение и DR-сценарии и когда что выбирать
Архитектура
Согласованность данных: где нужна строгая, а где достаточно «в итоге»
Статья архитектурно-аналитической серии на примере лунной базы: как выбирать уровень согласованности данных под реальные сценарии — строгая, eventual или пакетная — и почему «согласованность везде» ломает систему так же, как её отсутствие
Сообщения
Не потерять сообщение в RabbitMQ: durability, confirms, ack и DLQ
Durability и persistence, publisher confirms против тихих потерь, manual ack и prefetch, Dead Letter Queue и паттерн отложенной доставки через retry-queue, а также почему confirms предпочтительнее транзакций
Архитектура
Взаимодействия и интеграции: где ломается кажущаяся простота
Статья архитектурно-аналитической серии на примере лунной базы: как аналитика и архитектура по-разному смотрят на синхронные и асинхронные взаимодействия, REST, события, команды и очереди — и где простая на схеме интеграция оказывается дорогой
Сообщения
Отказоустойчивый RabbitMQ: quorum-очереди и failover без потерь
Почему одна нода RabbitMQ — не вариант, чем mirrored queues отличаются от quorum queues на Raft, какой трейдофф у строгого кворума и как развернуть кластер, переживающий падение ноды без потери сообщений
Архитектура
C4-модель для аналитика: не рисовать красиво, а думать точно
Статья архитектурно-аналитической серии на примере лунной базы: как использовать C4-модель не как способ рисовать красивые схемы, а как инструмент точного разговора между аналитикой, архитектурой, разработкой и инженерными командами
Архитектура
Как доменная модель ломает и спасает архитектуру
Статья архитектурно-аналитической серии на примере лунной базы: как ошибка в доменной модели превращается в ошибку архитектуры, а хорошая модель помогает точнее разделять контексты, взаимодействия и ответственность
Архитектура
DDD для аналитика без культа терминов
Зачем аналитику DDD, как bounded context и ubiquitous language помогают проектированию и почему доменная модель важнее терминов
Архитектура
Требования как архитектурные драйверы
Как требования превращаются в архитектурные драйверы, почему NFR часто важнее use cases и где видна будущая цена решений
Архитектура
Problem statement: симптомы, причины и метрики
Как не путать симптом с причиной, как формулировать problem statement и почему метрики нужны до архитектурного решения
Инфраструктура
imgproxy в production: обработка изображений на лету, S3, кеширование и подпись URL
Как вынести resize и конвертацию картинок в WebP/AVIF в отдельный сервис: подписанные URL, кеш перед imgproxy, сложности деплоя и реальные цифры — на примере khorost.tech
Архитектура
Почему аналитику недостаточно только требований
Где аналитика начинает влиять на архитектуру и почему одних требований недостаточно для проектирования сложной системы
Архитектура
Архитектура, аналитика и лунная база: о чём эта серия
Почему для серии об архитектуре и аналитике выбран кейс лунной базы и чем мысленный эксперимент полезнее абстрактного enterprise-примера
Инструменты
LikeC4: архитектура как код — от DSL до интерактивных диаграмм
Как описывать архитектуру системы кодом с помощью LikeC4: DSL для C4-модели, автоматическая генерация диаграмм, версионирование в Git, встраивание в документацию и сравнение с Mermaid, PlantUML и Structurizr
Инструменты
Git: от первого коммита до уверенной работы в команде
Учебный материал по Git: от базовых концепций до уверенной работы с ветками, конфликтами и командным workflow. Без магии, с объяснением что происходит внутри
AI
Паттерны снижения трения при работе с AI-ассистентами: разбор статьи Rahul Garg
Разбор статьи с martinfowler.com о пяти паттернах эффективной работы с AI-ассистентами в разработке: Knowledge Priming, Design-First Collaboration, Context Anchoring, Encoding Team Standards и Feedback Flywheel — с микропримерами, личным опытом и критическим взглядом
Инструменты
Как настроить окружение для изучения языка программирования
Универсальный гайд по настройке рабочего окружения для изучения любого языка: установка runtime, выбор редактора, первый запуск, менеджер зависимостей и альтернативный путь через Docker
Инфраструктура
Как ArgoCD выгнал меня из Nexus: переезд на Harbor, Verdaccio и Athens
История о том, как один artifact-сервер незаметно стал лицензионной ловушкой, и почему я разменял монолитный Nexus на три специализированных open-source сервиса
Базы данных
Миграции для ScyllaDB в Go: scyllamigrate, gocqlx/migrate, golang-migrate и goose
Практический разбор миграций для ScyllaDB в Go: scyllamigrate, gocqlx/migrate, golang-migrate и goose. Что лучше подходит для CQL, где важна зрелость экосистемы и какие риски есть у каждого подхода
Docker
Docker Compose для production без Kubernetes
Когда Docker Compose всё ещё подходит для production и как выстроить вокруг него вменяемый процесс эксплуатации
Инфраструктура
Закон об иностранных словах и IT: когда Deployment стал Разверженіемъ
Федеральный закон 168-ФЗ об ограничении иностранных слов вступил в силу 1 марта 2026. Что это значит для IT-индустрии, документации, курсов и повседневного общения разработчиков
Сообщения
RabbitMQ, Kafka, NATS и Redis: как не выбирать messaging layer по моде
Выбор брокера сообщений: чем в реальности различаются RabbitMQ, Kafka, NATS и Redis (Lists, Pub/Sub, Streams), какие задачи они решают лучше всего и где начинаются типовые ошибки выбора
Rust
Rust для backend: где он действительно уместен
Где Rust в backend даёт реальный выигрыш, а где переплата сложностью. Кейсы Discord, Cloudflare, Figma. Сравнение с Go и Java, диаграмма принятия решения, примеры кода
Kubernetes
Kubernetes для домашней лаборатории: когда он действительно нужен
Kubernetes в домашней лаборатории и небольших системах: когда он действительно полезен, какие задачи решает, где добавляет лишнюю сложность и как понять, нужен ли он именно вам
Java
Java для backend и контейнеров: где она по-прежнему очень сильна
Java в современном backend и контейнерной эксплуатации: где она особенно сильна, какие у неё реальные компромиссы, как выглядит контейнеризация на практике и почему образ языка как «тяжёлого энтерпрайза из прошлого» уже давно слишком упрощён
Архитектура
System Design без культа идеальных схем
Системный дизайн без академизма и культа «идеальных схем»: с чего начинать проектирование, как думать про контекст и trade-offs, и почему хорошая архитектура почти никогда не выглядит как красивая универсальная диаграмма
Docker
Docker Buildx и multi-arch образы: одна сборка для amd64 и arm64
Как собирать и публиковать multi-arch Docker-образы через buildx для amd64 и arm64: manifest list, кэширование, QEMU vs нативные builders и проверка результата
Наблюдаемость
OpenTelemetry Collector: зачем он нужен и как на него правильно смотреть
Зачем нужен отдельный слой сбора телеметрии, как Collector устроен, сколько ресурсов потребляет, какие deployment-паттерны бывают, типичные ошибки и когда он действительно оправдан
Docker
Docker volumes: как использовать тома правильно для скорости, надёжности и контроля доступа
Как правильно использовать Docker volumes и bind mounts, почему это влияет на производительность и надёжность, и как ограничивать доступ к данным
Go
Go: конфигурация через env без хаоса
Как выстроить конфигурацию Go-приложения через env vars без расползания параметров, неочевидных дефолтов и ошибок старта
Инфраструктура
Docker-хосты в Proxmox: LXC или VM
Как выбрать между LXC и VM в Proxmox для Docker-нагрузок и не усложнить себе сопровождение
Базы данных
Redis: где он помогает, а где только усложняет систему
Redis: когда он действительно нужен, какие паттерны и анти-паттерны встречаются чаще всего, где проходят его ограничения и почему “просто поставим кэш” — плохая постановка задачи
Инфраструктура
Proxmox VE: что это такое, какие есть подписки и когда он уместен
Proxmox VE: модель лицензирования и подписок, основные возможности, кластер, backup и честные плюсы и минусы
Docker
Golden builder image и Docker Registry: ускоряем сборку и публикуем образы
Когда нужен golden builder image, как его сопровождать и как работать с Docker Registry вне Docker Hub
Docker
Production-сборка Docker-образов: secrets, proxy, healthcheck и CI
Практики production-сборки Docker-образов: линтеры, сканирование, BuildKit secrets, proxy, healthcheck и разделение build-time и runtime
Docker
Multi-stage builds в Docker: собираем Go-приложение правильно
Как уменьшить Docker-образ Go-приложения с помощью multi-stage сборки и не потерять удобство эксплуатации
Go
Graceful shutdown в Go: завершаемся правильно
Как корректно завершать Go-сервис, не теряя запросы, останавливая фоновые задачи и закрывая ресурсы