在21年前世纪之交,全球的计算机系统和互联网曾经出过一个重大事件:千年虫。

当时的计算机系统处理年份的方式都是两位数(如1998年会被系统缩略成98),而2000年在老系统里仍然以00显示,则会被系统当成1900年。

然而谁都没想到的是,就在前几天,”千年虫“又重演了……

| 发生了什么?

首先,幸运的是,这次的事故规模,并没有千年虫那次那么大。目前已知受到影响的,只有采用了微软 Exchange Server2016 和2019 版本的企业本地邮件服务器。

因为全球很多企业内部的电子邮件,采用的都是自主搭建的系统(而非基于 Gmail、网易、阿里云等云端邮件的方案),而微软的 Exchange 服务器 (Microsoft Exchange Server) 则是很多企业用户都在用的本地邮件系统。

然而在2021年12月31日——去年的最后一天,在 IT 人员都已经放假的时候,微软突然推送了一个全新的 Exchange Server 版本,直接把所有企业客户的电子邮件系统都给搞宕机了,大量邮件积压在发送序列当中,却无法正常发送和接收。

错误代码大概是下面这样的:

Log Name: Application

Source: FIPFS

Logged: 1/1/2022 1:03:42 AM

Event ID: 5300

Level: Error

Computer: server1.contoso.com

Description: The FIP-FS "Microsoft" Scan Engine failed to load. PID: 23092, Error Code: 0x80004005. Error Description: Can't convert "2201010001" to long.

一夜之间,大量的 IT 人员在 Reddit 和微软官方技术社区上大倒苦水。

“这玩意儿是怎么发布出来的?而且还是在新年夜???”

“电话都被打爆了。微软你弄啥嘞?”

问题,出在微软推送的这次更新的版本号上。

这次的更新,里面包含的电子邮件恶意软件扫描引擎的版本号是2201010001,表示的是202201010001分。

微软的产品和系统在表示时间的时候,用的都是这种符号整数。然而,根据微软自己的开发文档,其系统能够接受的 Int32 符号整数的最大值是 2147483647。

这个最大值的前两位是21

也就是说,采用这种整数方式来记录和表示时间,只能够正常覆盖到2021年的最后一秒。

所以,当微软推送出这个 2201010001 版本的时候,版本数字超过了系统能够接受的整数最大值,结果就直接把 Exchange Server 邮件系统给搞崩溃了……

目前,微软方面已经提供了修复此问题的方法,可以执行 PowerShell 脚本来自动修复,也可以用手动方法修复。修复必须在所有被波及的 Exchange Server 2016 或 2019版本服务器上执行。

很多被影响到的公司 IT,在修复过程中也遇到了各种各样的问题。总的来说,这次微软送的这个新年大礼包,让大家整个新年都没过好……

在微软官方技术论坛上,一位用户发出了灵魂拷问:谁会在12月31日推送生产环境更新啊?

| 千年虫重演,原因依然很蠢

这次微软邮件服务器的 bug,以及其它公司/产品发生的类似的日期时间处理错误,一起被命名为Y2K22(也即 Year 2022 的缩写)。

为什么这样命名?正是因为,导致这些 bug 出现的问题,和21年前的千年虫 (Y2K bug),几乎一模一样。

文章开始提到,千年虫的出现,是因为当时一些相对比较古老的计算机系统,在处理年份的时候会采用两位数简写。

当时的普通人压根想不到,新千年的到来会让计算机系统出故障——唯一有可能预知这种情况发生的,也就只有程序员了。

而当千年虫事件即将发生的时候,那些已经投入使用十年甚至20年的系统,背后的 COBOL 程序员(大多已经或者快要退休了),又被请出山来修复他们当年“埋”下的这些漏洞……

在当时,有两种修复的思路:

1)全盘重写所有系统的代码,称为“expansion”;

2)打个快速的补丁,让计算机能够将从00到20的数字,正确识别为2000年到2020年——这种方式也被称为“windowing”.

具体来说,这个补丁让计算机系统将1970年1月1日0时0秒(也即程序员都非常熟悉的 Unix 时间戳)作为百年“时间窗口”的中间点,也即从1920年到2020年的任何一个时间点,在计算机系统里都可采用其到 Unix 时间戳的距离作为表示方法。

“高性能计算机新闻网”的一篇发布于1999年的报道显示,在当时,大约有八成的系统最后都是用第二种快速补丁的方式修复的。相比一劳永逸的全盘重写,快速补丁的方式的成本优势非常明显,然而即便如此,全世界的预估修复成本加起来也高达3000亿美元……

