时钟同步和时钟修正的小技巧

引入: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

wKiom1R7PUPCNP18AAD9EzDMsio971.jpg

这里也能够看出,个人笔记本时间比北京时间快9秒。

相关文章
相关标签/搜索