Java && Management
2 subscribers
1 link
Для senior Java-разработчиков, архитекторов и тимлидов: JVM, архитектура, эксплуатация и инженерное управление. Первичные источники, актуальные релизы и выводы для решений.

Автор — Андрей Овчаренко. Технический аудит: https://krot.name/
Download Telegram
Channel created
👋 Добро пожаловать в Java && Management

Здесь — практические разборы Java/JVM, архитектуры, Kafka, эксплуатации и инженерного управления: первичные источники, актуальные релизы, диаграммы и выводы для решений.

Навигация:
#Java — JVM, Spring и платформенные изменения
#Kafka — очереди, события и идемпотентность
#идемпотентность — retry, консистентность и надёжность
• комментарии — вопросы и разборы в связанном чате

Нужен независимый технический аудит Java/backend, инфраструктуры или интеграций?
https://krot.name/

Профили и кейсы: https://krot.name/profiles/
Java && Management pinned «👋 Добро пожаловать в Java && Management Здесь — практические разборы Java/JVM, архитектуры, Kafka, эксплуатации и инженерного управления: первичные источники, актуальные релизы, диаграммы и выводы для решений. Навигация: • #Java — JVM, Spring и платформенные…»
Решение важнее новостного пересказа

Информационного шума и так до хрена. Ценность технического контента не в том, сколько релизов я пересказал, а в том, помог ли разбор принять инженерное решение.

DORA сейчас использует 5 delivery metrics: 3 про throughput и 2 про instability. Сильные команды обычно хороши по всем пяти, но сама DORA предупреждает: чужие target без контекста — отличный способ красиво врать самим себе.

Google SRE показывает цену SLO за 30 дней:
— 99,9% оставляет 43 мин 12 с error budget;
— 99,99% — всего 4 мин 19 с.

Поэтому здесь схема простая: сигнал → доказательства → механизм → границы → решение. Иногда вывод будет скучным: пока ничего не менять. Это не трусость, а нормальная архитектура, если названы критерий и цена ожидания.

#Java #архитектура #исследования
Микросервисы: дорогой способ слишком рано почувствовать независимость

Микросервисы обещают независимые релизы, масштабирование и изоляцию отказов. А потом приносят сетевые вызовы, распределённое состояние и эксплуатационную координацию — сюрприз, бесплатной архитектуры опять не завезли.

Дэвид Парнас предлагал отделять модуль там, где он скрывает независимо меняющееся решение. Отдельный процесс нужен позже — когда независимость должна дойти до релиза, scaling или failure domain.

DeathStarBench 2019 собрал 6 end-to-end приложений: benchmark одного процесса не видит service graph и tail latency всей системы. В кейсе Prime Video прежний workflow упёрся примерно в 5% ожидаемой нагрузки; после локальной консолидации команда сообщила о снижении инфраструктурной стоимости на 90%.

Это не «монолит всех победил». Это напоминание: архитектурная религия — херовый заменитель измерений. Моя стартовая позиция — модульный монолит; сервис выделяется при самостоятельной бизнес-границе и измеримом эксплуатационном давлении.

#Java #архитектура #микросервисы
@Transactional не накрывает сеть священным куполом

Транзакция сохраняет инвариант: изменение фиксируется целиком либо не фиксируется. Но её власть заканчивается на границе базы. HTTP и broker на аннотацию смотрят без всякого благоговения.

По Spring Framework, @Transactional действует только в границе TransactionManager. Три детали, на которых регулярно строят уверенность из воздуха:
— self-invocation в proxy mode не перехватывается;
— checked exception по умолчанию не вызывает rollback;
— PostgreSQL принимает 4 названия isolation level, но реализует 3 режима: READ UNCOMMITTED работает как READ COMMITTED.

В READ COMMITTED каждый SELECT начинает новый snapshot. Serialization failure — SQLSTATE 40001, deadlock — 40P01; повторять нужно всю транзакцию, а не последний удобный кусок.

Для DB + broker данные и outbox фиксируются вместе. Debezium читает изменения через CDC, Event Router преобразует запись перед публикацией. Дубликаты возможны, поэтому consumer остаётся идемпотентным. Иначе получаем распределённый бардак с очень уверенной аннотацией.

#Java #Spring #транзакции
Exactly-once заканчивается там, где начинается бизнес

Идемпотентность нужна, чтобы retry не превращался в повторный платёж, заказ или списание. Транспорт может честно сказать «ровно один раз», но внешней системе на его самооценку плевать.

В Apache Kafka 4.3 producer idempotence включена по умолчанию без конфликтующих настроек и требует acks=all, retries>0, max.in.flight≤5. KIP-98 связывает records и offsets только через sendOffsetsToTransaction; consumer должен читать read_committed. Платёжный API в эту гарантию не входит.

AWS Builders’ Library рекомендует caller-provided request ID для повторов одного намерения. У себя я добавляю unique constraint, состояния IN_PROGRESS/SUCCEEDED и reconciliation неизвестного исхода.

Stripe ограничивает idempotency key 255 символами и может удалить его после того, как ключу исполнилось не менее 24 часов. После pruning старый retry станет новым запросом. Это контракт Stripe, а не вселенский закон.

Если деньги списались дважды, пользователю до лампочки, насколько охрененно exactly-once выглядел внутри Kafka.

#Java #Kafka #идемпотентность