昨天亲手挖了一个关于时间的坑,今天大部分时间用于填坑。不完全排除在填坑的同时又挖了一些新坑。
起源是服务端给客户端以时间戳的形式返回服务器的当前时间。时间戳理论上在全世界同一时间获取都是一致的。
注意时间戳的获取方式,以java为例:
用new Date().getTime()获取的时间戳是在当前时区下的时间戳,在不同时区下用new Date()的方式获取到的时间戳是不一致的。
以下说明同一时间戳在不同时区下代表的不同时间:
Date now=new Date();
System.out.println("now:"+now.getTime());
SimpleDateFormat df= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
df.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
System.out.println(df.format(now));
df.setTimeZone(TimeZone.getTimeZone("Greenwich"));
System.out.println(df.format(now));
输出:
now:1557409561045
2019-05-09 21:46:01
2019-05-09 13:46:01
这样获取的时间戳是一致的:
ZoneId.getAvailableZoneIds().forEach(zoneStr->{
ZoneId zone=ZoneId.of(zoneStr);
LocalDateTime localDateTime = LocalDateTime.now(zone);
Instant instant = localDateTime.atZone(zone).toInstant();
Date date=Date.from(instant);
System.out.println(date.getTime()+" "+df.format(date)+" "+"zoneStr:"+zoneStr);
});
输出(部分,此处不一致为执行代码的正常误差):
1557409561190 2019-05-09 13:46:01 zoneStr:America/Resolute
1557409561190 2019-05-09 13:46:01 zoneStr:Pacific/Tarawa
1557409561190 2019-05-09 13:46:01 zoneStr:Africa/Kampala
1557409561190 2019-05-09 13:46:01 zoneStr:Asia/Krasnoyarsk
1557409561190 2019-05-09 13:46:01 zoneStr:Greenwich
...
1557409561168 2019-05-09 13:46:01 zoneStr:Asia/Shanghai
1557409561168 2019-05-09 13:46:01 zoneStr:Universal
1557409561168 2019-05-09 13:46:01 zoneStr:Europe/Zagreb
这次的坑在这里
LocalDateTime localDateTime = LocalDateTime.now();
//以为这样获取instant对象对应的时间戳是一致的,以为这里可以获取正确的时间戳所以
//在上线的时候只验证Asia/Shanghai时区,其他时区没有完全验证,或者说当时就没有意识到还存在时区的问题
Instant instant = localDateTime.atZone(zone).toInstant();
//然后人家其实是在这里
LocalDateTime localDateTime = LocalDateTime.now(zone);
图片来自:https://www.jianshu.com/p/f45d435d244a
好了,挖坑的原因就是这样,下面胡乱"敢想"一下。
1、挖坑容易填坑难
举个简单例子把碗打碎很容易,再还原回去....
2、关于数据备份之知易行难
今天另外一个坑是想备份全量数据,结果是备份了部分数据(属于操作失误,但是在意识上认为是已全量备份了),导致部分现场丢失。
很怀念pl/sql,手动提交很重要。自动提交下一秒可能就是一个悲剧。重要的操作尽量结对编程,两个人都要参与。小黄鸭模式在这里不好使。
建议重要的db操作调整成手动提交模式。
3、软件的复杂度
常规复杂度: 业务自身复杂度(业务不负责用投入大量资源开发软件吗)、高性能(做过高并发的都知道这份酸爽)、高可用(本质是冗余,意味着要处理冗余带来的一致性等新的问题)、可扩展性、成本安全和规模等。
人员复杂度:目前软件系统需要多个角色的工程师共同协作,每个人有不同的背景和视角,意味着同一个软件系统再不同角色的眼中是不一致的,这种现象是正常不能可能所有人的视角都一致,所以需要在不一致带来的混沌条件下,达成相关方需要的"一致性"结果。
前提假设的关系:各个都在合理前提下能工作的假设搭配在一起可能就不工作了。这种复杂度存在的可能性和沟通渠道是一样多的,n(n-1)/2了解一下。
流程:流程是把双刃剑,在可能保证结果的同时也带来了各种成本,但是还是要遵守裁剪过流程,毕竟这是一个契约型的社会。
另外一篇: