我正在努力理解“零停机”配置。我目前的设置是为不同社区运行了几个 Discourse 实例。两者都采用了数据容器和 Web 容器的分离配置。我在主机层级部署了 Nginx,负责 SSL 终止,并通过套接字连接将请求转发给容器内的 Nginx。
我找到了两个相关主题:
We successfully performed the upgrade a couple of months ago. I’m posting our experience here for anyone who may have the same question in the future.
Discourse somewhat supports zero downtime upgrades by using post deployment migrations . The overall process, as we understood it, can be divided in 2 steps.
STEP 1: Upgrade to the new version and run safe migrations:
Update all your plugins and themes to be compatible with the new version. (This is actually quite a bit of work depending on you…
因此,我正在尝试理解这一过程。看起来其中包含了一些默认具备的知识。如果有人能提供帮助,那将非常感激。
首先,我想了解如何判断何时需要升级数据容器。似乎有些情况下不能仅重建 Web 容器。我如何才能确切地知道何时属于这种情况?这是否包括所有在管理 UI 面板中“升级”选项呈灰色不可用的情况,以及涉及主题和插件的自定义修改?我是否可以通过查看数据库架构迁移来确切判断?或者我是否需要搭建一个测试环境并尝试升级才能确认?
接下来,我想了解如何执行零停机升级。根据这两条链接的描述,似乎无论如何都需要重建数据容器和 Web 容器?我无法完全理解这一点。为了最终实现零停机,我是否需要单独部署数据容器和 Web 容器?
任何指导都将不胜感激!我本可以花费大量时间摸索出一套看似可行的方案,但更希望能站在巨人的肩膀上,尽量避免在生产环境中因边缘情况而付出代价(如果可能的话)。
如果您需要了解我具体设置的更多信息,请随时询问。我会直接回复并更新此帖子。
谢谢。
2 个赞
Mevo
2020 年9 月 10 日 19:52
2
我对“部署后迁移”了解不多,但根据我(在 meta 上)读到的内容,实现这一目标的一种方法是使用3 个容器 :1 个数据容器和 2 个 Web 容器。你先更新未运行的 Web 容器,待更新完成后将其切换为正在使用的容器。
3 个赞
我认为这说得通。所以数据容器不会通过启动器运行重建?我只需在主机级别的 Nginx 处理负载均衡。让我看看能否理清这个流程:
数据容器:
./launcher enter data_container
SKIP_POST_DEPLOYMENT_MIGRATIONS=1 rake db:migrate
web_container
./launcher rebuild web_container1 && \
sleep 60 && ./launcher rebuild web_container2
数据容器:
rails generate post_migration
SKIP_POST_DEPLOYMENT_MIGRATIONS=0 rake db:migrate
这样看起来合理吗?
Stephen
(Stephen)
2020 年9 月 10 日 20:13
4
这完全取决于数据容器需要进行哪些更新。
Postgres 12 的更新是不可避免停机时间的一个很好的例子。即使你有一个复制的数据容器,在数据库升级期间,你的复制站点也需要以只读模式运行。
唯一能永远避免停机时间的方法是永远不升级 。通过 /admin/upgrade 对单个容器安装进行的更新已经是零停机时间。通过 ssh 进行的更新(例如需要更新基础镜像时)的停机时间程度会有所不同,具体取决于你的预算和对复杂性的接受程度。
避免停机时间的最佳方法是构建一个预发布副本 ,否则每次更新后,如果插件或自定义内容遇到兼容性问题,你都将面临微小的停机风险。
2 个赞
好的。为了确保不会出现重大问题,先在预发布环境运行并观察结果……因此我会尝试上述步骤,看看数据容器是否会失败?
如果是这样,我的预发布环境可以包含 1 个数据节点和 1 个 Web 节点,而生产环境则包含 2 个数据节点和 2 个 Web 节点。最坏的情况是,如果先在预发布环境中尝试,然后在生产环境中执行以下步骤:
设置为只读
cp -rp shared/data1 到 shared/data2
升级 data2
停止 web2
将 data2 链接到 web2
重建 web2
将 data2 链接到 web1
重建 web1
取消只读设置
这样理解对吗?
Stephen
(Stephen)
2020 年9 月 10 日 20:25
6
这取决于你对‘停机’的定义。
如果用户无法访问网站,那显然是停机。
但如果他们无法注册、发帖、回复或点赞,你会认为这算停机吗?
如果这是一个大型社区,在 SSD 上运行多个数据容器的成本将相当可观。你是否考虑过使用外部 PostgreSQL 服务器,例如 Amazon RDS?
1 个赞
marianord
(Mariano Rodriguez)
2020 年9 月 10 日 22:20
10
@Stephen 指出的这类细节确实非常重要。因为我们需要理解什么是“零停机时间”。例如,我可以通过以下方式“黑客式”地满足零停机要求:
我将零停机定义为:在请求有效时,绝不 向用户返回除 HTTP 200 以外的任何状态码(同时根据需要保留 300 和 400 系列状态码)。然后,我在一台 10 美元的单容器 droplet 上部署 Discourse,并参考 Add an offline page to display when Discourse is rebuilding or starting up 来添加离线页面,从而避免 500 错误。这样一来,用户就不会看到网站已停机的提示。
那么,在理性的思维下,我会认为这算作零停机吗?绝对不会。但它是否按设想那样运行了呢?当然可以。我甚至可以再添加一台位于其他区域的备用服务器,使其更加“零停机可靠”。
这就是为什么界定和语义如此重要。始终向用户展示某些内容,与始终确保网站功能可用,两者并不相同。
3 个赞
marianord
(Mariano Rodriguez)
2020 年9 月 10 日 22:32
12
请帮助我们理解一下。为了实现您定义的零停机时间,您需要哪些条件?用户是否可以接受 10 到 30 分钟的只读状态?您是否有能力自行开发解决方案?您是否希望为我们的用户提供一个显示“正在维护,稍后回来”的友好页面?我们需要更多细节,以便为您提供真正适用的准确解决方案,或者至少为您指明正确的方向。
jomaxro
(Joshua Rosenfeld)
关闭
2020 年9 月 10 日 22:42
14
本讨论有些激烈且偏离主题。请在讨论话题时彼此尊重。提出澄清性问题是为了给出更精确的回答,因为每个人的配置和目标都不同。