我的 Discourse 速度很慢

我们的网站之前非常慢,因此我们将其迁移到了一台拥有4核CPU、8GB内存和8GB交换内存的服务器上,但网站依然很慢。我找不到优化网站的方法。

少些广告是个不错的开始,我认为是这样。:slightly_smiling_face:

哇,你没开玩笑!这完全没法用。我甚至还没放弃之前,都没能看出这个网站是做什么的。

单核 CPU 速度和 SSD 速度是关键因素。你的 CPU 有多快?你不会还在用机械硬盘吧?自从你增加了内存后,有没有运行过 Discourse 安装脚本或调整过内存设置?你优化过数据库设置吗?你使用的是 Discourse 官方标准安装 吗?

不过,既然你的网站主要是在展示广告,那就很难判断 Discourse 本身的性能如何了。

我们的服务器使用的是 SSD。


我已在启用广告拦截器的情况下测试过该网站,但速度仍然很慢。

Discourse 是由 DigitalOcean 安装的。

没有,我没有。

没有!

您应该重新运行 discourse-setup,或者阅读 app.yml 中的注释以调整内存配置。

您应该不需要任何交换空间。

您的数据库是否非常大?

我已经运行过 discourse-setup 了,但这并没有对速度产生任何影响。

是的,我们网站上有超过 27000 个主题。

根据我的经验,Topic List Previews(插件版)会显著拖慢 Discourse 的速度。你可以尝试切换到 Topic List Previews(TC 版),它的加载速度比插件版快得多。

如果完全禁用 Topic List Previews,Discourse 的速度会提升好几倍。:grinning:

我们使用了一个自定义插件,以便在主题中显示共享的 CDN 图片,并在通过社交媒体分享这些主题时,在元数据 Open Graph(OG)中包含这些图片。该 CDN 支持插件由 @fzngagan(Faizan)开发。请问您是否有任何方法可以将您编写的插件迁移到 TLP TC(主题列表预览主题分类),以便网站加载更快?

@pfaffman 您是否有具体的技术建议,说明我们究竟需要做些什么来加速我们的数据库和网站?我推测 howtodiscuss.com 拥有超过 50,000 个主题,是一个高流量网站。

我的问题如下:

  1. Discourse 中是否可以设置多线程、并行 CPU 或核心配置?NodeBB 提供此类功能以应对高流量。

  2. Discourse 是否支持服务器端缓存?如果有,在哪里以及如何配置?

  3. 我们如何实现 https://howtodiscuss.com 的 100% Google 页面速度评分?

  4. 我们可以在 app.yaml 文件中做哪些更改?我们目前使用的是 4 核 vCPU、8GB 内存的 DigitalOcean Droplet。

  5. 我们使用 Cloudflare 来托管我们的网站。在这方面有哪些优化措施可以采取?当我开启 Cloudflare 的 Rocket Loader 时,我的 Discourse 无法正常工作,并在客户端 JavaScript 控制台中报错。

  6. 是否有办法自动压缩 CSS、JS 和 HTML,并在服务器端启用 Gzip 压缩?

  7. 请分享一些关于 Meta.discourse.org 为应对高流量所进行的优化措施,我们可以尝试应用类似的方案。

  8. 请分享其他使用 Discourse 的高流量网站所尝试过的优化措施。

一旦我们能够加速网站,我们很乐意将我们的网站发布到“成功的 Discourse 社区”列表中。谢谢!

嗯,主题数量并不等同于帖子数量或数据库大小,不过后者本身也不算太大。

目前网站已下线,所以我无法查看帖子数量。

建议您手动编辑 app.yml 文件,查看其中的调优信息并重新构建。有一些主题讨论了数据库调优的方法。

您也可以考虑切换到 Digital Ocean 的新型更快 CPU 实例(droplet)。

嘿,@ahmed_khan1,千万别冒任何停机风险,哪怕只是几分钟的停机,也会在你宝贵的谷歌声誉上造成损失。

直接请专业人士一次性彻底解决吧。我看到你的网站流量相当可观,所以务必保持理智,切勿贪图便宜。

我推荐像 @pfaffman@angus 这样的人。

我在一台 2 核 2GB 的机器上运行着一个拥有 20,000 个主题的网站,没有任何问题(不过活跃度可能不如你的网站……)。

不过话说回来,如果问题出在运行大量 JavaScript 上,那么后端性能就无关紧要了。

