Хабрахабр

ASH Viewer: перезагрузка

Что делать, если надо работать с данными, которые по объему еще не Big data, но уже больше того, что умещается в памяти компьютера и для которых достаточно возможностей Excel? Для любителей велосипедостроения ответ очевиден – нужно писать что-то свое (да, мы не ищем легких путей).

Отставить в сторонку старые наработки, дать дорогу новому, вечному и светлому (да-да, и тут тоже без вариантов). Но как быть, если код, написанный тобой в прошлом, ужасен и не дает тебе возможности развивать проект?

Режиссер: братья и сестры Вачовски. Цитата из кф Матрица: “Достаточно одной таблетки, Нео”. США
Уже больше 10 лет назад я написал код для ASH Viewer (более подробно о моем пути здесь ), выложил сначала на sourceforge.net, а потом и на github чтобы люди подключались и могли добавлять функционал, править ошибки. 1999. Была сделана сборка проекта с помощью Gradle, решили вопросы с отображением графиков: практически полный список улучшений по ссылке.

Внешне все выглядело неплохо, функциональность была развита, люди активно пользовались и благодарили. Однако я понимал, что написанный десять лет назад код, мягко говоря, неидеален. Но внутри программа содержал все ошибки первого опыта кодирования и, конечно, это очень сильно тормозило развитие проекта.

И с каждой попыткой внедрить какую-либо функциональность или заняться исправлением ошибок я убеждался в этом. Каждому, кто был готов серьезно начать работу над приложением (например, dcvetkov), я говорил, что код требует полной переделки. Надеюсь, в будущем роботы научатся переписывать все сами, ну а пока было принято волевое решение начать с чистого листа, с учетом уже наработанного опыта в создании программ и написании кода. Доложу вам, править legacy-код — страшная пытка, особенно свой :).

Было сделано 3 достаточно крупных проекта на базе JfreeChart для анализа данных. С момента первого релиза ASH Viewer активно работал в этом направлении. В итоге остановился на том, что писать надо все на чистой Java, без использования библиотек специально предназначенных для создания графического интерфейса с нуля. Кроме этих проектов, пробовал разные подходы, парадигмы и библиотеки. Но все же применять сторонние библиотеки для решения каких-то узкоспециализированных задач вполне допустимо — это позволит сохранить необходимый уровень гибкости и не потребует значительных затрат времени на исправление багов и разработку требуемой функциональности своими руками.

Как все начиналось

Меня всегда волновало, а есть ли в свободном доступе пример, который бы давал основы правильного написания приложений средней сложности на Java Swing? Конечно, меня отсылали к самой библиотеке или к каким-то простым примерам из учебников. И в чем-то они были правы.

Причем хотелось иметь перед глазами рабочую систему, чтобы ее можно было «пощупать». Но я упорно искал код приложения, который можно было бы использовать в качестве примера «как надо делать правильно» на Java Swing.

Где-то это были простые ToDo, где-то слишком сложные (для меня на тот момент), в каких-то подводило качество, а иногда было и то, и другое. Начал изучать исходные коды приложений на Java Swing (всех их не перечесть). Но все же чего-то не хватало. Читал статьи на Хабре, писал код. Возможно, я как раз тогда набирал критический для решения этой задачи объем знаний.

Java Swing, простой функционал, чистый код, модульность – приятно читать! В один из дней обнаружил Angry IP Scanner уважаемого Антона Кекса antonkeks, посмотрел ее и сразу понял — вот оно! В общем, используемые в ней подходы я взял за основу при написании одного из своих предыдущих проектов, а затем и при переписывании ASH Viewer.

ПО и библиотеки, которые помогли улучшить качество кода и упростили работу

IDEA: уже лет пять использую эту IDE для программирования в Java. Подтверждаю мнение большинства — это действительно полезная программа и очень удобный инструмент для написания кода. Когда я пересел на нее с Эклипса www.eclipse.org/ide (а первая версия была написана на этой IDE), то после непродолжительного обучения понял, IDEA ведет тебя и сообщает, когда ты пытаешься перейти на темную сторону :). Подсветка повторов в коде держит тебя в тонусе и не дает заниматься тупой копипастой. Аве JetBrains!

Java 8: лямбда-выражения, которые дают возможность писать более короткий код, новое Time API, позволившее отменить использование сторонней библиотеки Joda Time.

Но как-то подсмотрел, как используется эта библиотека у Антона antonkeks, и стал делать по шаблону. Dagger 2: Dependency injection framework я раньше вообще не применял. Где это было невозможно, использовал создание объектов оболочек заранее, а потом проводил установку необходимых атрибутов или просто не использовал DI. Делить программу на модули, где это возможно, использовать внедрение зависимостей.

Именно это система сборки является стандартом де-факто, поэтому решил сделать добавление библиотек чисто, через pom.xml и использовать систему модулей от Maven для работы с кодом JFreeChart и Gantt в одном проекте. Система сборки Maven.

Правда, в некоторых случаях отказывался от ее использования, так как надо было переопределить equals и compareTo, но как быстро это сделать в Lombok не нашел. Lombok: тоже невероятно удобная библиотека, чтобы не писать и не поддерживать «портянки» однообразного кода (getter-ы, setter-ы и проч.).

