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

Автор — Андрей Овчаренко. Технический аудит: https://krot.name/
Download Telegram
Тайм-аут закончился. Что осталось работать?

Ошибка уже вернулась клиенту, а SQL ещё может занимать базу и соединение. На карте — четыре разных уровня: дедлайн операции, выполнение SQL, ожидание блокировки и аварийное закрытие сети.

Начните с полного разбора: https://t.me/management_Java/35

Здесь разбираю Java в production: где заканчиваются гарантии и что проверить в своём сервисе. JVM, базы, надёжность и инженерные решения — с первичными источниками и схемами.

Следующий шаг: выберите один медленный запрос и проверьте, что после отмены прекратилась работа в базе и освободился ресурс пула.

Автор — Андрей Овчаренко.
Решение важнее новостного пересказа

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

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. 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 #идемпотентность
Timeout завершает Future, но не работу

В CompletableFuture легко перепутать завершение обещания и остановку работы. Первое API делает за строку; второе за вас никто, зараза, не спроектирует.

Oracle API: cancel(...) завершает stage через CancellationException, но mayInterruptIfRunning здесь не имеет эффекта — interrupts не управляют обработкой. orTimeout завершает тот же Future через TimeoutException, а completeOnTimeout подставляет значение. Supplier, JDBC-запрос или HTTP-вызов могут продолжать занимать ресурс.

Поэтому я развожу четыре слоя:
— deadline операции;
— timeout реального ресурса;
— cooperative cancellation;
— completion для caller и dependents.

Fallback допустим только как явный бизнес-контракт. TimeoutException у caller и живой JDBC-запрос — не cancellation, а перенос проблемы в мониторинг.

#Java #concurrency #CompletableFuture #reliability
Hibernate экономит код. Базе данных на это плевать

ORM отлично убирает повторяющийся persistence-код и связывает данные с объектной моделью. Но SQL, сеть и materialization никуда не деваются — просто становятся менее заметны в Java-коде. Магия закончилась на аннотациях.

100 orders + lazy collection в цикле: 1 root query + до 100 secondary selects = до 101 SQL.

Две to-many коллекции по 10 и 20 элементов: JOIN способен вернуть до 200 rows на parent. Hibernate ORM User Guide также фиксирует: EAGER не гарантирует один JOIN, несколько bags могут вызвать MultipleBagFetchException, а IDENTITY отключает JDBC insert batching.

Поэтому я смотрю SQL statements, rows, план через PostgreSQL EXPLAIN и размер persistence context/flush, а не гадаю по красивым entities. Только потом выбираю JOIN FETCH, entity graph, batch fetch, DTO или native SQL.

Hibernate — инструмент. Делать вид, что он отменил SQL, — дорогая иллюзия.

#Java #Hibernate #JPA #SQL
TTL может синхронизировать отказ

Кэш снижает нагрузку, пока origin не начинает зависеть от него как от несущей стены. Общий expiry hot key превращает cache miss в thundering herd — календарь отказа теперь просто известен заранее.

AWS рекомендует request coalescing: один refresh на ключ, остальные ждут тот же результат. Cloudflare показывает probabilistic early revalidation — refresh распределяется до expiry без отдельного lock-сервиса. RFC 5861 задаёт ещё два договора: stale-while-revalidate и stale-if-error.

Мой набор для hot keys:
— TTL jitter;
— single-flight с timeout;
— bounded early refresh;
— stale только для безопасных данных;
— load test холодного cache и метрика origin amplification.

Если потеря cache может положить dependency, это часть модели надёжности. Поставить TTL и надеяться — не стратегия; это будильник для аварии.

#architecture #cache #reliability #systemdesign
JDK 27 заморозила scope — пора ломать стенд

16 июля JDK 27 перешла в Rampdown Phase Two: feature set frozen, новых JEP не будет. Initial RC — 6 августа, Final RC — 20 августа, GA — 15 сентября.

В scope 8 JEP. Для production особенно заметны G1 по умолчанию во всех окружениях, Compact Object Headers по умолчанию, JFR in-process redaction и post-quantum hybrid TLS 1.3.

Draft release notes от 17 июля фиксируют removal экспериментального JVMCI, связанных модулей/flags и -XX:+UseGraalJIT.

Действие сейчас: latest EA в compatibility CI; проверить flags, agents, heap/latency, JFR pipeline, TLS и зависимости от JVMCI. Нести EA в production ради галочки — херовый release plan. Pilot — после Final RC и своих regression-тестов.

#Java #JDK27 #JVM #новости
Радар июля: версии приехали, готовность — как обычно

Новая версия сама по себе никого не спасает. Она просто приносит новый набор рисков, пока команда радостно читает changelog по диагонали.

