首页 > 其他分享 >在Docker中升级时区规则

在Docker中升级时区规则

时间:2024-08-28 11:51:33浏览次数:9  
标签:tar JDK jar gz 升级 规则 镜像 Docker 时区

背景

最近, 由于部分国家和地区取消了了夏令时, 导致我们的系统中的定时任务出现了提前执行的情况。这个问题的根源在于, 我们当前使用的 Java 开发工具包 (JDK) 内置的时区规则数据已经过期, 无法及时反映各地区时区调整的最新变化。

为了解决这一问题, 在不升级整个 JDK 版本的前提下, 我们需要寻找一种更加便捷的方式, 来独立更新 JDK 中的时区规则数据。这不仅可以确保我们的系统时间处理功能与最新的时区规则保持一致, 也避免了全量升级 JDK 所带来的风险和工作量。

以下重点介绍在 Docker 中如何更新 JDK 的 time zone database。

了解 Time Zone Database

时区数据库 (Timezone Database) 通常被称为 tz 或 zoneinfo, 是一个由 IANA (互联网名称与数字分配机构) 管理和维护的权威数据库。它包含了全球各地区的时区信息, 包括时区边界、与 UTC (世界统一时间) 的偏移量, 以及夏令时的实施规则等详细数据。

该数据库遵循 BCP 175 标准, 会定期根据各国政府机构对时区规则的调整而进行更新, 以确保数据的准确性和时效性。这个数据库格式也被称为"Olson 数据库", 因为它最初是由艾伦·奥尔森 (Olson) 开发的。

Oracle 公司在其不同版本的 Java 开发工具包 (JDK) 中都内置了时区数据库的不同版本,具体可参考 Timezone Data Versions in the JRE Software。Oracle 依赖这些公开提供的时区数据, 并提供了 TZUpdater 工具, 允许用户根据需要更新 JDK 和 JRE 中的时区数据, 以适应各国夏令时规则的变化。

从 Java 8 开始, 时区数据库文件 tzdb. Dat 被放置在 JAVA_HOME/jre/lib 目录下。Oracle 的 JDK 中的时区数据库实现是基于 IANA 时区数据库, 并且可以通过 Oracle 提供的工具进行版本更新和维护, 以保证时区数据的最新状态。

关于 TZUpdater 的下载链接和使用方法, 可以分别参考 Oracle 官方提供的 Java SE Timezone Updater Download时区更新程序工具使用说明, 其中后者对工具的安装、命令选项、使用场景等进行了非常详细的介绍。

在 Docker 中更新 TZ

在 docker 中更新 TZ 主要是利用 TZUpdate 工具进行更新,在 Dockerfile 中将 tzupdate.jar 复制到 docker 容器中,再执行更新操作,具体步骤如下:

  1. 选择合适的基础镜像,通常使用官方的 OpenJDK 镜像作为基础镜像, 例如:
    FROM openjdk:8-jdk-slim
  2. 复制应用程序 JAR 文件和 TZUpdater 工具,将应用程序 JAR 文件和 TZUpdater 的 JAR 文件复制到 Docker 镜像中:
    COPY tzupdater.jar tzupdater.jar
  3. 获取最新的时区数据,有两种方式获取最新的时区数据:
    a. 下载最新 tzdata 包并复制到镜像中:
    COPY tzdata2024a.tar.gz tzdata2024a.tar.gz 
    RUN java -jar tzupdater.jar -l file:///tzdata-latest.tar.gz
    
    b. 直接指定最新 tzdata 包的链接,这种方式更加简洁, 每次构建镜像时都会自动下载最新的时区数据。
    RUN java -jar tzupdater.jar -l https://www.iana.org/time-zones/repository/tzdata-latest.tar.gz

整体的 Dockerfile 参考如下:

# 使用 OpenJDK 8 作为基础镜像  
FROM openjdk:8-jdk-slim  
  
VOLUME /tmp  
  
# 复制应用程序 JAR 文件  
COPY app.jar app.jar

# 复制 tzupdar.jar 到docker中
COPY tzupdater.jar tzupdater.jar  
  
# 更新时区数据
COPY tzdata2024a.tar.gz tzdata2024a.tar.gz  
RUN java -jar tzupdater.jar -l file///tzdata2024a.tar.gz 

# 或者这种
#RUN java -jar tzupdater.jar -l file///tzdata2024a.tar.gz](https://www.iana.org/time-zones/repository/tzdata-latest.tar.gz
  
EXPOSE 8080  
  
ENTRYPOINT ["java", "-jar", "app.jar"]

自制 JDK 并更新 TZ

为了避免在每次构建应用程序镜像时都重复执行时区更新操作, 从而产生不必要的开销, 我们可以采用一种更加优化的方式。首先, 基于官方的 JDK 基础镜像, 创建一个包含最新时区数据的自定义基础镜像。然后, 应用程序的 Dockerfile 直接使用这个自定义基础镜像作为基础镜像, 这样就无需在应用程序镜像构建过程中再执行时区更新操作了, 从而提高了效率。

基于 adoptopenjdk:8-jdk-hotspot 镜像, 我编写了一个自定义的 Dockerfile, 用于构建包含最新时区数据的基础镜像。Dockerfile 的内容如下:

FROM adoptopenjdk:8-jdk-hotspot