你把这个设置成零了吗?

这会有所帮助。

你可以迁移到 TC 来加快 TLP 的速度,但 它在基于 Chromium 的浏览器中存在渲染限制(这也是我尚未停用该插件的原因,我正在等待 LayoutNG 升级 Grid CSS)。

我们有了新的 DigitalOcean Droplet。只需在 1 上购买即可。
这是 app.yml

## 这是 Discourse Docker 容器的全功能独立模板

##

## 修改此文件后,您必须重新构建

## /var/discourse/launcher rebuild app

##

## 编辑时请*非常*小心!

## YAML 文件对空格或对齐的错误极其敏感!

## 如需验证,请访问 http://www.yamllint.com/

templates:

  - "templates/postgres.template.yml"

  - "templates/redis.template.yml"

  - "templates/web.template.yml"

  - "templates/web.ratelimited.template.yml"

## 如果您想添加 Lets Encrypt (https),请取消注释以下两行

#- "templates/web.ssl.template.yml"

#- "templates/web.letsencrypt.ssl.template.yml"

## 此容器应暴露哪些 TCP/IP 端口?

## 如果您希望 Discourse 与 Apache 或 nginx 等其他 Web 服务器共享端口,

## 请参阅 https://meta.discourse.org/t/17247 了解详情

expose:

  - "2045:80" # http

#  - "443:443" # https

params:

  db_default_text_search_config: "pg_catalog.english"

  ## 将 db_shared_buffers 设置为总内存的最大 25%。

  ## 将基于检测到的 RAM 由 bootstrap 自动设置,您也可以覆盖

  db_shared_buffers: "2048MB"

  ## 可改善排序性能,但会增加每个连接的内存使用量

  #db_work_mem: "40MB"

  ## 此容器应使用哪个 Git 版本?(默认:tests-passed)

  #version: tests-passed

env:

  LANG: en_US.UTF-8

  # DISCOURSE_DEFAULT_LOCALE: en

  ## 支持多少并发 Web 请求?取决于内存和 CPU 核心数。

  ## 将基于检测到的 CPU 由 bootstrap 自动设置,您也可以覆盖

  UNICORN_WORKERS: 8

  ## TODO: 此 Discourse 实例将响应的域名

  ## 必需。Discourse 无法仅使用裸 IP 地址运行。

  DISCOURSE_HOSTNAME: "howtodiscuss.com"

  ## 如果您希望容器使用与上述指定的相同主机名(-h 选项)启动,请取消注释

  ## (默认值为 "$hostname-$config")

  #DOCKER_USE_HOSTNAME: true

  ## TODO: 初始注册时将设为管理员和开发人员的逗号分隔电子邮件列表

  ## 示例:'user1@example.com,user2@example.com'

  DISCOURSE_DEVELOPER_EMAILS: "admin@gmail.com"

  ## TODO: 用于验证新账户和发送通知的 SMTP 邮件服务器

  # SMTP 地址、用户名和密码是必需的

  # 警告:SMTP 密码中的字符 '#' 可能会导致问题!

  DISCOURSE_SMTP_ADDRESS: smtp-relay.smtp.com

  DISCOURSE_SMTP_PORT: 587

  DISCOURSE_SMTP_USER_NAME: admin@gmail.com

  DISCOURSE_SMTP_PASSWORD: smtp_password

  #DISCOURSE_SMTP_DOMAIN: discourse.example.com    # (某些提供商要求)

  #DISCOURSE_NOTIFICATION_EMAIL: nobody@discourse.example.com    # (发送通知的地址)

  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (可选,默认为 true)

  ## 如果您添加了 Lets Encrypt 模板,请取消注释以下行以获取免费 SSL 证书

  #LETSENCRYPT_ACCOUNT_EMAIL: me@example.com

  #DISCOURSE_MAXMIND_LICENSE_KEY: 1234567890123456

  ## 此 Discourse 实例的 http 或 https CDN 地址(配置为拉取)

  ## 请参阅 https://meta.discourse.org/t/14857 了解详情

  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

## Docker 容器是无状态的;所有数据都存储在 /shared 中

volumes:

  - volume:

      host: /var/discourse/shared/standalone

      guest: /shared

  - volume:

      host: /var/discourse/shared/standalone/log/var-log

      guest: /var/log

## 插件放在这里

