Производительность в приложениях JavaEE 6 (Glassfish v3) - ведение журналов, DI, операции с базами данных, EJB, управляемые компоненты - PullRequest
5 голосов
/ 20 августа 2010

Важные технологии, которые я использую: Glassfish v3, JSF 2.0, JPA 2.0, EclipseLink 2.0.2, log4j 1.2.16, регистрация общего доступа 1.1.1.

Моя проблема в том, что некоторые части приложения работают довольно медленно. Я проанализировал это с помощью возможностей netbeans 6.8 Profiling .

I. Ведение журнала - я использую log4j и apache commons logging для создания журналов в файле журнала и в консоли. Журналы также появляются в журнале сервера Glassfish. Я использую регистраторы следующим образом:

    private static Log logger = LogFactory.getLog(X.class);
    ...
    if (logger.isDebugEnabled()) {
        ...
        logger.debug("Log...");
    }

Проблема в том, что иногда такие короткие заявления занимают много времени (около 800 мс). Когда я переключаюсь на java.util.logging, это не так плохо, но и очень медленно (полоса 200 мс). В чем проблема? Мне нужно некоторое ведение журнала ... ОБНОВЛЕНИЕ - Проблема с медленным ведением журнала была решена после перехода с Netbeans 6.8 на Netbeans 6.9.1. - Netbeans 6.8 возможно очень медленный, когда журналы печатаются на его консоли ?! Так что это не имеет никакого отношения к Log4J или регистрации общего достояния ..

II. Операция БД : Первый раз, когда я вызываю метод find следующего EJB, это занимает 2,4 с! Дополнительные звонки длятся всего несколько мс. Так почему же первая операция занимает столько времени? Это (только из-за) установление соединения или это как-то связано с инъекциями зависимости XFacade и когда выполняются эти инъекции?:

@Stateless
@PermitAll
public class XFacade {
    @PersistenceContext(unitName = "de.x.persistenceUnit")
    private EntityManager em;
    // Other DI's
    ...

    public List<News> find(int maxResults) {
      return em.createQuery(
      "SELECT n FROM News n ORDER BY n.published DESC").setMaxResults(maxResults).getResultList() 
    }
}

III. Внедрение зависимостей, JNDI Lookup : Есть ли разница между DI-подобным ( @ EJB ...) и поиском InitialContext, касающимся производительности? Есть ли разница (представление производительности) между введением локального, удаленного и неинтерфейсного EJB-компонентов?

IV. Управляемые компоненты - я использую много компонентов Session Scoped Beans, поскольку ViewScope кажется очень глючным, а Request Scoped - не всегда практически. Есть ли альтернатива? - потому что эти компоненты не работают медленно, но память на стороне сервера подвергается нагрузке в течение всего сеанса И когда пользователь выходит из системы, это занимает некоторое время!

V. EJBs - я не использую только MDB-компоненты Session Beans и Singleton Beans. Часто они вводят другие Бобы с аннотацией @ EJB . Один компонент Singleton Bean использует @ Schedule Аннотации для повторного запуска операций. Интересная вещь, которую я обнаружил, состоит в том, что начиная с EJB 3.1 вы можете использовать аннотацию @ Asynchronous , чтобы сделать асинхронный метод сессионного компонента. Что я обычно должен учитывать при реализации EJB относительно производительности?

Может быть, кто-то может дать мне несколько общих и / или специальных советов по повышению производительности приложений javaee, особенно в отношении вышеуказанных проблем. Спасибо!

Ответы [ 2 ]

4 голосов
/ 22 августа 2010

Для начала вы должны протестировать свое приложение в реальной среде, используя инструменты нагрузочного тестирования, вы не можете сделать правильные выводы из поведения, которое вы наблюдаете в вашей IDE.Кроме того, не забывайте, что профилирование фактически влияет на производительность.

I.Ведение журнала (...) Проблема с медленным ведением журнала была решена после перехода с Netbeans 6.8 на Netbeans 6.9.1

Это первое доказательство того, что вы не можете использовать доверие к поведению внутри вашей IDE.

II.Операция с БД: Первый раз, когда я вызываю метод find следующего EJB, это занимает 2,4 с!Дополнительные звонки длятся всего несколько мс.Так почему же так долго выполняется первая операция?

Может быть, потому что некоторые службы GlassFish загружаются (лениво), может быть, потому, что должны быть созданы экземпляры сессионных компонентов без сохранения состояния (SLSB), возможно, потому что EntityManagerFactory имеетбыть созданным.Что сказал профилирование?Почему вы видите при активации регистрации сервера приложений?И в чем проблема, поскольку последующие звонки в порядке?

III.Внедрение зависимостей, JNDI Lookup: Есть ли разница между поиском DI (@EJB ...) и InitialContext, касающимся производительности?

