# 背景
在接入集團一個平台的時候,發現錄制某個接口到測試環境回放,發現接口入參一致,一個start_day 一個end_day,但回放的時候會多調用一次數據庫查詢,很是奇怪;
查閱業務代碼,發現確實有邏輯會導致多查詢一次,於是重點觀察數據變化,發現錄制回放兩個時間不一致,相差12個小時;
繼續查閱業務日志,發現在第一次查詢DB的時候,兩次的時間不一樣,就是說接口入參(String類型)一致,通過應用轉化為int類型的時候就出問題了的,相差12個小時;
因此猜測是時區問題!!!
# 思路&解決
1. 既然發現是時區問題,比較好搞咯,去到錄制機器A和回放機器B,通過linux命令查看時區
date -R
發現都是Fri, 06 Jul 2018 12:11:22 +0800
都是+8,東八區
date +"%Z %z"
結果發現還是一致呀,都是CST +0800
2. 不對,時區一樣呀,那么問題就是java執行不一樣? 核對了jdk版本,發現一致
3. 那么就在兩台機器上執行java代碼試下:
System.out.println(TimeZone.getDefault()); //輸出當前默認時區
發現了問題了,兩台機器打印的不一致,A是上海,而B是紐約。。。
4. 那么問題變成了jvm從哪里去獲取時區的呢?經過查詢大致如下:
1)如有環境變量 TZ設置,則用TZ中設置的時區
2) 在 /etc/sysconfig/clock文件中找 "ZONE"的值
3)如2)都沒,就用/etc/localtime 和 /usr/share/zoneinfo 下的時區文件進行匹配,如找到匹配的,就返回對應的路徑和文件名。
簡單來說就是:
TZ環境變量 --> /etc/sysconfig/clock文件 --> /etc/localtime文件 依次尋找
5. 於是開始設置了,TZ不管了,加了/etc/sysconfig/clock,如下操作:
新建一個/etc/sysconfig/clock,內容如下:
ZONE="Asia/Shanghai" UTC=false ARC=false
然后繼續去查看時區,還是不對呀!!
6. 繼續設置/etc/localtime文件,如下操作:
unlink /etc/localtime
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
就是初始化/etc/localtime ,然后將東八區的綁定上
7. 在查看時區成功了,重新執行java代碼,發現正常了
8. 繼續翻閱資料,發現:
時區的配置文件是/etc/sysconfig/clock。用tzselect命令就可以修改這個配置文件,根據命令的提示進行修改就好了。
但是在實際工作中,發現這種方式是不能夠使得服務器上的時間設置馬上生效的,而且使用ntpdate去同步時間服務器也不能夠更改時間。即使你使用了 date命令手工設置了時間的話,如果使用ntpdate去進行時間同步的話,時間又會被改動到原來的錯誤時區的時間。而生產的機器往往是非常重要的,不能夠進行重啟等操作。
1)/etc/sysconfig/clock 文件,只對 hwclock
命令有效,且只在系統啟動和關閉的時候才有用(修改了其中的 UTC=true 到 UTC=false 的前后,執行 hwclock (--utc,
或 --localtime) 都沒有變化,要重啟系統后才生效);
在 /etc/sysconfig/clock 中 UTC=false 時,date、hwclock、hwclcok --localtime 輸出的時間應該都一致,且此時 hwclock --utc是沒有意義的;
在 /etc/sysconfig/clock 中 UTC=ture 時,date、hwclock 的輸出是一致的,hwclock --localtime 的輸出則是UTC時間;
系統關閉時會同步系統時間到硬件時鍾,系統啟動時會從硬件時鍾讀取時間更新到系統,這2個步驟都要根據 /etc/sysconfig/clock 文件中UTC的參數來設置時區轉換。
意思就是修改/etc/sysconfi/clock是可行的,但是不會立即生效,需要重啟。那么一切就說的通了
# 后記
參考資料:
https://www.nowcoder.com/questionTerminal/1e794493ad564324a16da1c47545c117
http://blog.51cto.com/5iwww/661863
https://my.oschina.net/huawu/blog/4646
http://linux.it.net.cn/CentOS/fast/2016/0511/21660.html
https://blog.csdn.net/splenday/article/details/47065557
https://unix.stackexchange.com/questions/110522/timezone-setting-in-linux