3

1、问题产生

昨晚后台的图片服务挂了,折腾之后发现是服务器的时间不对,于是看了一下Linux下面关于时区与时间相关的命令

[root@root:~] $ date -R
Tue, 31 Mar 2015 13:58:25 +0400
[root@root:~] $ 

北京时间为 +8000 时区,所以上述的时区设置不对
于是使用 tzselect 命令设置时区

首先选择洲

[root@root:~] $ tzselect
Please identify a location so that time zone rules can be set correctly.
Please select a continent or ocean.
 1) Africa
 2) Americas
 3) Antarctica
 4) Arctic Ocean
 5) Asia
 6) Atlantic Ocean
 7) Australia
 8) Europe
 9) Indian Ocean
10) Pacific Ocean
11) none - I want to specify the time zone using the Posix TZ format.
#? 5

选择国家

Please select a country.
 1) Afghanistan           18) Israel                35) Palestine
 2) Armenia               19) Japan                 36) Philippines
 3) Azerbaijan            20) Jordan                37) Qatar
 4) Bahrain               21) Kazakhstan            38) Russia
 5) Bangladesh            22) Korea (North)         39) Saudi Arabia
 6) Bhutan                23) Korea (South)         40) Singapore
 7) Brunei                24) Kuwait                41) Sri Lanka
 8) Cambodia              25) Kyrgyzstan            42) Syria
 9) China                 26) Laos                  43) Taiwan
10) Cyprus                27) Lebanon               44) Tajikistan
11) East Timor            28) Macau                 45) Thailand
12) Georgia               29) Malaysia              46) Turkmenistan
13) Hong Kong             30) Mongolia              47) United Arab Emirates
14) India                 31) Myanmar (Burma)       48) Uzbekistan
15) Indonesia             32) Nepal                 49) Vietnam
16) Iran                  33) Oman                  50) Yemen
17) Iraq                  34) Pakistan
#? 9

选择城市

Please select one of the following time zone regions.
1) east China - Beijing, Guangdong, Shanghai, etc.
2) Heilongjiang (except Mohe), Jilin
3) central China - Sichuan, Yunnan, Guangxi, Shaanxi, Guizhou, etc.
4) most of Tibet & Xinjiang
5) west Tibet & Xinjiang
#? 1

确定


The following information has been given: China east China - Beijing, Guangdong, Shanghai, etc. Therefore TZ='Asia/Shanghai' will be used. Local time is now: Tue Mar 31 14:04:49 CST 2015. Universal Time is now: Tue Mar 31 06:04:49 UTC 2015. Is the above information OK? 1) Yes 2) No #? 1

系统给出提示

You can make this change permanent for yourself by appending the line
        TZ='Asia/Shanghai'; export TZ
to the file '.profile' in your home directory; then log out and log in again.

Here is that TZ value again, this time on standard output so that you
can use the /usr/bin/tzselect command in shell scripts:
Asia/Shanghai

我们对当前用户改变时区,所以需要修改 /ect/profile 文件 ,并用source 命令使他生效

[root@root:~] $ vim /etc/profile
在 profile 文件中追加 TZ='Asia/Shanghai'; export TZ
[root@root:~] $ source /etc/profile

做了上述操作之后服务器的时间正确了,图片服务也没有出现因为时间不对签名校验失败的情况,图片正常上传

[root@root~]# date -R
Thu, 02 Apr 2015 11:36:44 +0800

2、第二天问题重现

第二天到公司发现在开发中的APP 接口参数签名错误,结果发现又是时间不对,上服务器一看,时间不正确了,明明昨天已经调回到东八区正确的时间了?

团队其他人处理这个问题,没搞定,于是自己接着解决,上服务器一看:

[root@root~]# date -R
date: multiple output formats specified

date -R 以及 date 下面所有带参数命令失效,无语了

[root@root~]# clock
Thu 02 Apr 2015 11:47:33 AM UTC -0.395946 seconds

UTC 如果使用UTC,那么也应该倒退8个小时才行(因为北京时间 UTC +8),决定直接调整为 CTS(China Standard Time) 时间

网上搜索需要修改 /ect/localtime 文件

[root@root/]# cd /etc/
[root@root/]# ll
lrwxrwxrwx   1 root root     34 Mar 31 15:09 localtime -> /usr/share/zoneinfo/Asia/Shanghai

