В рамках обучения разработчиков распределенных приложений, сегодня рассмотрим, как упростить тестирование и отладку заданий Apache Flink с помощью Byteman. Читайте далее, как внедрить Java-код в JVM, чтобы извлечь нужные сведения о выполнении Flink-приложения на платформе Veverica и ускорить разработку.
Разработка и отладка приложений Apache Flink: ежедневные сложности
В рассматриваемом примере рассматривается не «ванильный» Apache Flink, а коммерческий дистрибутив на базе Veverica Platform – немецкой компании, которая занимается продвижением и коммерциализацией этого фреймворка подобно тому, как Confluent связан с Kafka, а Databricks – со Spark. Впрочем, это не слишком меняет суть самого кейса, когда при отладке необходимо увидеть подробную информацию о логике приложения Apache Flink во время выполнения. Например, когда сторонние библиотеки не дают достаточно подробных логов. Хотя в инфраструктуре Apache Flink есть отличный механизм отказоустойчивости в виде контрольных точек, иногда требуется больше данных. В частности, при использовании AWS S3 в качестве пункта назначения контрольной точки Flink обычно использует библиотеки Hadoop или Presto для любого базового взаимодействия. Но бывает сложно устранить проблемы в этом участке кода Flink-приложения, где обработка выполняется в сторонних компонентах.
Чтобы исправить ошибку, можно изменить исходный код Flink-приложения, перекомпилировать и повторно развернуть его. Но это занимает много времени и может стать причиной появления нового бага. Поэтому целесообразно воспользоваться средствами, которые помогают разработчику отладить Java-код, внедрив его в JVM, чтобы извлечь полезные сведения о выполнении приложения [1]. Одним из таких инструментов является Byteman, о котором мы поговорим далее.
Что такое Byteman и чем он полезен разработчику Flink-приложений
Byteman упрощает отслеживание, мониторинг и тестирование поведения Java-приложения и исполняемого кода JDK, внедряя Java-код в методы пользовательского приложения или в методы среды выполнения без необходимости повторной компиляции, упаковки и развертывания. Внедрение может выполняться при запуске JVM или после него, пока приложение работает. Внедренный код может получить доступ к пользовательским данным и вызывать любые методы приложения. Этот код можно внедрить код практически куда угодно, без предварительной подготовки исходной программы. Можно удалить внедренный код и применить различные изменения во время выполнения приложения.
Самым простым способом использования Byteman является внедрение операторов печати, которые отслеживают, что делает пользовательское приложение, идентифицируя поток управления через его код и отображая значения переменных или статических данных. Это можно использовать для мониторинга или отладки оперативных развертываний, а также для тестирования кода при его разработке. Внедряя код в конкретные места, разработчик снижает накладные расходы на производительность, которые обычно возникают при отладке или трассировке продукта. Также можно отслеживать различные показатели в разных случаях. Наконец, Byteman позволяет внедрять любые методы Java не только в приложение, но и в библиотеки и среду выполнения JDK.
Byteman работает, изменяя байт-код классов пользовательского приложения во время выполнения на уровне Java, а не на уровне байт-кода. Пользователь задает Byteman одно или несколько правил, которые определяют код Java, который следует выполнить, и точку внедрения в методах приложений или runtime-классов. Byteman изменяет байт-код, чтобы он вел себя так, как будто исходная программа включает эти изменения. Поскольку Byteman нужен только доступ к байт-коду, это означает, что он может изменять код библиотеки, исходный код которого либо недоступен, либо не может быть перекомпилирован. Это даже включает в себя код Java, который является частью JVM, например, классы String, Thread и пр. Таким образом, с помощью Byteman можно отслеживать и проверять, что делает JVM по запросу пользовательского кода или вызывать классы JVM, такие как FileInputStream или Map для создания исключений, когда приложение их вызывает [2].
Byteman включает простой язык сценариев, основанный на формализме, называемом правилом действия по условию события (ECA, Event Condition Action), чтобы указать, где, когда и как должен быть преобразован исходный код Java. Правило определяет точку срабатывания и место внедрения кода. Когда выполнение программы достигает точки срабатывания триггера, оценивается условие правила – логическое выражение Java. Выражение Java или их последовательность в действии правила выполняется только тогда, когда условие истинно.
При использовании этого инструмента для Flink-приложений стоит помнить, что ссылки на файлы byteman в env.java.opts должны быть абсолютными путями. В Ververica Platform локальный путь по умолчанию для дополнительных зависимостей /flink/usrlib, поэтому полная конфигурация выглядит так:
env.java.opts: >-
-javaagent:/flink/usrlib/byteman.jar=script:/flink/usrlib/rules_v1.btm,boot:/flink/usrlib/byteman.jar
После внесения вышеуказанных изменений развертывание Flink-приложения на Ververica-платформе автоматически перезапустится. Проверить результаты можно в пользовательском интерфейсе Flink [1].
Разумеется, аналогичный прием с Byteman можно использовать не только для отладки Flink-приложений, но и других программ, например, заданий Spark и других вычислительных фреймворков в экосистеме Apache Hadoop, а также вне ее.
Освоить все тонкости разработки распределенных приложений аналитики больших данных с Apache Flink, а также прочими компонентами экосистемы Hadoop вам помогут специализированные курсы в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:
Источники