Puma或Unicorn VS Webbrick负载测试基准测试没有任何改进

Tik*_*boy 5 ruby performance multithreading ruby-on-rails heroku

安装程序

好的,我正在Heroku上运行rails应用程序(免费套餐).

我有2个独立的应用程序版本,我们称之为StagingFake-Production.

Staging中,我使用Webbrick作为服务器.我的Procfile

web: rails s -p $PORT
Run Code Online (Sandbox Code Playgroud)

Fake-Production中,我使用Puma作为服务器.我的Procfile

bundle exec puma -C config/puma.rb
Run Code Online (Sandbox Code Playgroud)

我已经配置puma运行2个工人和每个工人1个线程. config/puma.rb定义如下(取自Heroku的设置Puma Webserver)

workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['MAX_THREADS'] || 1)
threads threads_count, threads_count

preload_app!

rackup      DefaultRackup
port        ENV['PORT']     || 3000
environment ENV['RACK_ENV'] || 'development'

on_worker_boot do
  # Worker specific setup for Rails 4.1+
  # See: https://devcenter.heroku.com/articles/deploying-rails-applications-    with-the-puma-web-server#on-worker-boot
  ActiveRecord::Base.establish_connection
end
Run Code Online (Sandbox Code Playgroud)

database.yml被配置为具有20的连接池.

考试

为了进行负载测试,我使用笔记本电脑中的ApacheBench工具来访问API端点.API基本上做了一个非常简单的数据库查询,以返回固定数量的记录(不会更改).

我使用以下代码点击了两个部署:

ab -n 1000 -c 100 https://<some heroku endpoint>?access_token=f73f50514c
Run Code Online (Sandbox Code Playgroud)

结果

这里的结果是最令人惊讶的.我期待Puma的部署能够完全破坏Webbrick的部署,但实际上,它几乎是一样的.我尝试了不同的API端点以及Puma工作者和线程的不同组合(在某一点上,它是4个工作者和5个线程)然而没有任何明显的改进.

Webbrick结果

Server Software:        WEBrick/1.3.1
Server Hostname:        webbrick-build.herokuapp.com
Server Port:            443
SSL/TLS Protocol:       TLSv1,DHE-RSA-AES128-SHA,2048,128

Document Path:          /api/v1/packages?access_token=f73f50514c6
Document Length:        488 bytes

