JVM загружает TimeZone для чтения анализа приоритета файлов

Java JVM Операционная система Эксплуатация и обслуживание
JVM загружает TimeZone для чтения анализа приоритета файлов

проблемное явление

Несколько дней назад в сети была запущена новая программа Kafka Java Consumer. Возникла нештатная проблема. Потом, просмотрев лог, данные были записаны в индекс Elasticsearch, но фронтенд не смог запросить данные.

Окончательное принятие и разработка позиционирования вместе, причина в том, что из-за нашего бизнеса, проблемы с отметкой времени по умолчанию, необходимо использовать по умолчаниюUTC TimeZone; но когда эксплуатация и техническое обслуживаниеdateПри просмотре команды по умолчанию используется часовой пояс UTC, почему это все еще неправильно?

Потому что мы поддерживаем онлайн/etc/localtimeфайл для предотвращения проблем с часовым поясом, а такжеUTCчасовой пояс, но время записи данных все равно не правильное, а коллега, вышедший в интернет позже, сказал, что/etc/timezoneФайл удаляется, а затем программа-потребитель перезапускается.

Ну почему это, хотя я знаю, чтобы удалить/etc/timezoneПосле записи файла деловые данные пишутся нормально, но почему так, давайте разберемся.

найти правду

Обычно, когда я сталкиваюсь с такой проблемой, с которой раньше не сталкивался, я использую Google для поиска.После завершения поиска я получаю последовательность файлов часового пояса загрузки JVM следующим образом:

  1. Если системная переменная среды имеет настройку TZ, значение переменной TZ будет взято первым;
  2. если в файле/etc/sysconfig/clockЗначение ZONE можно найти в файле. Обратите внимание, что значение ZONE должно быть заключено в двойные кавычки, например ZONE="Asia/Shanghai"
  3. Если значение ZONE не найдено, он прочитает содержимое /etc/localtime и сопоставит файл часового пояса в /usr/hsare/zoneinfo.Если совпадение будет найдено, будет возвращен соответствующий путь.

Ссылка на китайский язык: https://blog.csdn.net/zj380475045/article/details/72765936 http://www.360doc.com/content/12/1011/17/110467_240881174.shtml Ссылка на английском языке: https://bugs.java.com/view_bug.do?bug_id=6456628

Тогда по результатам поиска моя ситуация не правильная, удалим онлайн/etc/timezoneФайл в порядке, поэтому он должен быть таким же, как файл/etc/timezoneЭто связано, поэтому я чувствую, что это должно быть связано с операционной системой и версией JAVA, поэтому я думаю, что если вы попрактикуетесь, вы должны раскрыть тайну.

разгадать тайну

окружающая обстановка операционная система JAVA-версия
aliyun Centos6.5 1.8.0_25

Приведенная выше таблица — это моя онлайн-среда, и процесс практики выглядит следующим образом.

Код теста Java выглядит следующим образом:

[root@Labhost2 src]# cat TimeTest.java 
import java.util.Date;
import java.util.TimeZone;

public class TimeTest {

    public static void main(String args[]) {
	long time = System.currentTimeMillis();
	String millis = Long.toString(time);
	Date date = new Date(time);
	System.out.println("Current time in milliseconds = " + millis + " => " + date.toString());
	System.out.println("Current time zone: " + TimeZone.getDefault().getID());
    }
}

[root@Labhost2 src]# javac TimeTest.java   # 生成测试类
[root@Labhost2 src]# ls
TimeTest.class  TimeTest.java

Из поиска мы знаем, что JVM читает часовой пояс и системные переменные.TZи файл/etc/sysconfig/clock,/etc/localtimeАктуально, я добавляю файлы, которые мы удалили здесь/etc/timezoneДавайте потренируемся вместе, и процесс проверки выглядит следующим образом:

[root@Labhost2 src]# export TZ="Pacific/Honolulu"
[root@Labhost2 src]# cat /etc/sysconfig/clock
ZONE="America/Los_Angeles"
UTC=false 
ARC=false
[root@Labhost2 src]# ll /etc/localtime 
lrwxrwxrwx 1 root root 23 4月  18 09:23 /etc/localtime -> /usr/share/zoneinfo/UTC
[root@Labhost2 src]# cat /etc/timezone
Asia/Shanghai

Из приведенной выше информации резюмируем статус:

Тестовые задания значение часового пояса
TZ Pacific/Honolulu
/etc/sysconfig/clock America/Los_Angeles
/etc/localtime UTC
/etc/timezone Asia/Shanghai

После установки указанного выше состояния выходные данные теста проверяются следующим образом:

[root@Labhost2 src]# java TimeTest
Current time in milliseconds = 1524275592096 => Fri Apr 20 15:53:12 HST 2018
Current time zone: Pacific/Honolulu
[root@Labhost2 src]# unset TZ
[root@Labhost2 src]# java TimeTest
Current time in milliseconds = 1524275606924 => Sat Apr 21 09:53:26 CST 2018
Current time zone: Asia/Shanghai
[root@Labhost2 src]# rm -rf /etc/timezone 
[root@Labhost2 src]# java TimeTest
Current time in milliseconds = 1524275627626 => Sat Apr 21 01:53:47 UTC 2018
Current time zone: UTC
[root@Labhost2 src]# rm -rf /etc/localtime 
[root@Labhost2 src]# java TimeTest
Current time in milliseconds = 1524275640872 => Sat Apr 21 01:54:00 GMT 2018
Current time zone: GMT

Как видно из приведенных выше результатов теста, в моей среде порядок, в котором JVM читает файлы часовых поясов, следующий:$TZ > /etc/timezone > /etc/localtime > 默认GMT, так что это отличается от искомой ситуации, с файлом/etc/sysconfig/clockЭто не имеет значения.

Хорошо, я получил здесь правильный ответ, я наконец понял, это может объяснить нашу ситуацию в Интернете, мы удаляем файлы в Интернете/etc/timezoneПосле этого переходим к чтению файла/etc/localtimeДа, мы подаем онлайн/etc/localtimeНастройка обслуживания по умолчанию:UTCЭто объясняется часовым поясом, который как раз соответствует потребностям нашего бизнеса.

Описание GMT ​​по умолчанию: исходный код метода getDefault в классе java.util.TimeZone показывает, что в конечном итоге он вызовет метод getTimeZone класса sun.util.calendar.ZoneInfo. Этот метод возвращает параметр String в качестве идентификатора нужного часового пояса. Идентификатор часового пояса по умолчанию получается из свойства user.timezone (система). Если user.timezone не определен, он попытается получить идентификатор из свойств user.country и java.home (System). Если ему не удается найти идентификатор часового пояса, он использует «резервное» значение GMT. Другими словами, если он не вычисляет идентификатор вашего часового пояса, он будет использовать GMT в качестве часового пояса по умолчанию.

Суммировать

Лучший способ избежать этой проблемы заключается в следующем:

[Рекомендуется] В сценарии запуска программы Java после выпуска можно указать часовой пояс и кодировку приложения через параметры JVM, например java -Duser.timezone=Asia/Shanghai -Dfile.encoding=utf8 DateTest

Неважно, есть ли у сотрудников отдела исследований и разработок в вашей компании соответствующие спецификации разработки Java или они указывают часовой пояс в сценарии запуска.Если есть требования, то возьмите на себя инициативу установить эти параметры в сценарии запуска, субъективная осведомленность об эксплуатации и обслуживании, а также уменьшить зависимость запущенных онлайн-программ от системной среды, чтобы избежать некоторых проблем.