Приложение Java работает очень медленно (в 10-100 раз медленнее, чем в Windows, Linux, AIX)

Мне нужна ваша помощь по поводу проблем с производительностью при запуске нашего корпоративного Java-приложения на сервере HP \ UX. Приложение представляет собой автономный инструмент, который синхронизирует данные в нескольких базах данных в одну, взаимодействует с удаленным управлением по протоколу XML-RPC и использует локальный экземпляр базы данных Derby (Java DB) для хранения данных конфигурации и т. Д. У нас нет проблем с производительностью в других средах на такая же нагрузка, как Windows XP, Linux и AIX, которые используют Sun JVM. После серии тестов мы выяснили, что больше всего времени занимает общение с базой данных Derby. Больше всего времени уходит на чтение из сокета и это время в 10-100 раз больше, чем на других платформах. Мы точно знаем, что Derby работает нормально, у нас есть резерв ЦП (загрузка около 30% -40%), поэтому наиболее вероятная причина - транспортный уровень между локальной базой данных и приложением.

Есть ли способ диагностировать проблемы ввода-вывода сокета на HP-UX или, возможно, есть некоторые возможные ограничения, которые можно настроить? Может быть, есть необходимая опция JVM? Мы будем очень признательны за любые идеи с вашей стороны.

Мы попытались оптимизировать параметры JVM в соответствии с http://publib.boulder.ibm.com/infocenter/wasinfo/v6r1/index.jsp?topic=/com.ibm.websphere.wsfep.multiplatform.doc/info/ae/ae/tprf_tunejvm_v61.html, но значительных улучшений не произошло.

Информация о JVM: Java HotSpot (TM) 64-разрядная серверная виртуальная машина (19.1-b02-jinteg: 2011mar11-16: 46 PA2.0W (aCC_AP), смешанный режим) Java: версия 1.6.0.10, поставщик "Hewlett-Packard Company"

Мы используем следующий экземпляр: ОС: HP-UX (B.11.23) Архитектура: PA_RISC2.0W 64-битные процессоры: 2

Общий объем физической памяти: 4088 МБ Размер подкачки: 4090 МБ

Вот пример медленно работающего кода. Выполнение на HP занимает несколько секунд, а в Windows - 10-30 мс:

/** Template to communicate with local db. */
SimpleJdbcTemplate jdbcTemplate;

@Transactional(readOnly = true)
public List<JobLogEntry> getLastLogs(Integer dbnr, JobDataType dtype) {
    try {
        String uid = jdbcTemplate.queryForObject("SELECT session_uuid FROM "
                                                         + tableName + " WHERE id=(SELECT max(id) FROM "
                                                         + tableName + " WHERE dbnr=? AND dtype=?)",
                                                         String.class, dbnr, dtype.name());
        List<JobLogEntry> list = jdbcTemplate.query("SELECT id, dbnr, dtype, zeit, level, message FROM "
                                                             + tableName
                                                             + " WHERE dbnr=? AND dtype=? AND session_uuid=? ORDER BY ID",
                                                             new ConRowMapper(), dbnr, dtype.name(), uid);
        return list;
    } catch (org.springframework.dao.EmptyResultDataAccessException e) {
        return new ArrayList<JobLogEntry>();
    }
}



class ConRowMapper implements RowMapper<JobLogEntry> {
    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");

    /**
     * Maps rows.
     */
    public JobLogEntry mapRow(ResultSet rs, int rowNum) throws SQLException {
        return new JobLogEntry(rs.getInt("dbnr"), 
                               rs.getString("dtype"), 
                               dateFormat.format(rs.getTimestamp("zeit")), 
                               rs.getString("level"), 
                               rs.getString("message"));
    }
}

Заранее спасибо за все ваши идеи


person Andrey Leontyev    schedule 26.05.2011    source источник
comment
Каковы ваши текущие настройки JVM, как вы думаете, почему проблема заключается в транспортном уровне? Вы профилировали свое приложение или даже подключили JConsole и т. Д.? Указано ли время только для первой казни?   -  person Michael    schedule 26.05.2011


Ответы (2)


Интересно по поводу метода getLastLogs(). Зачем запрашивать UUID сеанса, а затем использовать его в другом запросе? Я бы предположил, что это можно сделать одним запросом.

Когда вы говорите «Дерби», я думаю, что только Java имеет доступ к этой базе данных. Это правда? Знаете ли вы, что он хорошо оптимизирован (например, правильные индексы для каждого предложения WHERE)?

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

Я вижу jdbcTemplate, значит, вы используете Spring. Я бы подключил перехватчик отладки или трассировки и посмотрел, на что тратится время.

Я также рекомендовал бы Visual VM 1.3.2 установить все плагины. Это даст вам намного больше данных.

person duffymo    schedule 26.05.2011
comment
Привет, даффимо. Спасибо за ответ. Да, мы используем индексы Derby и пул соединений. Самое странное, что на всех остальных системах приложение работает очень быстро. VisualVM говорит, что приложение большую часть времени остается в методе. Мы подумали, что, возможно, на производительность влияют другие потоки jvm. Может проблема не в коде. Что вы думаете? - person Andrey Leontyev; 26.05.2011
comment
Может быть, сборщик мусора влияет на нашу производительность? Может ли быть, что HP JVM работает намного хуже, чем у Sun? - person Andrey Leontyev; 26.05.2011
comment
Не знаю, Андрей. Я бы подключил VisualVM 1.3.2 к вашему приложению и получил больше информации. Мы оба гадаем без данных. - person duffymo; 26.05.2011

Вероятной причиной может быть медленная и блокирующая работа GC на HP-UX. Попробуйте удалить избыточные вызовы System.gc () и использовать некоторые параметры JVM GC для оптимизации :)

См. Красивую презентацию о настройке производительности HP: http://www.scribd.com/doc/47433278/Javamemorymanagemen

person Maxim Kornienko    schedule 26.05.2011