美文网首页
【Vesta发号器源码】SimpleTimer

【Vesta发号器源码】SimpleTimer

作者: DeanChangDM | 来源:发表于2019-05-13 14:14 被阅读0次

    Vesta发号器源码解析——SimpleTimer

    这个类是Timer的一个简单的实现,主要负责对时间控制

    字段及属性

        //日志
        protected static final Logger log = LoggerFactory.getLogger(SimpleTimer.class);
        //Id元数据
        protected IdMeta idMeta;
        //Id的类型
        protected IdType idType;
        //最大时间
        protected long maxTime;
        //时间压缩的基础,相当于新的时间起点
        protected long epoch = EPOCH
    

    初始化方法

    初始化方法

        public void init(IdMeta idMeta, IdType idType) {
            this.idMeta = idMeta;
            //利用移位操作计算出时间的长度能够标示的最大时间
            this.maxTime = (1L << idMeta.getTimeBits()) - 1;
            this.idType = idType;
            this.genTime();
            this.timerUsedLog();
        }
    

    timer的使用日志

    记录出能够使用的天数

        public void timerUsedLog(){
            //最大的时间计算
            Date expirationDate = transTime(maxTime);
            //计算出最大的值所能标示的具体时间
            long days = ((expirationDate.getTime() - System.currentTimeMillis())/(1000 * 60 * 60 * 24));
            //记录日志
            log.info("The current time bit length is {}, the expiration date is {}, this can be used for {} days.",
                    idMeta.getTimeBits(), expirationDate, days);
        }
    

    设置时间压缩基础

        //设置epoch
        public void setEpoch(long epoch) {
            this.epoch = epoch;
        }
    

    时间转换函数

    时间转换函数,将压缩后的时间戳转换为date对象

        public Date transTime(long time) {
            //做好类型区分,区别到底按照毫秒级计算还是秒级
            if (idType == IdType.MILLISECONDS) {
                return new Date(time + epoch);
            } else {
                return new Date(time * 1000 + epoch);
            }
        }
    
    

    验证时间戳

    校验时间的先后顺序

        public void validateTimestamp(long lastTimestamp, long timestamp) {
            //发生了时钟回拨
            if (timestamp < lastTimestamp) {
                if (log.isErrorEnabled())
                    //记录日志,时钟回拨了,拒绝生成id,抛出异常
                    log.error(String
                            .format("Clock moved backwards.  Refusing to generate id for %d second/milisecond.",
                                    lastTimestamp - timestamp));
    
                throw new IllegalStateException(
                        String.format(
                                "Clock moved backwards.  Refusing to generate id for %d second/milisecond.",
                                lastTimestamp - timestamp));
            }
        }
    

    时间等待

    用于在发生次数满了的时候进行时间的等待,等待到了下一个时间周期来的时候返回新的时间戳

        public long tillNextTimeUnit(final long lastTimestamp) {
            //记录日志
            if (log.isInfoEnabled())
                log.info(String
                        .format("Ids are used out during %d. Waiting till next second/milisencond.",
                                lastTimestamp));
            //生成新的时间戳
            long timestamp = genTime();
            //新的时间戳如果没有比之前的大,说明仍然处于老时间
            //自旋锁等待
            while (timestamp <= lastTimestamp) {
                timestamp = genTime();
            }
            
            //时间更新,记录日志
            if (log.isInfoEnabled())
                log.info(String.format("Next second/milisencond %d is up.",
                        timestamp));
            //返回新的时间戳
            return timestamp;
        }
    

    生成时间

    生成压缩后的时间戳,也就是利用最新的时间减去压缩基础

        public long genTime() {
            long time;
            //按类型做好区分
            if (idType == IdType.MILLISECONDS) {
                time = (System.currentTimeMillis() - epoch);
            } else {
                time = (System.currentTimeMillis() - epoch) / 1000;
            }
            //校验生成的时间戳是否有效,主要是看是够超超时
            validateTimestamp(time);
            return time;
        }
    

    时间戳校验

    校验时间戳是否已经超过了最大的生成时间

    
        protected void validateTimestamp(long timestamp){
            if (timestamp > maxTime) {
                String error = String.format(
                        "The current timestamp (%s >= %s) has overflowed, Vesta Service will be terminate.", timestamp, maxTime);
                log.error(error);
                throw new RuntimeException(error);
            }
        }
    

    相关文章

      网友评论

          本文标题:【Vesta发号器源码】SimpleTimer

          本文链接:https://www.haomeiwen.com/subject/zbblaqtx.html