Ruby on rails 如何调优运行在Heroku上的Ruby on Rails应用程序,该应用程序使用生产级Heroku Postgres?

Ruby on rails 如何调优运行在Heroku上的Ruby on Rails应用程序,该应用程序使用生产级Heroku Postgres?,ruby-on-rails,postgresql,heroku,stress-testing,Ruby On Rails,Postgresql,Heroku,Stress Testing,我工作的那家公司决定把他们所有的人都搬到Heroku去。主要的动机是它的易用性:没有系统管理,没有哭泣。但我还是有一些问题 我正在应用平台和Postgres服务上做一些负载和压力测试。我正在使用blitz作为Heroku的插件。我攻击的用户数在1到250之间的站点。我得到了一些非常有趣的结果,我需要帮助来评估它们 测试堆栈: 应用规范 没有什么特别的 Rails 4.0.4 独角兽 database.yml设置为连接到Heroku postgres 不使用缓存 数据库 这是一个(Heroku

我工作的那家公司决定把他们所有的人都搬到Heroku去。主要的动机是它的易用性:没有系统管理,没有哭泣。但我还是有一些问题

我正在应用平台和Postgres服务上做一些负载和压力测试。我正在使用
blitz
作为Heroku的插件。我攻击的用户数在1到250之间的站点。我得到了一些非常有趣的结果,我需要帮助来评估它们

测试堆栈: 应用规范 没有什么特别的

  • Rails 4.0.4
  • 独角兽
  • database.yml
    设置为连接到Heroku postgres
  • 不使用缓存
数据库 这是一个(Heroku的命名约定总有一天会杀了我:)正确连接到应用程序

Heroku配置 我在unicorn.rb上应用了所有东西,正如“”文章中所说的。我有两个常规的网络动态

WEB_CONCURRENCY  : 2
DB_POOL          : 5
资料
  • 剧集
    表计数100.000~
  • eposion\u URL
    表格计数300.000~
  • 插曲图像
    表格计数75.000~
代码
剧集\u controller.rb

  def index
    @episodes = Episode.joins(:program).where(programs: {channel_id: 1}).limit(100).includes(:episode_image, :episode_urls)
  end
剧集/index.html.erb

<% @episodes.each do |t| %>
<% if !t.episode_image.blank? %>
<li><%= image_tag(t.episode_image.image(:thumb)) %></li>
<% end %>
<li><%= t.episode_urls.first.mas_path if !t.episode_urls.first.blank?%></li>
<li><%= t.title %></li>
<% end %>
结果: 这次冲刺在30秒内成功命中218次,我们 在应用程序内外传输了6.04 MB的数据。平均命中率 每秒7.27次的点击率相当于每天627840次

情景2: 结果: 这次冲刺在30秒内成功命中365次,我们 在应用程序内外传输10.12 MB数据。平均命中率 每秒12.17次的点击率相当于每天1051200次。这个 平均响应时间为622ms

情景3: 结果: 这次冲刺在30秒内成功命中371次,我们 在应用程序内外传输了10.29 MB的数据。平均命中率 每秒12.37次的点击率相当于每天1068480次。这个 平均响应时间为2631ms

情景4: 结果: 这次冲刺在30秒内成功命中484次,我们 在应用程序内外传输了13.43 MB的数据。平均命中率 每秒16.13次的点击率相当于每天1393920次。这个 平均响应时间为1856ms

情景5: 结果: 这次冲刺在30秒内成功命中386次,我们 在应用程序内外传输了10.76 MB的数据。平均命中率 每秒12.87次的点击率相当于每天1111680次。这个 平均响应时间为5446ms

情景6: 结果: 这次冲刺在30秒内成功命中428次,我们 在应用程序内外传输了11.92 MB的数据。平均命中率 每秒14.27次的点击率相当于每天约1232640次。这个 平均响应时间是4793毫秒。你有更大的问题, 尽管如此:26.21%的用户在这一高峰期间经历了超时或延迟 错误

概述:
  • 即使有150个用户向应用程序发送请求,“命中率”也不会超过15
  • 增加web动态对象的数量无助于处理请求
问题:
  • 当我使用caching和memcached(Heroku提供的Memcachier插件)时,即使是2个web dynos也可以处理每秒超过180次的点击。我只是想了解,没有缓存,dynos和postgres服务可以做什么。通过这种方式,我试图了解如何调整它们。怎么做

  • 据说标准天狗有200个并发连接。那么为什么它从来没有达到这个数字呢

  • 如果拥有一个功能级别的数据库和不断增加的网络动态无助于扩展我的应用程序,那么使用Heroku有什么意义呢

  • 可能是最重要的问题:我做错了什么


  • 谢谢你阅读这个疯狂的问题

    我特别发现了这个问题

    首先,请记住我在视图中的代码:

    <% @episodes.each do |t| %>
    <% if !t.episode_image.blank? %>
    <li><%= image_tag(t.episode_image.image(:thumb)) %></li>
    <% end %>
    <li><%= t.episode_urls.first.mas_path if !t.episode_urls.first.blank?%></li>
    <li><%= t.title %></li>
    <% end %>
    
    
    
  • 在这里,我将在迭代中获得每一集的图像。尽管我一直在控制器中使用
    includes
    ,但我的表模式还是犯了一个很大的错误在我的
    插曲图像
    表中,我没有插曲id的索引
    。这导致了极高的查询时间。我是用NewRelic的数据库报告找到的。所有其他查询时间为0.5毫秒或2-3毫秒,但
    插曲。插曲_image
    导致几乎6500毫秒

    我不太了解查询时间和应用程序执行之间的关系,但当我将索引添加到我的
    eposion\u images
    表中时,现在我可以清楚地看到差异。如果数据库模式正确,通过Heroku进行扩展可能不会遇到任何问题。但是,任何dyno都无法帮助您处理设计糟糕的数据库

    对于可能遇到相同问题的人,我想告诉你们一些我关于Heroku web dynos、Unicorn workers和Postgresql主动连接之间关系的发现:

    基本上,Heroku为您提供了一个dyno,它是一种小型虚拟机,具有1个内核和512MB ram。在这个小虚拟机中,您的Unicorn服务器运行。Unicorn有主进程和辅助进程。每个Unicorn Worker都有自己与现有Postgresql server的永久连接(别忘了签出)。这基本上意味着,当Heroku dyno上运行着3个Unicorn Worker时,至少有4个活动连接。如果您有2个web Dyno,则至少有8个活动连接

    假设你有一个标准的天谷博士后,有200个并发连接限制。如果您有问题的查询,数据库设计不好,没有缓存,db或更多dynos都无法保存您的数据。。。我认为,如果您有长时间运行的查询,那么除了缓存之外别无选择

    如果有什么发现的话,以上都是我自己的发现
    HITS 100.00% (484)
    ERRORS 0.00% (0)
    TIMEOUTS 0.00% (0)
    
    Web dynos   : 2
    Duration    : 30 seconds
    Timeout     : 8000 ms
    Start users : 20
    End users   : 20
    
    HITS 100.00% (484)
    ERRORS 0.00% (0)
    TIMEOUTS 0.00% (0)
    
    Web dynos   : 2
    Duration    : 30 seconds
    Timeout     : 8000 ms
    Start users : 50
    End users   : 50
    
    HITS 100.00% (484)
    ERRORS 0.00% (0)
    TIMEOUTS 0.00% (0)
    
    Web dynos   : 4
    Duration    : 30 seconds
    Timeout     : 8000 ms
    Start users : 50
    End users   : 50
    
    HITS 100.00% (484)
    ERRORS 0.00% (0)
    TIMEOUTS 0.00% (0)
    
    Web dynos   : 4
    Duration    : 30 seconds
    Timeout     : 8000 ms
    Start users : 150
    End users   : 150
    
    HITS 71.22% (386)
    ERRORS 0.00% (0)
    TIMEOUTS 28.78% (156)
    
    Web dynos   : 10
    Duration    : 30 seconds
    Timeout     : 8000 ms
    Start users : 150
    End users   : 150
    
    HITS 73.79% (428)
    ERRORS 0.17% (1)
    TIMEOUTS 26.03% (151)
    
    <% @episodes.each do |t| %>
    <% if !t.episode_image.blank? %>
    <li><%= image_tag(t.episode_image.image(:thumb)) %></li>
    <% end %>
    <li><%= t.episode_urls.first.mas_path if !t.episode_urls.first.blank?%></li>
    <li><%= t.title %></li>
    <% end %>