见微知著看技术误解——从裸光纤和NTPD谈起

一、裸光纤的故事

 

前几天和朋友聊天,谈到一根裸光纤可以分波分多大的问题。

 

几个业内好友都明确说一根裸光纤最多跑10G带宽,而于老板明确表示裸光纤任何一个波分(或者不做波分)都可以跑100G以上。

 

后来我和于老板深究原因,不可能几个朋友都骗我或者都蠢,很可能前些年光纤波分机自己只能甩出10G口,或运营商租光纤套餐里只有10G规格,给大家造成了裸光纤只能跑10G带宽的印象。同样固有的印象是光纤必须从运营商那里租,而且价格很贵还必须买波分设备等等;其实现在企业专线的市场竞争很充分,拉同城裸纤一公里也就小几百块钱,而且短距离裸纤也不值得上波分设备,直接对接模块即可。

 

二、NTD是试金石

 

我对裸光纤是门外汉,但同样的技术误解让我想到了NTP,我一直拿ntpd和ntpdate当做初中级系统工程师的试金石,分不清就月薪五千,分得清就八千以上(2014年市价)。但很多货真价实的IT专家也在此事上跌倒,我也希望通过聊清楚一层误会,说明高级工程师该少迷信多思考。

 

NTP是网络时间协议,它是多项传输、计算、加密技术的核心参数。

 

假设我认为TCP连接超时断开链接了,你怎么给我传输数据;

玩各种定时给奖励收益的花园经营类游戏,我经常通过修改时间快速刷分;

你的系统时间不对网银都会拒绝登陆,因为加密程序算不出双方认可的Token。

 

三、正确的时间是向量

 

Linux环境下有两个常用工具,NTPD和ntpdate。NTPD是一个时间同步服务,ntpdate是个时间同步命令。很多工程师都会采用Crond+ntpdate的方式同步时间,究其原因是“NTPD不太好用”。

 

而我不喜欢用ntpdate同步时间的工程师,NTPD是一个体系化的服务,而ntpdate只是一个动作,大部分人没做好为ntpdate这个动作负责。

 

正常的时间是个持续增长的向量,即老时间t1肯定小于新时间t2,新时间t2也小于最新的时间t3,而且t1必定会渐进增长到t2和t3。除了少数商业数据库服务自带时钟源以外,大部分业务服务对系统时间是盲目信任,不相信t1会越过t2直接达到t3(即断档跃变),而t2减去t1会得到负数或者0(即时钟停滞和回逆)。

 

四、NTPD的优势

 

如果我们用ntpdate同步时间,可能会带来时间的断档跃变或者停滞和回逆。时间不稳会威胁到的程序健壮性和业务安全性,甚至部分程序崩溃的稀里糊涂。

 

ntpdate只是个命令不是服务,它对远端时钟源是盲目信任;假设一个根NTP服务不稳定,所有的服务器获得了错误的时间,虽然现在业务层可以包容异常,不会出现算出负利息或倒扣费的情况,但业务混乱是免不了的。我们就说联机调试分布式日志,几个节点的时间有错可能日志就看不懂了。

 

NTPD服务做时间调整会有效减少这类情形,它不是简单的龟速调整时间,而是有柔性时间调整策略,让时间线的跃变和调整尽量少影响业务(详情见附录实验);也不会盲目信任远端时钟源,甚至固执的拒绝同步时间。NTPD服务相信本机时刻有可能不对,但不会忽快忽慢甚至停滞,NTPD通过多次收发包选择权威稳定的时间源,算出双方间的网络延迟,然后才会采信新的时刻进行时钟同步。

 

五、误解的根源和影响

 

因为NTPD不盲从其他时间源,让老一辈IT人会留下NTPD不好用、不靠谱的误会。2005年个人测试用虚拟机的时间经常走慢,到2010年虚拟机还要防范时间停滞的Bug。即使你用物理机投入生产,网络延迟仍然不确定,且要观测NTPD同步效果需要时间。我们很难成功调试NTPD服务,会装NTPD又没有会装LAMP可以拿去吹牛,时间长了NTPD服务就背上黑锅了。

 