发现该文件软连接到了 /usr/share/zoneinfo/Asia/Shanghai 现在这个指向实际上是昨天通过 tzselect 命令选择的
但是时间还是不对,我们查看 /usr/share/zoneinfo/Asia/Shanghai 文件

[root@root Asia]# cd /usr/share/zoneinfo/Asia/
[root@root Asia]# vim Shanghai
TZif2^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^@^@^C^@^@^@^@^@^@^@^Q^@^@^@^C^@^@^@^L°þ<9a><9b>È\^A<80>Èú'pÉÕ^N<80>ÊÛZð^^º6^@^_i^?p ~h<80>!Iap"^J<80>#)Cp$Gg^@%^R_ð&'I^@&òAð(^G+^@(Ò#ð^B^A^B^A^B^A^B^A^B^A^B^A^B^A^B^A^B^@^@qå^@^@^@^@~<90>^A^D^@^@p<80>^@^HLMT^@CDT^@CST^@^@^@^@^@^@^@TZif2^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^@^@^C^@^@^@^@^@^@^@^Q^@^@^@^C^@^@^@^Lÿÿÿÿ°þ<9a><9b>ÿÿÿÿÈ\^A<80>ÿÿÿÿÈú'pÿÿÿÿÉÕ^N<80>ÿÿÿÿÊÛZð^@^@^@^@^^º6^@^@^@^@^@^_i^?p^@^@^@^@ ~h<80>^@^@^@^@!Iap^@^@^@^@"^J<80>^@^@^@^@#)Cp^@^@^@^@$Gg^@^@^@^@^@%^R_ð^@^@^@^@&'I^@^@^@^@^@&òAð^@^@^@^@(^G+^@^@^@^@^@(Ò#ð^B^A^B^A^B^A^B^A^B^A^B^A^B^A^B^A^B^@^@qå^@^@^@^@~<90>^A^D^@^@p<80>^@^HLMT^@CDT^@CST^@^@^@^@^@^@^@
UTC-8

仔细比对另一台时间正确的服务器发现上述文件中末尾的 UTC-8 时间上应该是CTS-8
最后询问后得知是同事修改了该文件,果断把该文件末尾修改为 CTS-8

最关建的一步来了

我们一般使用“date -s”命令来修改系统时间。
比如将系统时间设定成2011年07月15日的命令如下。#date -s 07/15/2011
将系统时间设定成下午3点12分0秒的命令如下。#date -s 15:12:00
注意,这里说的是系统时间,是linux由操作系统维护的。

 在系统启动时,Linux操作系统将时间从CMOS中读到系统时间变量中,以后修改时间通过修改系统时间实现。为了保持系统时间与CMOS时间的一致性,Linux每隔一段时间(大约是11分钟)会将系统时间写入CMOS。由于该同步是每隔一段时间进行的,在我们执行date-s后,如果马上重起机器,修改时间就有可能没有被写入CMOS,这就是问题的原因。如果要确保修改生效可以执行如下命令。  
 ---- #clock -w  
 ---- 这个命令强制把系统时间写入CMOS。
[root@root ]# clock -w
[root@root ]# clock
Thu 02 Apr 2015 11:47:33 AM CTS-0.395946 seconds

至此,时间终于正确了,下一次Linux cmos写入也不会将时间改错了,实际上前一天做的工作就差这最后一步。

3、date -R 以及其他带参数命令错误的解决

搞了半天不知道什么原因造成的,上来提问
大神建议:

看看是不是环境变量被污染了,用“which date”看看你启动的这个date命令是不是built-in的date命令,再用"whereis
date"看看哪些目录都有"date"这个命令,默认是/bin/date的

于是上服务器一看:

[root@rootetc]# which date
alias date +"%Y%M%D"
/usr/bin/date

一问同事他给系统默认 date 起了别名

[root@root etc]# date -R
实际上
[root@root etc]# date +"%Y%M%D" -R

所以错了:
查看alias 的所有条目

[root@rootetc]# alias
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
alias date +"%Y%M%D"

使用 unalias 命令将 date 的别名取消

[root@root etc]# unalias date
[root@root etc]# date -R
Thu, 02 Apr 2015 13:02:00 +0800

现在 date 命令已经可以正常使用


Jacendfeng
544 声望23 粉丝

爱豆瓣,爱知乎,爱电影,KTV垃圾麦主,专注Java 服务器端开发,技术文章整理者。