По данным OpenJDK, JDK 26 достиг GA 17 марта: HTTP/3, снижение synchronization overhead G1, AOT cache с любым GC; Structured Concurrency — preview. JDK 27 GA запланирован на 15 сентября.

Официальный анонс Spring Boot 4.1.0 от 10 июня называет 5 highlights; требования — Java 17+, совместимость до Java 26 и Spring Framework 7.0.8+.

Release notes Apache Kafka 4.3.1 от 25 июня содержат 11 JIRA issues, включая 8 bugs; анонс благодарит 23 contributors. Среди важных fixes: KAFKA-20616 (RocksDB native-memory/OOM), 20663 (stale changelog offset), 20673 (Admin API hang).

Мои действия без релизного цирка: JDK — compatibility CI; Boot — migration backlog; Kafka 4.3.0 — patch после upgrade review.

#Java #JDK #SpringBoot #Kafka #новости
Обновили Java? Проверьте, что новая версия запущена

OpenJDK advisory от 21 июля сообщает об уязвимостях в Java 8, 11, 17, 21, 25 и 26. В основной таблице их 11, самая серьёзная получила 7,5 балла из 10. Отдельное обновление нужно приложениям на JavaFX.

Главная ловушка: команда меняет версию в настройках, а работающий сервис остаётся на старой Java. Без перезапуска риск никуда не делся.

Что сделать:
— найти Java во всех сервисах, контейнерах, виртуальных машинах и фоновых задачах;
— поставить исправленную сборку от своего поставщика;
— пересобрать образы и перезапустить сервисы;
— проверить используемые соединения, изображения и JavaFX;
— снова выполнить java -version и проверку безопасности.

Зелёная сборка — ещё не доказательство обновления. Доказательство — новая версия Java в каждом реально работающем процессе.

#Java #security #JDK #новости
Один таймер не спасает запрос к базе

Пять секунд в настройке ещё не гарантируют, что запрос остановился и освободил соединение.

Для обычного SQL-запроса Java задаёт отдельный срок. После его превышения driver возвращает SQLTimeoutException и пытается отменить работу. Это ещё не доказательство, что сервер базы уже остановился.

Для полностью зависшей сети действует аварийный предел. В терминах JDBC network timeout помечает connection closed — проще говоря, Java закрывает соединение. Oracle рекомендует делать этот срок длиннее обычного времени на запрос.

PostgreSQL разделяет долгий запрос, ожидание занятой записи и забытую открытую транзакцию. Им нужны разные пределы.

Мой порядок:
— срок всей пользовательской операции;
— меньший срок для SQL;
— ещё меньший — для ожидания блокировки;
— аварийное закрытие сети последним.

После ошибки проверяю, что запрос остановлен, а соединение вернулось в пул.

#Java #JDBC #PostgreSQL #reliability
Совместимая схема. Replay всё равно может разнести прод

Registry-check зелёный — и все счастливы. Жаль, что он не доказывает, сможет ли новый код безопасно перечитать старую историю.

Avro 1.12 задаёт для single-object encoding ровно 10 байт префикса: 2 байта marker C3 01 и 8 байт CRC-64 fingerprint. Fingerprint указывает на writer schema, но не заменяет её архив.

В конфигурации Apache Kafka 4.3 broker defaults — retention 168 часов и segment 1 GiB. Это не гарантия topic: overrides и compaction могут оставить меньше истории.

Replay безопасен, когда writer schemas сохранены, reader проверен на историческом корпусе, известны earliest offsets, dry run изолирован, а downstream идемпотентен.

Совместимость схемы — один чекбокс, а не бронежилет. Первый полный replay обычно объясняет это без лишней деликатности.

#Java #Kafka #Avro #архитектура
Один предохранитель не спасает сервис от перегрузки

Resilience4j CircuitBreaker замечает частые ошибки и медленные ответы. Если сервис явно болеет, новые обращения временно прекращаются.

Но в нормальном режиме все 20 вызовов всё равно могут уйти одновременно. Для защиты нужны разные ограничения:
— Bulkhead ограничивает число одновременных запросов;
— RateLimiter ограничивает скорость потока;
— TimeLimiter ограничивает время ожидания;
— Circuit Breaker решает, когда перестать доверять больному сервису.

Они дополняют друг друга. Наличие одного Circuit Breaker ещё не защищает от каскадного сбоя. Нагрузочный тест должен показать, что очереди и соединения не переполняются, повторы не усиливают аварию, а зависший запрос действительно останавливается.

#architecture #resilience #Java #systemdesign
JDK 27 предложит гибридный TLS без правок в коде

OpenJDK JEP 527 добавляет в TLS 1.3 гибридный обмен ключами. Схема X25519MLKEM768 соединяет классический X25519 и постквантовый ML-KEM-768: защита сохраняется, пока не сломаны обе части.

