第一部分:
一)概述:
事實上在Linux中有兩個時鍾系統,分別是系統時間和硬件時間
UTC是協調世界時(Universal Time Coordinated)英文縮寫,它比北京時間早8個小時.
二)date
date可以打印/設定系統時間.
打印系統時間時,date命令會通過調用clock_gettime函數獲取時間,同時會通過localtime文件(時區文件)計算出本地的時間.
設定系統時間時,date命令會通過讀取localtime文件(時區文件)確定本地的時區,再調用clock_settime函數計算出本地的時間.
三)hwclock
hwclock可以打印/設定硬件時鍾.
校正Linux系統時間並把系統時間寫入硬件
先校正Linux系統時間:
# ntpdate 0.cn.pool.ntp.org13 Nov 18:27:41 ntpdate[7167]: step time server 85.199.214.101 offset 340324836.877469 sec
# date
Mon Nov 13 18:27:47 CST 2017
查看硬件時鍾:
# hwclock --show
Wed 31 Jan 2007 08:19:51 PM CST -0.103558 seconds
然后把系統時間寫入到硬件:
# hwclock -w
# hwclock --show 或者hwclock -r
Mon 13 Nov 2017 07:04:03 PM CST -0.478211 seconds
通過strace我們可以跟蹤hwclock執行時打開的文件,如下:
strace -e trace=open hwclock -r
open("/etc/ld.so.cache", O_RDONLY) = 3
open("/lib/libaudit.so.1", O_RDONLY) = 3
open("/lib/libc.so.6", O_RDONLY) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 4
open("/dev/rtc", O_RDONLY|O_LARGEFILE) = 4
open("/etc/adjtime", O_RDONLY|O_LARGEFILE) = 5
open("/usr/share/zoneinfo/Universal", O_RDONLY) = 5
open("/etc/localtime", O_RDONLY) = 5
open("/usr/share/locale/locale.alias", O_RDONLY) = 5
open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/util-linux-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US.utf8/LC_MESSAGES/util-linux-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US/LC_MESSAGES/util-linux-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.UTF-8/LC_MESSAGES/util-linux-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.utf8/LC_MESSAGES/util-linux-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/util-linux-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
Mon 17 Oct 2011 02:29:49 AM CST -0.567399 seconds
注:
1)hwclock首先打開了/dev/rtc,讀取硬件時鍾.
2)打開/etc/adjtime文件,通過先前的記錄來估算硬件時鍾的偏差,並用來校正目前的時間.
3)打開/etc/localtime時區文件,將硬件時間轉換為當前時區對映的時間.
下面介紹hwclock常用的幾個參數:
-s(--hctosys)從硬件時鍾讀取時間更新到系統時鍾.
-w(--systohc)將系統時鍾時間寫入硬件時鍾.
--debug顯示hwclock執行時詳細的信息,例如:
hwclock -r --debug
hwclock from util-linux-ng 2.17.2
Using /dev interface to clock.
Last drift adjustment done at 1318866683 seconds after 1969
Last calibration done at 1318866683 seconds after 1969
Hardware clock is on UTC time
Assuming hardware clock is kept in UTC time.
Waiting for clock tick...
...got clock tick
Time read from Hardware Clock: 2011/10/17 15:51:32
Hw clock time : 2011/10/17 15:51:32 = 1318866692 seconds since 1969
Mon 17 Oct 2011 11:51:32 PM CST -0.117361 seconds
--set --date=<日期與時間>設定硬件時鍾,如下:
讀取硬件時間,現在是11:54(PM)
hwclock -r
Mon 17 Oct 2011 11:54:47 PM CST -0.003885 seconds
設定硬件時間為12:54(PM)
hwclock --set --date=12:54
再次讀取硬件時間,發現時間已經變為12:54(PM)
hwclock -r
Mon 17 Oct 2011 12:54:03 PM CST -0.027942 seconds
注:
最后要說明的是hwclock輸出的是帶有AM/PM表示方式的硬件時間.
我們可以通過hwclock --localtime將硬件時間轉換為utc時間.
如下:
hwclock --localtime
Mon 17 Oct 2011 05:00:49 PM CST -0.478863 seconds
hwclock
Tue 18 Oct 2011 01:00:52 AM CST -0.821415 seconds
四)AM與PM
AM是上午,PM是下午,例如:
01:30:56 AM表示24小時制的凌晨01:30:56
01:30:56 PM表示24小時制的下午13:30:56
我們可以用date命令在獲取系統時間時,是AM還是PM,如下:
date +%r
01:34:17 AM
五)時區與時間
只有設定了正確時區的前提下,才能正確的得出本地的時間.
例如:
如果我們在中國大陸,但選擇了美國的時區,通過ntpdate同步時,也得到的是美國當前時間.
時間文件是/etc/localtime,/usr/share/zoneinfo/目錄下存放了所有的時區文件.
我們使用的中國上海的時區文件,文件格式如下:
file /etc/localtime
/etc/localtime: timezone data, version 2, 3 gmt time flags, 3 std time flags, no leap seconds, 17 transition times, 3 abbreviation chars
有的人說也要設置/etc/sysconfig/clock文件,實際上這不是必須的,如下:
more /etc/sysconfig/clock
# The time zone of the system is defined by the contents of /etc/localtime.
# This file is only for evaluation by system-config-date, do not rely on its
# contents elsewhere.
ZONE="Asia/Shanghai"
六)RTC
Real time clock(RTC):實時時鍾是用來持久存放系統時間的設備,即便系統關閉后,它也可以靠主板上的微電池提供的電力保持系統定時.
查看rtc的詳細信息,如下:
cat /proc/driver/rtc
rtc_time : 17:16:08
rtc_date : 2011-10-16
alrm_time : 17:12:39
alrm_date : ****-**-**
alarm_IRQ : no
alrm_pending : no
24hr : yes
periodic_IRQ : no
update_IRQ : no
HPET_emulated : no
DST_enable : no
periodic_freq : 1024
batt_status : okay
注:這里的rtc_time時間是utc時間.
ls -l /sys/class/rtc/rtc0/
total 0
-r--r--r--. 1 root root 4096 Oct 18 00:00 date
-r--r--r--. 1 root root 4096 Oct 18 00:00 dev
lrwxrwxrwx. 1 root root 0 Oct 18 00:00 device -> ../../../00:04
-r--r--r--. 1 root root 4096 Oct 18 2011 hctosys
-rw-r--r--. 1 root root 4096 Oct 18 00:00 max_user_freq
-r--r--r--. 1 root root 4096 Oct 18 00:00 name
drwxr-xr-x. 2 root root 0 Oct 18 00:00 power
-r--r--r--. 1 root root 4096 Oct 18 00:00 since_epoch
lrwxrwxrwx. 1 root root 0 Oct 18 2011 subsystem -> ../../../../../class/rtc
-r--r--r--. 1 root root 4096 Oct 18 00:00 time
-rw-r--r--. 1 root root 4096 Oct 18 2011 uevent
-rw-r--r--. 1 root root 4096 Oct 18 00:00 wakealarm
從rtc中獲取的日期信息
cat /sys/class/rtc/rtc0/date
2011-10-17
從rtc中獲取的時間信息
cat /sys/class/rtc/rtc0/time
16:27:56
rtc設備的主設備號和從設備號
cat /sys/class/rtc/rtc0/dev
254:0
非特權用戶可以從這個rtc中請求的最大中斷率
cat /sys/class/rtc/rtc0/max_user_freq
64
從1970-01-01 00:00:00開始的時間累計(秒數)
cat /sys/class/rtc/rtc0/since_epoch
1318868801
注:可以用date +%s來獲取系統的時間.
七)總結:
我們可以通過date命令獲取系統的時間,系統時間是由可編程定時/計數器產生的輸出脈沖觸發中斷而產生的.每一個輸出脈沖也叫做一個時間滴答.
在操作系統中可以通過修改grub中的內核引導參數(tick_divider)來調整時鍾中斷頻率,例如:
我們將tick_divider=10,也就是100Hz,那么每秒就有100次時間滴答,每個時鍾滴答就是10毫秒(10ms).相應的系統時間就會每10ms增1.
內核通過通過變量jiffy來記錄系統啟動后產生的時間滴答的總數.
tick_divider可使用下列值:
2=500 Hz
4=250 Hz
5=200 Hz
8=125 Hz
10= 100 Hz
只限於X86和X86_64架構,不支持Xen.
第二部分:
一、首先要弄清幾個概念:
1. “ 系統時間”與“ 硬件時間”
系統時間: 一般說來就是我們執行 date 命令看到的時間,linux系統下所有的時間調用(除了直接訪問硬件時間的命令)都是使用的這個時間。
硬件時間: 主板上BIOS中的時間,由主板電池供電來維持運行,系統開機時要讀取這個時間,並根據它來設定系統時間(注意:系統啟動時根據硬件時間設定系統時間的過程可能存在時區換算,這要視具體的系統及相關設置而定)。
2. “ UTC時間”與“ 本地時間”
UTC時間:Coordinated Universal 8 e2 i( H7 t0 ^/ ^Time 世界協調時間(又稱世界標准時間、世界統一時間),在一般精度要求下,它與GMT(Greenwich Mean Time,格林威治標准時間)是一樣的,其實也就是說 GMT≈UTC,但 UTC 是以原子鍾校准的,更精確。
本地時間:由於處在不同的時區,本地時間一般與UTC是不同的,換算方法就是
1. “ 系統時間”與“ 硬件時間”
系統時間: 一般說來就是我們執行 date 命令看到的時間,linux系統下所有的時間調用(除了直接訪問硬件時間的命令)都是使用的這個時間。
硬件時間: 主板上BIOS中的時間,由主板電池供電來維持運行,系統開機時要讀取這個時間,並根據它來設定系統時間(注意:系統啟動時根據硬件時間設定系統時間的過程可能存在時區換算,這要視具體的系統及相關設置而定)。
2. “ UTC時間”與“ 本地時間”
UTC時間:Coordinated Universal 8 e2 i( H7 t0 ^/ ^Time 世界協調時間(又稱世界標准時間、世界統一時間),在一般精度要求下,它與GMT(Greenwich Mean Time,格林威治標准時間)是一樣的,其實也就是說 GMT≈UTC,但 UTC 是以原子鍾校准的,更精確。
本地時間:由於處在不同的時區,本地時間一般與UTC是不同的,換算方法就是
本地時間 = UTC + 時區 或 UTC = 本地時間 - 時區
時區東為正,西為負,例如在中國,本地時間都使用北京時間,在linux上顯示就是 CST(China Standard Time,中國標准時,注意美國的中部標准時Central Standard Time也縮寫為CST,與這里的CST不是一回事!),時區為東八區,也就是 +8 區,所以 CST=UTC+(+8小時) 或 UTC=CST-(+8小時)。
二、時間命令
1. 系統時間 date
直接調用 date,得到的是本地時間。如果想得到UTC時間的話,使用 date -u。
直接調用 /sbin/hwclock 顯示的時間就是 BIOS 中的時間嗎?未必!這要看 /etc/sysconfig/clock 中是否啟用了UTC,如果啟用了UTC(UTC=true),顯示的其實是經過時區換算的時間而不是BIOS中真正的時間,如果加上 --localtime 選項,則得到的總是 BIOS 中實際的時間.
這個文件用來設置系統的時區,將 /usr/share/zoneinfo/ 中相應文件拷貝到/etc下並重命名為 localtime 即可修改時區設置,而且這種修改對 date 命令是及時生效的。不論是 date 還是 hwclock 都會用到這個文件,會根據這個文件的時區設置來進行UTC和本地之間之間的換算。
4. /etc/sysconfig/clock
這個文件只對 hwclock 有效,而且似乎是只在系統啟動和關閉的時候才有用,比如修改了其中的 UTC=true 到 UTC=false 的前后,執行 hwclock (--utc, 或 --localtime) 都沒有變化,要重啟系統后才生效。注:如果設置 UTC=false 並重啟系統后,執行一些命令結果如下:
三、linux與windows雙系統間的時間同步
系統啟動和關閉時,硬件時間與系統時間之間的同步有兩種方式(假設在中國,用CST代表本地時間):
方式A: 使用UTC(對linux就是 /etc/sysconfig/clock 中 UTC=true)
開機: BIOS--------->UTC(將BIOS中的時間看成是UTC)------(時區變化)----->CST
關機: CST -------(時區變化)----->UTC-------存儲到------>BIOS
方式B: 不使用UTC(對linux就是 /etc/sysconfig/clock 中 UTC=false)
開機: BIOS----------------------->CST(將BIOS中的時間看成是CST)
關機: CST ---------存儲到------>BIOS
通過設定 /etc/sysconfig/clock,linux可以支持這兩種方式,然而windows只支持方式B(至少是默認支持B,而我不知道怎么能讓它支持A),那么在雙系統情況下,如果linux設成A方式,那么在linux與windows系統切換時一定會造成時間混亂的,解決辦法就是將linux中的UTC禁用,也設成B方式就可以了。
注:可以通過 hwclock --hctosys 來利用硬件時間來設置系統時間(注意不是簡單的復制BIOS中的時間為系統時間,要看是否使用UTC,如果使用的話則要做時區換算),通過 hwclock --systohc 來根據系統時間設置硬件時間(也要看是否啟用UTC來決定是否做時區換算)。總之,不論使用 --systohc 還是 --hctosys,同步后直接運行不帶參數的 hwclock 得到的時間與直接運行 date 得到的時間應該一致,這個時間是否就是BIOS中的時間(hwclock --localtime)那就不一定了,如果啟用了UTC就不是,沒啟用UTC就是。
而且好要注意:在系統中手動使用 hwclock hwclock --set --date='yyyy-mm-dd' 來設置BIOS時間只在系統運行時有效,因為當系統關閉時,還會按設定好的方式根據系統時間來重設BIOS時間的,於是手動的設置便被覆蓋掉了。
二、時間命令
1. 系統時間 date
直接調用 date,得到的是本地時間。如果想得到UTC時間的話,使用 date -u。
[12-01 19:07> ~]$ date
2009年 12月 07日 星期一 14:22:20 CST
[12-01 19:07> ~]$ date -u
2009年 12月 07日 星期一 06:22:22 UTC
2. 硬件時間 /sbin/hwclock
2009年 12月 07日 星期一 14:22:20 CST
[12-01 19:07> ~]$ date -u
2009年 12月 07日 星期一 06:22:22 UTC
直接調用 /sbin/hwclock 顯示的時間就是 BIOS 中的時間嗎?未必!這要看 /etc/sysconfig/clock 中是否啟用了UTC,如果啟用了UTC(UTC=true),顯示的其實是經過時區換算的時間而不是BIOS中真正的時間,如果加上 --localtime 選項,則得到的總是 BIOS 中實際的時間.
[12-01 19:07> ~]# hwclock
2009年12月07日 星期一 14時28分43秒 -0.611463 seconds
[12-01 19:07> ~]# hwclock --utc
2009年12月07日 星期一 14時28分46秒 -0.594189 seconds
[12-01 19:07> ~]# hwclock --localtime
2009年12月07日 星期一 06時28分50秒 -0.063875 seconds
3. /etc/localtime
2009年12月07日 星期一 14時28分43秒 -0.611463 seconds
[12-01 19:07> ~]# hwclock --utc
2009年12月07日 星期一 14時28分46秒 -0.594189 seconds
[12-01 19:07> ~]# hwclock --localtime
2009年12月07日 星期一 06時28分50秒 -0.063875 seconds
這個文件用來設置系統的時區,將 /usr/share/zoneinfo/ 中相應文件拷貝到/etc下並重命名為 localtime 即可修改時區設置,而且這種修改對 date 命令是及時生效的。不論是 date 還是 hwclock 都會用到這個文件,會根據這個文件的時區設置來進行UTC和本地之間之間的換算。
4. /etc/sysconfig/clock
這個文件只對 hwclock 有效,而且似乎是只在系統啟動和關閉的時候才有用,比如修改了其中的 UTC=true 到 UTC=false 的前后,執行 hwclock (--utc, 或 --localtime) 都沒有變化,要重啟系統后才生效。注:如果設置 UTC=false 並重啟系統后,執行一些命令結果如下:
date 2009年 12月 07日 星期一 19:26:29 CST
date -u 2009年 12月 07日 星期一 11:26:29 UTC
hwclock 2009年12月07日 星期一 19時26分30秒 -0.442668 seconds
hwclock --utc 2009年12月08日 星期二 03時26分31秒 -0.999091 seconds
hwclock --localtime 2009年12月07日 星期一 19時26分32秒 -0.999217 seconds
可見,如果不使用UTC,BIOS時間(紅色部分)就是系統本地時間,而且注意這時執行 hwclock --utc 得到的結果沒有任何意義,因為這里我們已經禁用了UTC,而且也明顯不符合“本地時間=UTC+時區”的關系。
date -u 2009年 12月 07日 星期一 11:26:29 UTC
hwclock 2009年12月07日 星期一 19時26分30秒 -0.442668 seconds
hwclock --utc 2009年12月08日 星期二 03時26分31秒 -0.999091 seconds
hwclock --localtime 2009年12月07日 星期一 19時26分32秒 -0.999217 seconds
三、linux與windows雙系統間的時間同步
系統啟動和關閉時,硬件時間與系統時間之間的同步有兩種方式(假設在中國,用CST代表本地時間):
方式A: 使用UTC(對linux就是 /etc/sysconfig/clock 中 UTC=true)
開機: BIOS--------->UTC(將BIOS中的時間看成是UTC)------(時區變化)----->CST
關機: CST -------(時區變化)----->UTC-------存儲到------>BIOS
方式B: 不使用UTC(對linux就是 /etc/sysconfig/clock 中 UTC=false)
開機: BIOS----------------------->CST(將BIOS中的時間看成是CST)
關機: CST ---------存儲到------>BIOS
通過設定 /etc/sysconfig/clock,linux可以支持這兩種方式,然而windows只支持方式B(至少是默認支持B,而我不知道怎么能讓它支持A),那么在雙系統情況下,如果linux設成A方式,那么在linux與windows系統切換時一定會造成時間混亂的,解決辦法就是將linux中的UTC禁用,也設成B方式就可以了。
注:可以通過 hwclock --hctosys 來利用硬件時間來設置系統時間(注意不是簡單的復制BIOS中的時間為系統時間,要看是否使用UTC,如果使用的話則要做時區換算),通過 hwclock --systohc 來根據系統時間設置硬件時間(也要看是否啟用UTC來決定是否做時區換算)。總之,不論使用 --systohc 還是 --hctosys,同步后直接運行不帶參數的 hwclock 得到的時間與直接運行 date 得到的時間應該一致,這個時間是否就是BIOS中的時間(hwclock --localtime)那就不一定了,如果啟用了UTC就不是,沒啟用UTC就是。
而且好要注意:在系統中手動使用 hwclock hwclock --set --date='yyyy-mm-dd' 來設置BIOS時間只在系統運行時有效,因為當系統關閉時,還會按設定好的方式根據系統時間來重設BIOS時間的,於是手動的設置便被覆蓋掉了。
--------------------------------------------------------
Linux的時間設置與同步 (NTP)
Network Time Protocol (NTP) 也是RHCE新增的考試要求. 學習的時候也順便復習了一下如何設置Linux的時間,現在拿出來和大家分享設置NTP服務器不難但是NTP本身是一個很復雜的協議. 這里只是簡要地介紹一下實踐方法和上次一樣,下面的實驗都在RHEL5上運行 1. 時間和時區 如果有人問你說現在幾點? 你看了看表回答他說晚上8點了. 這樣回答看上去沒有什么問題,但是如果問你的這個人在歐洲的話那么你的回答就會讓他很疑惑,因為他那里還太陽當空呢. 這里就有產生了一個如何定義時間的問題. 因為在地球環繞太陽旋轉的24個小時中,世界各地日出日落的時間是不一樣的.所以我們才有划分時區(timezone) 的必要,也就是把全球划分成24個不同的時區. 所以我們可以把時間的定義理解為一個時間的值加上所在地的時區(注意這個所在地可以精確到城市) 地理課上我們都學過格林威治時間(GMT), 它也就是0時區時間. 但是我們在計算機中經常看到的是UTC. 它是Coordinated Universal Time的簡寫. 雖然可以認為UTC和GMT的值相等(誤差相當之小),但是UTC已經被認定為是國際標准,所以我們都應該遵守標准只使用UTC 那么假如現在中國當地的時間是晚上8點的話,我們可以有下面兩種表示方式 20:00 CST 12:00 UTC 這里的CST是Chinese Standard Time,也就是我們通常所說的北京時間了. 因為中國處在UTC+8時區,依次類推那么也就是12:00 UTC了. 為什么要說這些呢(呵呵這里不是地理論壇吧...)? 第一,不管通過任何渠道我們想要同步系統的時間,通常提供方只會給出UTC+0的時間值而不會提供時區(因為它不知道你在哪里).所以當我們設置系統時間的時候,設置好時區是首先要做的工作第二,很多國家都有夏令時(我記得小時候中國也實行過一次),那就是在一年當中的某一天時鍾撥快一小時(比如從UTC+8一下變成UTC+9了),那么同理到時候還要再撥慢回來.如果我們設置了正確的時區,當需要改變時間的時候系統就會自動替我們調整 現在我們就來看一下如何在Linux下設置時區,也就是time zone 2. 如何設置Linux Time Zone 在Linux下glibc提供了我們事先編譯好的許多timezone文件, 他們就放在/usr/share/zoneinfo這個目錄下,這里基本涵蓋了大部分的國家和城市
代碼:
# ls -F /usr/share/zoneinfo/
Africa/ Chile/ Factory Iceland Mexico/ posix/ Universal
America/ CST6CDT GB Indian/ Mideast/ posixrules US/
Antarctica/ Cuba GB-Eire Iran MST PRC UTC
Arctic/ EET GMT iso3166.tab MST7MDT PST8PDT WET
Asia/ Egypt GMT0 Israel Navajo right/ W-SU
Atlantic/ Eire GMT-0 Jamaica NZ ROC zone.tab
Australia/ EST GMT+0 Japan NZ-CHAT ROK Zulu
Brazil/ EST5EDT Greenwich Kwajalein Pacific/ Singapore
Canada/ Etc/ Hongkong Libya Poland Turkey
CET Europe/ HST MET Portugal UCT在這里面我們就可以找到自己所在城市的time zone文件. 那么如果我們想查看對於每個time zone當前的時間我們可以用zdump命令
代碼:
# zdump Hongkong
Hongkong Fri Jul 6 06:13:57 2007 HKT那么我們又怎么來告訴系統我們所在time zone是哪個呢? 方法有很多,這里舉出兩種 第一個就是修改/etc/localtime這個文件,這個文件定義了我么所在的local time zone. 我們可以在/usr/share/zoneinfo下找到我們的time zone文件然后拷貝去到/etc/localtimezone(或者做個symbolic link) 假設我們現在的time zone是BST(也就是英國的夏令時間,UTC+1)
代碼:
# date
Thu Jul 5 23:33:40 BST 2007我們想把time zone換成上海所在的時區就可以這么做
代碼:
# ln -sf /usr/share/zoneinfo/posix/Asia/Shanghai /etc/localtime
# date
Fri Jul 6 06:35:52 CST 2007這樣時區就改過來了(注意時間也做了相應的調整) 第二種方法也就設置TZ環境變量的值. 許多程序和命令都會用到這個變量的值. TZ的值可以有多種格式,最簡單的設置方法就是使用tzselect命令
代碼:
# tzselect
...
TZ='America/Los_Angeles';export TZtzselect會讓你選擇所在的國家和城市(我省略了這些步驟),最后輸出相應的TZ變量的值.那么如果你設置了TZ的值之后時區就又會發生變化
代碼:
# date
Thu Jul 5 15:48:11 PDT 2007通過這兩個例子我們也可以發現TZ變量的值會override /etc/localtime. 也就是說當TZ變量沒有定義的時候系統才使用/etc/localtime來確定time zone. 所以你想永久修改time zone的話那么可以把TZ變量的設置寫入/etc/profile里 好了現在我們知道怎么設置時區了,下面我們就來看看如何設置Linux的時間吧 3. Real Time Clock(RTC) and System Clock 說道設置時間這里還要明確另外一個概念就是在一台計算機上我們有兩個時鍾:一個稱之為硬件時間時鍾(RTC),還有一個稱之為系統時鍾(System Clock) 硬件時鍾是指嵌在主板上的特殊的電路, 它的存在就是平時我們關機之后還可以計算時間的原因系統時鍾就是操作系統的kernel所用來計算時間的時鍾. 它從1970年1月1日00:00:00 UTC時間到目前為止秒數總和的值 在Linux下系統時間在開機的時候會和硬件時間同步(synchronization),之后也就各自獨立運行了 那么既然兩個時鍾獨自運行,那么時間久了必然就會產生誤差了,下面我們來看一個例子
代碼:
# date
Fri Jul 6 00:27:13 BST 2007
# hwclock --show
Fri 06 Jul 2007 12:27:17 AM BST -0.968931 seconds通過hwclock --show命令我們可以查看機器上的硬件時間(always in local time zone), 我們可以看到它和系統時間還是有一定的誤差的, 那么我們就需要把他們同步 如果我們想要把硬件時間設置成系統時間我們可以運行以下命令
代碼:
# hwclock --hctosys反之,我們也可以把系統時間設置成硬件時間
代碼:
# hwclock --systohc那么如果想設置硬件時間我們可以開機的時候在BIOS里設定.也可以用hwclock命令
代碼:
# hwclock --set --date="mm/dd/yy hh:mm:ss"如果想要修改系統時間那么用date命令就最簡單了
代碼:
# date -s "dd/mm/yyyy hh:mm:ss"現在我們知道了如何設置系統和硬件的時間. 但問題是如果這兩個時間都不准確了怎么辦? 那么我們就需要在互聯網上找到一個可以提供我們准確時間的服務器然后通過一種協議來同步我們的系統時間,那么這個協議就是NTP了. 注意接下去我們所要說的同步就都是指系統時間和網絡服務器之間的同步了 4. 設置NTP Server前的准備 其實這個標題應該改為設置"NTP Relay Server"前的准備更加合適. 因為不論我們的計算機配置多好運行時間久了都會產生誤差,所以不足以給互聯網上的其他服務器做NTP Server. 真正能夠精確地測算時間的還是原子鍾. 但由於原子鍾十分的昂貴,只有少部分組織擁有, 他們連接到計算機之后就成了一台真正的NTP Server. 而我們所要做的就是連接到這些服務器上同步我們系統的時間,然后把我們自己的服務器做成NTP Relay Server再給互聯網或者是局域網內的用戶提供同步服務 好了,前面講了一大堆理論,現在我們來動手實踐一下吧. 架設一個NTP Relay Server其實非常簡單,我們先把需要的RPM包裝上
代碼:
# rpm -ivh ntp-4.2.2p1-5.el5.rpm那么第一步我們就要找到在互聯網上給我們提供同步服務的NTP Server http://www.pool.ntp.org是NTP的官方網站,在這上面我們可以找到離我們城市最近的NTP Server. NTP建議我們為了保障時間的准確性,最少找兩個個NTP Server 那么比如在英國的話就可以選擇下面兩個服務器 0.uk.pool.ntp.org 1.uk.pool.ntp.org 它的一般格式都是number.country.pool.ntp.org 第二步要做的就是在打開NTP服務器之前先和這些服務器做一個同步,使得我們機器的時間盡量接近標准時間. 這里我們可以用ntpdate命令
代碼:
# ntpdate 0.uk.pool.ntp.org
6 Jul 01:21:49 ntpdate[4528]: step time server 213.222.193.35 offset -38908.575181 sec
# ntpdate 0.pool.ntp.org
6 Jul 01:21:56 ntpdate[4530]: adjust time server 213.222.193.35 offset -0.000065 sec假如你的時間差的很離譜的話第一次會看到調整的幅度比較大,所以保險起見可以運行兩次. 那么為什么在打開NTP服務之前先要手動運行同步呢? 1. 因為根據NTP的設置,如果你的系統時間比正確時間要快的話那么NTP是不會幫你調整的,所以要么你把時間設置回去,要么先做一個手動同步 2. 當你的時間設置和NTP服務器的時間相差很大的時候,NTP會花上較長一段時間進行調整.所以手動同步可以減少這段時間 5. 配置和運行NTP Server 現在我們就來創建NTP的配置文件了, 它就是/etc/ntp.conf. 我們只需要加入上面的NTP Server和一個driftfile就可以了
代碼:
# vi /etc/ntp.conf
server 0.uk.pool.ntp.org
server 1.uk.pool.ntp.org
driftfile /var/lib/ntp/ntp.drift非常的簡單. 接下來我們就啟動NTP Server,並且設置其在開機后自動運行
代碼:
# /etc/init.d/ntpd/start
# chkconfig --level 35 ntpd on6. 查看NTP服務的運行狀況 現在我們已經啟動了NTP的服務,但是我們的系統時間到底和服務器同步了沒有呢? 為此NTP提供了一個很好的查看工具: ntpq (NTP query) 我建議大家在打開NTP服務器后就可以運行ntpq命令來監測服務器的運行.這里我們可以使用watch命令來查看一段時間內服務器各項數值的變化
代碼:
# watch ntpq -p
Every 2.0s: ntpq -p Sat Jul 7 00:41:45 2007
代碼:
# ls -F /usr/share/zoneinfo/
Africa/ Chile/ Factory Iceland Mexico/ posix/ Universal
America/ CST6CDT GB Indian/ Mideast/ posixrules US/
Antarctica/ Cuba GB-Eire Iran MST PRC UTC
Arctic/ EET GMT iso3166.tab MST7MDT PST8PDT WET
Asia/ Egypt GMT0 Israel Navajo right/ W-SU
Atlantic/ Eire GMT-0 Jamaica NZ ROC zone.tab
Australia/ EST GMT+0 Japan NZ-CHAT ROK Zulu
Brazil/ EST5EDT Greenwich Kwajalein Pacific/ Singapore
Canada/ Etc/ Hongkong Libya Poland Turkey
CET Europe/ HST MET Portugal UCT在這里面我們就可以找到自己所在城市的time zone文件. 那么如果我們想查看對於每個time zone當前的時間我們可以用zdump命令
代碼:
# zdump Hongkong
Hongkong Fri Jul 6 06:13:57 2007 HKT那么我們又怎么來告訴系統我們所在time zone是哪個呢? 方法有很多,這里舉出兩種 第一個就是修改/etc/localtime這個文件,這個文件定義了我么所在的local time zone. 我們可以在/usr/share/zoneinfo下找到我們的time zone文件然后拷貝去到/etc/localtimezone(或者做個symbolic link) 假設我們現在的time zone是BST(也就是英國的夏令時間,UTC+1)
代碼:
# date
Thu Jul 5 23:33:40 BST 2007我們想把time zone換成上海所在的時區就可以這么做
代碼:
# ln -sf /usr/share/zoneinfo/posix/Asia/Shanghai /etc/localtime
# date
Fri Jul 6 06:35:52 CST 2007這樣時區就改過來了(注意時間也做了相應的調整) 第二種方法也就設置TZ環境變量的值. 許多程序和命令都會用到這個變量的值. TZ的值可以有多種格式,最簡單的設置方法就是使用tzselect命令
代碼:
# tzselect
...
TZ='America/Los_Angeles';export TZtzselect會讓你選擇所在的國家和城市(我省略了這些步驟),最后輸出相應的TZ變量的值.那么如果你設置了TZ的值之后時區就又會發生變化
代碼:
# date
Thu Jul 5 15:48:11 PDT 2007通過這兩個例子我們也可以發現TZ變量的值會override /etc/localtime. 也就是說當TZ變量沒有定義的時候系統才使用/etc/localtime來確定time zone. 所以你想永久修改time zone的話那么可以把TZ變量的設置寫入/etc/profile里 好了現在我們知道怎么設置時區了,下面我們就來看看如何設置Linux的時間吧 3. Real Time Clock(RTC) and System Clock 說道設置時間這里還要明確另外一個概念就是在一台計算機上我們有兩個時鍾:一個稱之為硬件時間時鍾(RTC),還有一個稱之為系統時鍾(System Clock) 硬件時鍾是指嵌在主板上的特殊的電路, 它的存在就是平時我們關機之后還可以計算時間的原因系統時鍾就是操作系統的kernel所用來計算時間的時鍾. 它從1970年1月1日00:00:00 UTC時間到目前為止秒數總和的值 在Linux下系統時間在開機的時候會和硬件時間同步(synchronization),之后也就各自獨立運行了 那么既然兩個時鍾獨自運行,那么時間久了必然就會產生誤差了,下面我們來看一個例子
代碼:
# date
Fri Jul 6 00:27:13 BST 2007
# hwclock --show
Fri 06 Jul 2007 12:27:17 AM BST -0.968931 seconds通過hwclock --show命令我們可以查看機器上的硬件時間(always in local time zone), 我們可以看到它和系統時間還是有一定的誤差的, 那么我們就需要把他們同步 如果我們想要把硬件時間設置成系統時間我們可以運行以下命令
代碼:
# hwclock --hctosys反之,我們也可以把系統時間設置成硬件時間
代碼:
# hwclock --systohc那么如果想設置硬件時間我們可以開機的時候在BIOS里設定.也可以用hwclock命令
代碼:
# hwclock --set --date="mm/dd/yy hh:mm:ss"如果想要修改系統時間那么用date命令就最簡單了
代碼:
# date -s "dd/mm/yyyy hh:mm:ss"現在我們知道了如何設置系統和硬件的時間. 但問題是如果這兩個時間都不准確了怎么辦? 那么我們就需要在互聯網上找到一個可以提供我們准確時間的服務器然后通過一種協議來同步我們的系統時間,那么這個協議就是NTP了. 注意接下去我們所要說的同步就都是指系統時間和網絡服務器之間的同步了 4. 設置NTP Server前的准備 其實這個標題應該改為設置"NTP Relay Server"前的准備更加合適. 因為不論我們的計算機配置多好運行時間久了都會產生誤差,所以不足以給互聯網上的其他服務器做NTP Server. 真正能夠精確地測算時間的還是原子鍾. 但由於原子鍾十分的昂貴,只有少部分組織擁有, 他們連接到計算機之后就成了一台真正的NTP Server. 而我們所要做的就是連接到這些服務器上同步我們系統的時間,然后把我們自己的服務器做成NTP Relay Server再給互聯網或者是局域網內的用戶提供同步服務 好了,前面講了一大堆理論,現在我們來動手實踐一下吧. 架設一個NTP Relay Server其實非常簡單,我們先把需要的RPM包裝上
代碼:
# rpm -ivh ntp-4.2.2p1-5.el5.rpm那么第一步我們就要找到在互聯網上給我們提供同步服務的NTP Server http://www.pool.ntp.org是NTP的官方網站,在這上面我們可以找到離我們城市最近的NTP Server. NTP建議我們為了保障時間的准確性,最少找兩個個NTP Server 那么比如在英國的話就可以選擇下面兩個服務器 0.uk.pool.ntp.org 1.uk.pool.ntp.org 它的一般格式都是number.country.pool.ntp.org 第二步要做的就是在打開NTP服務器之前先和這些服務器做一個同步,使得我們機器的時間盡量接近標准時間. 這里我們可以用ntpdate命令
代碼:
# ntpdate 0.uk.pool.ntp.org
6 Jul 01:21:49 ntpdate[4528]: step time server 213.222.193.35 offset -38908.575181 sec
# ntpdate 0.pool.ntp.org
6 Jul 01:21:56 ntpdate[4530]: adjust time server 213.222.193.35 offset -0.000065 sec假如你的時間差的很離譜的話第一次會看到調整的幅度比較大,所以保險起見可以運行兩次. 那么為什么在打開NTP服務之前先要手動運行同步呢? 1. 因為根據NTP的設置,如果你的系統時間比正確時間要快的話那么NTP是不會幫你調整的,所以要么你把時間設置回去,要么先做一個手動同步 2. 當你的時間設置和NTP服務器的時間相差很大的時候,NTP會花上較長一段時間進行調整.所以手動同步可以減少這段時間 5. 配置和運行NTP Server 現在我們就來創建NTP的配置文件了, 它就是/etc/ntp.conf. 我們只需要加入上面的NTP Server和一個driftfile就可以了
代碼:
# vi /etc/ntp.conf
server 0.uk.pool.ntp.org
server 1.uk.pool.ntp.org
driftfile /var/lib/ntp/ntp.drift非常的簡單. 接下來我們就啟動NTP Server,並且設置其在開機后自動運行
代碼:
# /etc/init.d/ntpd/start
# chkconfig --level 35 ntpd on6. 查看NTP服務的運行狀況 現在我們已經啟動了NTP的服務,但是我們的系統時間到底和服務器同步了沒有呢? 為此NTP提供了一個很好的查看工具: ntpq (NTP query) 我建議大家在打開NTP服務器后就可以運行ntpq命令來監測服務器的運行.這里我們可以使用watch命令來查看一段時間內服務器各項數值的變化
代碼:
# watch ntpq -p
Every 2.0s: ntpq -p Sat Jul 7 00:41:45 2007
remote refid st t when poll reach delay offset jitter
==============================================================================
+193.60.199.75 193.62.22.98 2 u 52 64 377 8.578 10.203 289.032
*mozart.musicbox 192.5.41.41 2 u 54 64 377 19.301 -60.218 292.411現在我就來解釋一下其中的含義 remote: 它指的就是本地機器所連接的遠程NTP服務器 refid: 它指的是給遠程服務器(e.g. 193.60.199.75)提供時間同步的服務器 st: 遠程服務器的級別. 由於NTP是層型結構,有頂端的服務器,多層的Relay Server再到客戶端. 所以服務器從高到低級別可以設定為1-16. 為了減緩負荷和網絡堵塞,原則上應該避免直接連接到級別為1的服務器的. t: 這個.....我也不知道啥意思^_^ when: 我個人把它理解為一個計時器用來告訴我們還有多久本地機器就需要和遠程服務器進行一次時間同步 poll: 本地機和遠程服務器多少時間進行一次同步(單位為秒). 在一開始運行NTP的時候這個poll值會比較小,那樣和服務器同步的頻率也就增加了,可以盡快調整到正確的時間范圍.之后poll值會逐漸增大,同步的頻率也就會相應減小 reach: 這是一個八進制值,用來測試能否和服務器連接.每成功連接一次它的值就會增加 delay: 從本地機發送同步要求到服務器的round trip time offset: 這是個最關鍵的值, 它告訴了我們本地機和服務器之間的時間差別. offset越接近於0,我們就和服務器的時間越接近 jitter: 這是一個用來做統計的值. 它統計了在特定個連續的連接數里offset的分布情況. 簡單地說這個數值的絕對值越小我們和服務器的時間就越精確 那么大家細心的話就會發現兩個問題: 第一我們連接的是0.uk.pool.ntp.org為什么和remote server不一樣? 第二那個最前面的+和*都是什么意思呢? 第一個問題不難理解,因為NTP提供給我們的是一個cluster server所以每次連接的得到的服務器都有可能是不一樣.同樣這也告訴我們了在指定NTP Server的時候應該使用hostname而不是IP 第二個問題和第一個相關,既然有這么多的服務器就是為了在發生問題的時候其他的服務器還可以正常地給我們提供服務.那么如何知道這些服務器的狀態呢? 這就是第一個記號會告訴我們的信息 * 它告訴我們遠端的服務器已經被確認為我們的主NTP Server,我們系統的時間將由這台機器所提供 + 它將作為輔助的NTP Server和帶有*號的服務器一起為我們提供同步服務. 當*號服務器不可用時它就可以接管 - 遠程服務器被clustering algorithm認為是不合格的NTP Server x 遠程服務器不可用 了解這些之后我們就可以實時監測我們系統的時間同步狀況了 7. NTP安全設置 運行一個NTP Server不需要占用很多的系統資源,所以也不用專門配置獨立的服務器,就可以給許多client提供時間同步服務, 但是一些基本的安全設置還是很有必要的那么這里一個很簡單的思路就是第一我們只允許局域網內一部分的用戶連接到我們的服務器. 第二個就是這些client不能修改我們服務器上的時間 在/etc/ntp.conf文件中我們可以用restrict關鍵字來配置上面的要求 首先我們對於默認的client拒絕所有的操作
代碼:
restrict default kod nomodify notrap nopeer noquery然后允許本機地址一切的操作
代碼:
restrict 127.0.0.1最后我們允許局域網內所有client連接到這台服務器同步時間.但是拒絕讓他們修改服務器上的時間
代碼:
restrict 192.168.1.0 mask 255.255.255.0 nomodify把這三條加入到/etc/ntp.conf中就完成了我們的簡單配置. NTP還可以用key來做authenticaiton,這里就不詳細介紹了 8. NTP client的設置 做到這里我們已經有了一台自己的Relay Server.如果我們想讓局域網內的其他client都進行時間同步的話那么我們就都應該照樣再搭建一台Relay Server,然后把所有的client都指向這兩台服務器(注意不要把所有的client都指向Internet上的服務器). 只要在client的ntp.conf加上這你自己的服務器就可以了
代碼:
server ntp1.leonard.com
server ntp2.leonard.com9. 一些補充和拾遺 1. 配置文件中的driftfile是什么? 我們每一個system clock的頻率都有小小的誤差,這個就是為什么機器運行一段時間后會不精確. NTP會自動來監測我們時鍾的誤差值並予以調整.但問題是這是一個冗長的過程,所以它會把記錄下來的誤差先寫入driftfile.這樣即使你重新開機以后之前的計算結果也就不會丟失了 2. 如何同步硬件時鍾? NTP一般只會同步system clock. 但是如果我們也要同步RTC的話那么只需要把下面的選項打開就可以了
代碼:
# vi /etc/sysconfig/ntpd
SYNC_HWCLOCK=yes10.
==============================================================================
+193.60.199.75 193.62.22.98 2 u 52 64 377 8.578 10.203 289.032
*mozart.musicbox 192.5.41.41 2 u 54 64 377 19.301 -60.218 292.411現在我就來解釋一下其中的含義 remote: 它指的就是本地機器所連接的遠程NTP服務器 refid: 它指的是給遠程服務器(e.g. 193.60.199.75)提供時間同步的服務器 st: 遠程服務器的級別. 由於NTP是層型結構,有頂端的服務器,多層的Relay Server再到客戶端. 所以服務器從高到低級別可以設定為1-16. 為了減緩負荷和網絡堵塞,原則上應該避免直接連接到級別為1的服務器的. t: 這個.....我也不知道啥意思^_^ when: 我個人把它理解為一個計時器用來告訴我們還有多久本地機器就需要和遠程服務器進行一次時間同步 poll: 本地機和遠程服務器多少時間進行一次同步(單位為秒). 在一開始運行NTP的時候這個poll值會比較小,那樣和服務器同步的頻率也就增加了,可以盡快調整到正確的時間范圍.之后poll值會逐漸增大,同步的頻率也就會相應減小 reach: 這是一個八進制值,用來測試能否和服務器連接.每成功連接一次它的值就會增加 delay: 從本地機發送同步要求到服務器的round trip time offset: 這是個最關鍵的值, 它告訴了我們本地機和服務器之間的時間差別. offset越接近於0,我們就和服務器的時間越接近 jitter: 這是一個用來做統計的值. 它統計了在特定個連續的連接數里offset的分布情況. 簡單地說這個數值的絕對值越小我們和服務器的時間就越精確 那么大家細心的話就會發現兩個問題: 第一我們連接的是0.uk.pool.ntp.org為什么和remote server不一樣? 第二那個最前面的+和*都是什么意思呢? 第一個問題不難理解,因為NTP提供給我們的是一個cluster server所以每次連接的得到的服務器都有可能是不一樣.同樣這也告訴我們了在指定NTP Server的時候應該使用hostname而不是IP 第二個問題和第一個相關,既然有這么多的服務器就是為了在發生問題的時候其他的服務器還可以正常地給我們提供服務.那么如何知道這些服務器的狀態呢? 這就是第一個記號會告訴我們的信息 * 它告訴我們遠端的服務器已經被確認為我們的主NTP Server,我們系統的時間將由這台機器所提供 + 它將作為輔助的NTP Server和帶有*號的服務器一起為我們提供同步服務. 當*號服務器不可用時它就可以接管 - 遠程服務器被clustering algorithm認為是不合格的NTP Server x 遠程服務器不可用 了解這些之后我們就可以實時監測我們系統的時間同步狀況了 7. NTP安全設置 運行一個NTP Server不需要占用很多的系統資源,所以也不用專門配置獨立的服務器,就可以給許多client提供時間同步服務, 但是一些基本的安全設置還是很有必要的那么這里一個很簡單的思路就是第一我們只允許局域網內一部分的用戶連接到我們的服務器. 第二個就是這些client不能修改我們服務器上的時間 在/etc/ntp.conf文件中我們可以用restrict關鍵字來配置上面的要求 首先我們對於默認的client拒絕所有的操作
代碼:
restrict default kod nomodify notrap nopeer noquery然后允許本機地址一切的操作
代碼:
restrict 127.0.0.1最后我們允許局域網內所有client連接到這台服務器同步時間.但是拒絕讓他們修改服務器上的時間
代碼:
restrict 192.168.1.0 mask 255.255.255.0 nomodify把這三條加入到/etc/ntp.conf中就完成了我們的簡單配置. NTP還可以用key來做authenticaiton,這里就不詳細介紹了 8. NTP client的設置 做到這里我們已經有了一台自己的Relay Server.如果我們想讓局域網內的其他client都進行時間同步的話那么我們就都應該照樣再搭建一台Relay Server,然后把所有的client都指向這兩台服務器(注意不要把所有的client都指向Internet上的服務器). 只要在client的ntp.conf加上這你自己的服務器就可以了
代碼:
server ntp1.leonard.com
server ntp2.leonard.com9. 一些補充和拾遺 1. 配置文件中的driftfile是什么? 我們每一個system clock的頻率都有小小的誤差,這個就是為什么機器運行一段時間后會不精確. NTP會自動來監測我們時鍾的誤差值並予以調整.但問題是這是一個冗長的過程,所以它會把記錄下來的誤差先寫入driftfile.這樣即使你重新開機以后之前的計算結果也就不會丟失了 2. 如何同步硬件時鍾? NTP一般只會同步system clock. 但是如果我們也要同步RTC的話那么只需要把下面的選項打開就可以了
代碼:
# vi /etc/sysconfig/ntpd
SYNC_HWCLOCK=yes10.