Значит, без современных средств журналирования никуда. Журналирование: делаем идеальную Java программу? Поэтому берем за основу Simple Logging Facade for Java SLF4J и Logback.

Достаточно сложный в освоении (в некоторых местах по старинке использую Swing layout manager-ы), но зато краткий. Layout менеджер: в основном использую Miglayout. Позволяет делать вот такие интересные эффекты, как на вкладке Detail.

Активно использую JXTable. Swingx от Swinglabs: давно заброшенный Java Swing UI tooklit. Произвольный выбор столбцов таблицы и встроенный поиск по содержимому ячеек облегчают детальный анализ данных истории активных сессий.

В старой версии использовал доработанную реализацию, которую нашел в Интернет. Сommons-dbcp2: полезен для создания connection pool подключений к БД.

Библиотеки, которые переехали из старой версии

Oracle Berkeley DB Java Edition v. 5.0.73: встраиваемая key-value storage. Для хранения агрегированных данных истории активных сессий.

Взял за основу экспериментальную версию, которая выложена на github и добавил ее как модуль. JFreeChart: тысячи проектов для анализа данных написаны с использованием этой библиотеки. Это было сделано для удобства работы с кодом, так как требовались изменения, чтобы Stacked Chart отображал график как нужно.

Следов ее сейчас не найти даже в интернетах, увы. E-Gantt: библиотека для создания Gantt-графиков в Java Swing. Тоже разместил отдельным модулем Maven в проекте.

Из интересного в коде, на что можно обратить внимание

Архитектурные изменения:

  1. Теперь настройки хранятся в отдельной встроенной БД, не в plain text файлах. Так как данных немного, используется расширенный паттерн EAV для хранения настроек подключения;
  2. Для хранения данных мониторинга решил сделать подобие OLAP-engine. Во-первых, для ускорения отображения детализации Gantt по SQL_ID/SESSION_ID по выбранному диапазону. Во-вторых, для возможности получения быстрой детализации по SQL_ID/SESSION_ID по stacked и Gantt графикам. В-третьих, формирования в будущем просмотра истории активных сессий (Top по ожиданиям, детализация по ожиданиям, детализация по SQL_ID/SESSION_ID). Все хранится в одной сущности (данные по секундному, 15-секундному и, в перспективе, по другим расширенным интервалам физически разделены);
  3. Побочным эффектом clean architecture имеем возможность поддержки мониторинга истории активных сессий других БД. На данный момент реализована поддержка Postgres. Чтобы подключить другие БД, нужен или готовый интерфейс к данными истории активных сессий (который добавили в Postgres или вот такая реализация) или самостоятельно настроенный сбор истории активных сессий в отдельную таблицу, к которому можно будет в последствии обращаться.

    Как включить поддержку другой БД

    1. Создать новый класс и реализовать интерфейс IProfile. Сделать аналогично, как и в случае Postgres;
    2. Добавить в процедуру loadProfile класса ConnectToDbArea и enum Function класса ConstantManager реализацию для новой версии БД;
    3. Подключиться и проверить работу приложения.

Графический интерфейс

Форма подключения к БД

Сейчас все в одном файле. Полностью переписана с нуля, раньше использовал наработки c открытого проекта Squirrel-sql. Красота!

Как подключиться к БД

  1. Создать новое подключение;
  2. Указать имя, URL (JDBC стандартно для Oracle: jdbc:oracle:thin:@host:port:SID, для Postgres: jdbc:postgresql://host:port:database), username/password, профиль и выбрать jdbc библиотеку;
  3. Для Oracle все работает с ojdbc6.jar, для PostgresDB проверена работа с postgresql-42.2.5

Интерфейс Top activity/Detail

Здесь без существенных изменений, аналогично как в старой версии, только без просмотра истории.

Детализация по SQL_ID/SESSION_ID

SQL

Только для Oracle предоставляются планы выполнения запроса по всем plan_hash_value.
Statistics: данные в табличном виде по SQL_ID: выборка из V$SQL. ASH: график активности по определенному SQL_ID, вызывается двойным кликом по строке с SQL_ID из Gantt-графика.
Sql text/plan: для Oracle/Postgres есть возможность получить полный текст запроса. реализацию). В коде есть возможность добавлять еще сущности, по которым можно делать выборку (см. но нужно быть очень аккуратным, так как могут быть проблемы с производительностью: например, выборка из V$SQLAREA на нагруженных системах работает очень медленно).

В коде есть возможность добавлять еще сущности, по которым можно делать выборку (см. Session

ASH: график активности по session_id, аналогично SQL вызывается двойным кликом по строке сессии из Gantt-графика.
Statistics: данные в табличном виде по SQL_ID: выборка из V$SESSION и V$PROCESS. реализацию).

Дальнейшие планы

  1. Устаканить API. Провести финальный рефакторинг кода. Реализовать динамическое хранение исходных данных мониторинга, который бы не зависел от версий и типов БД;
  2. Очень не хватает тестов, которые бы проверяли ключевые модули системы, CI и других передовых практик.

Код проекта на github, файлы проекта;
Ссылка на группу в Телеграмм t.me/ashviewer для информирования о последних обновлениях;

S. P. Кто надумает подключиться к разработке — пишите в ЛС, без излишнего ажиотажа и не создавая давки, естественно :).

Спасибо за внимание! На этом все.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть