Preface
The development colleagues in the business department encountered a strange bug a few days ago. First of all, they have a business that has been stored in the database. The creation time and the server time differed by 8 hours. Secondly, when the time was displayed on the front end, the time was actually the same as the service time. It was a few months away.
Today, I’m going to do a review on this issue. Let’s talk about when the business data time is different from the expected one, and from which direction can we investigate
Troubleshoot directions
1. The time of the database and the server are inconsistent
1. Check the time zone configured by the jdbc link, that is, the parameter configuration of serverTimezone
Note: The time zone in this article is based on Dongba District, and the database is mysql
example:
jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
The time zone configured as shown in the figure above is UTC, which is 8 hours away from Dongba District. If we follow this configuration method, when we use the new Date() method in the code layer, the time to the database will be 8 hours away from the time we expected. At this point we can change the time zone parameter configured on jdbc to
serverTimezone=Asia/Shanghai
2. View the default time zone configuration of the database
show variables like '%time_zone%';
As can be seen from the figure, the default configuration of the database time zone at this time is not Dongba District. We can modify it in the following ways
- a, through the command
##修改mysql全局时区为东八区
set global time_zone = '+8:00';
##修改当前会话时区
set time_zone = '+8:00';
Note: through the command line, there is no need to restart the mysql service, but when the mysql service is restarted again, the above configuration will disappear
- b, through the configuration file
For linux system, edit my.cnf and fill in the following content
[mysqld]
// 设置默认时区
default-time_zone='+8:00'
For the window system, edit my.ini and fill in the same content as linux
Note: modifying the configuration, you need to restart the mysql service
There is a difference of 8 hours in the creation time of the business departments because their business creation time is unified through the database configuration default time. At that time, the default time zone of their database is UTC, so the difference is 8 hours. Later, this problem was solved by adjusting the database time zone
2. The time of the container and the server are inconsistent
1. Go inside the container to check the time
docker exec -it 【容器ID或者NAME】 bin/bash -c date
2. If the container is already generated
You can directly copy the host's localtime to the docker container, provided that the host's time is also correct. The command is as follows
docker cp /etc/localtime 【容器ID或者NAME】:/etc/localtime
Or you can directly modify the time of the docker container. Enter the container content, execute date -s
3. Before the container is generated, configure directly through the dockerfile [recommended]
FROM adoptopenjdk/openjdk8
VOLUME /tmp
#ENV JAVA_OPTS="-Dcom.sun.management.jmxremote.port=39083 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"
ENV JAVA_OPTS=""
COPY localtime /etc/localtime
RUN echo "Asia/Shanghai" > /etc/timezone
COPY demo-biz/target/demo-service-biz-*.jar app.jar
ENTRYPOINT [ "sh", "-c", "exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
Note: because the business dockerfile is uniformly generated based on the template, so there is no such problem
3. The time format is incorrectly configured
In order to unify the processing time format, the business department has made the following configuration in the code
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
//格式化json数据格式
FastJsonConfig fastJsonConfig = new FastJsonConfig();
//序列化时避免精度丢失,转换为字符串
SerializeConfig serializeConfig = SerializeConfig.globalInstance;
serializeConfig.put(BigInteger.class, ToStringSerializer.instance);
serializeConfig.put(Long.class, ToStringSerializer.instance);
serializeConfig.put(Long.TYPE, ToStringSerializer.instance);
fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteMapNullValue);
fastJsonConfig.setSerializeConfig(serializeConfig);
fastJsonConfig.setDateFormat("yyyy-HH-dd HH:mm:ss");
fastConverter.setFastJsonConfig(fastJsonConfig);
List<MediaType> fastMediaTypes = new ArrayList<>();
fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
fastMediaTypes.add(MediaType.APPLICATION_JSON);
fastConverter.setSupportedMediaTypes(fastMediaTypes);
converters.add(0,fastConverter);
}
}
A sharp-eyed friend may have discovered that the time format is different from the normal format. Who would have thought that the weird bug was accidentally written in the wrong time format. The solution is very simple,
fastJsonConfig.setDateFormat("yyyy-HH-dd HH:mm:ss");
Change to
fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
to sum up
The above introduces several troubleshooting directions, especially the last one, because the time format is written incorrectly, which causes the time to be displayed incorrectly.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。