Стратегии оптимизации производительности в унаследованном приложении EJB3 - PullRequest
1 голос
/ 29 сентября 2010

Меня попросили взглянуть на устаревшее приложение EJB3 со значительными проблемами производительности. Первоначальный автор больше не доступен, поэтому все, что у меня есть, это исходный код и некоторые комментарии пользователей относительно неприемлемой производительности. Мои личные навыки EJB3 довольно просты, я могу читать и понимать аннотированный код, но это все, пока не знаю.

На сервере имеется база данных, несколько компонентов EJB3 (JPA) и несколько компонентов без сохранения состояния, чтобы разрешить CRUD для объектов домена 4..5 для удаленных клиентов. Сам клиент является Java-приложением. Лишь немногие подключены к серверу параллельно. Из комментариев пользователей я узнал, что

  • клиент / серверное приложение хорошо работало в локальной сети
  • приложение практически невозможно было использовать в глобальной сети (1 Мбит или более), поскольку операции чтения и обновления занимали слишком много времени (до нескольких минут)

Я видел одну потенциальную проблему - на всех EJB все отношения были определены с помощью стратегии извлечения FetchType.EAGER. Объяснит ли это проблемы с производительностью операций чтения, целесообразно ли начинать настройку со стратегиями выборки?

Но это не объясняет проблем с производительностью при операциях обновления или нет? Обновление обрабатывается EntityManager, клиент просто передает объект домена объекту управления, и сохранение выполняется только с помощью manager.persist(obj). Возможно, доменные объекты, отправляемые на сервер, слишком велики (возможно, это побочный эффект стратегии EAGER).

Итак, моя настоящая теория заключается в том, что слишком много байтов отправляется по довольно медленной сети, и я должен рассмотреть вопрос о сокращении размера наборов результатов.

Исходя из вашего опыта, каковы типичные и наиболее распространенные ошибки кодирования, которые приводят к проблемам с производительностью операций CRUD, с чего мне начать расследование / оптимизацию?

Ответы [ 4 ]

4 голосов
/ 29 сентября 2010

На всех EJB все отношения определены с помощью стратегии извлечения FetchType.EAGER. Объяснит ли это проблемы с производительностью операций чтения?

В зависимости от отношений между классами, вы можете получить гораздо больше (всю базу данных?), Чем на самом деле нужно при получении сущностей?

Желательно ли начинать настройку со стратегиями извлечения?

Я не могу сказать, что создание всех отношений EAGER - это очень стандартный подход. По моему опыту, вы обычно держите их ленивыми и используете "Fetch Joins" (тип объединения, позволяющий получить ассоциацию), когда вы хотите загружать ассоциацию для данного варианта использования.

Но это не объясняет проблем с производительностью при операциях обновления или не так ли?

Может. Я имею в виду, что если приложение получает большой граф толстых объектов при чтении, а затем отправляет тот же граф толстых объектов, чтобы обновить только корневую сущность, это может привести к снижению производительности. Но странно, что в коде используются em.persist(Object) до обновления сущностей.

Исходя из вашего опыта, каковы типичные и наиболее распространенные ошибки кодирования, которые приводят к проблемам с производительностью операций CRUD, с чего мне начать исследование / оптимизацию?

Очевидные из них:

  1. Получение большего количества данных, чем требуется
  2. N + 1 запрос проблем (плохая стратегия выборки)
  3. Плохо написанные JPQL-запросы
  4. Неадекватные стратегии наследования
  5. Ненужные обращения к базе данных (т.е. отсутствие кэширования)

Я бы начал с написания интеграционных или функциональных тестов, прежде чем что-то касаться, чтобы гарантировать, что вы не измените функциональное поведение. Затем я активировал бы ведение журнала SQL и начал бы смотреть на сгенерированный SQL для основных случаев использования и работать над указанными выше пунктами.

1 голос
/ 23 апреля 2011

В моем случае подобная проблема с производительностью не зависела от стратегии извлечения.Или, допустим, было невозможно изменить бизнес-логику в существующих стратегиях выборки.В моем случае решением было просто добавить индексы.Когда ваша объектная модель JPA имеет много отношений (OneToOne, OneToMany, ...), вы обычно используете операторы JPQL с большим количеством объединений.Это может привести к сложным переводам SQL.Когда вы посмотрите на модель данных (сгенерированную JPA), вы поймете, что нет никаких индексов ни для одной из строк вашей таблицы.Например, если у вас есть объект Customer и Address с отношением oneToOne, все будет хорошо работать с первого взгляда.Клиент и адрес имеют внешний ключ.Но если вы делаете выбор, подобный этому

Select c from Customer as c where c.address.zip='8888'

, вам следует позаботиться о столбце таблицы «zip» в таблице ADDRESS.JPA не будет создавать такой индекс для вас во время развертывания.Так что в моем случае я смог ускорить работу базы данных, просто добавив индексы.Оператор SQL в вашей базе данных выглядит следующим образом:

 ALTER TABLE `mydatabase`.`ADDRESS` ADD INDEX `zip_index`(`IZIP`);
1 голос
/ 29 сентября 2010

С позиции DBA.

Исходя из вашего опыта, каковы типичные и наиболее распространенные ошибки кодирования, которые приводят к проблемам с производительностью операций CRUD, с чего мне начать расследование / оптимизацию?

  1. Отключить кеширование
  2. Включить ведение журнала sql. Ejb3 / Hibernate по умолчанию генерирует множество чрезвычайно глупых запросов.
  3. Теперь вы понимаете, о чем я.
  4. Измените FetchType.EAGER на FetchType.LAZY
  5. Скажите «нет» для большой бизнес-логики между em.find em.persist
  6. Использовать ehcache http://ehcache.org/
  7. Включить кеш сущностей
  8. Если Вы можете сделать первичные ключи неизменяемыми (@Column (updatable = false, ...)
  9. Включить кеш запросов

Никогда не используйте Hibernate, если вы хотите большой производительности: http://www.google.com/search?q=hibernate+sucks

0 голосов
/ 30 сентября 2010

В вопросе и в других ответах я слышу много слов "возможно" и "возможно".

Сначала узнайте, что происходит. Если вы этого не сделали, мы все в темноте ковыряемся.

Я не специалист по такого рода системам, но этот метод работает на любом языке или операционной системе.

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

...