如何使用负载平衡器和托管数据库集群扩展 Discourse 部署

作者选择了 COVID-19 救援基金作为 Write for Donations计划的一部分接受捐款。

介绍

由StackOverflow的创始人之一创建的 Discourse是一个开源的讨论平台。

Discourse 通过使用 DigitalOcean 的单点安装在单个 Droplet 上运行得很好,但随着您的社区的增长,它可能会超过单个 Droplet。使用多个 Droplets 会使您的社区在您的 Droplets 之一离线时具有弹性。每个 Droplet 也会增加您的带宽容量。当您使用多个 Droplets 时,一个 Load Balancer 可以帮助扩展您的部署并为您的 Web 应用程序带来高可用性。

完成本教程后,您将有一个高度可用的,易于扩展的Discourse部署在DigitalOcean上运行,您将开始使用新的Ubuntu 20.04Dropplet,并完成一个可扩展的Discourse安装,其中包括负载平衡器,管理PostgreSQL集群,Redis实例(可选),以及额外的Dropplets。

前提条件

要遵循本教程,您将需要:

步骤 1 — 将 DigitalOcean 负载平衡器添加到演讲服务器

在此步骤中,您将添加一个DigitalOcean负载平衡器到您在前提条件下创建的Discourse服务器. 访问您的DigitalOcean控制面板,单击 网络,然后单击 负载平衡器,然后单击 创建负载平衡器

DigitalOcean Control Panel - Networking Tab

您需要为您的负载平衡器选择一个数据中心区域。 请确保为您的 Discourse Droplet 选择相同的区域。 负载平衡器使用其私人网络与您的 Droplet 进行通信,因此您的 Droplet 和 Load Balancer 都需要位于相同的区域。

Create Load Balancer - Choose Region

接下来,将您的 Droplet 添加到您的负载平衡器中,将您的 Droplet 名称键入文本字段。

Create Load Balancer - Add Droplets

Discourse 通常通过在安装过程中发行免费的 Let's Encrypt证书来为您处理 HTTPS,但是当您的 Droplet 处于负载平衡器背后时,Let's Encrypt 将无法更新您的证书,因为您的域的 IP 地址不会匹配您的 Droplet 的 IP。

幸运的是,DigitalOcean Load Balancers 可以为您管理证书. 您只需要将 HTTPS 的 _forwarding 规则添加到您的负载平衡器中。

<$>[注] 注: 有关转发规则的更多信息,请参阅 负载平衡器的产品文档

您需要两个转发规则,一个用于 HTTP 和一个用于 HTTPS. 通过为 HTTPS 添加转发规则,DigitalOcean 可以自动为您生成和更新证书。

由于您已将您的域名添加到 DigitalOcean 作为前提条件的一部分,所以添加 HTTPS 支持只需几个点击即可。在 传递规则部分中,添加一个名为HTTPS的新规则,您可以从下落列表中选择。

Create Load Balancer - Forwarding rules

然后给您的证书一个名字,然后点击 ** 生成证书** 以获得 DigitalOcean 请求并为您管理证书。

Create Load Balancer - Add certificate

您几乎已经完成了设置您的负载平衡器。点击 Edit Advanced Settings 按钮,然后点击标记为 Enable Proxy Protocol 的框。当启用 PROXY 协议时,负载平衡器将用户的 IP 地址等客户端信息转发到负载平衡器背后的 Droplets。

最后,选择您的负载平衡器的名称,然后单击 创建负载平衡器

现在您已经安装了 Load Balancer,您需要修改您的 Discourse 配置文件。

步骤 2 – 更改语音配置文件