Concurrency Level:      100
Time taken for tests:   21.484 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      995000 bytes
HTML transferred:       488000 bytes
Requests per second:    46.55 [#/sec] (mean)
Time per request:       2148.360 [ms] (mean)
Time per request:       21.484 [ms] (mean, across all concurrent requests)
Transfer rate:          45.23 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:      714 1242 278.1   1214    2012
Processing:   248  842 493.6    699    2883
Waiting:      247  809 492.3    677    2876
Total:       1072 2085 643.5   1929    4845

Percentage of the requests served within a certain time (ms)
  50%   1929
  66%   2039
  75%   2109
  80%   2168
  90%   2622
  95%   3821
  98%   4473
  99%   4646
 100%   4845 (longest request)
Run Code Online (Sandbox Code Playgroud)

记忆影响

source=web.1 dyno=heroku.1234567899 sample#memory_total=198.41MB sample#memory_rss=197.60MB sample#memory_cache=0.30MB sample#memory_swap=0.51MB sample#memory_pgpgin=103879pages sample#memory_pgpgout=53216pages
Run Code Online (Sandbox Code Playgroud)

美洲狮结果(无论工人/线程数多少都大致相同)

Server Software:        Cowboy
Server Hostname:        puma-build.herokuapp.com
Server Port:            443
SSL/TLS Protocol:       TLSv1,DHE-RSA-AES128-SHA,2048,128

Document Path:          /api/v1/packages?access_token=fb7168c147adc2ccd83b2
Document Length:        489 bytes

Concurrency Level:      100
Time taken for tests:   23.299 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      943000 bytes
HTML transferred:       489000 bytes
Requests per second:    42.92 [#/sec] (mean)
Time per request:       2329.949 [ms] (mean)
Time per request:       23.299 [ms] (mean, across all concurrent requests)
Transfer rate:          39.52 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:      743 1304 283.9   1287    2092
Processing:   253  951 740.3    684    5353
Waiting:      253  898 729.0    627    5196
Total:       1198 2255 888.0   1995    7426

Percentage of the requests served within a certain time (ms)
  50%   1995
  66%   2085
  75%   2213
  80%   2444
  90%   3755
  95%   4238
  98%   5119
  99%   5437
 100%   7426 (longest request)
Run Code Online (Sandbox Code Playgroud)

内存影响(4名工人,5个主题)

source=web.1 dyno=heroku.1234567890 sample#memory_total=406.75MB sample#memory_rss=406.74MB sample#memory_cache=0.00MB sample#memory_swap=0.00MB sample#memory_pgpgin=151515pages sample#memory_pgpgout=47388pages
Run Code Online (Sandbox Code Playgroud)

基于上面的代码片段,有时Puma部署将比Webbrick更快,而有时它可能更慢(如代码段所示).即使它更快,速度也不显着,可能只增加1-5个请求/秒.

我的问题是,我做错了什么?我的数据库池有问题吗?我错误地对它进行了基准测试吗?我错误地使用Puma了吗?

编辑:

Puma的最高CPU负载(每个工作5个工作线程和5个线程)

source=web.1 dyno=heroku.123456789 sample#load_avg_1m=2.98
Run Code Online (Sandbox Code Playgroud)

然而,大部分时间,它是0.00或小于0.1.

最重要的是,控制器中调用的唯一代码是:

@package = Package.all
Run Code Online (Sandbox Code Playgroud)

紧接着,之后是渲染在HAML中声明的JSON响应.

顺便说一下,Package.all只返回大约5条记录.

编辑2:

独角兽的结果

根据实施独角兽.跑3名麒麟工人.

Server Software:        Cowboy
Server Hostname:        unicorn-build.herokuapp.com
Server Port:            443
SSL/TLS Protocol:       TLSv1,DHE-RSA-AES128-SHA,2048,128

Document Path:          /api/v1/packages?access_token=f73f50514c6b8a3ea
Document Length:        488 bytes

Concurrency Level:      100
Time taken for tests:   22.311 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      942000 bytes
HTML transferred:       488000 bytes
Requests per second:    44.82 [#/sec] (mean)
Time per request:       2231.135 [ms] (mean)
Time per request:       22.311 [ms] (mean, across all concurrent requests)
Transfer rate:          41.23 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:      846 1326 294.5   1304    2720
Processing:   245  627 342.8    540    3061
Waiting:      244  532 313.6    470    3057
Total:       1232 1954 463.0   1874    4875

Percentage of the requests served within a certain time (ms)
  50%   1874
  66%   2016
  75%   2161
  80%   2250
  90%   2466
  95%   2799
  98%   3137
  99%   3901
 100%   4875 (longest request)
Run Code Online (Sandbox Code Playgroud)

我注意到的一件事是,多次运行相同的ab负载测试代码将返回不同的"每秒请求数".这适用于Unicorn和Puma.对于Unicorn和Puma来说,最好的"每秒请求数"大约为48-50,而最差的大约是25-33.

无论哪种方式,它仍然没有意义.为什么Puma或Unicorn要么粉碎Webbrick?

Mih*_*scu 0

我相信您已经彻底遵循了 Heroku 的《使用 Puma Web 服务器部署 Rails 应用程序》指南。

我的猜测是,您的测试环境最大限度地减少了多线程的优势,或者 HTTP 服务器受到 SQL 数据库的瓶颈。

您的 API 调用(尤其是当它们缓存数据库结果时)可能会占用 CPU 资源。当 CPU 仅由 1 个线程使用 100% 时,拥有 10 个线程并没有什么优势。在这种情况下,管理线程实际上会降低性能。

当工作线程长时间等待资源(数据库、文件等)而不是使用 CPU 时,多线程非常有用。

第二种可能是你的HTTP服务器受到数据库的限制。WEBrick 的移动速度可能与数据库允许的速度一样快,没有通过切换到性能更好的 HTTP 服务器来进行改进。

您应该阅读这份综合基准报告。

您会注意到 Puma 并不是最快的 Rails HTTP 服务器之一。如果您只关心速度,请尝试UnicornTorquebox 4(如果使用JRuby)。

这是有关如何在 Heroku 上设置 Unicorn 的指南。