真有TOP10的互联网公司和上亿国家级项目里用ntpdate+crond,上一代架构师为什么有这个误会无人深究,下一代人将误会固化为偏见,新一代人将偏见神化为迷信。

 

但无论误会、偏见还是迷信,时间跃变、回退和停滞对应用健壮性和业务安全性的威胁始终存在,时间不仅仅是我玩游戏时用的魔法,忽视问题并不能掩埋问题。

 

六、见微知著和防微杜渐

 

我讲NTPD和裸纤并不是为卖弄知识,也不是为做偏门科普,而是希望进阶工程师们多考虑一下如何规避这类误会?我们在做技术工作时,是不是只关注客户和同事能提出的需求?客户永远不知道裸纤的物理特性,同事也不会知道时间也能错误和波动,他们能说清楚业务逻辑就不错了。

 

把所有的精力都用到做业务逻辑,你只是个编程语言翻译机而已;自己主动观测技术环境依赖,有资格有能力做出技术选型决策,才是给Coder群集做技术校准的人。即使你不想做技术决策人和管理者,多怀疑和观察环境,也能少些沟通成本,少走一些冤枉路,多一份自信和自尊。

 

附录:NTPD时间跃变不遗漏Crond的实验

 

1、当前系统时间是 23点35分。

 

[root@instance-6ot6pwji ~]# date

Wed Nov 8 23:35:02 CST 2017

 

2、我故意把系统时间调整到 23点32分;注意这个时间不能和真实时间差太久,差太久了ntpd认为网络时钟源不权威,很久都不会进行时间同步。

 

[root@instance-6ot6pwji ~]# date-s 23:32:00

Wed Nov 8 23:32:00 CST 2017

 

3、做好日志打印的crond,设置每分钟打印一次时间,到第35分钟时打印一次时间:

 

注意不能时间太近,因为crond服务可能还没来得及载入新配置,ntpd服务也没完成时间校准,这些字我必须抢在2分钟内打完。

 

[root@instance-6ot6pwji ~]#crontab -l

*/1 * * * * echo"current" `date` >> /tmp/clock.log

### 上文是一个检证时间戳

35 * * * * echo "Hit time!!!" `date` >>/tmp/clock.log

### 这是一个命中测试时间戳。

 

4、用watch ntpq -p 查看ntpd对时钟源的校准状态。

 

5、如果在35分之前时钟校准完成,比如说现在时间是23点37分,则,/tmp/clock.log 里有个23点37分的时间戳。

 

[root@instance-6ot6pwji ~]# cat/tmp/clock.log

current Wed Nov 8 23:37:14 CST 2017

Hit time!!! Wed Nov 8 23:37:14 CST 2017

current Wed Nov 8 23:37:14 CST 2017

current Wed Nov 8 23:37:14 CST 2017

 

6、如果到了本地第34分(实际第38分)ntpd还没完成时间同步,因为马上和crontab里的35分打日志撞车了,可以快速修改crontab -e ,把打印hit日志的时间改为37分。中间随着时间的推迟可能多次修改hit的时间点,但不影响测试结果。

 

这次实验好玩的地方在于:

 

我定个35分的任务计划,结果ntpd将时间跃变越过了第35分直接到了37分,但该任务计划仍然执行了。而从执行输出结果是37分来看,这不是小步快跑的踩过35分,而是第35分被越过了不存在。

 

这个实验里坑很多,个人要和时间赛跑才能完成实验,我做了8次实验成功了3次,每次都等了10分钟以上。这个实验也不够严谨,我只是拿crond做实验,我在梦里记得其他有历史守规矩的程序也能和ntpd联动,但我没时间做实验了,也希望有朋友能帮我答疑解惑。

 

附录2:网上能找到一个写NTPD和ntpdate的水文和本文内容有些类似,那个是我多年以前写的,不是借鉴和抄袭,严肃脸。

收藏 评论(3)
分享到:
共3条回复 最后由筱Myselfkv 回复于2019-08-07 10:50
#2 筱Myselfkv 回复于2019-08-04

棒棒哒

0
#3 Q1058204131 回复于2019-08-05

棒棒哒

0
#4 筱Myselfkv 回复于2019-08-07

棒棒哒

0