新年第一天,3000台Apache服务器宕机

2022-12-19 0 395

【萨德基】回娘家当晚给伺服器提速,上班马路上修Bug……对于开发人员而言,这种的日常生活并不孤单。在圣诞节这天,欧美国家一名为Ali Josie 的应用软件技师、网络安全发烧友就历经了找Bug、Cadours、复原这种的事,因此还刊登了一则《This Is Why Our 3000 Apache Servers Went Down On The First Day of 2022》,具体内容是怎么一两件事呢?

译者 |Ali Josie 翻译者 | 弯月

公司出品 | CSDN(ID:CSDNnews)

圣诞节这天,又正逢周日,中午醒过来却看见一大堆整座基础建设读出来的预警!我的一名同僚就遭受了这种的真实世界,他当时的心境可见一斑。

新年第一天,3000台Apache服务器宕机

清早

具体而言,最重要的是恢复正常服务项目,把服务项目无法访问的影响降至最高,他们重新启动了大部份Apache伺服器,说实话没任何人难题。接下去要是找寻无法访问的其原因了。为何大部份伺服器都在圣诞节这天无法访问?这的确不是碰巧吧?

他们看见每台伺服器上都历史记录了如下表所示笔记:

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

libgomp是什么?他们先玩游戏查了一下那个严重错误。ServerFault上没人问过那个难题,但没法提问,最少没他们会用的东西。不过那个难题有点儿怪异,因为提问者说他的伺服器内要24~36半小时就会发生一场。

新年第一天,3000台Apache服务器宕机

思索

返回严重错误这类。他们每晚中午单厢做一场笔记Tiruvanamalai,这种每晚都用捷伊笔记。因此要重新启动伺服器。或许Apache已经获得成功重新启动,但由于libgomp严重错误又无法访问了。

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

“GOMP项目是C、C++和Fortran编译器OpenMP的一个实现……GOMP能简化大部份GNU系统上的并行编程。”

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

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

新年第一天,3000台Apache服务器宕机

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

“pthread_key_create会创建用于线程专有的数据键,可在进程的大部份线程中使用。pthread_key_create提供的键值是不透明的对象,用于定位线程专有的数据。虽然不同线程可以使用相同的键名称,通过pthread_setspecific绑定到键的值是按照线程维护的,在线程的整座生命周期都有效。”

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

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

系统资源不足,无法创建另一个线程特定数据键,或每个进程的键总数达到了 PTHREAD_KEYS_MAX 上限。

内存不足,无法创建键。”

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

新年第一天,3000台Apache服务器宕机新年第一天,3000台Apache服务器宕机

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

“pthread_key_create会拒绝超过 PTHREAD_KEYS_MAX pthread_key_t的创建请求。我遇到的难题是在NetBSD上Apache无法与多种模块一起工作,因为那个值太低了。时间长了,伺服器就会陷入无法提供服务项目的状态。”

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

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

新年第一天,3000台Apache服务器宕机

怀疑

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

为何会在1月1日发生?而且这么大的范围,真的是碰巧吗?

为何用了这么多年都没事儿?会不会因为是某个更捷伊其原因?

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

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

最后他们检查了Imagick的更新笔记,发现了那个:

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

在关闭过程中,如果可能,则调用omp_pause_resource_all

增加了 `

imagick.shutdown_sleep_count` (默认10)和`imagick.set_single_thread`(默认On)。两者都可以减少关闭时的段严重错误。”

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

新年第一天,3000台Apache服务器宕机

灵光乍现

在搜索了更多怪异的东西后,他们想看看一月份有没人遇到那个难题。

新年第一天,3000台Apache服务器宕机

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

新年第一天,3000台Apache服务器宕机

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

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

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

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

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

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

新年第一天,3000台Apache服务器宕机

检查

还有个未解决的难题:新版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)上运行同样的命令:

% timeseconds usecs/call callsfunction—— ———– ———– ———————————— ———– ———– ——————————100.00 0.000000 0 total

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

新年第一天,3000台Apache服务器宕机

总结

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

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

原文链接:

https://alijosie.medium.com/this-is-why-our-3000-apache-servers-went-down-on-the-first-day-of-2022-3cc5e9639587 新年第一天,3000台Apache服务器宕机

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

新年第一天,3000台Apache服务器宕机

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务