Minio(官方docker版)容器部署时区问题研究记录

文章目录

  • 感慨&概述
    • 补充:MINIO_REGION和容器时间的关系
  • 问题一:minio容器和本地容器时间不一致
    • 问题说明
    • 原因探究
    • 解决方法
    • 结果验证
  • 问题二:minio修改时间和本地查询结果不一致
    • 具体问题
    • 原因探究
    • 解决办法
    • 时间转化工具类
    • 调用测试和验证
    • 上传文件说明

感慨&概述

  • 在使用minio(容器部署方式)的过程中,由于使用容器时间和本地时间不同,然后寻求解决方法,花费了很多时间,然后才有以下的收获和整理。整个过程耗费不少时间。
  • 本文章对于bitnami/minio:latestminio/minio问题二:minio修改时间和本地查询结果不一致上均适用。在问题一:minio容器和本地容器时间不一致bitnami/minio:latest在部署时,使用TZ=Asia/Shanghai即可解决问题。

补充:MINIO_REGION和容器时间的关系

  • region描述的是服务器的物理位置,默认是us-east-1(美国东区1),也是亚马逊S3的默认区域。可以通过MINIO_REGION环境变量进行修改
  • 修改MINIO_REGION并不能解决,容器时间和本地时间问题,也不能解决文件最后修改时间在web控制台和java查询时间不一致的问题。这个可能是为了minio容器部署时,划分机器用的(如果错误,请大佬指导)
  • 当然,注意如果设置了MINIO_REGION请在java代码中配置同样的时区设置,否则导致代码运行失败,因为时区相差太大无法正常连接到minio
  • 当启动MinIO Docker容器时,可以通过设置环境变量MINIO_REGION来指定区域(如无需要,建议不要配置)
docker run -p 9000:9000 --name minio1 \-e "MINIO_ROOT_USER=minioadmin" \-e "MINIO_ROOT_PASSWORD=minioadmin" \-e "MINIO_REGION=cn-north-1" \-e "TZ=Asia/Shanghai" \minio/minio server /data
  • java minioclient配置
@Configuration
public class Config {//链式编程 构建MinioClient对象@Beanpublic MinioClient minioClient(){return MinioClient.builder().region("cn-north-1") //注意一致.endpoint("http://192.168.1.18:9000").credentials("minioadmin","minioadmin").build();}
}

问题一:minio容器和本地容器时间不一致

问题说明

  • 使用的Minio容器版本为1Panel中应用商店提供的minio官方镜像版本minio/minio:RELEASE.2024-04-06T05-26-02Z
  • minio容器内查看时间,刚好和本机相差八小时
    bash-5.1# date 
    Sat May  4 15:58:36 CST 2024
    bash-5.1# exit
    exit
    [root@yang ~]# date
    2024年 05月 04日 星期六 23:58:43 CST
    

原因探究

  • 这里不再详述探究的过程,简略地给出研究思路、方法。
  • 研究思路:查看容器中使用的时区,将其修改为东八区。
  • 研究过程和结果:在该版本容器内查看没有常见的linux时区设置的目录和文件,不过通过复制本地的文件到,minio容器中重新设置时区,可以成功解决容器时区和本地时区不一致的问题。

解决方法

  1. 查看容器信息
    # 查看运行中minio容器的名称
    docker ps
    
    • 例如:运行中的MInio容器ID为 826ab07a0a42,名称为 minio
    [root@yang ~]# docker ps
    CONTAINER ID   IMAGE                                      COMMAND                   CREATED          STATUS          PORTS                                                                                  NAMES
    826ab07a0a42   minio/minio:RELEASE.2024-04-06T05-26-02Z   "/usr/bin/docker-ent…"   14 minutes ago   Up 14 minutes   0.0.0.0:9001->9000/tcp, :::9001->9000/tcp, 0.0.0.0:9000->9001/tcp, :::9000->9001/tcp   minio
    
  2. 进入容器创建时区文件目录
    # 进入容器 下面的两个命令任选其一即可
    # 命令一
    docker exec -it  docker_Minio_name bash # 上一步查询的信息 minio
    # 命令二
    docker exec -it  docker_Minio_ID bash # 上一步查询的信息 826ab07a0a42
    # 在容器内执行命令:创建时区文件目录
    mkdir -p  /usr/share/zoneinfo/Asia/
    # 推出容器命令
    exit
    
  3. 复制本地时区文件到容器
    # 复制本地的时区配置文件到容器中
    [root@localhost ~]# docker cp /usr/share/zoneinfo/Asia/Shanghai docker_Minio_name:/usr/share/zoneinfo/Asia/
    # 操作成功演示
    [root@yang ~]# docker cp /usr/share/zoneinfo/Asia/Shanghai minio:/usr/share/zoneinfo/Asia/
    Successfully copied 2.56kB to minio:/usr/share/zoneinfo/Asia/
    
  4. 再次进入容器内部,修改本地时间
    # 再次进入容器 下面的两个命令任选其一即可
    # 命令一
    docker exec -it  docker_Minio_name bash # 上一步查询的信息 minio
    # 命令二
    docker exec -it  docker_Minio_ID bash # 上一步查询的信息 826ab07a0a42# 定义本地的时区配置文件
    ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime  
    # 演示
    bash-5.1# ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    

