Всем привет!
На этот раз у поста будет заголовок.
7 смертных грехов платформенных компонент.
И сразу небольшое уведомление - данные грехи возможны в любом сервисе, но в случае платформенных компонент они причиняют максимум боли) Ведь в чем суть платформы - не делай свой велосипед, вот тебе готовый, сертифицированный, спроектированный лучшими конструкторами на основе многолетнего опыта... Вы же бизнес-команда, вот и пилите свою бизнес-логику, а платформенные вещи оставьте профессионалам. А по факту ... бывает всякое.
Поехали!
1) слишком тесная связанность. Внешний компонент можно добавить в свой сервис разными способами. Как отдельный под рядом с основным сервисом, как сайдкар, как jar библиотеку. Варианты расположены в порядке увеличения связанности. Больше связанности - это плохо. Почему - отвечу на примере подключаемого jar. Как известно jar не приходит один. А тянет за собой зависимости. Их может быть много, они могут конфликтовать с другими зависимостями, содержать уязвимости, замедлять процесс старта, конфликтовать за общие ресурсы. Процесс подключения может быть нетривиален. А если подключение идет через корневой pom, то мы в каком-то смысле передаем управление нашим сервисом наружу.
2) отдельный пайплайн. Беда не приходит одна, и бывает так что внешний компонент тянет за собой свой CI или CD пайплайн. И то, и другое для конкретного сервиса может быть достаточно сложной и месяцами тщательно настраиваемой штукой. А теперь нам надо встроить туда чужой пайп. Или вызовом, или разобраться что же такого сложного делает внешний пайп и сэмулировать это в своем (а-ля реверс-инжиниринг). Второй вариант - сложно, остановимся на первом. Какие могут быть сложности с внешним пайпом?
а) много непонятных настроек
б) управляет версионированием дистрибутива (снова тесная связанность)
в) делает commits в наш репозиторий
г) требует особых доступов
д) замедляет сборки\установку
е) не дает настраивать манифесты k8s
3) плохая документация. Какой минимум там должен быть:
а) процесс подключения
б) все (!) настройки
в) типовые ошибки и способы их устранения
г) минимальные требования по ресурсам и их изменение в зависимости от нагрузки
д) контакты поддержки
е) канал с информацией об обновлениях
С чем я сталкивался:
а) неочевидные проблемы при сборке\установке. Когда из сообщения об ошибке и документации вообще не ясна причина проблемы
б) неожиданное поведение в runtime, связанное с повышенным потреблением памяти, не описанное четко в документации
в) нет информации о том, в какой версии поддерживается конкретная фича (реализовано требование)
г) нет инструкции по обновлению на новую версию. При этом есть опасение, что поднятием версии процесс не ограничивается
д) магия и ее отсутствие. Поясню. Обещали, что все заработает само. Оно не работает. Почему - не ясно, т.к. принцип работы не описан.
4) имитация поддержки. Она как правило всегда есть, но иногда по факту ее нет) Вот такая диалектика) Хорошо, когда компонента работает из коробки. Как рассказывали на митапе, где она была презентована. А если нет?)
Что я ожидаю:
а) чатик\почту от разработчиков компоненты. лучше чатик
б) таск-трекер и SLA по обработке задач
в) канал с новостями
г) отдельная команда, помогающая с подключением (при необходимости)
д) чатик пользователей для обмена опытом
5) повышенное потребление ресурсов. Компонент закрывает какое нефункциональное требование к системе. Таких требований много. А еще есть бизнес-логика. И выглядит странно, когда один служебный компонент в минимально рекомендуемой конфигурации "жрёт" столько же или больше ресурсов, чем собственно бизнес-сервис.
6) не держит нагрузку. От платформенного "велосипеда" я ожидаю оптимизации в плане производительности. Т.е. он должен держать любую нагрузку, которая может быть в компании, где эта платформа разработана. Не требуя при этом слишком много железа. Иначе зачем это все?)
На этот раз у поста будет заголовок.
7 смертных грехов платформенных компонент.
И сразу небольшое уведомление - данные грехи возможны в любом сервисе, но в случае платформенных компонент они причиняют максимум боли) Ведь в чем суть платформы - не делай свой велосипед, вот тебе готовый, сертифицированный, спроектированный лучшими конструкторами на основе многолетнего опыта... Вы же бизнес-команда, вот и пилите свою бизнес-логику, а платформенные вещи оставьте профессионалам. А по факту ... бывает всякое.
Поехали!
1) слишком тесная связанность. Внешний компонент можно добавить в свой сервис разными способами. Как отдельный под рядом с основным сервисом, как сайдкар, как jar библиотеку. Варианты расположены в порядке увеличения связанности. Больше связанности - это плохо. Почему - отвечу на примере подключаемого jar. Как известно jar не приходит один. А тянет за собой зависимости. Их может быть много, они могут конфликтовать с другими зависимостями, содержать уязвимости, замедлять процесс старта, конфликтовать за общие ресурсы. Процесс подключения может быть нетривиален. А если подключение идет через корневой pom, то мы в каком-то смысле передаем управление нашим сервисом наружу.
2) отдельный пайплайн. Беда не приходит одна, и бывает так что внешний компонент тянет за собой свой CI или CD пайплайн. И то, и другое для конкретного сервиса может быть достаточно сложной и месяцами тщательно настраиваемой штукой. А теперь нам надо встроить туда чужой пайп. Или вызовом, или разобраться что же такого сложного делает внешний пайп и сэмулировать это в своем (а-ля реверс-инжиниринг). Второй вариант - сложно, остановимся на первом. Какие могут быть сложности с внешним пайпом?
а) много непонятных настроек
б) управляет версионированием дистрибутива (снова тесная связанность)
в) делает commits в наш репозиторий
г) требует особых доступов
д) замедляет сборки\установку
е) не дает настраивать манифесты k8s
3) плохая документация. Какой минимум там должен быть:
а) процесс подключения
б) все (!) настройки
в) типовые ошибки и способы их устранения
г) минимальные требования по ресурсам и их изменение в зависимости от нагрузки
д) контакты поддержки
е) канал с информацией об обновлениях
С чем я сталкивался:
а) неочевидные проблемы при сборке\установке. Когда из сообщения об ошибке и документации вообще не ясна причина проблемы
б) неожиданное поведение в runtime, связанное с повышенным потреблением памяти, не описанное четко в документации
в) нет информации о том, в какой версии поддерживается конкретная фича (реализовано требование)
г) нет инструкции по обновлению на новую версию. При этом есть опасение, что поднятием версии процесс не ограничивается
д) магия и ее отсутствие. Поясню. Обещали, что все заработает само. Оно не работает. Почему - не ясно, т.к. принцип работы не описан.
4) имитация поддержки. Она как правило всегда есть, но иногда по факту ее нет) Вот такая диалектика) Хорошо, когда компонента работает из коробки. Как рассказывали на митапе, где она была презентована. А если нет?)
Что я ожидаю:
а) чатик\почту от разработчиков компоненты. лучше чатик
б) таск-трекер и SLA по обработке задач
в) канал с новостями
г) отдельная команда, помогающая с подключением (при необходимости)
д) чатик пользователей для обмена опытом
5) повышенное потребление ресурсов. Компонент закрывает какое нефункциональное требование к системе. Таких требований много. А еще есть бизнес-логика. И выглядит странно, когда один служебный компонент в минимально рекомендуемой конфигурации "жрёт" столько же или больше ресурсов, чем собственно бизнес-сервис.
6) не держит нагрузку. От платформенного "велосипеда" я ожидаю оптимизации в плане производительности. Т.е. он должен держать любую нагрузку, которая может быть в компании, где эта платформа разработана. Не требуя при этом слишком много железа. Иначе зачем это все?)
7) слишком сложный релизный цикл. Это когда подключение компонента требует пройти 7 кругов ада. А прохождения некоторых кругов приходится ждать неделями или месяцами, например, из-за отсутствия железа. Я ожидаю понятного чек-листа подключения по всем средам - дев, тест и пром - и плана внедрения учитывающего наличие железа. Особенно если компонент подключается массово, или он обязательный.
P.S. Если говорить в позитивном ключе - что должны быть у переиспользуемой компоненты - см. мой пост https://t.me/javaKotlinDevOps/162
#platform
P.S. Если говорить в позитивном ключе - что должны быть у переиспользуемой компоненты - см. мой пост https://t.me/javaKotlinDevOps/162
#platform
Telegram
(java || kotlin) && devOps
Всем привет!
Уже говорил про переиспользование кода в общих библиотеках https://t.me/javaKotlinDevOps/137
Поднимемся на уровень выше: возьмем набор библиотек с общим кодом, добавим туда реализацию обязательных архитектурных стандартов, требований сопровождения…
Уже говорил про переиспользование кода в общих библиотеках https://t.me/javaKotlinDevOps/137
Поднимемся на уровень выше: возьмем набор библиотек с общим кодом, добавим туда реализацию обязательных архитектурных стандартов, требований сопровождения…
Всем привет!
Я сейчас на Highload-е. Оффлайн.
Сделаю серию заметок по докладам, которые посетил. Названия докладов примерные)
Нужен ли кэш при работе с современными БД?
Казалось бы ответ очевиден, но нет) В смысле не всегда.
Если брать инстанс СУБД Postgres или MySQL - да, кэш будет быстрее, но не то, что на порядок - даже не в разы. Два основных условия - инстанс БД используется только для чтения и используется актуальная версия СУБД. Более того - они ещё и неплохо масштабируются по ядрам CPU. Вопрос что дешевле - держать сервер кэша или ещё один сервер СУБД. В общем эффективность кэша нужно подтверждать на НТ.
Еще одно открытие для меня - MySQL не сильно медленнее Postgres. А пропатченный - даже быстрее. У меня был травматический опыт десятилетней давности с MySQL и обратное представление)
P.S. Если кто ещё на конференции?
#rdbms #caching
Я сейчас на Highload-е. Оффлайн.
Сделаю серию заметок по докладам, которые посетил. Названия докладов примерные)
Нужен ли кэш при работе с современными БД?
Казалось бы ответ очевиден, но нет) В смысле не всегда.
Если брать инстанс СУБД Postgres или MySQL - да, кэш будет быстрее, но не то, что на порядок - даже не в разы. Два основных условия - инстанс БД используется только для чтения и используется актуальная версия СУБД. Более того - они ещё и неплохо масштабируются по ядрам CPU. Вопрос что дешевле - держать сервер кэша или ещё один сервер СУБД. В общем эффективность кэша нужно подтверждать на НТ.
Еще одно открытие для меня - MySQL не сильно медленнее Postgres. А пропатченный - даже быстрее. У меня был травматический опыт десятилетней давности с MySQL и обратное представление)
P.S. Если кто ещё на конференции?
#rdbms #caching
Ещё один интересный момент про кэши: кэши - этот не только про скорость. Ещё два плюса:
1) более простой API, по крайней мере по сравнению с традиционным реляционными БД. noSQL решения играют на том же поле. Условно getByKey() сильно проще, чем SELECT a,b,c FROM x INNER JOIN ... Сложность выборки данных прячется в сервисе, заполняющем кэш
2) кэши в общем случае лучше масштабируются, вертикально и горизонтально, за счёт более простого устройства. Ключевое слово - в общем случае, как раз на докладе показали, что не все так хорошо
И сразу один жирный минус: усложнение системы, дублирование данных, синхронизация, допустимость устаревших данных...
#rdbms #caching
1) более простой API, по крайней мере по сравнению с традиционным реляционными БД. noSQL решения играют на том же поле. Условно getByKey() сильно проще, чем SELECT a,b,c FROM x INNER JOIN ... Сложность выборки данных прячется в сервисе, заполняющем кэш
2) кэши в общем случае лучше масштабируются, вертикально и горизонтально, за счёт более простого устройства. Ключевое слово - в общем случае, как раз на докладе показали, что не все так хорошо
И сразу один жирный минус: усложнение системы, дублирование данных, синхронизация, допустимость устаревших данных...
#rdbms #caching
Транзакционность в Kafka.
Транзакцию легко реализовать в рамках БД. Еще есть распреденные транзакции: старый недобрый JTA - долго и дорого, паттерн Сага с eventually consistentcy - работает, при этом требует проработки архитектуры системы в целом.
А что Kafka?
Казалось бы - append only запись и чтение, какие транзакции? Транзакции внутри Kafka - запись на N брокеров, Zookeeper и возврат ответа в producer - выносим за скобки, не было бы тут транзакционности - кто бы ей пользовался)
Но транзакции могут быть на уровне бизнес-логики. Например, мы можем перекладывать сообщения из одного топика в другой попутно выполняя над ними преобразования. Запись - понятно, а чтение из Kafka - это тоже запись, точнее сдвиг текущей позиции для данного consumer в топике.
Так что с транзакциям внутри Kafka (внутри- это принципиально)? Они есть. С ACID, все как положено.
Детали тут https://www.confluent.io/blog/transactions-apache-kafka/
Интересно, что запись в топике появится сразу. Но это запись «почтальона Печкина», consumer вам ее не покажет, потому что у вас документов нету, тьфу, не то, потому что транзакция не зафиксирована) Регулируется это служебными заголовками. Данный лайфхак улучшает время чтения данных из транзакции, по сути это предварительное кэширование.
Полноценно функционал доступен начиная с версии 3.6. Последняя на данный момент 3.9
#kafka #transactions #streaming
Транзакцию легко реализовать в рамках БД. Еще есть распреденные транзакции: старый недобрый JTA - долго и дорого, паттерн Сага с eventually consistentcy - работает, при этом требует проработки архитектуры системы в целом.
А что Kafka?
Казалось бы - append only запись и чтение, какие транзакции? Транзакции внутри Kafka - запись на N брокеров, Zookeeper и возврат ответа в producer - выносим за скобки, не было бы тут транзакционности - кто бы ей пользовался)
Но транзакции могут быть на уровне бизнес-логики. Например, мы можем перекладывать сообщения из одного топика в другой попутно выполняя над ними преобразования. Запись - понятно, а чтение из Kafka - это тоже запись, точнее сдвиг текущей позиции для данного consumer в топике.
Так что с транзакциям внутри Kafka (внутри- это принципиально)? Они есть. С ACID, все как положено.
Детали тут https://www.confluent.io/blog/transactions-apache-kafka/
Интересно, что запись в топике появится сразу. Но это запись «почтальона Печкина», consumer вам ее не покажет, потому что у вас документов нету, тьфу, не то, потому что транзакция не зафиксирована) Регулируется это служебными заголовками. Данный лайфхак улучшает время чтения данных из транзакции, по сути это предварительное кэширование.
Полноценно функционал доступен начиная с версии 3.6. Последняя на данный момент 3.9
#kafka #transactions #streaming
Confluent
Transactions in Apache Kafka | Confluent
Learn the main concepts needed to use the transaction API in Apache Kafka effectively.
Всем привет!
Окей, транзакции в Kafka и в БД по отдельности у нас есть. А можно объединить их в одной транзакции?
Во-первых у нас есть паттерн Сага.
А во-вторых - YDB (от Яндекса).
Вообще интересно развивалась данная СУБД. Вначале это было быстрое и горизонтально масштабируемое облачное noSQL хранилище с полноценными транзакциями. Потом разработчикам не понравилось, как работает Kafka в многопользовательском режиме, и они добавили в YDB топики. Ещё один плюс - не надо отдельно разворачивать Kafka. И наконец «финалочка» - появилась поддержка транзакций топики+таблицы. Паттерн Transaction outbox - давай, до свидания)
Вообще людям, которые могут себе позволить облако Яндекса по финансовым и идеологическим соображениям, не завязанных на существующий технологический стек - им можно только позавидовать)
Ложка дёгтя - транзакции в YDB пока работают медленнее Kafka. И медленнее, чем хотелось бы команде Яндекса. Команда работает над этим)
#rdbms #transactions #kafka #streaming
Окей, транзакции в Kafka и в БД по отдельности у нас есть. А можно объединить их в одной транзакции?
Во-первых у нас есть паттерн Сага.
А во-вторых - YDB (от Яндекса).
Вообще интересно развивалась данная СУБД. Вначале это было быстрое и горизонтально масштабируемое облачное noSQL хранилище с полноценными транзакциями. Потом разработчикам не понравилось, как работает Kafka в многопользовательском режиме, и они добавили в YDB топики. Ещё один плюс - не надо отдельно разворачивать Kafka. И наконец «финалочка» - появилась поддержка транзакций топики+таблицы. Паттерн Transaction outbox - давай, до свидания)
Вообще людям, которые могут себе позволить облако Яндекса по финансовым и идеологическим соображениям, не завязанных на существующий технологический стек - им можно только позавидовать)
Ложка дёгтя - транзакции в YDB пока работают медленнее Kafka. И медленнее, чем хотелось бы команде Яндекса. Команда работает над этим)
#rdbms #transactions #kafka #streaming
Как мне напомнили в комментариях - история развивается по спирали.
Очереди (очереди не равно топики Kafka) есть в Oracle https://docs.oracle.com/en/database/oracle/oracle-database/19/adque/aq-introduction.html
И они поддерживают общие транзакции с таблицами.
Также у Oracle есть шлюз для связывания внутренних и внешних очередей https://docs.oracle.com/en/database/oracle/oracle-database/21/adque/messaging_gateway.html
Аналогично для MSSQL https://learn.microsoft.com/ru-ru/sql/database-engine/service-broker/benefits-of-programming-with-service-broker?view=sql-server-ver16
Спасибо @AViIgnatov
#rdbms #mq #transactions
Очереди (очереди не равно топики Kafka) есть в Oracle https://docs.oracle.com/en/database/oracle/oracle-database/19/adque/aq-introduction.html
И они поддерживают общие транзакции с таблицами.
Также у Oracle есть шлюз для связывания внутренних и внешних очередей https://docs.oracle.com/en/database/oracle/oracle-database/21/adque/messaging_gateway.html
Аналогично для MSSQL https://learn.microsoft.com/ru-ru/sql/database-engine/service-broker/benefits-of-programming-with-service-broker?view=sql-server-ver16
Спасибо @AViIgnatov
#rdbms #mq #transactions
Oracle Help Center
Advanced Queuing User's Guide
Advanced Queuing (AQ) is a robust and feature-rich message queuing system integrated with Oracle Database. These topics discuss Oracle Database Advanced Queuing (AQ) and the requirements for complex information handling in an integrated environment.
Ещё один интересный доклад - про самую производительную утилиту для НТ - и это wrk2. Позволяет на типовой машине 8 ядер и 12 Гб (надеюсь правильно запомнил конфигурацию, но плюс минус так) подымать 10 000+ параллельных соединений в несколько потоков. Плюс минимизировать эффект от временной недоступности тестируемой системы - т.наз. Coordinated Omission - как числом потоков, так и математической корректировкой результата теста и дальнейшей последовательности вызовов. Надеюсь, заинтриговал) Минус - утилита заброшена автором с 2016 года, но этот минус поправили, см https://t.me/rybakalexey/98
По ссылке - блог автора доклада. Плюс сам доклад https://t.me/rybakalexey/170
#нт #tools
По ссылке - блог автора доклада. Плюс сам доклад https://t.me/rybakalexey/170
#нт #tools
Telegram
System Design & Highload (Alexey Rybak)
Нагрузочное тестирование с wrk2/wrkx. Онлайн-митап DevHands.io 14 мая 18:30 MSK
В прошлом году когда я запускал хайлоад-буткемп и делал модуль про нагрузочное тестирование, мониторинг и тюнинг, я выбрал wrk2. Выбрал за скорость и простоту и ни разу не пожалел…
В прошлом году когда я запускал хайлоад-буткемп и делал модуль про нагрузочное тестирование, мониторинг и тюнинг, я выбрал wrk2. Выбрал за скорость и простоту и ни разу не пожалел…
Ещё интересный доклад - про нетривиальное использование трейсинга (tracing).
Начнём с того, что далеко не у всех он настроен. Окей, настроили. Теперь нам проще разбирать проблемы на ПРОМ в микросервисной архитектуре.
Все?
Нет) А если взять трейсы за некий период, отсемплировать их уменьшив объём и сложить их в графовую БД? Получим реверс-инжиниринг архитектуры. Причём это будет не «мертвая» архитектура, по кем-то когда-то написанной аналитике, а настоящая. Да, не 100% точная, из-за мертвых интеграций и поломанного трейсинга, но все же. Что с ней можно сделать? Контролировать... архитектуру. Например:
- Общая схема вызовов
- Циклические ссылки
- Длина цепочек вызовов
- Лишние с точки зрения разделения на бизнес-домены связи
- Критичность сервисов - сервисы, которые чаще всего используются другими сервисами
- Однотипные вызовы, которые можно объединить в batch запрос
- Вызовы в цикле
- Анализ использования практики Graceful degradation
Сама идея - практически бесплатный для бизнес-команд инструмент анализа архитектуры - отлично IMHO.
P.S. для этих же целей в теории можно использовать данные из Service Mesh, только добавляется ещё один снижающий точность фактор - не все компоненты находятся в облаке (и не все компоненты в облаке используют Service Mesh)
P.P.S. Конечно идея идеально подходит для компаний а-ля Яндекс и Авито (собственно в Авито ее и внедрили) - там, где нет жёсткого контроля интеграций на уровне согласования аналитики. Но IMHO в любом случае можно использовать как контрольный механизм, ещё одну «сеть»
#arch #tracing
Начнём с того, что далеко не у всех он настроен. Окей, настроили. Теперь нам проще разбирать проблемы на ПРОМ в микросервисной архитектуре.
Все?
Нет) А если взять трейсы за некий период, отсемплировать их уменьшив объём и сложить их в графовую БД? Получим реверс-инжиниринг архитектуры. Причём это будет не «мертвая» архитектура, по кем-то когда-то написанной аналитике, а настоящая. Да, не 100% точная, из-за мертвых интеграций и поломанного трейсинга, но все же. Что с ней можно сделать? Контролировать... архитектуру. Например:
- Общая схема вызовов
- Циклические ссылки
- Длина цепочек вызовов
- Лишние с точки зрения разделения на бизнес-домены связи
- Критичность сервисов - сервисы, которые чаще всего используются другими сервисами
- Однотипные вызовы, которые можно объединить в batch запрос
- Вызовы в цикле
- Анализ использования практики Graceful degradation
Сама идея - практически бесплатный для бизнес-команд инструмент анализа архитектуры - отлично IMHO.
P.S. для этих же целей в теории можно использовать данные из Service Mesh, только добавляется ещё один снижающий точность фактор - не все компоненты находятся в облаке (и не все компоненты в облаке используют Service Mesh)
P.P.S. Конечно идея идеально подходит для компаний а-ля Яндекс и Авито (собственно в Авито ее и внедрили) - там, где нет жёсткого контроля интеграций на уровне согласования аналитики. Но IMHO в любом случае можно использовать как контрольный механизм, ещё одну «сеть»
#arch #tracing
Highload прошел, но интересные доклады еще остались)
"AppHost: как Яндекс организует взаимодействие сотен микросервисов"
Честно - не ожидал такого хода от Яндекса.
В чем суть?
У Яндекса микросервисная архитектура, большое количество микросервисов и жесткие требования по времени ответа пользователю. При этом очень сложно контролировать всю цепочку вызовов микросервисов по конкретной фиче, чтобы оптимизировать время ответа. Убрать лишние вызовы или найти самый долгий для его оптимизации. Один из вариантов решения проблемы есть в предыдущем моем посте (реверс-инжиниринг по трейсам), но ребят данный вариант не устроил из-за его не 100% точности.
Они тоже сделали граф вызовов для каждого бизнес-процесса. Но граф этот задается владельцем процесса явно в текстовом виде. Ремарка - как найти владельца для бизнес-процесса из десятка микросервисов - отдельный вопрос. Возвращаясь к сути, из того что я увидел: в конфигурации задаются сервисы - поставщики данных, их зависимости, таймауты, протоколы и схемы обмена данными. И это не просто часть аналитики, более того - как я понимаю в Яндексе нет требований по наличию аналитики. Это исполняемая спецификация: каждый запрос вначале попадает на новый микросервис - собственно AppHost из названия доклада - который загружает граф и выполняет его. Вызывая нужные микросервисы, предварительно проверяя необходимость и возможность его вызова. В итоге получаем топологию микросервисов в виде звезды, где AppHost в центре.
Сразу же возникает вопрос по надежности решения.
Ответы:
а) AppHost - stateless сервис, горизонтально масштабируемый, более того его инсталляции разделены по разным бизнес-доментам. Плюс есть всякие лайфхаки - например, при сбое по умолчанию пользовательский запрос отправляется на повторное выполнение, но при наличии специфических ошибок (ошибок, ломающих логику AppHost) повтор отключается
б) всегда есть критически важные сервисы, от которых зависят все или почти все остальные. Аутентификация, авторизация, прокси - как минимум. И ничего - они тоже дорабатываются, новые версии выкатываются. Здесь главное не сделать такой оркестратор слишком сложным.
Да, возвращаясь к принципу: все новое - это хорошо забытое старое. Во-первых это мне напоминает паттерн Сага в виде оркестратора. Во-вторых - старый недобрый ESB - Enterprise Service Bus - на новом витке развития. Напомню, его ключевое отличие от Kafka - брокер ESB содержит бизнес-логику и занимается маппингом данных, а брокер Kafka - в основном обеспечивает отказоустойчивость.
Ну и отдельно - вот принцип Architecture As Code в действии. Этап вливания конфигурации с графом сервисов - хорошая точка для контроля архитектуры. В целом идея мне нравится, ключевой момент тут - сознательное ограничение сложности оркестратора. Тогда получим увеличение надежности системы в целом. Но повторюсь - не ожидал, что эта идея возникнет у Яндекса.
#arch #aac #saga #esb
"AppHost: как Яндекс организует взаимодействие сотен микросервисов"
Честно - не ожидал такого хода от Яндекса.
В чем суть?
У Яндекса микросервисная архитектура, большое количество микросервисов и жесткие требования по времени ответа пользователю. При этом очень сложно контролировать всю цепочку вызовов микросервисов по конкретной фиче, чтобы оптимизировать время ответа. Убрать лишние вызовы или найти самый долгий для его оптимизации. Один из вариантов решения проблемы есть в предыдущем моем посте (реверс-инжиниринг по трейсам), но ребят данный вариант не устроил из-за его не 100% точности.
Они тоже сделали граф вызовов для каждого бизнес-процесса. Но граф этот задается владельцем процесса явно в текстовом виде. Ремарка - как найти владельца для бизнес-процесса из десятка микросервисов - отдельный вопрос. Возвращаясь к сути, из того что я увидел: в конфигурации задаются сервисы - поставщики данных, их зависимости, таймауты, протоколы и схемы обмена данными. И это не просто часть аналитики, более того - как я понимаю в Яндексе нет требований по наличию аналитики. Это исполняемая спецификация: каждый запрос вначале попадает на новый микросервис - собственно AppHost из названия доклада - который загружает граф и выполняет его. Вызывая нужные микросервисы, предварительно проверяя необходимость и возможность его вызова. В итоге получаем топологию микросервисов в виде звезды, где AppHost в центре.
Сразу же возникает вопрос по надежности решения.
Ответы:
а) AppHost - stateless сервис, горизонтально масштабируемый, более того его инсталляции разделены по разным бизнес-доментам. Плюс есть всякие лайфхаки - например, при сбое по умолчанию пользовательский запрос отправляется на повторное выполнение, но при наличии специфических ошибок (ошибок, ломающих логику AppHost) повтор отключается
б) всегда есть критически важные сервисы, от которых зависят все или почти все остальные. Аутентификация, авторизация, прокси - как минимум. И ничего - они тоже дорабатываются, новые версии выкатываются. Здесь главное не сделать такой оркестратор слишком сложным.
Да, возвращаясь к принципу: все новое - это хорошо забытое старое. Во-первых это мне напоминает паттерн Сага в виде оркестратора. Во-вторых - старый недобрый ESB - Enterprise Service Bus - на новом витке развития. Напомню, его ключевое отличие от Kafka - брокер ESB содержит бизнес-логику и занимается маппингом данных, а брокер Kafka - в основном обеспечивает отказоустойчивость.
Ну и отдельно - вот принцип Architecture As Code в действии. Этап вливания конфигурации с графом сервисов - хорошая точка для контроля архитектуры. В целом идея мне нравится, ключевой момент тут - сознательное ограничение сложности оркестратора. Тогда получим увеличение надежности системы в целом. Но повторюсь - не ожидал, что эта идея возникнет у Яндекса.
#arch #aac #saga #esb
На Highload услышал упоминание про timeout propagation и вспомнил, что давно хотел эту тему поднять.
В чем суть - где-то настроен timeout, и для того, чтобы upstream сервисы знали про него - мы передаём его в заголовках, также как и traceId. Наилучшее место для создания этих заголовков - входной шлюз. Или API Gateway - именно так сделали в Avito. Передать таймуат можно двумя способами - как длительность, X-Timeout = 5s или как время - X-Deadline: 06.12.2024 14:55:45. Второй вариант проще обрабатывать на upstream серверах, т.к. не нужно вычислять сколько из первоначального таймаута осталось, но требуется синхронизация времени на всех серверах.
Казалось бы - добавили таймаут, пробросили по цепочке, сервисы знают дедлайн и могут прервать обработку и не тратить лишние ресурсы, если результат уже не нужен. Вот он профит.
Но возникает вопрос - будут ли его использовать? Как это проконтролировать? К тому же не каждый процесс можно прерывать. На первый взгляд можно операции чтения - ведь клиент уже не прочитает данные, соединение прервется выше по цепочке. Но возможно имеет смысл вернуть клиенту хоть что-то - или fallback ответ, или часть ответа, которую успели подготовить. И вернуть чуть раньше дедлайна, чтобы запрос успел дойти до клиента. Т.е. в общем случае задачу автоматически решить кажется можно, но нужен фреймворк и его внедрение по всей цепочке сервисов. Причём фреймворк, работающий поверх существующих контроллеров и клиентов.
#reliability #timeout
В чем суть - где-то настроен timeout, и для того, чтобы upstream сервисы знали про него - мы передаём его в заголовках, также как и traceId. Наилучшее место для создания этих заголовков - входной шлюз. Или API Gateway - именно так сделали в Avito. Передать таймуат можно двумя способами - как длительность, X-Timeout = 5s или как время - X-Deadline: 06.12.2024 14:55:45. Второй вариант проще обрабатывать на upstream серверах, т.к. не нужно вычислять сколько из первоначального таймаута осталось, но требуется синхронизация времени на всех серверах.
Казалось бы - добавили таймаут, пробросили по цепочке, сервисы знают дедлайн и могут прервать обработку и не тратить лишние ресурсы, если результат уже не нужен. Вот он профит.
Но возникает вопрос - будут ли его использовать? Как это проконтролировать? К тому же не каждый процесс можно прерывать. На первый взгляд можно операции чтения - ведь клиент уже не прочитает данные, соединение прервется выше по цепочке. Но возможно имеет смысл вернуть клиенту хоть что-то - или fallback ответ, или часть ответа, которую успели подготовить. И вернуть чуть раньше дедлайна, чтобы запрос успел дойти до клиента. Т.е. в общем случае задачу автоматически решить кажется можно, но нужен фреймворк и его внедрение по всей цепочке сервисов. Причём фреймворк, работающий поверх существующих контроллеров и клиентов.
#reliability #timeout
Всем привет!
Уже писал про импортозамещение в ПО:
1) IDE https://t.me/javaKotlinDevOps/353
2) Spring plugins https://t.me/javaKotlinDevOps/358
Две ремарки - термин импортозамещение сильно скомпрометировали, но другой более удачный я пока не придумал) И некоторые из описываемых продуктов разрабатывались не для импортозамещения, но события последних лет дали неплохой импульс для их развития.
Так вот, на Highload-е нашёл 2 аналога GitLab/GitHub:
1) GitVerse от Сбера. Как и GigaIDE находится в процессе разработки, в частности аналог Git Actions планируют допилить в ближайших релизах, сейчас для настройки требуется много ручных действий. Две основные фишки: интеграция с GigaCode и облачная IDE на основе VS Code, доступная в рамках бета-тестирования. Для облачной IDE нужен аккаунт и настройка в облаке Сбера - cloud.ru. И к сожалению не поддерживается Java - зато есть Python, Go, С#. Интерфейс аскетичный, но подсветка синтаксиса, AutoComplete, работа с тестами, отладка и консоль есть. Пока все бесплатно, конечно временно) Еще фишка - доступно AI ревью кода https://gitverse.ru/docs/collaborative-work/code-review/#ai-ревью И в целом ревью неплохое - я скормил ему кусок кода "с запахами", и AI нашел там 6 багов из 18. Минус: все работает медленно - думаю сказывается бесплатность и статус беты.
2) GitFlic от Астра (которая Linux). В нём есть Ci/CD, реестр артефактов, статический анализ кода (названный почему-то SAST), REST API и интеграция с Telegram и JIRA. И платная версия, позволяющая добавлять более 5 человек в private репозиторий плюс расширенную поддержку https://gitflic.ru/price Пока нет полноценно баг-трекера, обещают сделать. Еще плюс - тут я быстро нашел как разрешить force push, в отличие от GitVerse)
GitFlic на данный момент выглядит законченным продуктом, но у GitVerse есть свои плюсы - см. выше. Плюс тесная интеграция с облачным провайдером cloud.ru
#импортозамещение #git
Уже писал про импортозамещение в ПО:
1) IDE https://t.me/javaKotlinDevOps/353
2) Spring plugins https://t.me/javaKotlinDevOps/358
Две ремарки - термин импортозамещение сильно скомпрометировали, но другой более удачный я пока не придумал) И некоторые из описываемых продуктов разрабатывались не для импортозамещения, но события последних лет дали неплохой импульс для их развития.
Так вот, на Highload-е нашёл 2 аналога GitLab/GitHub:
1) GitVerse от Сбера. Как и GigaIDE находится в процессе разработки, в частности аналог Git Actions планируют допилить в ближайших релизах, сейчас для настройки требуется много ручных действий. Две основные фишки: интеграция с GigaCode и облачная IDE на основе VS Code, доступная в рамках бета-тестирования. Для облачной IDE нужен аккаунт и настройка в облаке Сбера - cloud.ru. И к сожалению не поддерживается Java - зато есть Python, Go, С#. Интерфейс аскетичный, но подсветка синтаксиса, AutoComplete, работа с тестами, отладка и консоль есть. Пока все бесплатно, конечно временно) Еще фишка - доступно AI ревью кода https://gitverse.ru/docs/collaborative-work/code-review/#ai-ревью И в целом ревью неплохое - я скормил ему кусок кода "с запахами", и AI нашел там 6 багов из 18. Минус: все работает медленно - думаю сказывается бесплатность и статус беты.
2) GitFlic от Астра (которая Linux). В нём есть Ci/CD, реестр артефактов, статический анализ кода (названный почему-то SAST), REST API и интеграция с Telegram и JIRA. И платная версия, позволяющая добавлять более 5 человек в private репозиторий плюс расширенную поддержку https://gitflic.ru/price Пока нет полноценно баг-трекера, обещают сделать. Еще плюс - тут я быстро нашел как разрешить force push, в отличие от GitVerse)
GitFlic на данный момент выглядит законченным продуктом, но у GitVerse есть свои плюсы - см. выше. Плюс тесная интеграция с облачным провайдером cloud.ru
#импортозамещение #git
Telegram
(java || kotlin) && devOps
Всем привет!
Есть такая отличная IDE для Java и Kotlin - IntelliJ IDEA.
Лучшая если быть точным)
И у нее есть 2 версии: Community и Ultimate.
Отличия можно посмотреть тут https://www.jetbrains.com/products/compare/?product=idea&product=idea-ce
Плохая новость…
Есть такая отличная IDE для Java и Kotlin - IntelliJ IDEA.
Лучшая если быть точным)
И у нее есть 2 версии: Community и Ultimate.
Отличия можно посмотреть тут https://www.jetbrains.com/products/compare/?product=idea&product=idea-ce
Плохая новость…
В нескольких недавно выпущенных русскоязычных книгах замечаю отдельное упоминание о научном редакторе, являющимся практикующим ИТ инженером. Аллилуйя!) Google translate и студентов лингвистических вузов маловато для качественного перевода) Надеюсь, это станет стандартом
#books
#books
Всем привет!
Читаю сейчас книжку Open Telemetry, первая глава, вступление о том, зачем все это нужно.
Обычно во вступлении не так много ценной информации, но бывают исключения)
Нашел сравнение Open Telemetry с DevOps. Казалось бы, что может быть у них общего? Кроме того, что DevOps инженеры настраивают Open Telemetry систему совместно с разработчиками и сопровождением.
Ответ - идеология.
Для начала - что такое DevOps?
Набор инструментов - да. Но в первую очередь идея о том, что для быстрого деплоя приложения на ПРОМ важно сотрудничество Dev и Ops, а также забытых в этой формуле Test и Sec)
Аналогично, OpenTelemetry - это не просто стандарт сбора, передачи и хранения логов, метрик и трейсов. Это идея о том, что для разбора, а в идеале предсказания проблемы нужно единое представление перечисленных ранее данных. Назовем все эти данные телеметрией.
Т.е. ключевая идея - сами по себе логи, метрики и трейсы конечно же полезны. Но вместе их ценность сильно возрастает. И, естественно, в телеметрии должны быть признаки для матчинга этих данных между собой.
Читаю дальше)
Ввожу новый тэг -
#telemetry
Читаю сейчас книжку Open Telemetry, первая глава, вступление о том, зачем все это нужно.
Обычно во вступлении не так много ценной информации, но бывают исключения)
Нашел сравнение Open Telemetry с DevOps. Казалось бы, что может быть у них общего? Кроме того, что DevOps инженеры настраивают Open Telemetry систему совместно с разработчиками и сопровождением.
Ответ - идеология.
Для начала - что такое DevOps?
Набор инструментов - да. Но в первую очередь идея о том, что для быстрого деплоя приложения на ПРОМ важно сотрудничество Dev и Ops, а также забытых в этой формуле Test и Sec)
Аналогично, OpenTelemetry - это не просто стандарт сбора, передачи и хранения логов, метрик и трейсов. Это идея о том, что для разбора, а в идеале предсказания проблемы нужно единое представление перечисленных ранее данных. Назовем все эти данные телеметрией.
Т.е. ключевая идея - сами по себе логи, метрики и трейсы конечно же полезны. Но вместе их ценность сильно возрастает. И, естественно, в телеметрии должны быть признаки для матчинга этих данных между собой.
Читаю дальше)
Ввожу новый тэг -
#telemetry
Всем привет!
Есть много способов получить данные из БД с помощью JPA:
1) JPQL
2) JPQL Native Query
3) HQL
4) Spring Data JPA Repository
5) Criteria API
6) QueryDSL
...
Предположим, нам нужно вернуть набор строк. Задать параметры запроса можно по-разному, а итог будет один - List или другая коллекция (Collection) с набором данных. Верно? Не совсем)
Если посмотреть на список возвращаемых Spring Data JPA данных https://docs.spring.io/spring-data/jpa/reference/repositories/query-return-types-reference.html#appendix.query.return.types то там можно увидеть много чего интересного. В т.ч. Stream.
А вот пример его использования: https://vladmihalcea.com/spring-data-jpa-stream/
Аналогично можно вернуть Stream и из обычного JPA - см. метод getResultStream, вот пример: https://thorben-janssen.com/jpa-2-2s-new-stream-method-and-how-you-should-not-use-it/
Зачем это может быть нужно?
Во-первых это просто красиво... Шучу. Если вы используете Stream в бизнес-логике - то кажется логичным использовать их и при обращении к БД.
А во-вторых: главная особенность стриминга - равномерная выборка данных. И в каждый момент данных в обработке будет одна запись.
Рассмотрим кейс, когда нужно обработать на клиенте миллион записей.
Ремарка: если у вас такой кейс - подумайте, нет ли проблем в архитектуре. Данные лучше обрабатывать на сервере СУБД. Если все же проблем нет - продолжим)
Так вот, какие у нас варианты:
1) вытащить на клиент миллион записей. Запрос к БД будет один, она выдержит, но с неплохой вероятностью можно убить клиент через Out of Memory.
2) организовать пагинацию, например, вот так: https://www.baeldung.com/spring-data-jpa-iterate-large-result-sets. Данных на клиенте в моменте не много, по размеру страницы, но запросов к БД ... тысяча.
3) использовать стримы. Запрос к БД один, данных на клиенте немного. Не обязательно одна запись, но в любом случае немного, детали ниже.
К слову, стриминг по БД с JPA аналогичен перемещению курсора по ResultSet в JDBC. С накладными расходами и плюшкам, которые дает сессия JPA, конечно.
И про объем данных на клиенте. Казалось бы - вытаскиваем записи поштучно. Но если не указать fetch size - объём предварительной выборки - для некоторых СУБД Hibernate вытащит на клиента все данные за раз, и мы вернемся к варианту 1 (((
#jpa #java_streams #rdbms
Есть много способов получить данные из БД с помощью JPA:
1) JPQL
2) JPQL Native Query
3) HQL
4) Spring Data JPA Repository
5) Criteria API
6) QueryDSL
...
Предположим, нам нужно вернуть набор строк. Задать параметры запроса можно по-разному, а итог будет один - List или другая коллекция (Collection) с набором данных. Верно? Не совсем)
Если посмотреть на список возвращаемых Spring Data JPA данных https://docs.spring.io/spring-data/jpa/reference/repositories/query-return-types-reference.html#appendix.query.return.types то там можно увидеть много чего интересного. В т.ч. Stream.
А вот пример его использования: https://vladmihalcea.com/spring-data-jpa-stream/
Аналогично можно вернуть Stream и из обычного JPA - см. метод getResultStream, вот пример: https://thorben-janssen.com/jpa-2-2s-new-stream-method-and-how-you-should-not-use-it/
Зачем это может быть нужно?
Во-первых это просто красиво... Шучу. Если вы используете Stream в бизнес-логике - то кажется логичным использовать их и при обращении к БД.
А во-вторых: главная особенность стриминга - равномерная выборка данных. И в каждый момент данных в обработке будет одна запись.
Рассмотрим кейс, когда нужно обработать на клиенте миллион записей.
Ремарка: если у вас такой кейс - подумайте, нет ли проблем в архитектуре. Данные лучше обрабатывать на сервере СУБД. Если все же проблем нет - продолжим)
Так вот, какие у нас варианты:
1) вытащить на клиент миллион записей. Запрос к БД будет один, она выдержит, но с неплохой вероятностью можно убить клиент через Out of Memory.
2) организовать пагинацию, например, вот так: https://www.baeldung.com/spring-data-jpa-iterate-large-result-sets. Данных на клиенте в моменте не много, по размеру страницы, но запросов к БД ... тысяча.
3) использовать стримы. Запрос к БД один, данных на клиенте немного. Не обязательно одна запись, но в любом случае немного, детали ниже.
К слову, стриминг по БД с JPA аналогичен перемещению курсора по ResultSet в JDBC. С накладными расходами и плюшкам, которые дает сессия JPA, конечно.
И про объем данных на клиенте. Казалось бы - вытаскиваем записи поштучно. Но если не указать fetch size - объём предварительной выборки - для некоторых СУБД Hibernate вытащит на клиента все данные за раз, и мы вернемся к варианту 1 (((
#jpa #java_streams #rdbms
Vlad Mihalcea
The best way to use Spring Data JPA Stream methods - Vlad Mihalcea
Learn what is the best way to use Spring Data JPA Stream query methods to avoid prefetching all the data in MySQL and PostgreSQL.
Всем привет!
Я снова вернулся)
И предновогодний пост будет снова про AI и Java.
Для начала про LLM. Чтобы LLM дала осмысленный ответ - ей нужен правильный промт и побольше контекста. Не даром в новых версиях моделей объем контекста растет - возьмем тот же Gemini с 1 млн токенов.
Но с точки зрения разработки - важен не только объем, но автоматизация работы с контекстом, т.е. некая бизнес-логики. Например, если мы делаем свой агент и у нас несколько источников точных данных, которые мы хотим скормить модели. И эта бизнес-логика скорее всего будет похожая у разных агентов...
LLM - область достаточно молодая, стандарты в ней зарождаются прямо сейчас. Встречайте MCP https://spec.modelcontextprotocol.io/specification/ - сайт стандарта - и https://habr.com/ru/articles/862312/ - интро на русском.
Он стандартизирует в первую очередь транспортное API - клиент и сервер - для работы с источниками точных данных и LLM. Содержит ряд готовых серверов для работы с файловыми данными, СУБД, веб-поиском.
Как это все относится к Java? А вот как: есть Spring AI, уже писал про него https://t.me/javaKotlinDevOps/241 Он дает универсальное API для обращения к различным LLM. Сейчас туда добавили - в статусе experimental - Spring AI MCP https://docs.spring.io/spring-ai/reference/api/model-context-protocol.html
Причем добавили достаточно быстро, хотя до Python конечно же далеко. Вообще поддержка Python, я полагаю, появилась вместе со стандрартом)
P.S. Да, вспоминая Kotlin в названии канала - если посмотреть примеры Spring AI - получите, распишитесь: https://github.com/spring-projects/spring-ai-examples/blob/main/kotlin/
#llm #spring
Я снова вернулся)
И предновогодний пост будет снова про AI и Java.
Для начала про LLM. Чтобы LLM дала осмысленный ответ - ей нужен правильный промт и побольше контекста. Не даром в новых версиях моделей объем контекста растет - возьмем тот же Gemini с 1 млн токенов.
Но с точки зрения разработки - важен не только объем, но автоматизация работы с контекстом, т.е. некая бизнес-логики. Например, если мы делаем свой агент и у нас несколько источников точных данных, которые мы хотим скормить модели. И эта бизнес-логика скорее всего будет похожая у разных агентов...
LLM - область достаточно молодая, стандарты в ней зарождаются прямо сейчас. Встречайте MCP https://spec.modelcontextprotocol.io/specification/ - сайт стандарта - и https://habr.com/ru/articles/862312/ - интро на русском.
Он стандартизирует в первую очередь транспортное API - клиент и сервер - для работы с источниками точных данных и LLM. Содержит ряд готовых серверов для работы с файловыми данными, СУБД, веб-поиском.
Как это все относится к Java? А вот как: есть Spring AI, уже писал про него https://t.me/javaKotlinDevOps/241 Он дает универсальное API для обращения к различным LLM. Сейчас туда добавили - в статусе experimental - Spring AI MCP https://docs.spring.io/spring-ai/reference/api/model-context-protocol.html
Причем добавили достаточно быстро, хотя до Python конечно же далеко. Вообще поддержка Python, я полагаю, появилась вместе со стандрартом)
P.S. Да, вспоминая Kotlin в названии канала - если посмотреть примеры Spring AI - получите, распишитесь: https://github.com/spring-projects/spring-ai-examples/blob/main/kotlin/
#llm #spring
Всем привет!
Прочитал статью про работу с секретами в Java: https://habr.com/ru/companies/sberbank/articles/870116/
Лично я из статьи подметил три интересных момента:
1) Сейчас много говорят о безопасной разработке. Книги, доклады на конференциях… Что имеем на практике? Вот есть понятная рекомендация — хранить пароли не в String, а в char[]. Так как String — это объект, и его содержимое будет в heap dump до очередной уборки мусора. А уборка мусора проходит в несколько этапов, и принудительно вызвать её мы не можем. А char[] мы можем очистить сразу после использования. Так вот — в статье у нас есть embedded Tomcat, Jersey HTTP client и Hikari pool. Три широко распространённых компонента, требующих секретов при работе. Сколько из них поддерживают передачу секретов в char[]? Увы, только Jersey client. И это уровень фреймворков и библиотек, на бизнес-уровне всё будет ещё хуже.
2) Перегружаемые настройки Spring Cloud, работающие через @RefreshScope и описанные мною ранее, подходят, увы, не всегда. Основная проблема — передача секрета в компоненты, инициализируемые сложно, однократно при старте или некорректно обрабатывающие событие обновления секретов — например, сбрасывающие активные клиентские сессии.
3) Кроме @RefreshScope изобрели ещё два “велосипеда", причём оба в Spring Boot: SSL bundles и Spring Cloud Vault. Первый предназначен для работы с хранилищами сертификатов, второй — для работы с HashiCorp Vault. Оба поддерживают обновление секретов на лету. Все три инструмента взаимодополняют друг друга, хотя и не покрывают 100% кейсов.
#security #spring
Прочитал статью про работу с секретами в Java: https://habr.com/ru/companies/sberbank/articles/870116/
Лично я из статьи подметил три интересных момента:
1) Сейчас много говорят о безопасной разработке. Книги, доклады на конференциях… Что имеем на практике? Вот есть понятная рекомендация — хранить пароли не в String, а в char[]. Так как String — это объект, и его содержимое будет в heap dump до очередной уборки мусора. А уборка мусора проходит в несколько этапов, и принудительно вызвать её мы не можем. А char[] мы можем очистить сразу после использования. Так вот — в статье у нас есть embedded Tomcat, Jersey HTTP client и Hikari pool. Три широко распространённых компонента, требующих секретов при работе. Сколько из них поддерживают передачу секретов в char[]? Увы, только Jersey client. И это уровень фреймворков и библиотек, на бизнес-уровне всё будет ещё хуже.
2) Перегружаемые настройки Spring Cloud, работающие через @RefreshScope и описанные мною ранее, подходят, увы, не всегда. Основная проблема — передача секрета в компоненты, инициализируемые сложно, однократно при старте или некорректно обрабатывающие событие обновления секретов — например, сбрасывающие активные клиентские сессии.
3) Кроме @RefreshScope изобрели ещё два “велосипеда", причём оба в Spring Boot: SSL bundles и Spring Cloud Vault. Первый предназначен для работы с хранилищами сертификатов, второй — для работы с HashiCorp Vault. Оба поддерживают обновление секретов на лету. Все три инструмента взаимодополняют друг друга, хотя и не покрывают 100% кейсов.
#security #spring
Хабр
Секреты в Java-сервисах на Spring: где брать и как обновлять
Привет, Хабр! Меня зовут Андрей Чернов, я Java‑архитектор в СберТехе, где разрабатываю архитектуру микросервисов. Сейчас я расскажу про нюансы работы с секретами в Java‑сервисах...
Всем привет!
Разбираясь с HashiCorp Vault, понял, что многие, как минимум я, недооценивают его. Что такое Vault? В первую очередь — безопасное хранилище секретов. Аутентификация и авторизация, хранение всех данных в зашифрованном виде. Причём до ввода мастер-пароля администратором само приложение не имеет к ним доступа. Это всё понятно.
Но есть ещё киллер-фича: автогенерация секретов. Архитектура Vault оперирует понятием движка (engine) для работы с различными секретами. Рассмотрим, как ротация сделана для разных движков.
Движок для работы с сертификатами — PKI engine — умеет перегенерировать сертификаты с истекающим сроком. Вот документация: https://www.hashicorp.com/blog/certificate-management-with-vault
Database engine умеет создавать «одноразовых» пользователей в СУБД с помощью фичи под названием dynamic secrets: https://www.hashicorp.com/blog/why-we-need-dynamic-secrets. «Одноразовых» — то есть с ограниченным временем жизни, на один типовой сеанс работы с БД. Причём API Vault позволяет продлить время жизни пользователя для синхронизации с временем сессии. Не уверен, что любая БД выдержит такой режим работы, но видится, что эта функция сильно увеличивает безопасность работы с БД. Может возникнуть вопрос — как Vault их создаёт. ANSI SQL — это хорошо, но диалекты отличаются, да и в конкретной компании могут быть свои правила. Тут всё просто — SQL-запрос для создания пользователя и выдача ему необходимых прав создаются администратором Vault. Естественно, нужно задать логин и пароль администратора СУБД, под которым будут выполняться эти запросы. Но кажется, Vault вполне можно считать безопасным местом для их хранения. Больше деталей здесь: https://www.baeldung.com/vault, а в части интеграции со Spring Vault — здесь: https://www.baeldung.com/spring-cloud-vault.
Также есть возможность ротировать пароли доменных пользователей, используя Active Directory engine — см. https://developer.hashicorp.com/vault/docs/secrets/ad.
И обычные пароли: https://www.hashicorp.com/resources/painless-password-rotation-hashicorp-vault. Странно, что для последнего нужен внешний плагин, но такая возможность есть.
Итого: автоматическая ротация секретов и распространение их с помощью Vault Agent (в виде сайдкаров или JAR-библиотек) выглядят крутой фичей в плане безопасности и упрощения работы администраторов. Наверняка на этом пути будут подводные камни, но путь однозначно верный.
#security #vault #spring
Разбираясь с HashiCorp Vault, понял, что многие, как минимум я, недооценивают его. Что такое Vault? В первую очередь — безопасное хранилище секретов. Аутентификация и авторизация, хранение всех данных в зашифрованном виде. Причём до ввода мастер-пароля администратором само приложение не имеет к ним доступа. Это всё понятно.
Но есть ещё киллер-фича: автогенерация секретов. Архитектура Vault оперирует понятием движка (engine) для работы с различными секретами. Рассмотрим, как ротация сделана для разных движков.
Движок для работы с сертификатами — PKI engine — умеет перегенерировать сертификаты с истекающим сроком. Вот документация: https://www.hashicorp.com/blog/certificate-management-with-vault
Database engine умеет создавать «одноразовых» пользователей в СУБД с помощью фичи под названием dynamic secrets: https://www.hashicorp.com/blog/why-we-need-dynamic-secrets. «Одноразовых» — то есть с ограниченным временем жизни, на один типовой сеанс работы с БД. Причём API Vault позволяет продлить время жизни пользователя для синхронизации с временем сессии. Не уверен, что любая БД выдержит такой режим работы, но видится, что эта функция сильно увеличивает безопасность работы с БД. Может возникнуть вопрос — как Vault их создаёт. ANSI SQL — это хорошо, но диалекты отличаются, да и в конкретной компании могут быть свои правила. Тут всё просто — SQL-запрос для создания пользователя и выдача ему необходимых прав создаются администратором Vault. Естественно, нужно задать логин и пароль администратора СУБД, под которым будут выполняться эти запросы. Но кажется, Vault вполне можно считать безопасным местом для их хранения. Больше деталей здесь: https://www.baeldung.com/vault, а в части интеграции со Spring Vault — здесь: https://www.baeldung.com/spring-cloud-vault.
Также есть возможность ротировать пароли доменных пользователей, используя Active Directory engine — см. https://developer.hashicorp.com/vault/docs/secrets/ad.
И обычные пароли: https://www.hashicorp.com/resources/painless-password-rotation-hashicorp-vault. Странно, что для последнего нужен внешний плагин, но такая возможность есть.
Итого: автоматическая ротация секретов и распространение их с помощью Vault Agent (в виде сайдкаров или JAR-библиотек) выглядят крутой фичей в плане безопасности и упрощения работы администраторов. Наверняка на этом пути будут подводные камни, но путь однозначно верный.
#security #vault #spring
HashiCorp
X.509 certificate management with Vault
In this blog post, we’ll look at practical public key certificate management in HashiCorp Vault using dynamic secrets rotation.
Всем привет!
Нашел хорошую статью и проект, показывающий как должны работать компоненты телеметрии (OpenTelemetry) в связке:
Статья: https://habr.com/ru/companies/otus/articles/761334/
Проект: https://github.com/marcingrzejszczak/observability-boot-blog-post
Слава Docker, развернуть все это у себя на машине можно в пару кликов) Что настоятельно рекомендую сделать.
На что хотелось бы обратить внимание:
1) на одном дашборде собраны трейсы, метрики и логи
2) из лога по атрибуту traceId можно провалится в трейсы и наоборот
3) на панели метрик нужно присмотреться к "ромбикам" - это т.наз. exemplars - метаданные метрики, включающие связку метрики и трейса. И естественно из метрики тоже можно провалиться в trace.
4) еще удобная фича - на большом мониторе можно раскрыть рядом окно трейсинга и логов. Я не про 2 окна ОС, а это встроенная фишка Grafana
5) достаточно удобный формат работы с телеметрией в коде: открываем контекст OpenTelemetry, что приводит к тому, что автоматически формируются идентификаторы трейсов и добавляются ко всем метрикам и логам внутри контекста. Открыть контекст можно как императивно - вызовом метода, так и декларативно - аннотацией.
Ну и ложка дегтя - если брать последний коммит из репозитория выше, то там перешли на OpenTelemetry протокол для метрик, в котором exemplars не поддерживаются. Чтобы увидеть все в сборе надо откатиться на несколько коммитов, но при этом зафиксировать версию образа Grafana Tempo (сервер для трейсинга), т.к. последние его версии похоже не поддерживают Zipkin протокол, на котором работают exemplar) Похоже, стандарт становится зрелым прямо сейчас.
#telemetry
Нашел хорошую статью и проект, показывающий как должны работать компоненты телеметрии (OpenTelemetry) в связке:
Статья: https://habr.com/ru/companies/otus/articles/761334/
Проект: https://github.com/marcingrzejszczak/observability-boot-blog-post
Слава Docker, развернуть все это у себя на машине можно в пару кликов) Что настоятельно рекомендую сделать.
На что хотелось бы обратить внимание:
1) на одном дашборде собраны трейсы, метрики и логи
2) из лога по атрибуту traceId можно провалится в трейсы и наоборот
3) на панели метрик нужно присмотреться к "ромбикам" - это т.наз. exemplars - метаданные метрики, включающие связку метрики и трейса. И естественно из метрики тоже можно провалиться в trace.
4) еще удобная фича - на большом мониторе можно раскрыть рядом окно трейсинга и логов. Я не про 2 окна ОС, а это встроенная фишка Grafana
5) достаточно удобный формат работы с телеметрией в коде: открываем контекст OpenTelemetry, что приводит к тому, что автоматически формируются идентификаторы трейсов и добавляются ко всем метрикам и логам внутри контекста. Открыть контекст можно как императивно - вызовом метода, так и декларативно - аннотацией.
Ну и ложка дегтя - если брать последний коммит из репозитория выше, то там перешли на OpenTelemetry протокол для метрик, в котором exemplars не поддерживаются. Чтобы увидеть все в сборе надо откатиться на несколько коммитов, но при этом зафиксировать версию образа Grafana Tempo (сервер для трейсинга), т.к. последние его версии похоже не поддерживают Zipkin протокол, на котором работают exemplar) Похоже, стандарт становится зрелым прямо сейчас.
#telemetry
Хабр
Observability в Spring Boot 3
Отдел Observability Spring уже довольно долго работает над поддержкой наблюдаемости в Spring-приложениях, и мы рады сообщить вам, что в Spring Framework 6 и Spring Boot 3 вы наконец-то увидите...
Всем привет!
Возвращаюсь к теме хранения секретов — вот ещё неплохая статья https://habr.com/ru/articles/872128/
показывающая, что если вы «доросли» до вопроса управления секретами, вариантов немного.
Если вы находитесь в коммерческом облаке — Google, AWS, Azure, и скорее всего Яндекс, VK, Сбер — там будет встроенное хранилище секретов, и логично его использовать. Иначе — все дороги ведут в Vault.
Если рассмотреть альтернативы из статьи:
1) Docker Swarm умирает, проигрывая Kubernetes.
2) BuildKit — технология в себе, закрытая в плане сообщества и документации.
#security #vault
Возвращаюсь к теме хранения секретов — вот ещё неплохая статья https://habr.com/ru/articles/872128/
показывающая, что если вы «доросли» до вопроса управления секретами, вариантов немного.
Если вы находитесь в коммерческом облаке — Google, AWS, Azure, и скорее всего Яндекс, VK, Сбер — там будет встроенное хранилище секретов, и логично его использовать. Иначе — все дороги ведут в Vault.
Если рассмотреть альтернативы из статьи:
1) Docker Swarm умирает, проигрывая Kubernetes.
2) BuildKit — технология в себе, закрытая в плане сообщества и документации.
#security #vault
Хабр
Как организовать безопасное хранение секретов в Docker: лучшие практики
Хей, Хабр! Секреты — это такая щекотливая тема, из‑за которой у безопасников начинаются нервные подёргивания глаза. Вроде бы «просто пароль» или «просто токен», но в 2025 году...