当面临一个足够大的问题的时候,相信一般人的正常反应,都是“这个问题迟早得彻底解决”,并且也会倾向于一劳永逸地解决问题。

然而在当时,人们没有选择一劳永逸,而是选择了打补丁,还有另一层考虑,也即:这些系统已经足够老了,在未来的20年里总是要还的,所以没必要一劳永逸的重写了,反正到时候换新系统的时候,把日期时间的问题搞好,不就行了。

对此,伦敦经济学院的 Dylan Mulvin 教授表示,“Windowing 即使在当时也是所有可选方案中最差的一个,它就是把皮球踢给后人的做法。

果不其然,当新系统替代旧系统的时候,当年的编程思路,仍然被继承了下来了……

事实上,到了2020年的时候,一些千年虫修复过的系统,以及新安装的系统,都又一次出现了和千年虫几乎一样的问题:Y2K20 bug.

比如,在当时有些用户惊讶地发现,他们从宽带公司收到的账单显示日期为1920年:

游戏公司 2K 开发的摔角游戏《WWE 2K20》,也在游戏标题里这一年的第一天的第一秒就宕机了:

当时纽约市的很多停车自动缴费机,也因为系统时间错误而触发了防火墙机制,无法接受信用卡支付:

结果你猜怎么着?这些故障,很快就被修复了。

至于他们采用了哪种思路——是一劳永逸,还是快速补丁——你应该也能猜出来了……

如果说人类一定有什么做不到的话,那一定是从历史中吸取教训。

紧接着,Y2K21 bug 又来了。比如,去年美国气象局 (NWS) 的官方数据库出现了重大误差,对外提供的接口的数据晚了足足一天,导致很多第三方机构的天气数据都出现了错误,影响了民航、海洋捕捞、畜牧养殖等诸多行业的正常运作。

也有一些普通用户发现,自己的电脑梦回1921年了:

再然后,2021年也翻篇了,Y2K22 bug 也毫无悬念地按时来到了……

除了这次微软 Exchange Server 出了故障之外,一些本田车主也发现,他们的车每天早上启动都会把时间自动跳回到2002年。

汽车专业人士调查分析发现,本田车载系统的问题原因和微软一样,都是出在 Int32 整数上,开头22的字符串无法被读取,在本田这里就变成时间回退到2002年了……从2004到2012年的上百款车型都有较高几率遇到此问题。

在公开场合,本田公司发言人表示,目前还在调查这个问题的具体原因。不过有车友在论坛上发帖表示,本田公司派人联系他们,说这个问题会在今年8月份自行消除……

在可见的未来,Y2K23, 24, 25...各种各样的问题还会陆续发生。

并且,已经在各种计算机系统中广泛采用的 Unix 时间戳,还会在32位系统中导致一个问题,使得某些软件在2038年1月19日3时14分07秒后无法工作:

对于”2038年问题“,整个行业(特别是硬件寿命极长的嵌入式行业)的应对方式,和21年前如出一辙:反正到了2038年的时候,应该新系统又换了一茬了吧,到时候再说吧……

看来,大家根本不想彻底解决”千年虫“以及其衍生问题。

可这又是为什么?

| “一劳永逸”,不如多劳多得?

对于千年虫这样反复出现的情况,有人开玩笑说是程序员埋的坑

至少在千年虫肆虐的时候,那些 COBOL 老古董程序员被请出山来修复问题的时候,就有人质疑:他们是不是当年故意给我们埋的坑啊?

这种想法有它的道理:程序员的职业生涯是有限的,不是所有人都能升到高管。那么那些平庸的程序员,如何保证在自己临到退休的时候还能够被需要?

埋个只有自己才懂得怎么修的漏洞,也没什么毛病?20年一个周期,正好覆盖从大学毕业到中年不惑……

当然,实际上,在具体操作中,大多数运作计算机系统的公司,在事故发生的时候,也一定会更倾向于选择速度快、见效快、成本低的修复方式。

所以,程序员也不是什么阴谋家,因为他们不是决策者——他们只是在正确的时间,执行了对大家都合适的解决方案而已。

来源:品玩

