gpt4 book ai didi

c++ - 将正在运行的应用程序中的共享对象热更新到 Linux 上的新版本

转载 作者:行者123 更新时间:2023-12-04 15:08:47 33 4
gpt4 key购买 nike

我们有一个服务器,必须能够在不停机的情况下进行更新。

我们通过使应用程序只是一个薄加载层来实现这一点,并且所有逻辑都在应用程序 dlopen 的共享对象中。我们将此库称为 libmyservice.so.1.23

当请求传入时,服务器会创建一个线程并从库中调用适当的 API 来为其提供服务。

当服务器需要热更新时,它会下载一组新的库并使用 dlopen 加载它们让我们将新库称为 libmyservice.so.1.24

在更新期间有一个中间阶段,在这个阶段,已经运行的请求仍然由旧库提供服务,而新请求由新库提供服务。当旧请求完成时,旧库将被卸载,所有请求都将使用新库。因此在更新期间没有停机时间。

库被编译为尽可能独立。它依赖于 boost、openssl 和许多其他我们无法控制的 C++ 东西。所有这些依赖项都随库一起提供,并且 rpath 用于从与库相同的目录加载它们。

在实践中我们遇到了两个问题:

  • 符号冲突:加载新库时,动态链接器会重用旧库中的符号,这会导致奇怪的错误。我们发现可以通过将 RTLD_DEEPBIND 传递给 dlopen 来解决这个问题。但我们也有 dlmopen 做类似的事情。当目标是完全隔离新旧库集时,应使用两者中的哪一个?

  • 静态初始化和清理:我们有一个错误,当使用 RTLD_DEEPBIND 加载库时,使用 dlopened 库中的 std::cerr 等全局对象会导致崩溃。我们仍然不完全理解为什么会发生这种情况。我们相信,当使用 RTLD_DEEPBIND 加载一组新的 libstdc++ 符号时,静态初始化不会发生。这对我来说似乎是动态链接器中的一个错误。静态初始化和清理应该如何在共享对象中工作?

我如何才能同时加载两个共享库及其所有依赖项,而不会在两者之间产生任何冲突?有可能吗?即无符号冲突,静态初始化无冲突。

该软件已经在 Windows 上正常运行,因为 DLL 似乎不像共享对象那样相互冲突。

编辑:

虽然我喜欢多进程的想法,但架构已经确定,没有很多批准我不能改变它(我不太可能得到)。

为了使事情变得复杂(我在最初的问题中不希望这样),实际架构是这样的:服务器应用程序 -> 主库 -> 可热更新的核心库。 “主库”是热插拔核心库之上的代理产品。客户获取此库并将其集成到他们的产品中。在更新期间,客户的产品下载更新包并调用主库中的函数来触发热插拔。主库不执行线程,但实现为线程安全的。

所以多进程并不是真正的选择。

最佳答案

我不打算回答这个问题,但这条建议太长了,不适合发表评论... TL;DR:当心 XY problem :)

我不知道是否可以重新加载动态库,但正如您所注意到的,即使您可以让它工作,它也是一个麻烦的来源。所以我会考虑一种不同的、更习惯的方法。

您可以创建一个“ super 服务器”可执行文件,其任务只是监听传入请求并将它们传递给实际服务器。

当一个新连接进来时, super 服务器fork进入一个新进程(inherits the connection's file descriptor)并且exec请求处理程序可执行文件。在最简单的情况下,你甚至不需要写这个; xinetd正是这样做的。 Systemd 也可以做到这一点,使用 socket activation .

如果每个请求一个进程的开销太大,您还可以将您的 super 服务器编码为 hand off the connection's file descriptor到现有的长时间运行的服务器进程。然后,实际服务器可以根据需要处理请求,例如使用线程或基于 select() 的 react 器。 super 服务器可以通过发送 SIGTERM 信号来关闭服务器;服务器应该被编码以通过完成所有正在进行的请求然后关闭来处理这个问题。

最后,如果您真的不能容忍任何停机时间,那么如果您的服务器仅在一台机器上运行并且机器出现故障(或需要重新启动以进行内核更新),那么这些技巧都无法挽救您。您将需要多台服务器形式的冗余。到那时,您还不如通过一台一台地拆除这些服务器来升级这些服务器,实际上不需要任何这种热插拔。

关于c++ - 将正在运行的应用程序中的共享对象热更新到 Linux 上的新版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65612300/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com