Java время выходит из синхронизации - PullRequest
0 голосов
/ 15 января 2019

В последнее время я испытываю очень странную ошибку, которую не могу воспроизвести локально. Это происходит на сервере (CentOS) внутри приложения Spring Boot.

вызов new Date() (java.util.Date) производит неправильное время. И я не говорю о разнице в часах из-за разного часового пояса. Дата выключена на Х минут. Похоже, что оно постепенно начинает отставать от текущего времени.

При получении текущего времени системных часов оно кажется правильным, но время Java постепенно увеличивает разницу (не на одну минуту каждую минуту, а медленнее). Почти как JVM существовал в некотором временном пузыре с различными законами времени.

Эта проблема стала возникать случайно сегодня после длительного периода без каких-либо проблем.

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

EDIT: сервер работает в виртуализированном стеке виртуальных машин, как я только что узнал. Я не уверен насчет конкретной конфигурации HW.

EDIT2: я думаю, что нашел проблемную часть. Компонент, вызывающий эту проблему, работает внутри пула потоков, поэтому я подозреваю, что все потоки в пуле заняты, а запросы помещены в очередь, поэтому для обработки запросов, в которых я устанавливаю текущую метку времени, требуется больше времени.

Пример:

@Async
public Date sendTimeToOtherServer() {
  Date date = new Date()
  // code that sends the date to different server
}

1 Ответ

0 голосов
/ 15 января 2019

Java получает время от ОС через системный вызов. Это должно в свою очередь получить время от аппаратных часов.

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

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

Я увеличил размер пула потоков, и он начал работать правильно, поэтому это должно быть узкое место в пуле потоков

Возможно, вы преждевременно спешите с выводами здесь. Кстати, я никогда не слышал, чтобы точность часов зависела от размера пула потоков Java.


Я имел в виду, что, вероятно, понадобилось некоторое время, чтобы пул потоков был готов предоставить какой-то поток для обработки моей задачи, в которой я вызывал новый Date().

Ах. Понимаю. Хорошо, если вы фиксируете время начала запроса в рабочем потоке, и в пуле недостаточно потоков, то то, что вы получаете с new Date(), скорее всего, будет точной отметкой времени (относительно системных часов) ; время не синхронизировано.

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

  • В первом случае увеличение размера пула является правильным решением.

  • В последнем случае это не сильно поможет и может ухудшить ситуацию.

Конечным ограничивающим фактором пропускной способности будут такие факторы, как количество ядер, объем памяти, производительность базы данных, пропускная способность сети и т. Д. Увеличение пула потоков может позволить параллельно обрабатывать больше запросов. Однако, если у вас уже не хватает ресурсов, это не увеличит скорость обработки запросов. Действительно, чрезмерное количество рабочих потоков может привести к:

  • увеличено использование памяти и загрузка GC,
  • отдельные запросы занимают так много времени, что клиент их истекает.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...