Поиск JNDI дорогой, и было де-факто практикой использование некоторого кэшированияв старом добром сервисном локаторе.Таким образом, я не ожидаю, что производительность будет хуже при использовании DI (на самом деле я ожидаю, что контейнер будет хорош в этом).И, честно говоря, это никогда не было проблемой для меня.

Когда вы работаете над оптимизацией производительности, типичным рабочим процессом является 1) обнаружение медленной операции 2) поиск узкого места 2) работа над ним 3) если операция все еще не достаточно быстрая, вернитесь к 2).По моему опыту, узкое место составляет 90% времени в DAL.Если у вас узкое место DI, у вас нет проблем с производительностью IMO.Другими словами, я думаю, что вы слишком беспокоитесь, и вы очень близки к «преждевременной оптимизации».

IV.Управляемые компоненты. Я использую множество компонентов Session Scoped, поскольку ViewScope кажется очень глючным, а Request Scoped - не всегда практически.Есть ли альтернатива?- потому что эти компоненты не работают медленно, но память на стороне сервера подвергается нагрузке в течение всего сеанса.И когда пользователь выходит из системы, это занимает некоторое время!

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

V.EJB - я не использую только MDB-компоненты Session Beans и Singleton Beans.Часто они вводят другие Бобы с аннотацией @EJB.Один компонент Singleton Bean использует аннотации @Schedule для повторного запуска операций.Интересная вещь, которую я обнаружил, состоит в том, что начиная с EJB 3.1 вы можете использовать аннотацию @Asynchronous, чтобы сделать асинхронный метод сессионного компонента.Что я должен учитывать при реализации EJB относительно производительности?

SLSB (и MDB) в целом работают очень хорошо.Но вот некоторые моменты, которые следует иметь в виду при использовании SLSB:

  • Предпочитать Local над Remote интерфейсами, если ваши клиенты и EJB размещаются во избежание накладных расходов на удаленные вызовы.
  • Используйте Stateful Session Bean (SFSB) только при необходимости (их сложнее использовать, управление состоянием приводит к снижению производительности и по своей природе не очень хорошо масштабируется).
  • Избегайте слишком большого количества цепочек EJB (особенноесли они являются удаленными), предпочтите грубые методы, а не вызовы нескольких методов.
  • Настройте пул SLSB (чтобы у вас было достаточно компонентов для обслуживания одновременно работающих клиентов, но не слишком много, чтобы не тратить ресурсы)).
  • Используйте транзакции надлежащим образом (например, используйте NOT_SUPPORTED для методов только для чтения).

Я бы также предложил не использовать что-либо, если вам действительно не нужна эта функция, а реальная проблема для решения (например, @Asynchronous).

Может быть, кто-то может дать мне несколько общих и / или специальных советов по повышению производительности приложений javaee, особенно в отношении вышеуказанных проблем. Спасибо!

Сосредоточьтесь на вашем коде доступа к данным, я уверен, что это составляет 80% времени выполнения большинства бизнес-потоков.

И, как я уже намекнул, вы уверены, что у вас действительно есть проблемы с производительностью? Я не убежден. Но если вы на самом деле, измерьте производительность вне вашей IDE.

1 голос
/ 23 августа 2010

Я согласился с Паскалем Тивентом в том, что «преждевременная оптимизация» - это плохо.Хорошо спроектируйте свой код, и , а затем беспокоитесь о производительности.

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

Мне действительно очень нравится профилировщик NetBeans;это один из лучших бесплатных, IMHO.

Я бы порекомендовал:

  1. Профилирование для производительности, но с ограничением области действия либо только вашими собственными пакетами (например, de.x)или исключая основные классы Java.Это сделано для того, чтобы ваше приложение не увязало в профилировании и не вводило в заблуждение показатели производительности.В основном, старайтесь максимально снизить «накладные расходы», как указано в нижней части шкалы.

alt text

Просмотрите ваше веб-приложение на некоторое время и посмотрите, что занимает большую часть вашего процессорного времени.Также обратите внимание на тот факт, что некоторые объекты загружаются лениво, поэтому при первом обращении к фрагментам кода это может быть медленно.Кроме того, вы используете JIT-компилятор, поэтому код может быть медленным в первый (или второй ...) раз, когда вы его запускаете, но он будет быстрее, если вы будете чаще использовать этот фрагмент кода.Короче говоря, используйте веб-приложение на некоторое время.Вы можете «записать» веб-сеанс, используя Selenium , и «воспроизвести» его.Это позволит вам получить более высокие показатели производительности и увидеть, где ваше приложение действительно работает медленно, вместо измерения «времени прогрева».

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

Если у вас есть определенный фрагмент кода, вызывающий васпроблемы, не стесняйтесь писать об этом.

...