JDK ставит эту группу первой. Обычный код на javax.net.ssl получит её автоматически, если сервер тоже поддерживает группу и приложение не закрепило свой список. Традиционный x25519 остаётся запасным вариантом.

Что проверить на стенде:
— какая группа реально согласована;
— проходят ли рукопожатия через прокси и средства проверки трафика;
— как изменились размер и время рукопожатия;
— не задан ли старый jdk.tls.namedGroups.

Спецификации гибридных групп ещё могут измениться до RFC. Поэтому новый default полезен, но совместимость всей TLS-цепочки всё равно доказывает тест.

#Java #JDK27 #TLS #security #новости
Virtual Threads не размножают CPU и коннекты. Сюрприз

Virtual Threads масштабируют blocking I/O без отдельного дорогого platform thread на каждую задачу. Они удешевляют ожидание, но не создают CPU, соединения с БД или capacity downstream — физика опять испортила презентацию.

OpenJDK в JEP 444 показывает 10 000 одновременных задач как демонстрацию и прямо советует не пулить virtual threads. JEP 491 в JDK 24 устранил почти всё synchronized-pinning; JFR сохраняет диагностику редких native/class-init случаев.

Статусы OpenJDK: Virtual Threads final в JDK 21, Scoped Values final в 25, Structured Concurrency — 6-й preview в 26 и 7-й в 27.

100 000 запросов к pool из 100 DB connections дают максимум 100 активных операций и до 99 900 ожидающих. Ограничивать нужно scarce resource, а не virtual threads.

Забивать очередь дешёвыми потоками — всё ещё херовая архитектура, просто теперь она дешевле ждёт.

#Java #JVM #VirtualThreads
Большой review тормозит не автора, а команду

Автор экономит на разбиении работы, а счёт получает вся очередь review.

Google Engineering Practices определяет малое изменение как одну самостоятельную мысль вместе с тестами. Его проще внимательно проверить, вернуть, влить и откатить. Большой пакет требует отдельного окна, быстрее устаревает и чаще конфликтует.

Ориентир, а не норматив: около 100 строк часто удобно, около 1000 обычно уже слишком много. Суть не в счётчике, а в одной проверяемой цели и отдельном откате.

Для скорости Google рекомендует отвечать не позже одного рабочего дня. Это не значит прерывать сосредоточенную работу: review берут в ближайшей естественной паузе.

Если разбор требует героического свободного вечера, проблема обычно возникла раньше — при нарезке работы.

#engineeringmanagement #codereview #delivery #teamlead
Три коробки observability — ещё не наблюдаемость

Можно купить backend для метрик, логов и traces, а потом всё равно узнавать о падении от пользователя. Коробки есть, понимания системы — как повезёт.

Для 30-дневного SLO 99,9% бюджет равен 43 мин 12 с. Google SRE Workbook предлагает стартовые multi-window alerts:
— page: 14,4×, окна 1 h / 5 min, расход 2%;
— page: 6×, 6 h / 30 min, расход 5%;
— ticket: 1×, 3 d / 6 h, расход 10%.

Метрика показывает форму ущерба, trace — путь, structured log — детали. OpenTelemetry задаёт semantic attributes вроде service.name; trace_id приходит из trace context, это другой слой.

Page должен отвечать на пользовательский симптом или быстрый burn rate, а не на внутреннюю метрику, которую просто удобно повесить на дежурного.

Observability — это способность ответить «что сломалось и почему», а не три дорогих логотипа в архитектурной схеме.

#Java #SRE #observability
👍1
Channel name was changed to «AI && Java && Management»
ChatGPT теперь пишет как вы. Промпт «сделай в моём стиле» потихоньку уходит на пенсию

ChatGPT Work получил Writing Style: он может брать примеры из подключённых Gmail, Google Drive, Slack и SharePoint и переносить характерные фразы, структуру предложений, подписи и прочие привычки в новые тексты. На части аккаунтов также доступны Teams, Notion и Outlook.

Раньше для нормального письма приходилось каждый раз объяснять: короче, суше, без корпоративной патоки, вот три моих примера. Теперь источником стиля становится сама рабочая переписка.

Это не fine-tuning вашей персональной модели и не гарантия, что текст стал умнее. Система использует реальные примеры как контекст для генерации. Ошибки, факты и смысл всё равно проверяет человек — характерный оборот речи достоверности не добавляет.

Практический выигрыш очевиден: письма, follow-up, сообщения в ТГ и документы требуют меньше ручного редактирования. Но подключать весь корпоративный архив ради красивой подписи — тоже сомнительная оптимизация: scopes и разрешения стоит ограничивать тем, что действительно нужно.

Теперь и Стиль можно автоматизировать. Ответственность за написанное пока нет.

#AI #ChatGPT #OpenAI #новости