照这样下去,“千年虫”还得再来十遍相关推荐

  1. [强文]有几个还活着?十年应用软件之路

    转贴自:http://www.cnbeta.com/articles/67188.htm ugmbbc发布于 2008-10-16 08:35:02|<script src="http ...

  2. 左手代码,右手带娃,还能发十几篇 paper,程序员女神是如何炼成的?

    作者 | 李磊       责编 | 欧阳姝黎 出品 | CSDN(ID:CSDNnews) 一道简单的数学题:如果程序员中男女比例是 9:1,普通程序员与优秀程序员的比例也是 9:1,那么一位优秀的 ...

  3. 身为程序员——你还不知道这十几个网站?

    写在前面 这篇文章主要来介绍一下,我学习编程的时候,经常访问的几个网站,如果觉得不错,建议收藏! 哔哩哔哩 哔哩哔哩可以说是让我入坑了Java编程,很多人都说学习不要看视频,说实话,我当时也尝试了不看 ...

  4. 重磅盘点!2018年更受欢迎的技术干货,来来回回也就看了几十遍吧

    导读:年终岁末,相信大家看过了各类回顾和展望.在这一年里,有些关键词是绕不开的,比如上半年超级火爆,下半年又凉凉的区块链:比如鼓吹声.唱衰声和理性的反思并存的AI:还有继续发展同时也持续暴出隐私安全等 ...

  5. 排列组合 “n个球放入m个盒子“里,再来一遍

    1.球同,盒不同,无空箱 C(n-1,m-1), n>=m 0, n<m 使用插板法:n个球中间有n-1个间隙,现在要分成m个盒子,而且不能有空箱子,所以只要在n-1个间隙选出m-1个间隙 ...

  6. Spring boot再来一遍

    spring-boot-starter-parent 作为spring boot快速构建spring工程所依赖包的模板 spring-boot-starter-parent的继承了spring-b b ...

  7. 勇敢猿猿不怕困难!为去大厂我把这个Java大厂面试真题刷了几十遍!(2021最新版)

    BAJT等互联网公司的高薪和福利吸引了很多工程师的加入,面试难度也水涨船高,一线互联网公司面试有哪些特点,如何更好的准备互联网公司的面试?本篇文章就针对一线大厂后端面试,从方法论到实战,帮你梳理一个J ...

  8. unity3d 重要类+方法 。。。再来一遍吧。。。

      static var matrix : Matrix4x4 描述:设置用于渲染所有gizmos的矩阵. 类方法 ◆ Static function DrawCube(center:Vector3, ...

  9. 只做macd二次金叉_一位金牌操盘手分享:MACD二次金叉实战心得,值得仔细读上十遍!...

    运用分时图的环境多数是震荡行情或者是弱势行情,牛市很少会看分时图来买卖股票,更多的是看日线抓大机会. 弱势行情看分时,一般会选择在午后,早盘变动大,而且可以利用早盘表现来确认操作安全性.如果早盘股价一 ...

最新文章

  1. unity 骨骼击碎_保证击碎$ 100挑战的创新策略
  2. 使用Canvas进行验证码识别
  3. 伤疤好了有黑印怎么办_搞笑gif动态图片:“发现相亲对象的闺蜜更有实力,我后悔了”哈哈哈好一个见色起意...
  4. 【前端】JSON.stringfy 和 JSON.parse(待续)
  5. java函数求方程,Commons Math学习笔记——函数方程求解
  6. Jetson Nano 改成国内源(中科大源)
  7. Linux游戏0 A.D.操作说明(持续更新中)
  8. gdb ldexp_带有Python示例的math.ldexp()方法
  9. 贝叶斯分层回归模型的推理、EM求解和Java编程
  10. 查找算法(一)顺序查找
  11. 【NLP新闻-2013.06.16】Representative Reviewing
  12. Mysql中eft join、right join、inner join的区别
  13. oracle 11g rac进程起停
  14. 【vuejs】有关UI框架“ydui”中的倒计时组件的使用
  15. SNMP原理和MIB库
  16. 【导数术】10.导数数列不等式
  17. Matlab中text函数在图像中固定位置添加信息的用法
  18. 为构建大型复杂系统而生的微服务框架 Erda Infra
  19. 永磁体磁偏角测试原理和测量设备介绍
  20. 2019年电赛准备程序STM32版本

热门文章

  1. 新书推荐 |《用户增长方法论:找到产品长盛不衰的增长曲线》
  2. (原创)使用AsyncTask(带修改线程池方式)+自定义ImageLoader+LRU算法对图片三级缓存及其显示优化(只有在ListView滑动停止的时候才去网络请求获取图片数据)
  3. IP地址192.168.48.10,掩码为255 255.255.128,其所在的子网为(),广播地址为),有效的主机IP地址范围从()到().
  4. 聊天室程序python_Python聊天室程序(基础版)_python
  5. 加餐0 | 前后端快速入门学习路线
  6. ZZULIOJ:1023大小写转换
  7. 对当前两种热门软件创新性分析
  8. 金蝶 EAS 编码规则 新增显示且不允许断号
  9. bug记录--------JSON parse error:Cannot deserialize value of type `com.test.EnumTest` from String
  10. VMware虚拟机实现局域网互通