结果验证

  1. 使用命令查看容器和本机时间是否一致
    # 验证解决结果
    bash-5.1# date 
    Sat May  4 23:58:36 CST 2024
    bash-5.1# exit
    exit
    [root@yang ~]# date
    2024年 05月 04日 星期六 23:58:43 CST
    

  • Minio上传文件测试时间是否生效
  • 在观察页面显示正常,但是遗憾的是,如果使用java minio客户端查询还是显示相差八小时。(这是第二个问题)
    在这里插入图片描述

问题二:minio修改时间和本地查询结果不一致

具体问题

  • minio在web管理显示的文件最后修改时间和本地一致,然后使用java代码查询出来的时间和本地时间差八个小时
    在这里插入图片描述
  • 查询代码和结果
//查询代码
@Test
void testObjectExists() throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {StatObjectResponse response = minioClient.statObject(StatObjectArgs.builder().bucket("test02").object("image.jpg").build());System.out.println(response);
}		
//查询结果
ObjectStat{bucket=test02, object=image.jpg, last-modified=2024-05-04T06:53:55Z, size=563102}

原因探究

  • MinIO存储文件的元数据时,通常会使用UTC(协调世界时间)来记录时间戳。这意味着无论实际的物理服务器位置如何,时间都会按照UTC来记录。但在Web管理界面中,MinIO会根据浏览器的时区设置自动调整显示时间,使其看起来与本地时间一致。
  • 当使用Java代码通过MinIO的API查询文件的最后修改时间时,如果没有正确处理时区,Java可能会默认将UTC时间作为本地时间(即不进行时区转换)来处理。导致看到的时间比实际的本地时间少8小时(中国大陆时间为UTC+8)。

解决办法

  • Java代码在处理时间时将UTC时间转换为本地时间(虽然麻烦,但只能这么解决问题)

时间转化工具类

  • 这里我给出一个已验证可用的工具类
import java.lang.annotation.Retention;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;public class TimeConverter {// 使用自定义格式化模式private static final DateTimeFormatter isoFormatter = new DateTimeFormatterBuilder().append(DateTimeFormatter.ISO_LOCAL_DATE).appendLiteral('T').append(DateTimeFormatter.ISO_LOCAL_TIME).optionalStart().appendOffsetId().optionalEnd().toFormatter();private static final DateTimeFormatter customFormatter = new DateTimeFormatterBuilder().append(DateTimeFormatter.ISO_LOCAL_DATE).appendLiteral('T').append(DateTimeFormatter.ISO_LOCAL_TIME).appendLiteral('Z') // 添加字面值 'Z' 表示时区偏移量.toFormatter();/*** 将UTC时间转换为指定时区的时间,格式保持ISO-8601 默认时区为东八区* @param utcTimeString UTC时间字符串(ISO-8601格式)* @return 指定时区的时间字符串(ISO-8601格式)*/public static String convertUtcToLocal(String utcTimeString) {String zoneIdString="Asia/Shanghai";return convertUtcToLocal(utcTimeString,zoneIdString);}/*** 将UTC时间转换为指定时区的时间,格式保持ISO-8601* @param utcTimeString UTC时间字符串(ISO-8601格式)* @param zoneIdString 时区ID,如"Asia/Shanghai"* @return 指定时区的时间字符串(ISO-8601格式)*/public static String convertUtcToLocal(String utcTimeString, String zoneIdString) {Instant utcTime = Instant.parse(utcTimeString);ZonedDateTime localTime = utcTime.atZone(ZoneId.of(zoneIdString));DateTimeFormatter formatter = customFormatter.withZone(ZoneId.of(zoneIdString));return formatter.format(localTime);}/*** 将本地时间转换为UTC时间* @param localTimeString 本地时间字符串(ISO-8601格式)* @param zoneIdString 时区ID,如"Asia/Shanghai"* @return UTC时间字符串(ISO-8601格式)*/public static String convertLocalToUtc(String localTimeString) {String zoneIdString="Asia/Shanghai";return convertLocalToUtc(localTimeString,zoneIdString);}/*** 将本地时间转换为UTC时间* @param localTimeString 本地时间字符串(ISO-8601格式)* @param zoneIdString 时区ID,如"Asia/Shanghai"* @return UTC时间字符串(ISO-8601格式)*/public static String convertLocalToUtc(String localTimeString, String zoneIdString) {ZonedDateTime localTime = ZonedDateTime.parse(localTimeString, customFormatter.withZone(ZoneId.of(zoneIdString)));Instant utcTime = localTime.toInstant();return isoFormatter.format(utcTime.atZone(ZoneId.of("UTC")));}// 测试主方法public static void main(String[] args) {String utcTime = "2024-05-07T04:20:00Z";System.out.println("原UTC时间: " + utcTime);System.out.println("转换为北京时间: " + convertUtcToLocal(utcTime));String shanghaiTime = "2024-05-20T20:20:00Z";System.out.println("从北京时间转换回UTC时间: " + convertLocalToUtc(shanghaiTime));}
}
  • 测试结果
    UTC时间: 2024-05-07T04:20:00Z
    转换为北京时间: 2024-05-07T12:20:00Z
    从北京时间转换回UTC时间: 2024-05-20T12:20:00Z
    

