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

引入:

时钟同步一直是一个比较热的话题。因为它涉及到许多具体场景。

场景A: 2个系统做交易,A系统下订单,B系统管理订单。结果因为B系统比A慢5分钟,A下单完了,B获得的时间居然是一个未来的时间。

场景B: 搞双十一了,某公司的网上电子商城需要在11月11北京时间凌晨0点启用应急预案,然后启用强大的促销规则。结果因为时钟比北京时间慢了10分钟。等11月11零点,大量抢购的人一下子拥入网上电子商城,造成该公司访问量的“井喷”式的增长,但是因为服务器还在11月10日晚上23:50,所以没有启用应急预案,也没有使用促销规则。结果服务器挂了,客户跑了。。。

解决方案:

以上就是目前一些非常典型的时钟不同步的例子:

对于场景A,一般做法是吧某台服务器作为中央时钟服务器,让其作为标准的时钟服务器。然后确保所有服务器都可以访问此中央时钟服务器,并且依次在每台需要时钟同步的机器上运行命令 ntpupdate <时钟服务器IP>即可。

但是场景A有一个致命缺陷就是所有的服务器都必须能连接到时钟服务器。这对于大型企业有多个区段划分,彼此多个网段,网段之间相互又不通的情况,无法解决。那么在联网的情况下,这里有一个变通的轻量级的方法,可以让所有服务器(尤其是服务器上运行着代码的地方),和北京时间同步,这种解决方案也许更加适合场景B。

这里我写了一个工具类,它可以有效的和北京时间同步,代码如下:

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:[email protected])
 *
 */
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");
        }    
        
    }

}

执行示例代码中的测试,我们可以看到:

这里也可以看出,我的笔记本时间比北京时间快9秒。

时间: 2024-08-10 23:30:36

时钟同步和时钟修正的小技巧的相关文章

[每天一个Linux小技巧] 查看时钟源精度

$ dmesg | grep clock [0.000000] OMAP clocksource: GPTIMER1 at 24000000 Hz [0.000000] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 178956ms 这里的精度是41ns [每天一个Linux小技巧] 查看时钟源精度

分布式系统----时钟同步

一.问题产生 时间是一个绝对量,而实体计算机的时间是相对量 1.  物理天地本身导致的时间不一致,地球自传.闰年.闰秒 2.  现实的不能绝对一致性,A机器时间同步至B机器,网络传输时间是不确定性的,AB存在绝对不一致性 如上图,computer A在2144  Tick点执行分布式任务 create output.o,注意2144是A的绝对计算量.而此时的集群computer B也许出于2143Tick点,即使B也运气恰到好处的出于2144tick,A任务同步至B消耗的tick是不确定的.获取

(3)I2C总线的字节格式,时钟同步和仲裁

字节格式 发送到SDA线上的每个字节必须是8位.每次传输的字节数量是不受限制的.每个字节后必须跟着一个ACK应答位.数据从最高有效位(MSB)开始传输.如果从机要执行一些功能后才能接收或者发送新的完整数据,比如说服务一个内部中断,那么它可以将时钟线SCL拉低来强制使主机进入wait状态.当从机准备好新的字节数据传输时,释放时钟线SCL,数据传输便继续进行. ACK和NACK 每个字节后都有ACK发生.ACK应答位允许接收器通知发送器字节成功接收了下一个字节可以发送了.主机产生所有的时钟脉冲,包括

LED时钟|语音同步LED时钟农历计算代码(立显光电)

LED时钟|语音同步LED时钟农历计算代码由深圳市立显光电有限公司技术部提供,欢迎指正,谢谢! void Lunar_Calculation(void){ unsigned char  temp1,temp2,temp3,month_p;    unsigned int temp4,table_addr; unsigned char flag2,flag_y; unsigned char year=time_buf[1];//阳历年 unsigned char month=time_buf[2]

记一次蛋疼的 时钟同步问题

公司部署了三台虚拟机用来跑CDH的套件,不过一次重启后突然CDH就起不来了.查看zookeeper的日志文件,就是 connection refused,感觉很莫明. 后来查看了 slave2的日志发现了: The host's NTP service was not synchronized to any remote server. 竟然是时钟同步问题! 运行: [[email protected] log]# service ntpd stop [[email protected] log

buildroot ntp 网络时钟同步

/********************************************************************** * buildroot ntp 网络时钟同步 * 说明: * 文件系统需要网络时钟同步,于是使用ntp来做这件事情. * * 2016-12-1 深圳 南山平山村 曾剑锋 *********************************************************************/ 一.buildroot配置: 1. 时区:

安装和配置CentOS时钟同步服务

Type the following command to install ntp: # yum install -y ntp Turn on service: # chkconfig ntpd on Synchronize the system clock with 0.pool.ntp.org server: # ntpdate pool.ntp.org Start the NTP: # /etc/init.d/ntpd start 安装和配置CentOS时钟同步服务

ntpd时钟同步服务

原网址:http://blog.csdn.net/wzyzzu/article/details/46515129 ntpd时钟同步服务 目录 参考: CentOS配置时间同步NTP: http://www.crsay.com/wiki/wiki.php/server/centos/ntp-set 解决ntp的错误 no server suitable for synchronization found:http://www.blogjava.net/spray/archive/2008/07/1

两台都不能上公网的Ubuntu如何进行时钟同步

在安装OpenStack过程中,先安装了控制节点,并安装(sudo apt-get install ntp)启动了ntp服务,同时配置sudo vi /etc/nova/nova.conf,增加如下内容实现以本地时钟为准: 当安装了计算节点后,计算节点如何与控制进行时钟同步,走了如下弯路,最后算是搞定了吧. 起先认为:计算节点最好不要安装ntp服务了,否则可能会出现与控制节点时钟不同步的情况,不同步会导致各种奇怪的问题.但如果安装了,可以用如下命令永久停止ntp服务: sudo update-r