解耦 Discourse 应用 - 使用 Discourse 的托管 Redis、托管 Postgres 和 Digital Ocean Volume

我正尝试将 Discourse 连接到 Digital Ocean 托管的 Redis 数据库。我成功地将 PostgreSQL 与 Digital Ocean 托管的 PostgreSQL 数据库配合使用,但 Redis 却报错。您能分析一下这是怎么回事吗?

    templates:
      - templates/web.template.yml
      - templates/web.ssl.template.yml
    # 使用 'links' 键将容器链接在一起,即使用 Docker --link 标志。
    expose:
      - '80:80'
      - '443:443'
    params:
      db_default_text_search_config: pg_catalog.english
      db_shared_buffers: 512MB
    env:
      LANG: en_US.UTF-8
      UNICORN_WORKERS: 8
    
      # https://github.com/discourse/discourse/blob/master/config/discourse_defaults.conf
      DISCOURSE_HOSTNAME: blah.example.com
      DISCOURSE_DEVELOPER_EMAILS: email@example.com
      DISCOURSE_SMTP_ADDRESS: smtp.mailgun.org
      DISCOURSE_SMTP_PORT: 587
      DISCOURSE_SMTP_USER_NAME: blah@mail.com
      DISCOURSE_SMTP_PASSWORD: 9cd16e-aff2d1b9-36c86fff
      DISCOURSE_DB_NAME: defaultdb
      DISCOURSE_DB_USERNAME: doadmin
      DISCOURSE_DB_PASSWORD: gp5m224
      DISCOURSE_DB_HOST: private-digitalocean-stage-discuss-postgres-do-user-.ondigitalocean.com
      DISCOURSE_DB_PORT: 25060
      DISCOURSE_REDIS_USERNAME: default
      DISCOURSE_REDIS_PASSWORD: dex3mf
      DISCOURSE_REDIS_HOST: private-digitalocean-stage-discuss-redis-do-user-966537-0.b.db.ondigitalocean.com
      DISCOURSE_REDIS_PORT: 25061
      DISCOURSE_REDIS_CLIENT_ID: ~
    volumes:
      - volume:
          host: /var/discourse/shared/standalone
          guest: /shared
      - volume:
          host: /var/discourse/shared/standalone/log/var-log
          guest: /var/log
    hooks:
      after_code:
        - exec:
            cd: $home/plugins
            cmd:
              - 'git clone https://github.com/discourse/docker_manager.git'
    run:
      - exec: echo "开始自定义命令"
      - exec: echo "结束自定义命令"

请看这里,我添加了:

  DISCOURSE_REDIS_USERNAME: default
  DISCOURSE_REDIS_PASSWORD: dex3mf
  DISCOURSE_REDIS_HOST: private-digitalocean-stage-discuss-redis-do-user-.db.ondigitalocean.com
  DISCOURSE_REDIS_PORT: 25061
  DISCOURSE_REDIS_CLIENT_ID: ~

但我遇到了以下错误:

  I, [2021-02-13T04:05:48.508236 #1]  INFO -- : > cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate'
  报告错误失败:连接丢失 (ECONNRESET) 2 连接丢失 (ECONNRESET) 订阅失败,将在 1 秒后重新连接。调用堆栈 /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:275:in `rescue in io'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:267:in `io'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:279:in `read'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:131:in `block in call'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:248:in `block (2 levels) in process'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:389:in `ensure_connected'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:238:in `block in process'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:325:in `logging'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:237:in `process'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:131:in `call'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:113:in `block in connect'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:313:in `with_reconnect'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:111:in `connect'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:294:in `with_socket_timeout'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:144:in `call_loop'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/subscribe.rb:44:in `subscription'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/subscribe.rb:14:in `subscribe'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis.rb:3507:in `_subscription'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis.rb:2326:in `block in subscribe'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis.rb:69:in `block in synchronize'
    /usr/local/lib/ruby/2.7.0/monitor.rb:202:in `synchronize'
    /usr/local/lib/ruby/2.7.0/monitor.rb:202:in `mon_synchronize'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis.rb:69:in `synchronize'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis.rb:2325:in `subscribe'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/message_bus-3.3.4/lib/message_bus/backends/redis.rb:287:in `global_subscribe'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/message_bus-3.3.4/lib/message_bus.rb:766:in `global_subscribe_thread'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/message_bus-3.3.4/lib/message_bus.rb:714:in `block in new_subscriber_thread'
    rake aborted!

我之前曾努力确保我们与 Digital Ocean 的所有托管服务兼容。他们的 Redis 强制要求使用 SSL,而当时我们尚未支持该功能。

要让他们的 Redis 正常工作,请使用以下配置:

  DISCOURSE_REDIS_HOST: falcoland-redis-do-user-435229-0.a.db.ondigitalocean.com
  DISCOURSE_REDIS_PASSWORD: vp39d0dpy8dxn68n
  DISCOURSE_REDIS_PORT: 25061
  DISCOURSE_REDIS_USE_SSL: true
4 个赞

谢谢 @Falco ~~ 成功了!!!

我下一步是将 /var/discourse 迁移到 Digital Ocean 卷上,以便 Discourse 应用服务器可以共享。您只需挂载该卷并创建目录的符号链接吗?

我的目标架构是:负载均衡器 → 多个 Discourse 服务器,搭配 Digital Ocean 的 Redis 和 PostgreSQL,以及一个由多个 Discourse 服务器共享的 Digital Ocean 卷,而不是让每个服务器拥有自己的卷。

您怎么看?

为什么要这样做?

将所有静态资源和用户上传的文件放到 Digital Ocean Spaces 上,参考 使用对象存储进行上传(S3 及克隆),这样您的应用服务器就不需要共享任何内容了。

需要注意的是,如果使用多个应用 Droplet、托管 Redis、PostgreSQL 和对象存储,费用将非常接近我们的 托管服务 :wink:

4 个赞

谢谢,我的论坛不使用前端模板。我使用 NodeJS 构建了一个 API,前端采用 VueJS。因此,我只使用 Discourse 来共享和存储数据。我的论坛不允许上传图片。

所以这是我的使用场景:所有 Discourse 应用服务器可以共享负载均衡器后面的一个文件卷。除了 /var/discourse 卷之外,每个部分现在都已解耦。这样理解对吗?

@Falco,我很快就想通了:

首先,在 DigitalOcean (DO) 中创建卷,并在 DO 的步骤中确保将你的 Droplet 与该卷关联,然后
SSH 登录到你的 Discourse 机器:

mv /var/discourse /var/discourse.bak
mkdir /home/discourse
mount /dev/sda /home/discourse
mv /var/discourse.bak/* /home/discourse
nano /home/discourse/containers/app.yml

更新 volumes 部分:

volumes:
  - volume:
      host: /home/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /home/discourse/shared/standalone/log/var-log
      guest: /var/log

然后:

cd /home/discourse
sudo ./launcher rebuild app

现在你的 Discourse 已从卷提供服务,可以创建快照,并部署在负载均衡器之后,因为所有组件现在都已解耦。

祝好!

2 个赞