在公司的內部網路,由於無法連接到一般的 NTP (時間伺服器),所以隨著時間長久,每台的時間不太一樣。要一台一台去設定,其實也是蠻麻煩的,經年累月的差距下,甚至會差到半小時。這對於 SVN 或 Auto Builder Server 其實容易造成一些混淆,因此,才會起心動念想要架一個內部的時間伺服器。
當然,時間伺服器自己的時間也會偏掉,此時就要外接一個 USB GPS 來當做校正來源,這樣就可以全自動的進行時間完美校準了。
套件安裝
在 Ubuntu 上,安裝 ntp 套件,就會包含 Server 的部份。
1 |
apt-get install ntp |
若是客戶端,則安裝 ntpdate
1 |
apt-get install ntpdate |
這2個程式不能同時安裝,不然在執行ntpdate會發生 socket 被佔用的問題。
比較奇怪的是,我在使用 lxc 的虛擬機當伺服器時,一直無法從Windows同步成功, 但從單獨的程式就可以。若以實體機器當伺服器,則無此問題。
Windows Client 時間同步
要讓 Windows 同步時,開起控制台的「日期和時間」 –> 「網際網路時間」–> 「變更設定」,將伺服器設定成你的 Time Server 來進行設定。
Linux Client 時間同步
若系統沒有 NTP 的圖型界面,可以利用 crontab 執行 ntpdate 並指定 IP 就能進行同步
1 |
ntpdate NTP_SERVER_IP |
NTP Server 取得 GPS 時間
由於 Server 的時間也會偏移,但處於內部網路也無法與外路伺服器同步,此時就需要借助 GPS 來進行時間同步。台灣賣廠的 USB GPS 模組不太好找或偏貴,到淘寶會好找一點。若不怕麻煩,在 Server 上進行時間設定也是可以。
USB 的 GPS 在插入 Linux 後,一般都會以 UART 的裝置來存取,至於 baudrate 可能會有所不同,需要自行試試看。訊息的部份,都是以 NMEA 標準來顯示裝態,其中的 RMC 欄位就是定位後的時間、經緯度。以下是取得 GPS 時間的 Shell Script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#!/bin/bash MEET=0 while read m do echo "$m" | grep GPRMC &> /dev/null if [ $? -ne 0 ];then continue fi hhmmss=`echo $m | cut -d, -f 2 | cut -d. -f 1` ddmmyy=`echo $m | cut -d, -f 10` hh=`echo $hhmmss | cut -b 1-2` mm=`echo $hhmmss | cut -b 3-4` ss=`echo $hhmmss | cut -b 5-6` hh=`expr $hh + 8` hh=`printf "%02d" $hh` dd=`echo $ddmmyy | cut -b 1-2` MM=`echo $ddmmyy | cut -b 3-4` yy=`echo $ddmmyy | cut -b 5-6` yy=`expr 2000 + $yy` time="${yy}-${MM}-${dd} ${hh}:${mm}:${ss}" # +8, 0930 echo $time if [ ${hh}${mm}${ss} = "093000" ];then echo "Going to set Time" date -s "${yy}-${MM}-${dd} ${hh}:${mm}:${ss}" hwclock -w fi done < /dev/ttyUSB0 |
上面的 Script 是以 GPS 時間 (GPRMC) 來當做參考時間,若是伽利略、北斗、Glonass 則會有不同的開頭,混合則會是 GNRMC。一般用 GNRMC 或 GPRMC 應該就可以取得時間。
此腳本若抓到每天 9點30分0秒的訊息,就會進行時間同步。訊息還會包含 CRC, 這邊沒有做嚴謹的檢查, 有可能會造成時間誤判。當初的想法就是訊息錯誤機會不大,若錯誤的話設定時間也可能會擋住,若真的錯的話,隔天還是會設定成正確的時間。
結語
電腦時間這個東西看似不重要,但有時又覺得很重要。透過內部架設伺服器,就可以解決這個不重要的重要事情了。