Назад | Перейти на главную страницу

Толстый клиент Java работает медленно при подключении к localhost, быстро с удаленным

У меня возникают проблемы с (обычно) настольным Java-приложением с привязкой к задержке, подключенным к настраиваемому серверу базы данных.

Пока он работает на удаленном хосте (Windows XP), он работает быстро (большая форма открывается менее чем за 2 секунды). Когда он работает на том же хосте, база данных включена (с использованием X11vnc и NX), это очень медленно (та же форма открывается примерно через 20 секунд). На сервере работает SuSE Linux Enterprise Server 10.

Что проверил:

Глядя в atop похоже, нет узких мест:

Единственное, что различается между удаленным и локальным запуском, - это использование сети, в то время как локальный процесс извлекает данные со скоростью около 1200 кбит / с, удаленный - около 15 Мбит / с.

В настоящее время я работаю над дублированием проблемы с моим оборудованием, поэтому любые советы по этим вопросам тоже приветствуются.

РЕДАКТИРОВАТЬ: изменение lo значение MTU интерфейса от 16k до 1500 устраняет проблему. Проблема была продублирована на Debain lenny 64bit.

Это будет звучать странно, но у меня это сработало некоторое время назад.
Проверьте файл / etc / hosts, чтобы ваше имя хоста было в строке с localhost или добавьте один, указывающий на 127.0.0.1 или тот, который слушает.

Все, что у меня есть для вас, - это еще несколько идей для отладки в произвольном порядке ...

  • действительно ли проблема в петле? Вы пытались подключиться к сетевому IP-адресу сервера, а не к 127.0.0.1? (в моей системе используется интерфейс обратной связи, но это должно исключать нечетные проблемы с DNS)
  • это система высокая загрузка в это время (проблемы с io могут привести к тому, что нагрузка на систему будет выше, чем может показаться для всех отдельных процессов вместе)?
  • Проверьте информацию netstat для каждого процесса, если Recv-Q клиента высокий, клиентский процесс не читает из своего сокета на регулярной основе.
  • Попробуйте посмотреть tcpdump -i lo, это может помочь выяснить, есть ли очевидная закономерность в передаваемых пакетах.
  • Показывает ли "vmstat 1" кардинально иное поведение для удаленного доступа и версий с локальным доступом (т.е. удерживает набор данных в ОЗУ как на сервере db, так и на клиенте java, заставляя вас менять местами)?
  • Попробуйте увеличить MTU на устройстве с обратной связью, мое значение по умолчанию - 16436. Это не сильно поможет, если вы выполняете много маленьких битовых пакетов. Маленькие битовые пакеты, кажется, имеют свои собственные проблемы. Я не программист на Java, поэтому не знаю, как это сделать, но попробуйте установить TCP_NODELAY (системный вызов setsockopt) для соединения. Кажется, что у него есть культ карго, но предположительно, если связь односторонняя, клиент будет более регулярно отвечать TCP ACK и поддерживать поток данных.
  • Еще кое-что, что нужно попробовать: echo 1 > /proc/sys/net/ipv4/tcp_low_latency
  • Играя с setsockopt, посмотрите, что произойдет, если вы увеличите буферы отправки и получения в клиенте?
  • Вы же не используете какое-то древнее ядро ​​2.2? По-видимому, была какая-то огромная ошибка обратной связи, исправленная еще в 2.3.x согласно 2.4 TODO.
  • Может быть, есть ошибка в клиенте (или в Java), запускали ли вы тот же клиент в отдельной системе Linux с той же средой выполнения java?

Чтобы исключить X11vnc и NX как возможные причины задержки, я бы написал тестовую программу Java без графического интерфейса пользователя в консольном режиме, которая выполняет поиск в базе данных или тестовые транзакции и время, когда это приложение запускается на ПК и на сервере (например, используя SSH / Putty для вызова Это).

Долгий план: я бы также проверил обратное разрешение DNS на случай, если драйверы JDBC используют это (например, для ведения журнала), если DNS не настроен должным образом, программное обеспечение может зависнуть в ожидании тайм-аутов разрешения DNS. Как настраивается расположение СУБД в приложении Java?

Вы пробовали подключиться к 127.0.0.1 вместо localhost? Это делает несколько вещей. Одним из них является предотвращение безумных проблем с DNS, но также многие клиенты видят "localhost", а затем решают вообще не использовать сеть и вместо этого используют какой-то локальный сокет. Возможно, именно этот автоматический переключатель технологий убивает ваше приложение. Некоторые программы делают это, например mysql. Использование адреса обратной связи localhost по IP заставляет их фактически использовать сетевой сокет.

Мой любимый инструмент для решения подобных проблем - strace. Возможно, вы сможете просто привязать клиента и увидеть, как он приостанавливается после выполнения чего-либо (блокирующего вызова, такого как подключение или чтение). Если есть какой-то цикл событий, который скрывает паузу, вы можете попытаться отфильтровать эти системные вызовы или можете включить параметры синхронизации, чтобы выполнить strace и сохранить весь вывод в файле. Еще одна уловка - дождаться, пока он «закончит» все, что его удерживало, и нажать ^ C, чтобы вы могли посмотреть, что случилось, и вывести его из ступора.

Оказалось, ошибка в приложении. При небольшом MTU TCP фрагментировал пакеты, не обнаруживая ошибки. При высоком MTU на loopback ошибка проявлялась.