调用测试和验证

  • 测试类代码
    @SpringBootTest
    class MinioApplicationTests {@Resourceprivate MinioClient minioClient;/*** 判断文件是否存在*/@Testvoid testObjectExists() throws Exception {StatObjectResponse response = minioClient.statObject(StatObjectArgs.builder().bucket("test02").object("image.jpg").build());System.out.println("修改前文件信息:"+response);String localLastModifiedTime = TimeConverter.convertUtcToLocal(response.lastModified().toString());ZonedDateTime localLastModified = ZonedDateTime.parse(localLastModifiedTime);//通过反射 修改文件信息 不影响minio存储的文件信息try {Field lastModifiedField = response.getClass().getDeclaredField("lastModified");lastModifiedField.setAccessible(true);lastModifiedField.set(response, localLastModified);} catch (NoSuchFieldException | IllegalAccessException e) {e.printStackTrace();}System.out.println("修改后文件信息:"+response);}
    }
    
  • 测试结果
    修改前文件信息:ObjectStat{bucket=test02, object=image.jpg, last-modified=2024-05-04T06:53:55Z, size=563102}
    修改后文件信息:ObjectStat{bucket=test02, object=image.jpg, last-modified=2024-05-04T14:53:55Z, size=563102}
    

在这里插入图片描述

上传文件说明

  • 在查询文件信息时,需要将文件修改时间进行本地化转化,但是在上传文件的时候,我没找到直接设置文件修改时间的配置。所以,上传文件的时候,正常上传就行。
/*** 上传文件*/
@Test
void testObjectUpload() throws Exception {ObjectWriteResponse response = minioClient.uploadObject(UploadObjectArgs.builder().bucket("test02").object("image3.jpg").filename("src/main/resources/picture/image.jpg").build());System.out.println(response);
}
  • 上传成功后,在web控制台正常显示本地时间。查询时,使用工具类就可以了!
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/7945.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高级数据结构与算法习题(9)

一、判断题 1、Let S be the set of activities in Activity Selection Problem. Then the earliest finish activity am​ must be included in all the maximum-size subset of mutually compatible activities of S. T F 解析:F。设S是活动选择问题中的一…

flutter开发实战-webview_flutter 4.x版本使用

flutter开发实战-webview_flutter 4.x版本使用 在之前使用的webview_flutter版本是3.x的,升级到4.x后,使用方式有所变化。 一、webview_flutter 在工程的pubspec.yaml中引入插件 webview_flutter: ^4.4.2二、使用webview_flutter 在4.x版本中&#…

JAVA语言开发的(智慧校园系统源码)智慧校园的痛点、智慧校园的安全应用、智慧校园解决方案

一、智慧校园的痛点 1、信息孤岛问题:由于校园内各部门或系统独立开发,缺乏统一规划和标准,导致数据无法有效整合和共享,形成了信息孤岛。 2、技术更新与运维挑战:智慧校园的建设依赖于前沿的信息技术,如云…

15【PS作图】像素画地图绘制

绘制视角 绘制地图的时候,有的人会习惯把要绘制的 房子、车子、围栏 小物件先画好,然后安放在地图上 但这样绘制出的各种物件之间,会缺乏凝聚力 既然物品都是人构造出的,不如以人的视角去一步步丰富地图; 比如下图…

关于c++ 中 string s { ‘a‘ , ‘b‘ , ‘c‘ , ‘d‘ } 的方式的构造过程

(1)这样的构造方式不常见,但也确实 STL 库提供了这样的构造函数 (2)以反汇编分析这行代码 (3)谢谢阅读

【数据结构与算法】力扣 239. 滑动窗口最大值

题干描述 给你一个整数数组 nums,有一个大小为 k **的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例 1: 输入: nums [1,3,-1,-3,5,3…

嵌入式开发常见概念简介

目录 0. 《STM32单片机自学教程》专栏总纲 API Handle(句柄) 0. 《STM32单片机自学教程》专栏总纲 本文作为专栏《STM32单片机自学教程》专栏其中的一部分,返回专栏总纲,阅读所有文章,点击Link: STM32单片机自学教程-[目录总纲]_stm32 学习-CSD…

每日OJ题_贪心算法三⑤_力扣134. 加油站

目录 力扣134. 加油站 解析代码 力扣134. 加油站 134. 加油站 难度 中等 在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一…

SpringBoot3项目打包和运行

六、SpringBoot3项目打包和运行 6.1 添加打包插件 在Spring Boot项目中添加spring-boot-maven-plugin插件是为了支持将项目打包成可执行的可运行jar包。如果不添加spring-boot-maven-plugin插件配置,使用常规的java -jar命令来运行打包后的Spring Boot项目是无法找…

Java学习第01天-Java基本内容

目录 单行注释 多行注释 文档注释(GPT生成) 字面量 分类 使用示例 变量 定义 定义格式 注意事项 数据类型分类 命名指导规范 补充 单行注释 public class note {public static void main(String[] args) {// 单行注释} }多行注释 publ…

FileBird Pro插件下载:革新您的WordPress媒体库管理

WordPress媒体库是您网站的重要组成部分,它存储了所有的图片、视频、文档等文件。但随着网站的扩展,媒体库的管理变得越来越复杂。FileBird Pro插件,作为一款专为WordPress用户设计的媒体库管理工具,以其直观的界面和强大的功能&a…

Elastic 通过 AI 驱动的安全分析改变 SIEM 游戏

作者:Santosh Krishnan, Jennifer Ellard 借助由搜索 AI 提供支持的新攻击发现功能,优先考虑攻击,而不是警报。 传统的安全信息与事件管理系统(SIEM)在很大程度上依赖屏幕背后的人类才能取得成功。警报、仪表盘、威胁…

Python面向对象编程思想的深入学习

魔术方法的使用 案例体验 class Student:def __init__(self, name, age):self.name nameself.age age# __str__魔术方法, 如果不去写这个方法,那么print输出的则是信息存储的内存地址。def __str__(self):return fStudent类对象,name:{self.name}, ag…

PVZ2 植物克僵尸【第二期】

众所周知,PVZ2(植物大战僵尸2)中有许多恶心的僵尸,而我们不得不派出它们的————克星!(*为建议方法) 5.战机小鬼 战机小鬼,恶心会发射子弹,所以: 1&…

Ubuntu18.04设置SSH密钥登录

我们一般使用 VSCode 、MobaXterm、PuTTY等 SSH 客户端来远程管理 Linux 服务器。但是,一般的密码方式登录,容易有密码被暴力破解的问题。所以,一般我们会将 SSH 的端口设置为默认的 22 以外的端口,或者禁用 root 账户登录。但是即…

Autosar NvM配置-手动配置Nvblock及使用-基于ETAS软件

文章目录 前言NvDataInterfaceNvBlockNvM配置SWC配置RTE Mapping使用生成的接口操作NVM总结前言 NVM作为存储协议栈中最顶层的模块,是必须要掌握的。目前项目基本使用MCU带的Dflash模块,使用Fee模拟eeprom。在项目前期阶段,应该充分讨论需要存储的内容,包括应用数据,诊断…

JSP企业快信系统的设计与实现参考论文(论文 + 源码)

【免费】JSP企业快信系统.zip资源-CSDN文库https://download.csdn.net/download/JW_559/89277688 JSP企业快信系统的设计与实现 摘 要 计算机网络的出现到现在已经经历了翻天覆地的重大改变。因特网也从最早的供科学家交流心得的简单的文本浏览器发展成为了商务和信息的中心…

【C++ 关键字】const 关键字详解

文章目录 1. const 概念2.常量指针 和 指针常量 的区别2.1 常量指针(底层 const)2.2 指针常量 (顶层 const) 3.const 关键字的作用4.const 和 define 的区别5.const 总结 1. const 概念 const 是一个关键字,被修饰的值不能改变,是…

通过 Java 操作 redis -- 连接 redis

如果我们想在本地主机上访问 Linux 服务器上的 redis ,我们就需要通过 ssh 进行端口转发,推荐看 本地主机访问服务器的Redis -- 配置 ssh 端口转发 通过 Java 操作 redis 已经有大佬创建了很多第三方库,这里我们使用 jedis ,因为它…

Git系列:git push (-u) 与 git branch (-u)

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…