Всем привет.
В дополнение к предыдущему посту - ещё один способ получить IDEA Ultimate в России.
6) участие в программе EAP - Early Access Program. https://www.jetbrains.com/idea/nextversion
За подсказку спасибо @poeticpragmatic
Особенности:
а) критичные баги не замечены
б) имеет смысл автоматизировать накат новой версии скриптом с сохранением предыдущей для возможности отката. Если критичные баги все же появятся)
Не заблокируют ли этот вариант - да кто его знает)
#ide #idea
В дополнение к предыдущему посту - ещё один способ получить IDEA Ultimate в России.
6) участие в программе EAP - Early Access Program. https://www.jetbrains.com/idea/nextversion
За подсказку спасибо @poeticpragmatic
Особенности:
а) критичные баги не замечены
б) имеет смысл автоматизировать накат новой версии скриптом с сохранением предыдущей для возможности отката. Если критичные баги все же появятся)
Не заблокируют ли этот вариант - да кто его знает)
#ide #idea
JetBrains
Early Access Program (EAP) - IntelliJ IDEA
Code-centric IDE, focused on your productivity. Full Java EE support, deep code understanding, best debugger, refactorings, everything right out of the box...
Всем привет!
И ещё пару мыслей по развитию IDEA в России.
1) кажется, что со стороны Сбера было бы разумнее использовать готовый сильный продукт в виде Amplicode, чем в спешном порядке делать свой Spring плагин. Даже с учётом потенциальной монетизации Amplicode.
2) Haulmont активно развивается. Вначале JPA Buddy, теперь Amplicode, включающий его функционал. Что дальше?
IDEA, к слову, начинала с 2 плагинов к Borland JBuilder https://blog.jetbrains.com/ru/team/2013/02/28/nikolaj-chashnikov-intellij-idea-ide-kotoraya-ponimaet-kod/
Да, эти два пути противоречат друг другу. Да и российский рынок не выдержит 2 IDE) Их в мире по большому счёту три.
#ide #idea
И ещё пару мыслей по развитию IDEA в России.
1) кажется, что со стороны Сбера было бы разумнее использовать готовый сильный продукт в виде Amplicode, чем в спешном порядке делать свой Spring плагин. Даже с учётом потенциальной монетизации Amplicode.
2) Haulmont активно развивается. Вначале JPA Buddy, теперь Amplicode, включающий его функционал. Что дальше?
IDEA, к слову, начинала с 2 плагинов к Borland JBuilder https://blog.jetbrains.com/ru/team/2013/02/28/nikolaj-chashnikov-intellij-idea-ide-kotoraya-ponimaet-kod/
Да, эти два пути противоречат друг другу. Да и российский рынок не выдержит 2 IDE) Их в мире по большому счёту три.
#ide #idea
The JetBrains Blog
IntelliJ IDEA — IDE, которая понимает код | Блог JetBrains
Николай Чашников рассказывает о разных сторонах IntelliJ IDEA
Всем привет!
Давно хотел написать небольшую памятку по уровням логирования.
Стандартный набор уровней логирования для бизнес приложений:
TRACE
DEBUG
INFO
WARNING
ERROR
Встречается еще один - FATAL - но на моей практике это что-то разряда OutOfMemory, которое прикладной код не выбрасывает.
TRACE - самый редко встречающийся уровень. Почему? Потому что всегда, когда стоит выбор между трассировкой через логи или запуском в режиме отладчика - нужно выбирать второе. Это банально быстрее, т.к. не требует пересборок. Почему именно пересборки, во множественном числе - потому что у нас ООП, куча классов и методов, с первого раза расставить TRACE правильно вряд ли получится. Единственный минус отладки - если это происходит на тестовом или dev стенде - другие люди не смогут там работать. Т.е. их нужно предупредить. Или еще лучше - иметь минимум 2 подходящих стенда. Когда стенд не подходящий - это ПРОМ (PROD) или PROD-like стенды, куда нет сетевого доступа с компьютера разработчика. Вот это пожалуй единственное место, где может понадобиться TRACE. И если он там понадобился, то возможно у вас проблемы либо на этапе тестирования. Либо какие-то значимые отличия в конфигурации стендов, что тоже может быть поводом задуматься.
Что делать с TRACE - убирать сразу после нахождения проблемы, т.е. в следующем хотфиксе.
DEBUG - используется как правило на тестовых стендах чтобы разобраться с пришедшими от смежников данными и как эти данные влияют на состояние нашего сервиса. Разработка и отладка идет на заглушках, что там придет от смежников до конца не ясно, несмотря на согласованную аналитику - вот этот вот кейс. Если используется для трассировки шагов - см. абзац выше)
Что делать с DEBUG - убирать перед фиксацией ПРОМ релиза. Почему бы не оставить? Даже не из-за производительности, этот момент решить можно, а из-за ухудшения читаемости. Размер кода увеличивается, лог как правило дублирует близлежащий метод в плане доносимой информации, т.е. нарушаем DRY. Если DEBUG во внешней библиотеке - отключаем через настройку уровня логирования для конкретного пакета.
Все уровни далее по большому счету пишутся для сопровождения и тестировщиков.
INFO - нет ошибки, но сервис дошел до некой важной точки, и эта информация поможет при разборе полетов в случае ошибок и сбоев. Я видел кейсы, когда сопровождение запрещало писать на ПРОМ с уровнем INFO, но со временем оно одумывалось, и запрет снимали).
WARN - ошибки, не позволяющей вернуть данные клиенту, нет. Но есть либо некритичная ошибка, либо отсутствуют какие-то данные. И поэтому мы либо уходим в альтернативную ветку пользовательского сценария, либо берем данные из кэша, и возвращаем ответ клиенту.
ERROR - ошибка, прокидываемая клиенту. Не в виде stack trace конечно) Суть в том, что процесс обработки клиентского запроса прерывается, возвращается ошибка согласно API. Две самые частые ошибки, что я здесь вижу:
а) вывод error на любую ошибку смежника, даже не блокирующую.
б) error из используемой библиотеки, которая для нашего процесса не является блокирующей. В этом случае ее нужно убирать либо через настройку уровня логирования для пакета этой библиотеки, либо через ее доработку (если это возможно).
Эти три уровня убирать перед релизом не нужно, но стоит периодически их просматривать на предмет актуальности.
И последнее - по производительности. Просадка в производительности из-за логирования может быть из-за вычисления параметров даже в том случае, когда текущий уровень логирования выключен. Спасает ленивое вычисление параметров для выводимого в лог сообщения.
Это поддерживается в
а) log4j https://logging.apache.org/log4j/2.12.x/manual/api.html
б) slf4j https://www.slf4j.org/faq.html#logging_performance
через lambda параметры начиная с Java 8. Т.е. в большинстве инсталляций. Ну я надеюсь на это)
Еще просадка может быть из-за количества сообщений. Тогда смотри абзацы про TRACE и DEBUG выше. Еще можно глянуть мой пост про производительность в log4j https://t.me/javaKotlinDevOps/77 и поднять уровень логирования для ПРОМ.
#java #logging
Давно хотел написать небольшую памятку по уровням логирования.
Стандартный набор уровней логирования для бизнес приложений:
TRACE
DEBUG
INFO
WARNING
ERROR
Встречается еще один - FATAL - но на моей практике это что-то разряда OutOfMemory, которое прикладной код не выбрасывает.
TRACE - самый редко встречающийся уровень. Почему? Потому что всегда, когда стоит выбор между трассировкой через логи или запуском в режиме отладчика - нужно выбирать второе. Это банально быстрее, т.к. не требует пересборок. Почему именно пересборки, во множественном числе - потому что у нас ООП, куча классов и методов, с первого раза расставить TRACE правильно вряд ли получится. Единственный минус отладки - если это происходит на тестовом или dev стенде - другие люди не смогут там работать. Т.е. их нужно предупредить. Или еще лучше - иметь минимум 2 подходящих стенда. Когда стенд не подходящий - это ПРОМ (PROD) или PROD-like стенды, куда нет сетевого доступа с компьютера разработчика. Вот это пожалуй единственное место, где может понадобиться TRACE. И если он там понадобился, то возможно у вас проблемы либо на этапе тестирования. Либо какие-то значимые отличия в конфигурации стендов, что тоже может быть поводом задуматься.
Что делать с TRACE - убирать сразу после нахождения проблемы, т.е. в следующем хотфиксе.
DEBUG - используется как правило на тестовых стендах чтобы разобраться с пришедшими от смежников данными и как эти данные влияют на состояние нашего сервиса. Разработка и отладка идет на заглушках, что там придет от смежников до конца не ясно, несмотря на согласованную аналитику - вот этот вот кейс. Если используется для трассировки шагов - см. абзац выше)
Что делать с DEBUG - убирать перед фиксацией ПРОМ релиза. Почему бы не оставить? Даже не из-за производительности, этот момент решить можно, а из-за ухудшения читаемости. Размер кода увеличивается, лог как правило дублирует близлежащий метод в плане доносимой информации, т.е. нарушаем DRY. Если DEBUG во внешней библиотеке - отключаем через настройку уровня логирования для конкретного пакета.
Все уровни далее по большому счету пишутся для сопровождения и тестировщиков.
INFO - нет ошибки, но сервис дошел до некой важной точки, и эта информация поможет при разборе полетов в случае ошибок и сбоев. Я видел кейсы, когда сопровождение запрещало писать на ПРОМ с уровнем INFO, но со временем оно одумывалось, и запрет снимали).
WARN - ошибки, не позволяющей вернуть данные клиенту, нет. Но есть либо некритичная ошибка, либо отсутствуют какие-то данные. И поэтому мы либо уходим в альтернативную ветку пользовательского сценария, либо берем данные из кэша, и возвращаем ответ клиенту.
ERROR - ошибка, прокидываемая клиенту. Не в виде stack trace конечно) Суть в том, что процесс обработки клиентского запроса прерывается, возвращается ошибка согласно API. Две самые частые ошибки, что я здесь вижу:
а) вывод error на любую ошибку смежника, даже не блокирующую.
б) error из используемой библиотеки, которая для нашего процесса не является блокирующей. В этом случае ее нужно убирать либо через настройку уровня логирования для пакета этой библиотеки, либо через ее доработку (если это возможно).
Эти три уровня убирать перед релизом не нужно, но стоит периодически их просматривать на предмет актуальности.
И последнее - по производительности. Просадка в производительности из-за логирования может быть из-за вычисления параметров даже в том случае, когда текущий уровень логирования выключен. Спасает ленивое вычисление параметров для выводимого в лог сообщения.
Это поддерживается в
а) log4j https://logging.apache.org/log4j/2.12.x/manual/api.html
б) slf4j https://www.slf4j.org/faq.html#logging_performance
через lambda параметры начиная с Java 8. Т.е. в большинстве инсталляций. Ну я надеюсь на это)
Еще просадка может быть из-за количества сообщений. Тогда смотри абзацы про TRACE и DEBUG выше. Еще можно глянуть мой пост про производительность в log4j https://t.me/javaKotlinDevOps/77 и поднять уровень логирования для ПРОМ.
#java #logging
logging.apache.org
Log4j – Log4j 2 API - Apache Log4j 2
Всем привет!
Продолжим про логи. Какие требования к ним предъявляются?
Для начала поговорим про разработку:
0) библиотека логирования. Очевидная вещь - для кода, работающего в ПРОМе, логи пишутся только через библиотеку логирования. Т.к. библиотека позволяет настраивать место хранения, формат, фильтрацию логов и многое другое.
1) структурированность. Должна быть возможность точного поиска по логам, а, возможно, настройки мониторинга по логам. Для этого ключевые события - в частности ошибки - должны однозначно (!) находится по специфической "метке". Пример: " ERROR " при выводе через log4j с форматом по умолчанию. Аналогично нужны "метки" для конкретных типов ошибок, если их нужно отслеживать.
2) достаточная детализация:
а) число записей. Достаточная детализация = логов не слишком мало, чтобы можно было понять причину ошибку, но и не слишком много. Конечно поиск рулит, но лишний объем - это замедление при передаче, хранении и обработке логов.
б) вывод стектрейсов. По умолчанию стектрейсы нужно логировать. Исключения - однозначно локализуемые в коде ошибки или бизнесовые ошибки.
в) поясняющий текст. Данные, содержащиеся в некой переменной, в лог стоит выводить предваряя их поясняющим текстом. Аналогично с текстом пришедшей извне ошибки.
3) корректность:
а) уровень ошибки. ERROR - должен быть ошибкой, прерывающей обработку запроса клиента. Об этом я писал в посте выше
б) отсутствие дублей. Одна ошибка не должна приводить к нескольким стектрейсам в логе. Т.е. выводить в лог исходное исключение, бросать свое, ловить его и снова выводить в лог - это не корректные логи, затрудняющие их обработку.
4) понятный вывод времени. Казалось бы, при чем тут разработчики? Речь о часовом поясе, а это настройки таймзоны для Java. Если время пишется в GMT - нужно постоянно помнить о смещении при разборе логов, а при разборе инцидентов приводит к некорректным выводам.
5) маскирование персональных данных. Если у вас есть ИБ (информационная безопасность) - требования можно спросить у них. Иначе - нагуглить в интернете. Зачем маскировать - излишний вывод (хранение) персональные данных нарушает закон
#logging
Продолжим про логи. Какие требования к ним предъявляются?
Для начала поговорим про разработку:
0) библиотека логирования. Очевидная вещь - для кода, работающего в ПРОМе, логи пишутся только через библиотеку логирования. Т.к. библиотека позволяет настраивать место хранения, формат, фильтрацию логов и многое другое.
1) структурированность. Должна быть возможность точного поиска по логам, а, возможно, настройки мониторинга по логам. Для этого ключевые события - в частности ошибки - должны однозначно (!) находится по специфической "метке". Пример: " ERROR " при выводе через log4j с форматом по умолчанию. Аналогично нужны "метки" для конкретных типов ошибок, если их нужно отслеживать.
2) достаточная детализация:
а) число записей. Достаточная детализация = логов не слишком мало, чтобы можно было понять причину ошибку, но и не слишком много. Конечно поиск рулит, но лишний объем - это замедление при передаче, хранении и обработке логов.
б) вывод стектрейсов. По умолчанию стектрейсы нужно логировать. Исключения - однозначно локализуемые в коде ошибки или бизнесовые ошибки.
в) поясняющий текст. Данные, содержащиеся в некой переменной, в лог стоит выводить предваряя их поясняющим текстом. Аналогично с текстом пришедшей извне ошибки.
3) корректность:
а) уровень ошибки. ERROR - должен быть ошибкой, прерывающей обработку запроса клиента. Об этом я писал в посте выше
б) отсутствие дублей. Одна ошибка не должна приводить к нескольким стектрейсам в логе. Т.е. выводить в лог исходное исключение, бросать свое, ловить его и снова выводить в лог - это не корректные логи, затрудняющие их обработку.
4) понятный вывод времени. Казалось бы, при чем тут разработчики? Речь о часовом поясе, а это настройки таймзоны для Java. Если время пишется в GMT - нужно постоянно помнить о смещении при разборе логов, а при разборе инцидентов приводит к некорректным выводам.
5) маскирование персональных данных. Если у вас есть ИБ (информационная безопасность) - требования можно спросить у них. Иначе - нагуглить в интернете. Зачем маскировать - излишний вывод (хранение) персональные данных нарушает закон
#logging
Всем привет!
Небольшое развитие поста про выбор альтернативы IDEA Ultimate.
В посте особое внимание по понятным причинам было обращено на поддержку Spring.
Так вот, благодаря комментариям выяснилось, что в России пилится 3 плагина для Spring:
1) Amplicode https://amplicode.ru/
2) Sber\Giga - назовем его так, т.к. его еще никто не видел
3) Explyt https://github.com/explyt/spring-plugin/wiki/Videos
Последний я изучил по видосам - выглядит неплохо как плагин чисто для Spring. А Amplicode вырывается вперед благодаря поддержке JPA, Liquibase, MapStruct, Docker....
Конкуренция, однако. Вот что импортозамещение делает) Будем наблюдать.
За наводку на Explyt спасибо @alex_inozemtsev
#idea #spring
Небольшое развитие поста про выбор альтернативы IDEA Ultimate.
В посте особое внимание по понятным причинам было обращено на поддержку Spring.
Так вот, благодаря комментариям выяснилось, что в России пилится 3 плагина для Spring:
1) Amplicode https://amplicode.ru/
2) Sber\Giga - назовем его так, т.к. его еще никто не видел
3) Explyt https://github.com/explyt/spring-plugin/wiki/Videos
Последний я изучил по видосам - выглядит неплохо как плагин чисто для Spring. А Amplicode вырывается вперед благодаря поддержке JPA, Liquibase, MapStruct, Docker....
Конкуренция, однако. Вот что импортозамещение делает) Будем наблюдать.
За наводку на Explyt спасибо @alex_inozemtsev
#idea #spring
amplicode.ru
Инструменты разработки веб-приложений | Amplicode
Современные инструменты разработки веб-приложений и сервисов на Spring Boot: надежные инструменты для разработчиков
Всем привет!
Небольшая памятка по созданию бинов в Spring контексте. Рассматриваем Spring Boot приложение.
Что влияет на итоговый набор бинов?
0) база - влияют собственно определенные в сервисе бины.
Я насчитал 5 способов определения бинов в порядке распространнености:
а) Spring annotation-based - через @Component сотоварищи
б) Java-based configuration, причем что интересно - методы @Bean могут быть не только у них, но и у Annotation-based, о разнице можно почитать тут: https://stackoverflow.com/questions/3330618/bean-inside-class-with-configuration-and-without-it
в) старые и уже наверное не добрые xml-based configuration
г) экзотические groovy bean definitions https://docs.spring.io/spring-framework/reference/core/beans/basics.html#beans-factory-groovy
д) Spring понимает JSR 330 (привет от Java EE) аннотации при добавлении соответствующих зависимостей https://docs.spring.io/spring-framework/reference/core/beans/standard-annotations.html
Причем способы можно миксовать, например, добавляя xml и groovy конфигурации через context.loadBeanDefinitions() или @ImportResource.
1) кроме того бины тянутся из подключенных в проекте стартеров, при включенной @AutoConfiguration (или @SpringBootApplication), исключить лишнее можно через параметр exclude
2) корневые пакеты для поиска бинов. По умолчанию он один и равен пакету, где лежит класс с @SpringBootApplication. Может быть переопределен @SpringBootApplication(scanBasePackages = "com.example.myproject"). К слову, @SpringBootApplication под капотом включает в себя @ComponentScan - автоматический поиск бинов.
3) можно не использовать автоматический поиск бинов (@ComponentScan), а собрать их в конфигурации и явно их импортировать через @Import
4) у Spring Data JPA свои настройки корневых пакетов для поиска репозиториев, указываются через @EnableJpaRepositories(basePackages="com.example.myproject")
5) использование профилей Spring при запуске и наличие @Profile в @Configuration и @Component
6) более гибко условное подключение бинов можно сделать через разного рода @Conditional. Это целый пакет аннотаций, бывают условия с SpeL и даже бины, задающие условие c помощью Java кода. Детальнее тут https://www.baeldung.com/spring-boot-annotations
7) можно вклинится в момент, когда метаданные (BeanDefinition) уже созданы, а Bean - еще нет, через создание своего BeanFactoryPostProcessor https://docs.spring.io/spring-framework/reference/core/beans/factory-extension.html#beans-factory-extension-factory-postprocessors
и что-нибудь подшаманить - например, заменить bean.
8) есть печально знаменитая опция allowBeanDefinitionOverriding, позволяющая переопределять бины просто создавая новый бин с тем же интерфейсом позже по времени
9) более предсказуемая, но также не рекомендуемая аннотация @Primary на компоненте, "хардкодящая" главный бин для внедрения
И возможно, я что-то забыл)
Вот такой простой и понятный процесс инициализации бинов. Казалось бы, что может пойти не так?)
Например, это приводит к головной боли у разработчиков плагинов, пытающихся воссоздать Spring context без запуска Spring приложения. Это не так-то легко в первую очередь из-за динамических частей - там где наличие бина определяется в Java коде. Вот хорошая, "с кишочками" статья про решение этой проблемы https://habr.com/ru/companies/explyt/articles/854304/
И выходит, что создатели Spring, увы, не подумали о разработчиках плагинов.
#spring #ide
Небольшая памятка по созданию бинов в Spring контексте. Рассматриваем Spring Boot приложение.
Что влияет на итоговый набор бинов?
0) база - влияют собственно определенные в сервисе бины.
Я насчитал 5 способов определения бинов в порядке распространнености:
а) Spring annotation-based - через @Component сотоварищи
б) Java-based configuration, причем что интересно - методы @Bean могут быть не только у них, но и у Annotation-based, о разнице можно почитать тут: https://stackoverflow.com/questions/3330618/bean-inside-class-with-configuration-and-without-it
в) старые и уже наверное не добрые xml-based configuration
г) экзотические groovy bean definitions https://docs.spring.io/spring-framework/reference/core/beans/basics.html#beans-factory-groovy
д) Spring понимает JSR 330 (привет от Java EE) аннотации при добавлении соответствующих зависимостей https://docs.spring.io/spring-framework/reference/core/beans/standard-annotations.html
Причем способы можно миксовать, например, добавляя xml и groovy конфигурации через context.loadBeanDefinitions() или @ImportResource.
1) кроме того бины тянутся из подключенных в проекте стартеров, при включенной @AutoConfiguration (или @SpringBootApplication), исключить лишнее можно через параметр exclude
2) корневые пакеты для поиска бинов. По умолчанию он один и равен пакету, где лежит класс с @SpringBootApplication. Может быть переопределен @SpringBootApplication(scanBasePackages = "com.example.myproject"). К слову, @SpringBootApplication под капотом включает в себя @ComponentScan - автоматический поиск бинов.
3) можно не использовать автоматический поиск бинов (@ComponentScan), а собрать их в конфигурации и явно их импортировать через @Import
4) у Spring Data JPA свои настройки корневых пакетов для поиска репозиториев, указываются через @EnableJpaRepositories(basePackages="com.example.myproject")
5) использование профилей Spring при запуске и наличие @Profile в @Configuration и @Component
6) более гибко условное подключение бинов можно сделать через разного рода @Conditional. Это целый пакет аннотаций, бывают условия с SpeL и даже бины, задающие условие c помощью Java кода. Детальнее тут https://www.baeldung.com/spring-boot-annotations
7) можно вклинится в момент, когда метаданные (BeanDefinition) уже созданы, а Bean - еще нет, через создание своего BeanFactoryPostProcessor https://docs.spring.io/spring-framework/reference/core/beans/factory-extension.html#beans-factory-extension-factory-postprocessors
и что-нибудь подшаманить - например, заменить bean.
8) есть печально знаменитая опция allowBeanDefinitionOverriding, позволяющая переопределять бины просто создавая новый бин с тем же интерфейсом позже по времени
9) более предсказуемая, но также не рекомендуемая аннотация @Primary на компоненте, "хардкодящая" главный бин для внедрения
И возможно, я что-то забыл)
Вот такой простой и понятный процесс инициализации бинов. Казалось бы, что может пойти не так?)
Например, это приводит к головной боли у разработчиков плагинов, пытающихся воссоздать Spring context без запуска Spring приложения. Это не так-то легко в первую очередь из-за динамических частей - там где наличие бина определяется в Java коде. Вот хорошая, "с кишочками" статья про решение этой проблемы https://habr.com/ru/companies/explyt/articles/854304/
И выходит, что создатели Spring, увы, не подумали о разработчиках плагинов.
#spring #ide
Stack Overflow
@Bean inside class with @Configuration and without it
There is a @Bean annotation in Spring 3.0. It allows to define a Spring bean directly in a Java code. While browsing Spring reference I found two different ways of using this annotation - inside cl...
Всем привет!
Последняя статья из цикла про журналирование.
Все разработчики сталкиваются с разбором логов. При отладке, в логах сервиса на тестовых средах и ПРОМ, в логах пайплайна сборки или деплоя... Но не все там находят причину проблемы. Перечислю типовые ошибки при разборе. К слову - со всеми из них я сталкивался на практике. Поехали!
1) копать глубже. Найти первую попавшуюся ошибку в логе (или последнюю, смотря с какого края просматривается лог) и успокоится - плохо. Пусть разработчики сервиса, который пишет эти логи, придерживаются правила: ERROR - это всегда ERROR. Все равно - ошибок может быть несколько, ошибки могут выстраиваться в цепочку. Вывод - нужно анализировать весь(все) лог(и).
2) первопричина. Окей - смотрим весь лог, видим цепочку идущих подряд ошибок. Куда смотреть? На первую ошибку по времени. И последнюю в стектрейсе. Это и есть первопричина.
3) ошибки - не всегда ошибки. К сожалению. Встречаются "вечные" ошибки. Или, более приемлемый вариант, постоянные WARNing-и, говорящие о том, что для вашей среды что-то там не поддерживается. И то, и другое нужно игнорировать. Как это понять? Только насмотренность - после того, как этот лог увидишь в десятый (или пятидесятый) раз.
4) случайные ошибки. Если анализировать достаточно большой лог - там с большой вероятностью будут случайные ошибки. "Моргнула" сеть, рестартовал какой-то сервис... Особенно в тестовом контуре, но и на ПРОМе тоже. Снова вопрос - как понять, что ошибку не стоит разбирать? Первое - сравнить количество ошибок разных типов, второе - снова насмотренность.
5) не те логи. В k8s есть логи контейнера сервиса, а есть логи его сайдкаров. Если брать Openshift - для раскатки новой версии DeploymentConfig сервиса в нем используются т.наз. deploy поды, их логи как правило бесполезны. Если брать сервера приложений - там есть логи собственно сервера, а есть - каждого сервиса, развернутого на нем. Ошибка в логах джобы деплоя часто даёт мало информации о причине падения деплоя, нужно смотреть логи контейнеров. Т.е. вначале нужно определится - где может быть ошибка, которую мы ищем. И в конце концов - если в ваших логах есть ошибка интеграции, но причина ее не понятна - стоит попробовать достать логи смежного сервиса.
6) чужая ошибка. Если у нас нагруженная многопользовательская система - в логах могут встречаться ошибки разных пользователей. А мы сейчас разбираем проблему конкретного. Тут поможет фильтрация по атрибуту логов, содержащего id пользователя. Если конечно такой атрибут есть) Спойлер: должен быть)
7) ошибки не то, кем кажутся. Самый сложный кейс - когда сообщение об ошибке не дает полезной информации и даже вводит в заблуждение. Четкого рецепта тут нет - поисковик, ChatGPT, помощь более опытных коллег, просмотр по логам действий, предшествующих ошибке...
#logging
Последняя статья из цикла про журналирование.
Все разработчики сталкиваются с разбором логов. При отладке, в логах сервиса на тестовых средах и ПРОМ, в логах пайплайна сборки или деплоя... Но не все там находят причину проблемы. Перечислю типовые ошибки при разборе. К слову - со всеми из них я сталкивался на практике. Поехали!
1) копать глубже. Найти первую попавшуюся ошибку в логе (или последнюю, смотря с какого края просматривается лог) и успокоится - плохо. Пусть разработчики сервиса, который пишет эти логи, придерживаются правила: ERROR - это всегда ERROR. Все равно - ошибок может быть несколько, ошибки могут выстраиваться в цепочку. Вывод - нужно анализировать весь(все) лог(и).
2) первопричина. Окей - смотрим весь лог, видим цепочку идущих подряд ошибок. Куда смотреть? На первую ошибку по времени. И последнюю в стектрейсе. Это и есть первопричина.
3) ошибки - не всегда ошибки. К сожалению. Встречаются "вечные" ошибки. Или, более приемлемый вариант, постоянные WARNing-и, говорящие о том, что для вашей среды что-то там не поддерживается. И то, и другое нужно игнорировать. Как это понять? Только насмотренность - после того, как этот лог увидишь в десятый (или пятидесятый) раз.
4) случайные ошибки. Если анализировать достаточно большой лог - там с большой вероятностью будут случайные ошибки. "Моргнула" сеть, рестартовал какой-то сервис... Особенно в тестовом контуре, но и на ПРОМе тоже. Снова вопрос - как понять, что ошибку не стоит разбирать? Первое - сравнить количество ошибок разных типов, второе - снова насмотренность.
5) не те логи. В k8s есть логи контейнера сервиса, а есть логи его сайдкаров. Если брать Openshift - для раскатки новой версии DeploymentConfig сервиса в нем используются т.наз. deploy поды, их логи как правило бесполезны. Если брать сервера приложений - там есть логи собственно сервера, а есть - каждого сервиса, развернутого на нем. Ошибка в логах джобы деплоя часто даёт мало информации о причине падения деплоя, нужно смотреть логи контейнеров. Т.е. вначале нужно определится - где может быть ошибка, которую мы ищем. И в конце концов - если в ваших логах есть ошибка интеграции, но причина ее не понятна - стоит попробовать достать логи смежного сервиса.
6) чужая ошибка. Если у нас нагруженная многопользовательская система - в логах могут встречаться ошибки разных пользователей. А мы сейчас разбираем проблему конкретного. Тут поможет фильтрация по атрибуту логов, содержащего id пользователя. Если конечно такой атрибут есть) Спойлер: должен быть)
7) ошибки не то, кем кажутся. Самый сложный кейс - когда сообщение об ошибке не дает полезной информации и даже вводит в заблуждение. Четкого рецепта тут нет - поисковик, ChatGPT, помощь более опытных коллег, просмотр по логам действий, предшествующих ошибке...
#logging
Всем привет!
На этот раз у поста будет заголовок.
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