我们的 discourse 因自定义插件而过载。请帮助我

哦,罗伯特,
我们迁移到了一个新的vps,有4个核心(Ryzen 9 5950x),
CPU使用率仍然接近100%。我真的不知道哪里出了问题。



我以为您要迁移到一台 8 核的 Scaleway 服务器?

这台服务器声称的带宽是多少?我想知道低带宽是否会导致连接缓慢/断开成为瓶颈?

Scaleway 的 VPS 带宽有每秒数百兆比特,而不是 30。

对我来说,30 似乎非常低。

这是规格。

4096MB DDR3 ECC RAM
4 CPU vCores (3.4+ GHz E3-1231 v3/1241 v3/1240 v5)
200GB Raid 10 HDD 存储
5TB 带宽 @ 1Gb/s(分配用完后速度限制为 5Mb/s)
1 个 IPv4,/64 个 IPv6
20Gb/s TCP DDoS 保护,提供 200Gb/s 升级
华盛顿州西雅图,美国
Virtualizor 控制面板
非托管

因为时差,我们最终选择了这家云服务提供商。他们为我们国家的访问者优化了网络。

顺便说一句,htop 的输出是


100% CPU 使用率是不正常的。 :fearful:
除了负载和 CPU 使用率之外,一切都很好。

访问日志中有奇怪的地方吗?

现在似乎正在平静下来。


我们猜测从备份恢复会导致 CPU 使用率飙升。
总之,非常感谢你,Robert!

2 个赞

是的,这就可以了!

嗯,你应该选择固态硬盘

2 个赞

Benjamin,抓得好!

Scaleway 等厂商提供 NVMe SSD。好多了!

CPU 可能在等待磁盘。

1 个赞

哦,抱歉,我刚才粘贴了错误的配置。
配置是

4096MB DDR4 ECC 内存
4 个 CPU vCore (3.4GHz AMD Ryzen 5950X)
100GB Raid NVMe SSD 存储
5TB 带宽 @ 10Gb/s(分配用完后速度限制为 5Mb/s)
1 个 IPv4,/64 IPv6
20Gb/s TCP DDoS 防护,可选升级至 200Gb/s
美国华盛顿州西雅图
Virtualizor 控制面板
非托管

是 NVMe。 :flushed:

3 个赞

我认为我们安装的插件可能增加了负载。
该插件对用户模型进行了更改,导致我们在访问发现路由时,会多次计算用户模型在主题模型中的积分。

add_to_class(:user, :total_earned_points) do
    self.user_points.sum(:reward_points)
  end

  add_to_class(:user, :available_points) do
    self.total_earned_points - self.user_rewards.sum(:points)
  end

  add_to_class(:user, :rewards) do
    DiscourseRewards::Reward.where(created_by_id: self.id)
  end

  add_to_serializer(:basic_user, :total_earned_points) do
    user&.total_earned_points
  end

  add_to_serializer(:basic_user, :available_points) do
    user&.available_points
  end

  add_to_serializer(:current_user, :total_earned_points) do
    scope.user.total_earned_points
  end

  add_to_serializer(:current_user, :available_points) do
    scope.user.available_points
  end

  add_to_serializer(:current_user, :user_rewards) do
    scope.user.user_rewards
  end

  add_to_serializer(:current_user, :rewards) do
    scope.user.rewards
  end

你不是说你已经删除了所有插件,而且它的行为还是一样的吗?

这个有索引吗?

user_rewards 表有多少行?有趣的是它没有区分用户……(但我假设它一定是以某种方式在此级别之下)。

恐怕它没有设置索引。
模型如下所示。

module DiscourseRewards
  class Reward < ActiveRecord::Base
    self.table_name = 'discourse_rewards_rewards'

    has_many :user_rewards
    belongs_to :created_by, class_name: 'User'

    default_scope { where(deleted_at: nil) }
  end
end
module DiscourseRewards
  class UserPoint < ActiveRecord::Base
    self.table_name = 'discourse_rewards_user_points'

    belongs_to :user
    belongs_to :user_badge
    belongs_to :user_points_category

    def self.user_total_points(user)
      UserPoint.where(user_id: user.id).sum(:reward_points)
    end
  end
end
module DiscourseRewards
  class UserReward < ActiveRecord::Base
    self.table_name = 'discourse_rewards_user_rewards'

    belongs_to :user
    belongs_to :reward

    enum status: [:applied, :granted]
  end
end

我禁用了安全模式下的所有插件。但是,你知道,数据库没有改变。:smiling_face_with_tear:

我怀疑这需要和作者沟通。

看起来它可能无法满足您的大量用户需求?

你可能需要禁用该插件后重建。这将是一个很好的比较,或许可以确认问题是否由该插件引起。

如果查询没有运行,表的存在无关紧要。

2 个赞

discourse_rewards_user_points | 233525 | 27 MB | 5152 kB | 32 MB
discourse_rewards_user_rewards | 61 | 16 kB | 16 kB | 32 kB
discourse_rewards_user_points_categories | 9 | 16 kB | 16 kB | 32 kB
discourse_rewards_rewards | 4 | 16 kB | 16 kB | 32 kB

discourse_rewards_user_points 表很大。

1 个赞

将其完全移除(从构建中移除,无需销毁表),看看会发生什么。

2 个赞

谢谢,我现在就试试。

1 个赞

哦,罗伯特,我不用插件就重建了,发现路线页面的响应时间从之前的 2-3 秒减少到 200 毫秒以下。:fearful:

1 个赞

那么,这就是全部了。您可以与作者讨论优化问题,或者如果您有能力,可以提交拉取请求(PR)?

1 个赞

我正在向熟悉数据库的朋友寻求帮助。
但他正在从事JAVA方面的工作。我认为这需要一些时间。

1 个赞