【问题标题】:Improve erlang cowboy performance提高 erlang 牛仔性能
【发布时间】:2019-05-09 02:38:40
【问题描述】:

我们一直在 GCP 上的 Compute Engine 机器上使用 Cowboy 进行生产,我们开始进行基准测试并改进我们的服务性能以处理更多的请求/秒(在我们的例子中,因为我们在 Adtech 中,它是出价/秒)。

在分离和处理了很多问题之后,我们归结为 Cowboy 优化,这些是我们目前的发现和局限性:

牛仔设置

我们使用的是 Cowboy 2.5,有 200 个接受者,最大积压为 1024 个

init(Req, _State) ->
    T1 = erlang:monotonic_time(),
    {ok, BRjson, _} = cowboy_req:read_body(Req),
    %% ---- rest of work goes here but is switched off for our test---
    erlang:send_after(60, self(), {'RSP', x, no_workers}),
    {cowboy_loop, Req, #state{t1 = T1}, hibernate}.

二郎虚拟机

OTP 21

虚拟机参数:-smp auto +P 134217727 +K true +A 64 -rate 1200 +stbt db +scl false +sfwi 500 +spp true +zdbbl 8092

加载

Json 请求的大小约为 4KB。并且使用 jmeter 在同一内部网络(无 SSL)上使用单独的机器进行测试。所有请求都是 POST 并保持活动状态

服务器

GCP Compute Engine 10 个 vcpu 内核和 14GB RAM(现在和之前使用 4 个 vcpu 测试过)

调查结果

我们能够达到约 1900 个请求/秒,但 htop 中的所有 CPU 内核都显示出几乎 80% 的利用率

在 1000 个请求/秒时,我们将 cpu 利用率保持在每个内核 45-50%(请记住,我们的应用程序没有其他部分正在运行,这仍然很高)

*注意:使用 4 个 vcpu 机器,我们能够达到接近 700 个请求/秒,并且在我们所有的测试中内存几乎没有被利用或随负载变化


问题:如何提高cpu使用率方面的牛仔性能?

【问题讨论】:

  • 我认为 200 个接受者对于 1024 个 backlog 来说太多了。我也看不到 erl 的 +Q 选项。
  • 我刚刚尝试使用 +Q 65000(与 ulimit 中的数字相同),但这并没有改变任何东西并将接受者降低到 50
  • erlang:send_after/3 的意义何在?以及为什么要让进程休眠 60 毫秒?
  • 这是一个异步牛仔调用;它收到请求在系统内部发送,另一个进程必须在 100ms 内发回响应(这是业界的投标响应 SLA​​ 超时标准)
  • 你在没有休眠的情况下试过这个吗?你增加了牧场最大连接数吗?

标签: performance erlang webserver cowboy


【解决方案1】:

首先,感谢@Pouriya 的建议——实际上,来回讨论这个问题让我回过头来重新检查我的一个 cmets 以了解适合这项工作的工具。 PS:我们在 GCP 上,所以在这个阶段 72 个核心是没有问题的。

牛仔太棒了!但它确实在每个请求的关键路径中增加了一些开销——一个不需要的特性(或在我的情况下的问题)。

我们再次使用 Elli (https://github.com/elli-lib/elli) 进行了测试,但这次建立了适当的测试设置,它提供了高达 20% 的改进 ~ 正是我们所需要的!

如果 Cowboy/Ranch 团队中的任何人有办法大幅提高 CPU 开销,我们将很乐意进行测试,因为我们仍在 API 中使用它,但不是关键路径。

【讨论】:

  • 不客气。由于我来自伊朗,GCP 不会向我们提供任何东西。所以我没有这方面的经验。
猜你喜欢
  • 2020-09-05
  • 2021-05-09
  • 1970-01-01
  • 2017-11-28
  • 2014-10-06
  • 2020-09-28
  • 2016-03-07
  • 2018-03-23
  • 2017-07-09
相关资源
最近更新 更多