業(yè)務(wù)場景
由于開發(fā)用的laravel框架,業(yè)務(wù)中用了很多job定時任務(wù),時間幾乎分布在全天的任何時間點(精確到秒),如果服務(wù)器時間校準(zhǔn)出現(xiàn)時間跳躍的話,很有可能導(dǎo)致某些計劃任務(wù)無法執(zhí)行。
實現(xiàn)方法分析
首先想到的就是定時執(zhí)行
20 3 * * * ntpdate 1.cn.pool.ntp.org >> /root/cron.log 2>$1
但是這樣的話會導(dǎo)致如果任務(wù)A是在20:18:18執(zhí)行,但是ntpdate從20:18:15開始校準(zhǔn),一下把服務(wù)器時間設(shè)置成了20:18:20秒,那么計劃任務(wù)A就被跳過了,沒有執(zhí)行。
解決以上問題的方案
- 先用
ntpdate每天同步一次(最好在閑時同步) - 然后用
ntpd守護(hù)進(jìn)程服務(wù)來校準(zhǔn)。
為什么要這樣做呢?原因如下
- ntpd在實際同步時間時是一點點的校準(zhǔn)過來時間的,最終把時間慢慢的校正對。
- ntpdate不會考慮其他程序是否會陣痛,直接調(diào)整時間。
使用ntpdate導(dǎo)致的問題
不幸的是,ntpdate調(diào)整時間的方式就是我們所說的”躍變“:在獲得一個時間之后,ntpdate使用(當(dāng)誤差大于0.5秒的時候,用settimeofday直接設(shè)置系統(tǒng)時間,小于0.5秒的時候用adjtime和偏移量來)設(shè)置系統(tǒng)時間,這有幾個非常明顯的問題:
- 這樣做不安全。ntpdate的設(shè)置依賴于ntp服務(wù)器的安全性,攻擊者可以利用一些軟件設(shè)計上的缺陷,拿下ntp服務(wù)器并令與其同步的服務(wù)器執(zhí)行某些消耗性的任務(wù)。由于ntpdate采用的方式是跳變,跟隨它的服務(wù)器無法知道是否發(fā)生了異常(時間不一樣的時候,唯一的辦法是以服務(wù)器為準(zhǔn))。
- 這樣做不精確。一旦ntp服務(wù)器宕機(jī),跟隨它的服務(wù)器也就會無法同步時間。與此不同,ntpd不僅能夠校準(zhǔn)計算機(jī)的時間,而且能夠校準(zhǔn)計算機(jī)的時鐘。
- 這樣做不夠優(yōu)雅。由于是跳變,而不是使時間變快或變慢,依賴時序的程序會出錯(例如,如果ntpdate發(fā)現(xiàn)你的時間快了,則可能會經(jīng)歷兩個相同的時刻,對某些應(yīng)用而言,這是致命的)。
因而,唯一一個可以令時間發(fā)生跳變的點,是計算機(jī)剛剛啟動,但還沒有啟動很多服務(wù)的那個時候。其余的時候,理想的做法是使用ntpd來校準(zhǔn)時鐘,而不是調(diào)整計算機(jī)時鐘上的時間。
NTPD 在和時間服務(wù)器的同步過程中,會把 BIOS 計時器的振蕩頻率偏差,或者說 Local Clock 的自然漂移(drift)記錄下來。這樣即使網(wǎng)絡(luò)有問題,本機(jī)仍然能維持一個相當(dāng)精確的走時。
最后提醒一下使用vmware的各位,因為虛擬機(jī)的時鐘不太正常,比正常速度慢好多秒,所以在虛擬機(jī)上測試ntpd很難得到理想的結(jié)果,我當(dāng)年就是為這個問題耽擱了好幾天。。