## 请参阅 https://meta.discourse.org/t/19157 了解详情

hooks:

  after_code:

    - exec:

        cd: $home/plugins

        cmd:

          - git clone https://github.com/discourse/docker_manager.git

          - git clone https://github.com/discourse/discourse-sitemap.git

          - git clone https://github.com/discourse/discourse-math.git # 用于数学 JAX 支持的自定义插件

          - git clone https://github.com/discourse/discourse-solved.git # 用于问答和选择最佳答案的自定义插件

          - git clone https://github.com/discourse/discourse-voting.git # 仅用于对主题投票的自定义插件

          - git clone https://github.com/discourse/discourse-yearly-review.git # 用于自动发布年度论坛活动主题的自定义插件

          - git clone https://github.com/discourse/discourse-user-notes.git # 允许工作人员为用户添加备注的自定义插件

          - git clone https://github.com/paviliondev/discourse-question-answer.git # 用于帖子上 SO 风格问答投票的非官方自定义插件

          - git clone https://github.com/discourse/discourse-adplugin.git # 用于广告的官方自定义插件

          - git clone https://github.com/discourse/discourse-whos-online.git # 用于查看谁在线的自定义插件

          - git clone https://github.com/paviliondev/discourse-topic-previews.git # 用于美观显示主题预览的自定义插件

          - git clone https://github.com/paviliondev/discourse-ratings.git # 允许用户对主题进行评分的自定义插件

          - git clone https://github.com/discourse/discourse-cakeday.git # 用于生日和加入日期庆祝的官方插件

          - git clone https://github.com/discourse/discourse-saved-searches.git # 用于保存搜索通知的官方插件

          - git clone https://github.com/paviliondev/discourse-follow.git # 允许用户互相关注的自定义插件

          - git clone https://github.com/FaizanZahid/discourse-amp-htd-plugin.git # 为 HTD 构建的 AMP 支持自定义版本

          - git clone https://github.com/discourse/discourse-assign.git # 用于将主题分配给工作人员的自定义插件

          - git clone https://github.com/paviliondev/x-discourse-tlp-thumbnail.git # 用于从 CDN 图像显示缩略图的自定义插件

## 构建后运行的任何自定义命令

run:

  - exec: echo "开始自定义命令"

  ## 如果您想设置首次注册的“发件人”电子邮件地址,请取消注释并修改:

  ## 收到首次注册邮件后,请重新注释该行。它只需运行一次。

  - exec: rails r "SiteSetting.notification_email='noreply@howtodiscuss.com'"

  - exec: echo "自定义命令结束"

我认为您是在这台单实例上运行了多个站点。不确定这会对性能问题产生何种影响。

我们只在这台服务器上运行这一个站点。

您可以将 db_work_mem 提升至 100。

您的反向代理可能会出现问题,导致系统变慢。

Mini Profiler 显示了什么?

您还可以安装 Prometheus 插件以获取更多数据。

您尝试过禁用“在线用户”插件了吗?

我尝试过了,但没看到明显改善。
@pfaffman
这是 CPU 和内存使用情况:

我已将 Unicorn 工作进程数改为 24,并将内存缓冲区改为 4096MB。

你看过浏览器端的情况吗?

虽然这只是一个快照,但你的 CPU 利用率看起来非常低。我认为你的配置过高了。

内存使用量高仅仅是因为独角兽(unicorn)进程的数量较多。如果开始严重触发交换空间(swap),请减少它们的数量。

我强烈建议你在浏览器的开发者工具中检查数据检索和 JavaScript 的延迟情况。

感知到的缓慢可能源于浏览器正在执行的大量工作。

从 HTTP 响应头来看,您似乎同时使用了 Ezoic 和 Cloudflare。是这样吗?我不太确定 Ezoic 具体做了什么,但这可能是导致感知速度慢的另一个因素。

我的建议是:先从一个简单的设置开始,不要使用任何代理,也不要将您的 Discourse 站点置于 Cloudflare 之后。确保其运行速度合理之后,再按照 Enable a CDN for your Discourse 的指南进行优化;或者,如果您确实想使用 Cloudflare,请参考 https://meta.discourse.org/t/full-site-cdn-acceleration-for-discourse/21467。

没错,这台服务器上通过 NGINX 仅托管了一个网站,即 https://howtodiscuss.com。您有什么方法可以提升它的速度吗?