Друзья, мы с kent2171, моим коллегой из CleverDATA, побывали на одной из крупнейших конференций Европы – Jax London 2017, посвященной экосистеме Java и всему, что ее окружает в современном мире, – микросервисной архитектуре, Continuous Delivery, а также культуре и практикам DevOps.
Объем полученной за четыре дня информации оказался настолько огромным, что обзор пришлось разбить на две части. Сегодня мы предлагаем вашему вниманию первую часть, в которой расскажем о Chaos Engineering подходе к построению устойчивых распределенных систем, а также о том, как контейнеризация java-приложений сказывается на процессе разработки и какие преимущества кроме синтаксиса дают lambda выражения. Это основные моменты. Остальное — под катом.
JAX всегда, по моим наблюдениям, собирала большое количество участников. Успех подкрепляли спикеры с мировыми именами (например, Хенни Кевлин, Дэниел Брайант, Стивен Коулберн), с которыми можно было пообщаться вживую, задавая вопросы из зала, а также в перерывах и во время кофе-брейков.
2017 год не стал исключением, конференция длилась четыре дня и собрала невиданное ранее количество посетителей из более чем 40 стран мира. В первый и последний день были организованы воркшопы, а второй и третий день были посвящены докладам.
В этом году, впрочем, как и всегда, конференция проходила в центре Лондона в здании Business Design Center.
А вот другой, исторический фасад этого здания, известный лондонцам как Royal Agricultural Hall.
Из аэропорта Heathrow на конференцию можно попасть тремя способами. Самый дешевый, но при этом довольно удобный и комфортный – London Underground, из всех терминалов есть прямая ветка до станции Kings Cross. Маршрут занимает в среднем около часа. Нам было любопытно попробовать именно этот вид транспорта. Экспресс и такси – это вторая и третья альтернативы, но они значительно дороже.
«Production ненавидит вас. Машины, сеть, каждый пользователь вашего сервиса ненавидят вас. Это наша реальность, и это то, что превращает production в кровавое поле битвы», — так начался воркшоп Раса Майлса (Russ Miles) о Chaos Engineering – о том, как повысить стабильность приложений и идентифицировать возможные проблемы до того, как они произошли.
Chaos Engineering – практика, которая позволяет эмпирическим путем выявлять и в итоге устранять слабые стороны разрабатываемых систем и приложений, не позволяя изменениям в дальнейшем вносить регрессию в приложения.
Chaos Engineering. C чего начать?
Архитектура и дизайн, готовый к Chaos Engineering
Любая сложная распределенная система состоит из множества компонентов, и даже когда каждый отдельный компонент функционирует должным образом, взаимодействие между компонентами зачастую вызывает проблемы, из-за которых система в целом ведет себя непредсказуемо. При дизайне системы необходимо учитывать SLA всех компонентов, образующих систему, нужно стремиться минимизировать количество внешних зависимых систем, напрямую влияющих на доступность системы в целом.
Гипотезы устойчивого состояния системы
Понятие устойчивого состояния системы определяется из требований к системе:
Имея представление об устойчивом состоянии системы, можно говорить о возможных отклонениях и о действиях, которые необходимо предпринять в том или ином случае.
Суть Chaos Engineering – имея значения метрик работы системы как результатов Chaos экспериментов, удостовериться, что система не работает, нежели пытаться проверить то, как она работает.
Разработка сценариев Chaos экспериментов
Имея представление об устойчивом состоянии системы, следующим шагом необходимо определить все возможные стресс-факторы, которые могут вывести систему из этого состояния. Например, проблемы, связанные с ограниченностью вычислительных ресурсов (сеть, CPU, память, дисковое пространство и т.д.), а также проблемы, возникающие на уровне системы (недоступность одного из зависимых сервисов, базы данных, и т.д.).
Запуск Chaos экспериментов
Начинать рекомендуется с «отладки» Сhaos сценариев, сбора результатов поведения системы в зависимости от окружения, в котором находится система.
Автоматизация Chaos экспериментов
Наконец, у нас все готово для автоматизации процесса: набор сценариев, состоящих из стресс-факторов и ожидаемое поведение системы в виде SLO. В качестве инструмента для автоматизации стрессовых сценариев рассматривался Chaos Toolkit – бесплатный инструмент, который отлично подходит для проведения Chaos-экспериментов с большинством платформ и приложений.
В этот день на официальном открытии конференции с приветственным словом выступил Себастьян Мейен (Sebastian Meyen), а первый доклад был посвящен ответственности разработчиков за свой код и за пользователей, страдающих от различных багов.
Henney приводит последствия, казалось бы, незначительных проблем, приводящие к сбоям различного характера – от незначительных курьезов и утечек информации до весьма существенных материальных потерь, а иногда и до катастроф. Разумеется, большинство сбоев и катастроф можно избежать, всего лишь следуя простым и всем известным практикам.
А что если не следовать?
Knight Capital Group, 2012 год
В рамках обновления системы предполагалось декомитить (то есть по сути ликвидировать) старый функционал, не используемый более восьми лет. По причине человеческого фактора один из восьми SMARS серверов не был обновлен и продолжил работать. За 45 минут компания потеряла $460 млн.
Любой процесс, в котором присутствует человеческий фактор, несет риски из-за возможности неверного объяснения, восприятия или выполнения требуемых действий.
Cluster (spacecraft), 1996 год
При запуске космического корабля Cluster произошло крушение из-за ошибки в программном обеспечении. Суть ошибки заключалась в неадекватной защите от целочисленного переполнения. Юнит-тест на граничные значения и переполнения стоил компании $370 млн.
Анализ сбоев в распределенных системах (Cassandra, HBase, HDFS, MapReduce, Redis), проведенный ассоциацией USENIX (Advanced Computing Technical Association), показал следующие интересные результаты.
Несмотря на то, что на момент этого доклада уже вышла Java 9, иногда полезно обернуться назад и посмотреть на lambda выражения – невероятно полезный и мощный инструмент, появившийся в предыдущем релизе Java платформы.
С помощью lambda выражений можно решить любую задачу, хотя это не всегда и рекомендуется (каждый инструмент должен решать ту задачу, для которой он создан).
Simon Ritter рассмотрел, какие же преимущества дает использование lambda выражения по сравнению с анонимными классами.
Для ответа на этот вопрос необходимо рассмотреть, во что же компилируется код в обоих случаях:
Из названия «анонимный класс» следует, что мы по-прежнему имеем дело с классом. Поэтому компилятор сгенерирует класс.
Недостатки такого подхода:
Лямбда выражения потенциально могли бы быть синтаксическим сахаром и компилироваться подобным образом, как компилируются анонимные классы, но с появлением инструкции invokedynamic в jdk7 и началом ее использования компилятором в jdk-8 дела обстоят совсем иначе.
Важно отметить преимущества использования лямбд.
В завершение в качестве примера того, как далеко можно зайти, используя лишь один функциональный интерфейс и lambda выражения, Simon Ritter продемонстрировал вычисление выражения 2+2. На видео доклада можно проследить всю цепочку занимательного процесса.
Daniel Bryant, консультант, CTO в SpectoLabs, погрузился в область operations несколько лет назад. В этом докладе он делится опытом о Continuous delivery java приложений в контейнерах.
Continuous delivery – набор практик и дисциплин, целью которых является непрерывный выпуск новых версий программного обеспечения в короткие промежутки времени. Основу данного процесса составляет build-pipeline, задача которого доказать, что изменения в коде соответствуют всем требованиям, необходимым для выпуска версии. Основная ценность build-pipeline – это мгновенная обратная связь в виде метрик, отражающих результат выполнения каждой фазы пайплайна.
Bryant рассказал о том, каким изменениям подвергается build-pipeline при контейнеризации Java приложений, перечислил лучшие практики, применимые к каждой фазе в отдельности.
Разработка приложений
Сборка и упаковка приложений в контейнеры и выполнение тестов происходит локально на машине разработчика.
Основные моменты:
Continuous integration (выполнение юнит и интеграционных тестов)
Публикацию Java артефактов (JAR, WAR и т.д.) заменяет публикация образов контейнеров в такие репозитории, как, например, Docker-hub.
Основные моменты:
Component Testing (приемочные и нагрузочные тесты)
Основные моменты:
На этом я беру паузу. О докладах последних двух дней лондонской конференции расскажет мой коллега kent2171. Но это будет уже на следующей неделе. Подписывайтесь на блог, чтобы не пропустить.
Объем полученной за четыре дня информации оказался настолько огромным, что обзор пришлось разбить на две части. Сегодня мы предлагаем вашему вниманию первую часть, в которой расскажем о Chaos Engineering подходе к построению устойчивых распределенных систем, а также о том, как контейнеризация java-приложений сказывается на процессе разработки и какие преимущества кроме синтаксиса дают lambda выражения. Это основные моменты. Остальное — под катом.
В том же месте в тот же час
JAX всегда, по моим наблюдениям, собирала большое количество участников. Успех подкрепляли спикеры с мировыми именами (например, Хенни Кевлин, Дэниел Брайант, Стивен Коулберн), с которыми можно было пообщаться вживую, задавая вопросы из зала, а также в перерывах и во время кофе-брейков.
2017 год не стал исключением, конференция длилась четыре дня и собрала невиданное ранее количество посетителей из более чем 40 стран мира. В первый и последний день были организованы воркшопы, а второй и третий день были посвящены докладам.
В этом году, впрочем, как и всегда, конференция проходила в центре Лондона в здании Business Design Center.
А вот другой, исторический фасад этого здания, известный лондонцам как Royal Agricultural Hall.
Из аэропорта Heathrow на конференцию можно попасть тремя способами. Самый дешевый, но при этом довольно удобный и комфортный – London Underground, из всех терминалов есть прямая ветка до станции Kings Cross. Маршрут занимает в среднем около часа. Нам было любопытно попробовать именно этот вид транспорта. Экспресс и такси – это вторая и третья альтернативы, но они значительно дороже.
День первый. Воркшоп Russ Miles
Production Microservices. Chaos from Order
«Production ненавидит вас. Машины, сеть, каждый пользователь вашего сервиса ненавидят вас. Это наша реальность, и это то, что превращает production в кровавое поле битвы», — так начался воркшоп Раса Майлса (Russ Miles) о Chaos Engineering – о том, как повысить стабильность приложений и идентифицировать возможные проблемы до того, как они произошли.
Chaos Engineering – практика, которая позволяет эмпирическим путем выявлять и в итоге устранять слабые стороны разрабатываемых систем и приложений, не позволяя изменениям в дальнейшем вносить регрессию в приложения.
Chaos Engineering. C чего начать?
Архитектура и дизайн, готовый к Chaos Engineering
Любая сложная распределенная система состоит из множества компонентов, и даже когда каждый отдельный компонент функционирует должным образом, взаимодействие между компонентами зачастую вызывает проблемы, из-за которых система в целом ведет себя непредсказуемо. При дизайне системы необходимо учитывать SLA всех компонентов, образующих систему, нужно стремиться минимизировать количество внешних зависимых систем, напрямую влияющих на доступность системы в целом.
Гипотезы устойчивого состояния системы
Понятие устойчивого состояния системы определяется из требований к системе:
- SLI (Service level indicators) – количественная характеристика (метрика) одного из аспектов уровня предоставляемого сервиса, например, пропускная способность, латентность, процент ошибок
- SLO (Service level objectives) – диапазон допустимых значений уровня предоставляемого сервиса, ограниченный с двух сторон SLI.
Имея представление об устойчивом состоянии системы, можно говорить о возможных отклонениях и о действиях, которые необходимо предпринять в том или ином случае.
Суть Chaos Engineering – имея значения метрик работы системы как результатов Chaos экспериментов, удостовериться, что система не работает, нежели пытаться проверить то, как она работает.
Разработка сценариев Chaos экспериментов
Имея представление об устойчивом состоянии системы, следующим шагом необходимо определить все возможные стресс-факторы, которые могут вывести систему из этого состояния. Например, проблемы, связанные с ограниченностью вычислительных ресурсов (сеть, CPU, память, дисковое пространство и т.д.), а также проблемы, возникающие на уровне системы (недоступность одного из зависимых сервисов, базы данных, и т.д.).
Запуск Chaos экспериментов
Начинать рекомендуется с «отладки» Сhaos сценариев, сбора результатов поведения системы в зависимости от окружения, в котором находится система.
Автоматизация Chaos экспериментов
Наконец, у нас все готово для автоматизации процесса: набор сценариев, состоящих из стресс-факторов и ожидаемое поведение системы в виде SLO. В качестве инструмента для автоматизации стрессовых сценариев рассматривался Chaos Toolkit – бесплатный инструмент, который отлично подходит для проведения Chaos-экспериментов с большинством платформ и приложений.
День второй. Лямбды, баги и Continuous delivery
В этот день на официальном открытии конференции с приветственным словом выступил Себастьян Мейен (Sebastian Meyen), а первый доклад был посвящен ответственности разработчиков за свой код и за пользователей, страдающих от различных багов.
Henney Kevlin. The Error of Our Ways
Henney приводит последствия, казалось бы, незначительных проблем, приводящие к сбоям различного характера – от незначительных курьезов и утечек информации до весьма существенных материальных потерь, а иногда и до катастроф. Разумеется, большинство сбоев и катастроф можно избежать, всего лишь следуя простым и всем известным практикам.
А что если не следовать?
Knight Capital Group, 2012 год
В рамках обновления системы предполагалось декомитить (то есть по сути ликвидировать) старый функционал, не используемый более восьми лет. По причине человеческого фактора один из восьми SMARS серверов не был обновлен и продолжил работать. За 45 минут компания потеряла $460 млн.
Любой процесс, в котором присутствует человеческий фактор, несет риски из-за возможности неверного объяснения, восприятия или выполнения требуемых действий.
Cluster (spacecraft), 1996 год
При запуске космического корабля Cluster произошло крушение из-за ошибки в программном обеспечении. Суть ошибки заключалась в неадекватной защите от целочисленного переполнения. Юнит-тест на граничные значения и переполнения стоил компании $370 млн.
Анализ сбоев в распределенных системах (Cassandra, HBase, HDFS, MapReduce, Redis), проведенный ассоциацией USENIX (Advanced Computing Technical Association), показал следующие интересные результаты.
- Почти все катастрофические сбои происходят в результате некорректной обработки некритичных ошибок приложения, которые явно дают о себе знать.
- Причину 58% катастроф можно обнаружить, всего лишь покрыв тестами код обработки ошибок приложений. Например, 35% ошибок из этой категории можно легко выявить с помощью статического анализа кода или кода ревью.
- 77% проблем может быть легко воспроизведено с помощью юнит-тестов.
Simon Ritter (Azul Systems). Lambdas: It’s Java Jim, but not as we know it
Несмотря на то, что на момент этого доклада уже вышла Java 9, иногда полезно обернуться назад и посмотреть на lambda выражения – невероятно полезный и мощный инструмент, появившийся в предыдущем релизе Java платформы.
С помощью lambda выражений можно решить любую задачу, хотя это не всегда и рекомендуется (каждый инструмент должен решать ту задачу, для которой он создан).
Simon Ritter рассмотрел, какие же преимущества дает использование lambda выражения по сравнению с анонимными классами.
Для ответа на этот вопрос необходимо рассмотреть, во что же компилируется код в обоих случаях:
- лямбда выражения:
myList.forEach(w -> System.out.println(w));
- и анонимного класса:
myList.forEach(new Consumer<String>() {
@Override
public void accept(String w) {
System.out.println(w);
}
});
Из названия «анонимный класс» следует, что мы по-прежнему имеем дело с классом. Поэтому компилятор сгенерирует класс.
Недостатки такого подхода:
- генерируется большое количество типов, чем на самом деле нужно приложению, что приводит к замусориванию типов (type pollution);
- анонимный класс – это по-прежнему класс, соответственно, в рантайме его необходимо загрузить и инициализировать;
- инстанцирование класса приводит к бОльшей нагрузки на память и на сборщик мусора;
- нестатический анонимный класс занимает больше места ввиду хранения ссылки на экземпляр класса, на который он ссылается.
Лямбда выражения потенциально могли бы быть синтаксическим сахаром и компилироваться подобным образом, как компилируются анонимные классы, но с появлением инструкции invokedynamic в jdk7 и началом ее использования компилятором в jdk-8 дела обстоят совсем иначе.
- Лямбда выражение конвертируется в метод:
— не захватывающие лямбда выражения и лямбда выражения, захватывающие статические переменные, конвертируются в статический метод класса, в котором они используются.
— лямбда, захватывающие ссылку на экземпляр класса, в котором они объявлены, конвертируется в метод этого класса.
- Вызов лямбда выражения компилируется в инструкцию invokedynamic, с которой при помощи мета-фабрики LambdaMetafactor ассоциируется CallSite – фабрики «функциональных объектов», имплементирующие один или несколько интерфейсов посредством делегирования в указанный MethodHandle.
Важно отметить преимущества использования лямбд.
- Создание экземпляров функциональных объектов – ленивое: если лямбда не используется, то нет никаких накладных расходов.
- Конвертация лямбда выражений в методы является более эффективным с точки зрения расхода памяти по сравнению с анонимными классами, особенно в случае захвата ссылки на экземпляр класса.
- Захват контекста лямбдами эффективно работает в многопоточной среде
В завершение в качестве примера того, как далеко можно зайти, используя лишь один функциональный интерфейс и lambda выражения, Simon Ritter продемонстрировал вычисление выражения 2+2. На видео доклада можно проследить всю цепочку занимательного процесса.
Continuous Delivery with Containers: The Good, the Bad, and the Ugly
Daniel Bryant, консультант, CTO в SpectoLabs, погрузился в область operations несколько лет назад. В этом докладе он делится опытом о Continuous delivery java приложений в контейнерах.
Continuous delivery – набор практик и дисциплин, целью которых является непрерывный выпуск новых версий программного обеспечения в короткие промежутки времени. Основу данного процесса составляет build-pipeline, задача которого доказать, что изменения в коде соответствуют всем требованиям, необходимым для выпуска версии. Основная ценность build-pipeline – это мгновенная обратная связь в виде метрик, отражающих результат выполнения каждой фазы пайплайна.
Bryant рассказал о том, каким изменениям подвергается build-pipeline при контейнеризации Java приложений, перечислил лучшие практики, применимые к каждой фазе в отдельности.
Разработка приложений
Сборка и упаковка приложений в контейнеры и выполнение тестов происходит локально на машине разработчика.
Основные моменты:
- Содержимое Docker file-ов (выбор OS, конфигурации, открытие портов, JDK vs JRE, нужен ли Python Virtual env).
- Детали работы приложений/middleware в linux контейнерах. Для этого идеально привлекать команду operations для принятия лучших решений и практик. Их багаж знаний очень может пригодится в этот момент.
- Для локальных тестов необходимо использовать production образы контейнеров для исключения влияния конфигурации тестового контейнера на работу приложения.
Continuous integration (выполнение юнит и интеграционных тестов)
Публикацию Java артефактов (JAR, WAR и т.д.) заменяет публикация образов контейнеров в такие репозитории, как, например, Docker-hub.
Основные моменты:
- использование уже готовых инструментов для сборки и публикации образов, например, Jenkins plugin;
- стоит избегать использования тэга the latest в качестве версии образа, обязательно использовать версионирование образов;
- использование метаданных для описания образа контейнера:
— метаданные приложения (версия/git sha);
— метаданные сборки (дата сборки, название образа, вендор и т.д.);
— метаданные QA;
существует конвенция для схемы метаданных;
- использование меток (label) в качестве метаданных приводит к созданию нового образа, что не всегда допустимо, в качестве обходного пути предлагается хранение метаданных отдельно от образа. Jfrog Artifactory + Docker, а также NexussOSS поддерживают раздельную схему хранения метаданных.
Component Testing (приемочные и нагрузочные тесты)
Основные моменты:
- использование инструментов для описания и запуска мультиконтейнерных приложений (например, Docker Compose, Ephemeral Kubernetes Clusters);
- использование готовых инструментов для запуска компонентных тестов например Pipeline as Code with Jenkins.
На этом я беру паузу. О докладах последних двух дней лондонской конференции расскажет мой коллега kent2171. Но это будет уже на следующей неделе. Подписывайтесь на блог, чтобы не пропустить.
Кстати, в ЛАНИТ есть открытые вакансии для разработчиков Java