Docker 伺服器下java查詢時區問題
最近遇到時區問題,著實讓人糾結,利用docker部署spring boot 服務(伺服器宿主機不是內地的,docker容器為centos7),當部署應用的時候出現了時間少8個鐘或者多8個鐘的問題...嘗試了
jdbc連線的時區修改,最終以失敗告終...
這是遇到問題的過程...:
用postman進行測試資料插入,查詢資料的時候時間會與現在的時間少8個或者多8個鐘.懷疑伺服器時間不對,進入容器執行date命令後,發現docker時間確實不對,然後找到了docker時間同步方法(當然也可以在建立容器的時候新增環境變數實現同步).設定docker時間與伺服器宿主機同步後,資料庫時間插入的時間和查詢時間終於都正確了.但是又發現了一個問題,假如直接用LocaldateTime.now()獲取本地時間返回頁面或者進行輸出,而不經過資料庫查詢,你可以發現獲取到的當前時間仍然少八個鍾(最後找到原因是jre獲取的時間時區不正確)最後大體解決步驟是這樣的:
step1:資料庫連線配置
db.url=jdbc:mysql://localhost:3306/goddess?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2b8&autoReconnect=true&failOverReadOnly=false
注意 serverTimezone必須設定時區GMT%2b8 (GMT+8)
step2: 設定docker時間與宿主機時間同步 進入docker容器,執行cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 命令,
然後再執行date命令檢視時間是否已經同步為北京時間
step3: 設定jdk讀取時間檔案 執行 echo "Asia/Shanghai" > /etc/timezone 命令 替換掉該檔案下的"Etc/UTC"改成Asia/Shanghai, jre是通過該配置檔案讀取本地時間的,如沒有該檔案,新增該檔案(一定要注意自己的作業系統),cat /etc/timezone 可見內容已被置為Asia/Shanghai,好了,為以防萬一,重新啟動docker容器即可,此時LocaldateTime.now()已經獲取正確.
當然總不能每次建立容器的時候都要去修改時區,此時,我們可以寫個shell腳本當容器建立的時候執行該指令碼即可,可把指令碼放在宿主機掛載進去,也可以在容器裡編寫指令碼建立自己的映象。
以java映象為例建立一個帶指令碼映象
1.建立指令碼init.sh,放在/home/sh資料夾下
內容如下:
#! /bin/bash
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo "Asia/Shanghai" > /etc/timezone
echo "set time success "
sleep 1d #休眠一天確保有一個執行緒在執行,否則容器會退出。
2.建立並執行容器
docker run --name java -v /home/sh:/root java /bin/bash ./root/init.sh (掛載指令碼到root目錄下並在執行容器時執行該指令碼)