проблемное явление
Несколько дней назад в сети была запущена новая программа Kafka Java Consumer. Возникла нештатная проблема. Потом, просмотрев лог, данные были записаны в индекс Elasticsearch, но фронтенд не смог запросить данные.
Окончательное принятие и разработка позиционирования вместе, причина в том, что из-за нашего бизнеса, проблемы с отметкой времени по умолчанию, необходимо использовать по умолчаниюUTC TimeZone
; но когда эксплуатация и техническое обслуживаниеdate
При просмотре команды по умолчанию используется часовой пояс UTC, почему это все еще неправильно?
Потому что мы поддерживаем онлайн/etc/localtime
файл для предотвращения проблем с часовым поясом, а такжеUTC
часовой пояс, но время записи данных все равно не правильное, а коллега, вышедший в интернет позже, сказал, что/etc/timezone
Файл удаляется, а затем программа-потребитель перезапускается.
Ну почему это, хотя я знаю, чтобы удалить/etc/timezone
После записи файла деловые данные пишутся нормально, но почему так, давайте разберемся.
найти правду
Обычно, когда я сталкиваюсь с такой проблемой, с которой раньше не сталкивался, я использую Google для поиска.После завершения поиска я получаю последовательность файлов часового пояса загрузки JVM следующим образом:
- Если системная переменная среды имеет настройку TZ, значение переменной TZ будет взято первым;
- если в файле
/etc/sysconfig/clock
Значение ZONE можно найти в файле. Обратите внимание, что значение ZONE должно быть заключено в двойные кавычки, например ZONE="Asia/Shanghai" - Если значение 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 или они указывают часовой пояс в сценарии запуска.Если есть требования, то возьмите на себя инициативу установить эти параметры в сценарии запуска, субъективная осведомленность об эксплуатации и обслуживании, а также уменьшить зависимость запущенных онлайн-программ от системной среды, чтобы избежать некоторых проблем.