COPY tzupdater.jar tzupdater.jar
COPY tzdata2024a.tar.gz tzdata2024a.tar.gz
RUN java -jar tzupdater.jar -l file:///tzdata2024a.tar.gz

接下来, 我可以基于这个自定义的 Dockerfile 构建包含最新时区数据的基础镜像。构建完成后, 可以为该镜像打上适当的标签, 并将其推送到团队共享的镜像仓库中, 供其他成员使用。

总结

为了解决由于时区规则变更导致的定时任务执行异常问题, 我们需要更新 JDK 中内置的时区数据库 (Time Zone Database)。Oracle 提供了 TZUpdater 工具, 允许我们独立更新 JDK 中的时区数据, 无需升级整个 JDK 版本。

在 Docker 环境中, 我们可以在 Dockerfile 中利用 TZUpdater 工具更新时区数据,为了进一步优化, 我们可以基于官方 JDK 镜像创建一个自定义的基础镜像, 在其中预先更新好最新的时区数据。这样, 应用程序的 Dockerfile 只需要使用这个自定义基础镜像, 就无需再执行时区更新操作, 从而提高了构建效率。该自定义基础镜像可以在团队内部共享使用。

通过以上方式, 我们可以确保 Docker 容器中运行的 Java 应用程序始终使用最新的时区规则, 避免由于时区变更导致的问题, 同时也遵循了 Docker 镜像分层和复用的最佳实践, 提高了开发效率。

标签:tar,JDK,jar,gz,升级,规则,镜像,Docker,时区
From: https://www.cnblogs.com/lvancoder/p/18384307

相关文章

  • Apache RocketMQ 中文社区全新升级丨阿里云云原生 7 月产品月报
    云原生月度动态云原生是企业数字创新的最短路径。《阿里云云原生每月动态》,从趋势热点、产品新功能、服务客户、开源与开发者动态等方面,为企业提供数字化的路径与指南。趋势热点......
  • 未来浏览器的守护者:CSS @supports 规则全解析
    标题:未来浏览器的守护者:CSS@supports规则全解析摘要随着CSS语言的不断发展,新特性层出不穷,但并非所有浏览器都同步支持这些特性。@supports规则是CSS中用于检测浏览器是否支持特定CSS特性的一种条件性规则。本文将详细介绍@supports规则的使用方法,并通过代码示例展示如何......
  • 7-9 期末编程作业计分规则
    期末编程作业计分规则。PTA上的题目集的排名页以总分(满分不一定是100分)的形式按排名顺序显示每个同学的成绩,但相同分数的同学无论排名是靠前还是最后得分都是一样的。为了表示排名区分度,根据排名给出了一个简单的计分规则,以示有所区分。计分规则如下:成绩折合成100分(取整),然后......
  • Docker下使用llama.cpp部署带Function calling和Json Mode功能的Mistral 7B模型
    Docker下使用llama.cpp部署带Functioncalling和JsonMode功能的Mistral7B模型说明:首次发表日期:2024-08-27参考:https://www.markhneedham.com/blog/2024/06/23/mistral-7b-function-calling-llama-cpp/https://github.com/abetlen/llama-cpp-python?tab=readme-ov-file#fu......
  • docker 安装后第一次启动时报错
    启动服务:systemctlstartdocker发生错误未能启动查看日志:systemctlstatusdockerjournalctl-xe发现错误:DependencyfailedforDockerApplicationContainerEngine.应该是有依赖服务未启动成功查看依赖服务:systemctllist-dependenciesdocker.service发现是docker.s......
  • docker和containerd的区别
    目录容器运行时Docker:原先的翘楚Containerd:K8s生态系统的标配容器运行时接口(CRI)Kubernetes与dockershim当前支持的CRI后端Dockershim调用关系对比常用命令容器运行时容器运行时(ContainerRuntime)是一种负责在操作系统层面创建和管理容器的软件工具或组件。它是容器化技术的......
  • firewalld:富规则的优先级顺序
    一,firewalld的rich规则执行逻辑如下: 1,日志规则2,drop/reject规则3,accept规则二,例子:验证是否先匹配reject规则1,添加两条规则:第一条允许指定ip访问22端口第二条禁止同一个ip访问[root@blog~]#firewall-cmd--add-rich-rule='rulefamily="ipv4"sourceaddress="13.17.12.21......
  • Docker在CentOS上的安装
    一、yum方式安装更新软件包索引:sudoyumcheck-update安装所需的软件包,以支持通过HTTPS使用Docker仓库:sudoyuminstall-yyum-utilsdevice-mapper-persistent-datalvm2添加Docker的官方YUM仓库:sudoyum-config-manager--add-repohttps://download./linux/cent......
  • Docker常用命令大全2-表格总结的 Docker 命令:
    Docker容器命令命令 描述dockerps 列出所有运行中的容器dockerps-a 列出所有容器(不考虑状态)dockerps-s 列出所有运行中的容器及文件大小dockerps-q 列出运行中容器的IDdockerps-aq 列出所有容器的ID(不考虑状态)dockerps--filter'key=value' 过滤容器列表doc......
  • Docker常用命令大全
    一、docker运行管理类启动dockersystemctlstartdocker关闭dockersystemctlstopdocker重新启动dockersystemctlrestartdockerdocker设置自启动systemctlenabledocker查看docker运行状态systemctlstatusdocker查看docker版本号等信息dock......