在此步骤中,您将更改包含在 Discourse.SSH 中的默认配置文件到您的 Droplet 并使用此命令移动到 `/var/discourse’ 目录:

1cd /var/discourse

使用 nano 或您最喜欢的文本编辑器,在名为 loadbalancer.template.yml 的模板目录中创建并打开新文件:

1sudo nano templates/loadbalancer.template.yml

模板文件夹为您的 Discourse 配置存储文件. 在这里,您正在添加一个新的自定义模板,以启用 PROXY 协议支持您的 Discourse 安装。

loadbalancer.template.yml中,插入以下行:

1[label templates/loadbalancer.template.yml]
2run:
3  - exec: "sed -i 's:listen 80: listen 80 proxy_protocol:g' /etc/nginx/conf.d/discourse.conf"
4  - exec: "sed -i 's:$remote_addr:$proxy_protocol_addr:g' /etc/nginx/conf.d/discourse.conf"
5  - exec: "sed -i 's:X-Forwarded-For $proxy_add_x_forwarded_for:X-Forwarded-For $proxy_protocol_addr:g' /etc/nginx/conf.d/discourse.conf"

第一行修改了 Discourse Nginx 配置以启用 PROXY 协议的支持。

第二行执行查找和替换,以$proxy_protocol_addr代替$remote_addr的所有发生。$proxy_protocol_addr包含客户端的IP地址,由负载平衡器转发。

最后一行将X-Forwarded-For $proxy_add_x_forwarded_for的所有事件代替为X-Forwarded-For $proxy_protocol_addr,确保X-Forwarded-For标题正确记录客户端IP地址,而不是负载平衡器的IP地址。

保存并关闭文件,按CTRL+X,然后按y

您需要做的最后一件事是将模板加载到 Discourse 并重建 Discourse。

使用 nano 或您最喜欢的文本编辑器,在容器目录中编辑名为app.yml的文件:

1sudo nano containers/app.yml

首先,您将添加您刚刚创建的模板。在模板下,如下所示,添加突出的行:

1[label containers/app.yml]
2templates:
3  - "templates/postgres.template.yml"
4  - "templates/redis.template.yml"
5  - "templates/web.template.yml"
6  - "templates/web.ratelimited.template.yml"
7  - "templates/loadbalancer.template.yml"

请确保在templates/web.template.yml下面的一行中添加新模板。

接下来,请确保两个行 web.ssl.template.ymltemplates/web.letsencrypt.ssl.template.yml 都通过添加字符符号 [#] 来评论:

 1[label containers/app.yml]
 2templates:
 3  - "templates/postgres.template.yml"
 4  - "templates/redis.template.yml"
 5  - "templates/web.template.yml"
 6  - "templates/web.ratelimited.template.yml"
 7  - "templates/loadbalancer.template.yml"
 8## Uncomment these two lines if you wish to add Lets Encrypt (https)
 9#  - "templates/web.ssl.template.yml"
10#  - "templates/web.letsencrypt.ssl.template.yml"

最后,走几行,直到你看到暴露。评论-443:443 # https通过添加一个英镑符号 [#]如下所示:

1[label containers/app.yml]
2...
3expose:
4  - "80:80"   # http
5# - "443:443" # https

当您重建 Discourse 时,HTTPS 连接将在 Load Balancer 中终止,而 Load Balancer 将通过 DigitalOcean 的安全私人网络与您的 Droplet 通信,因此您不需要直接在 Discourse 服务器上设置 HTTPS。

保存并关闭文件,按CTRL+X,然后按y

若要应用配置并重建 Discourse,请运行以下命令:

1sudo ./launcher rebuild app

这个命令需要超级用户权限,这就是为什么它被预先称为sudo

此时,您已经完成了对话和负载平衡器的配置,然后将您的域名指向负载平衡器的 IP 地址。

第3步:更新您的DNS

在此步骤中,您将您的域名指向 Load Balancer 的 IP 地址,而不是 Droplet 的 IP 地址。

如果您正在使用 DigitalOcean 的 DNS 托管,请进入控制面板,然后单击 网络. 点击您的域名,然后搜索指向您的 Droplet 的 A 记录。

Editing the A record

您的 Discourse 服务器将运行在 DigitalOcean 负载平衡器后面,您不必管理自己的 SSL 证书,因为 DigitalOcean 将为您做。

通过访问您的域名来测试您的 Discourse 安装工作,您应该看到一个看起来类似于此的页面:

Discourse landing page

现在,您的域指向负载平衡器,您将添加一个受管理的数据库实例,为用户创建一致的体验。

步骤 4 — 添加管理的数字海洋数据库

在此步骤中,您将创建一个 DigitalOcean Managed PostgreSQL 实例,并将其添加到您的 Discourse 部署中。

负载平衡器的主要优点是将您的流量分为多个Dropplets。 到目前为止,您的数据库、Redis服务器和Web服务器都运行在一个Dropplets上。 如果您添加第二个Discourse实例,它将拥有自己的数据库、Redis服务器和Web服务器,并将作为一个完全不同的网站行事。 您的访问者可能会觉得他们正在访问其他网站,具有不同的帖子和用户,因为他们将连接到不同的数据库。 您可以通过使用DigitalOcean的Managed PostgreSQL实例来解决这个问题,而不是在每个Discourse Droplet上运行单独的数据库。

通过进入DigitalOcean控制面板来设置一个DigitalOcean Managed PostgreSQL实例. 点击 DataBases,然后点击 Create Database Cluster,最后选择 PostgresSQL,设置区域以匹配您的Droplet的位置,然后点击 Create a Database Cluster

当您的数据库正在配置时,请将您的Droplet添加到您的数据库中作为可信来源,从而允许您的Droplet使用DigitalOcean的安全私人网络与您的数据库进行通信。

Create Database - Trusted sources

在下一个屏幕上,选择 VPC 网络,并记住数据库主机、用户名、密码和端口的值,因为您需要将这些值添加到您的 containers/app.yml 文件中。

Create database - VPC network

创建数据库集群后,您需要更新 Discourse 的配置。

1sudo nano containers/app.yml

模板部分中,如下所示,评论- templates/postgres.template.yml一行:

1[label containers/app.yml]
2templates:
3# - "templates/postgres.template.yml"
4  - "templates/redis.template.yml"
5  - "templates/web.template.yml"
6  - "templates/web.ratelimited.template.yml"
7  - "templates/loadbalancer.template.yml"

这阻止了Discourse在重新构建时提供自己的Postgres服务器。

接下来,搜索containers/app.ymlenv部分,并添加下面的行,以数据库用户名、密码、主机、名称和端口为自己的值取代值。

1[label containers/app.yml]
2env:
3    DISCOURSE_DB_USERNAME: your_db_username
4    DISCOURSE_DB_PASSWORD: your_db_password
5    DISCOURSE_DB_HOST: your_db_host
6    DISCOURSE_DB_NAME: your_db_name
7    DISCOURSE_DB_PORT: your_db_port

这些额外的变量允许您的 Droplet 连接到您的外部数据库。

保存文件,按CTRL+X,然后按y

如果您有已有的 Discourse 安装,您应该将其导出作为备份,您可以通过进入网站的管理区域,点击 备份,然后点击 备份来完成此操作。

<$>[注] 注: 有关备份和恢复您的网站的更多信息,请参阅 Discourse 产品文档, Move Your Discourse Instance to a Different Server

若要应用配置并重建 Discourse,请运行以下命令:

1sudo ./launcher rebuild app

即使您已导出您的网站,您还需要再次通过 Discourse Web 安装来创建新的管理员帐户,然后您可以使用此帐户恢复 Discourse 现在您已连接到您的新数据库。

最后,您将更改一个设置,以确保用户在访问网站时留在相同的 Droplet 上。

在 DigitalOcean 控制面板中回到 Load Balancer 的设置,然后转到 网络,然后转到 负载平衡器,然后转到 设置,然后搜索 粘贴会话

Sticky Sessionsnone更改为 Cookie,然后点击 Save

Load Balancer - Sticky sessions

Sticky Sessions 确保通过 Load Balancer 访问您的网站的每个用户在访问期间都连接到相同的 Droplet. 这很重要,因为每个 Droplet 仍然有自己的 Redis 实例,而 Redis 是 Discourse 跟踪用户登录时的方式。

正如我们在数据库中所做的那样,您可以将 Redis 移动到自己的专用实例中,然后您不需要 Sticky Sessions。

步骤 5 — (可选) 添加 DigitalOcean 管理 Redis 实例

此步骤是可选的,需要一个DigitalOcean Managed Redis实例. 直到此时,Redis实例被烤到负载平衡器背后的Droplet中,这需要Sticky Sessions来确保用户保持登录。 如果Droplet下载,Load Balancer会将用户共享到您的剩余Droplets中。

将 Redis 服务器外部添加到 Droplets 可以解决这个问题,这将有效地将 Discourse 状态从您的 Droplets 移除。

您可以建立一个 DigitalOcean 管理 Redis 服务器,就像您创建了管理 PostgreSQL 数据库一样。 进入 DigitalOcean 控制面板. 点击 Databases,然后点击 Create,然后点击 Database,并为您的数据库引擎选择 Redis. 选择与其他资源相同的区域,以确保它们在相同的 VPC 网络上。 给您的服务器一个名字,然后点击 Create a database cluster

就像创建您的 Postgres 数据库一样,你会看到一个欢迎屏幕,其中包含一些 开始步骤。 点击 安全这个数据库集群,输入您的 Droplet 名称,然后点击 只允许这些输入源

Redis - Trusted sources

现在您需要为您的 Redis 服务器选择退出策略。选择 allkeys-lru. 此策略意味着如果您的 Redis 服务器填充,它将开始删除其最古老的条目。

Redis - Eviction policy

如您的 PostgreSQL 数据库,在 ** 连接详细信息 ** 屏幕上,选择 ** VPC 网络 **。

创建 Redis 实例后,您将需要更新您的 Discourse 配置. 使用 nano 打开 containers/app.yml:

1sudo nano containers/app.yml

如下所示,将 Redis 连接细节添加到env部分中,请确保用您自己的信息来替换突出的文本(您不需要包含用户名字段)。

1[label containers/app.yml]
2env:
3    DISCOURSE_REDIS_HOST: your_redis_host
4    DISCOURSE_REDIS_PASSWORD: your_redis_password
5    DISCOURSE_REDIS_PORT: your_redis_port
6    DISCOURSE_REDIS_USE_SSL: true

接下来,在模板部分中,如下所示,评论- templates/redis.template.yml一行:

1[label containers/app.yml]
2templates:
3# - "templates/postgres.template.yml"
4# - "templates/redis.template.yml"
5  - "templates/web.template.yml"
6  - "templates/web.ratelimited.template.yml"
7  - "templates/loadbalancer.template.yml"

这阻止了 Discourse 创建自己的 Redis 实例。

保存并关闭文件,按CTRL+X,然后按y

若要应用配置并重建 Discourse,请运行以下命令:

1sudo ./launcher rebuild app

有了受管理的 Redis 实例,您将不再需要 Sticky Sessions. 如果您想要,您可以关闭此选项,但您的用户无论如何都不会注意到任何差异。

现在您已将管理数据库添加到配置中,您将创建 Discourse 服务器的快照,以添加更多 Droplets。

步骤6 - 添加额外的滴滴

在此步骤中,您将创建一个 Snapshot of your Discourse Droplet,这使得创建新服务器更容易。

通过访问 DigitalOcean 控制面板创建一个新的快照。 点击 Droplets,找到您的快照,然后点击 Snapshots. 给您的快照一个名字,然后点击 Take live snapshot

Creating a snapshot

您可以使用此快照在您的负载平衡器背后添加额外的滴滴,并增加您的网站的容量。

每次创建一个新 Droplet 时,您需要更新您的 Postgres 和 Redis 服务器上的可信源,您可以通过控制面板进行更新,就像您在上一步中所做的那样,选择您想要修改的数据库实例,转到 ** Overview**,然后到 Secure this database cluster. 将您的新 Droplet IP 地址添加到可信源列表中。

Create Database - Trusted sources

在此步骤中,您使用了 Snapshot 创建额外的 Droplets,并将其添加到您的 PostgreSQL 和 Redis 实例中作为可信来源。

结论

在本教程中,您将设置一个DigitalOcean负载平衡器背后的Discourse服务器。 为了帮助扩展您的部署,您还添加了一个Managed PostgreSQL数据库和Managed Redis实例。 最后,使用快照和控制面板,您添加了更多的Dropplets。 使用控制面板,您可以随着社区的增长添加更多的资源。

现在你已经设置了负载平衡器,你可以探索其他 DigitalOcean Load Balancers 的使用案例,如 Canary 部署. 你也可以尝试使用命令行连接到你的 Redis 实例,按照教程, 如何通过 Stunnel 和 redis-cli 连接到 TLS 的管理 Redis 实例

Published At
Categories with 技术
comments powered by Disqus