引入:java
時鐘同步一直是一個比較熱的話題。由於它涉及到許多具體場景。web
場景A: 2個系統作交易,A系統下訂單,B系統管理訂單。結果由於B系統比A慢5分鐘,A下單完了,B得到的時間竟然是一個將來的時間。服務器
場景B: 搞雙十一了,某公司的網上電子商城須要在11月11北京時間凌晨0點啓用應急預案,而後啓用強大的促銷規則。結果由於時鐘比北京時間慢了10分鐘。等11月11零點,大量搶購的人一會兒擁入網上電子商城,形成該公司訪問量的「井噴」式的增加,可是由於服務器還在11月10日晚上23:50,因此沒有啓用應急預案,也沒有使用促銷規則。結果服務器掛了,客戶跑了。。。app
解決方案:ide
以上就是目前一些很是典型的時鐘不一樣步的例子:工具
對於場景A,通常作法是吧某臺服務器做爲中央時鐘服務器,讓其做爲標準的時鐘服務器。而後確保全部服務器均可以訪問此中央時鐘服務器,而且依次在每臺須要時鐘同步的機器上運行命令 ntpupdate <時鐘服務器IP>便可。測試
可是場景A有一個致命缺陷就是全部的服務器都必須能鏈接到時鐘服務器。這對於大型企業有多個區段劃分,彼此多個網段,網段之間相互又不通的狀況,沒法解決。那麼在聯網的狀況下,這裏有一個變通的輕量級的方法,可讓全部服務器(尤爲是服務器上運行着代碼的地方),和北京時間同步,這種解決方案也許更加適合場景B。ui
這裏我寫了一個工具類,它能夠有效的和北京時間同步,代碼以下:url
package com.charles.study; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; /** * 這個工具類用於得到標準的北京時間 * @author charles.wang(mailto:charles_wang888@126.com) * */ public class BeijingDateTimeUtil { private BeijingDateTimeUtil(){} public static final String BEIJING_TIME_SERVICE_URL="http://www.beijing-time.org/time.asp"; public static final String BEIJING_TIME_ZONE = "GMT+8"; /** * retrieve the standard beijing time by beijing time service * @return Calendar which stands for current beijing time */ public static Calendar retrieveBeijingStandardDatetime() { try{ //access the webpage which can provide precise beijing-time URL url = new URL(BEIJING_TIME_SERVICE_URL); HttpURLConnection uc = (HttpURLConnection) url.openConnection(); uc.connect(); StringBuilder sb = new StringBuilder(); BufferedReader br = new BufferedReader(new InputStreamReader(uc.getInputStream())); String line; while ((line = br.readLine()) != null) { sb.append(line); } String beijingTimeInfoString = sb.toString(); String[] infos = beijingTimeInfoString.split(";"); //split information which can stand for year/month/day/dayOfWeek/hour/minute/second int year = Integer.parseInt(infos[1].substring(infos[1].indexOf("=")+1)); int month = Integer.parseInt(infos[2].substring(infos[2].indexOf("=")+1)); int day = Integer.parseInt(infos[3].substring(infos[3].indexOf("=")+1)); int dayOfWeek = Integer.parseInt(infos[4].substring(infos[4].indexOf("=")+1)); int hour = Integer.parseInt(infos[5].substring(infos[5].indexOf("=")+1)); int minute = Integer.parseInt(infos[6].substring(infos[6].indexOf("=")+1)); int second = Integer.parseInt(infos[7].substring(infos[7].indexOf("=")+1)); //create a calendar object //make sure that (1)using Beijing timezone // (2)month starts from 0 instead of 1 Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(BEIJING_TIME_ZONE)); cal.set(year,month-1,day,hour,minute,second); return cal; }catch(MalformedURLException ex){ ex.printStackTrace(); return null; }catch(IOException ex){ ex.printStackTrace(); return null; } } public static void main(String [] args) { Calendar beijingCalendar = retrieveBeijingStandardDatetime(); if(beijingCalendar!=null){ Date beijingDatetime = beijingCalendar.getTime(); DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z"); String dateFormatStr = df.format(beijingDatetime); System.out.println("Beijing Current Datetime:"+dateFormatStr); }else{ System.out.println("BeijingTime service not available"); } } }
執行示例代碼中的測試,咱們能夠看到:.net
這裏也能夠看出,個人筆記本時間比北京時間快9秒。