西门子冰箱报警器一直响不制冷(西门子冰箱报警不制冷怎么解决)

西门子冰箱报警器一直响不制冷(西门子冰箱报警不制冷怎么解决)

首页家电维修冰箱更新时间:2022-03-06 12:39:12

【编者按】新婚现场给服务器扩容,下班路上修Bug……对于程序员来说,这样的日常并不陌生。在新年第一天,国外一名叫Ali Josie 的软件工程师、信息安全爱好者就经历了找Bug、复现、修复这样的事情,并且还发表了一篇《This Is Why Our 3000 Apache Servers Went Down On The First Day of 2022》,具体是怎么一回事呢?

作者 |Ali Josie 译者 | 弯月

出品 | CSDN(ID:CSDNnews)

新年第一天,又恰逢周六,早上醒来却看到一堆整个基础设施挂掉的警报!我的一位同事就遭遇了这样的真实,他当时的心情可想而知。

大清早

首先,最重要的是恢复服务,把服务宕机的影响降到最低,我们重启了所有Apache服务器,还好没有任何问题。接下来就要找出宕机的原因了。为什么所有服务器都在新年第一天宕机?这肯定不是偶然吧?

我们看到每台服务器上都记录了如下日志:

AH00171: Graceful restart requested, doing restartlibgomp: could not create thread pool destructor.

libgomp是什么?我们先上网查了一下这个错误。ServerFault上有人问过这个问题,但没人回答,至少没有我们能用的东西。不过这个问题有点奇怪,因为提问者说他的服务器每隔24~36小时就会发生一次。

思考

回到错误本身。我们每天早上都会做一次日志轮转,这样每天都用新的日志。因此要重启服务器。似乎Apache已经成功重启,但由于libgomp错误又宕机了。

在网上搜索到的大量结果中寻找答案无异于大海捞针,于是我们开始阅读libgomp的源代码,看看究竟发生了什么。首先,libgomp是什么?根据其主页的描述:

所以它是OpenMP的实现。它怎么会出问题?

搜索了一下源代码, 我们发现错误消息的唯一出处是这里:

所以显然,它在试图创建一个线程键,但出错了。检查PTHREAD_key_create的手册:

有意思!那返回值是什么?

“pthread_key_create函数会在下述情况失败:

然后检查了代码,看看发生了什么,以及PTHREAD_KEYS_MAX最大值是多少:

所以说,key只是一个0~1024之间(不含1024)的数字,赋给pthread_key_create的调用者。这些键由一个简单的CAS负责赋值,因此肯定有某个地方释放这些键。似乎我们找到了问题。我们只需要增大PTHREAD_KEYS_MAX。但是,这个值是常量。我们甚至找到了一个帖子,要求增加PTHREAD_KEYS_MAX:

这篇帖子描述的问题域我们相似,因此我们的假设可能是正确的。但是我们依然没办法增大这个值。

我们开始调查为何重新加载Apache会进入libgomp的这段代码。所以显然,重载Apache会导致mod_php调用一个名为Imagick的模块。Imagick是什么?它是一个使用ImageMagick库来创建和修改图片的PHP扩展。

怀疑

似乎关闭Imagick就可以避免使用libgomp,这样就不会遇到最大线程数的问题了。而且只需要设置一个环境变量即可。似乎这个方案非常安全,但我们依然有一个最大的疑问:

这样解决问题显然不能让我们满意。还有好多未解之谜。我们开始进一步阅读Apache HTTP的和libgomp的代码,但似乎一切都很正常,至少我们没发现任何问题。问题也无法重现,很快这个问题就会变成未解之谜。我们搜索了许多无关的关键字,甚至找到了一些关于“2038年问题”的帖子。

但这些都没有任何帮助。我们甚至怀疑过Apache的最大uptime。

最后我们检查了Imagick的更新日志,发现了这个:

“多个修改来减少GOMP段错误的发生,包括:

这符合我们的猜测:将Imagick的最大线程数设置为1就能解决问题。但并没有解答有关时间的最大疑问。

灵光乍现

在搜索了更多奇怪的东西后,我们想看看一月份有没有人遇到这个问题。

第一篇文章正是解开这一切的钥匙!

突然想到……要是线程键从来没有被释放,会怎样?有可能吗?因为从部署依赖就从来没有发生过这个问题……所以我们重新计算了一下,1024个键,如果每天早上重新加载,就需要两年零10个月才会超过1024次重新加载。如果过去1024天内每天早上都分配一个线程键,而这个键从未被释放的话……

终于看到了一丝曙光。我们终于找到了重现该问题的方法。我们做了一个测试环境,用同样的服务器配置,然后简单地运行这个脚本。

for i in seq{1..1100}; do sudo systemctl reload apache2;done

重新加载apache2 1100次(多了76次作为冗余)。然后果然问题出现了!

Apache在重新加载了1024次以后,libgomp就报错了。现在所有问题都得到了解答。

来看看能否通过增加环境变量MAGICK_THREAD_LIMIT(新版Imagick是OMP_THREAD_LIMIT)。很不幸,问题依旧。所以下一步就是更新Imagick版本到一个修正了该问题的版本(v3.5.0 )。很幸运,更新之后重新加载数千次都不会出问题。

检查

还有个未解决的问题:新版Imagick有没有删除这个键?为了解答这个疑问,我们使用了一个工具:ltrace这个工具可以截获并记录程序运行的特定命令。我们首先在旧版本的Imagick(v.3.4.4)的服务器上运行ltrace:

ltrace -xpthread_key_*@libpthread.so.0 -L -c /usr/sbin/apache2 -k graceful

-x是特定库中的函数的搜索字符串,此处为 libpthrad.so.0中的 pthrad_key_create 和 pthread_key_delete。

-L告诉ltrace忽略默认的过滤器,以降低噪声。

-c会在末尾汇总所有结果。而 /usr/sbin/apache2 -k graceful相当于systemctlreload apache。

结果并没有出乎意料:

% time seconds usecs/call calls function------ ----------- ----------- -----------------------------100.00 0.000157 157 1 pthread_key_create------ ----------- ----------- -----------------------------100.00 0.000157 1total

3.4.4版只调用了pthread_key_create而没有删除!

然后在新版(v3.6.0)上运行同样的命令:

% time seconds usecs/call calls function------ ----------- ----------- ------------------------------------ ----------- ----------- ------------------------------100.00 0.000000 0 total

看来,新版都没有使用多线程,因此完全没有创建键。

总结

终于解决了,但是为什么这么长时间都没有重启过?我们决定不再在这个问题上浪费时间了,因为“如果排除一切不可能的选项,那么剩下来的那个无论多么不可思议,都是真相。”

解决这个问题后感觉挺奇怪。虽然解决问题感觉挺自豪,但世界上还有很多长时间运行的服务器不知道在什么时候就会遇到这个问题。

原文链接:http://alijosie.medium.com/this-is-why-our-3000-apache-servers-went-down-on-the-first-day-of-2022-3cc5e9639587

本文为 CSDN 翻译,转载请注明来源出处。

《新程序员003》正式上市,50余位技术专家共同创作,云原生和数字化的开发者们的一本技术精选图书。内容既有发展趋势及方法论结构,华为、阿里、字节跳动、网易、快手、微软、亚马逊、英特尔、西门子、施耐德等30多家知名公司云原生和数字化一手实战经验!

,

大家还看了
也许喜欢
更多栏目

© 2021 3dmxku.com,All Rights Reserved.