我正在接管Ruby on Rails网站,我发现该网站存在巨大的性能问题。有时网站甚至没有加载。这对网站来说并不新鲜。
它位于拥有2GB Ram的Rackspace Server(第一代)上。
它使用Apache2和MySQL在Ubuntu Hardy上运行。 RoR站点运行旧版本的Ruby(1.8.7)和Rails(3.2.1)。
根据top(shift m),Apache(res列)每个进程使用大约6mb到10mb。
它使用prefork mpm以下规格: StartServers 2 MinSpareServers 2 MaxSpareServers 2 MaxClients 50 MaxRequestsPerChild 100
乘客将拥有: PassengerMaxPoolSize 10
Passenger-memory-stats显示Rails平均使用大约40mb。
free -ml始终显示100mb到1500mb的可用内存。
乘客状态有时在等待全局队列时显示高达250,但通常在0到100之间变化。
我尝试过使用MaxClients和PoolSize,但最终网站会迟缓或者在某些时候无法访问,但可能,我假设当流量缓解时,稍后会再次加载。
加载实际的Rails站点有时可能会花费很长时间,但加载静态文件(图像,txt文件)可以正常工作。虽然有时它甚至无法加载静态文件。
试图让这个工作的任何指针?对于它获得的流量(每月约250万次展示),服务器似乎应该适用于此网站。
编辑: 我回答了评论,不管怎样我都把它放在这里。
数据库大小约为1GB。有相当多的垃圾邮件问题(新帐户是明显的垃圾邮件,平均每天约1k,垃圾邮件/评论等)。到目前为止,Mysql-slow.log没有显示任何内容。
感谢所有评论。我原本以为我只是在Apache或Passenger服务器设置上做个白痴。我接下来的步骤是开始调查代码和查询。
答案 0 :(得分:4)
我不知道多少,我只能提供更一般的建议。为了提高网站效果,请记住the Perfomance Golden Rule:
最终用户响应时间的80-90%用于前端。从那里开始。
以下是非详尽的列表,以提高Rails应用程序的性能:
用于识别性能问题的有用的诊断工具是Yslow。它是一个浏览器扩展程序,用于诊断和识别减慢应用程序速度的常见问题(特别是在前端)。
对于您的Rails后端,我建议使用Bullet&等工具。 NewRelic直接进入您的开发流程,以便在您开发过程中,您可以立即发现错误的查询,同时仍然可以轻松修复。
检查服务器日志是诊断Rails应用程序的哪些组件花费时间最长的有效方法。例如。下面是来自我本地开发环境中运行的两个不相关的生产Rails应用程序的示例日志(排除了巨大的数据库i / o部分):
# app1: slowish
Rendered shared/_header.html.erb (125.9ms)
Rendered clients/details.html.erb within layouts/application (804.6ms)
Completed 200 OK in 3655ms (Views: 566.9ms | ActiveRecord: 1236.9ms)
# app2: debilitatingly slow
Rendered search/_livesearch_division_content.js.erb (5390.0ms)
Rendered search/livesearch.js.haml (34156.6ms)
Completed 200 OK in 34173ms (Views: 31229.5ms | ActiveRecord: 2933.4ms)
App1& App2的性能问题都很严重,但App2的性能问题显然很慢。但是对于这些服务器日志,我知道App1我应该调查clients/details.html.erb
,对于App2我绝对需要调查search/livesearch.js.haml
。 (我发现App2已经解密了大量数据的大量N + 1查询 - 我稍后会对此进行处理)
为了保持快速加载时间,您需要减少页面资源的数量/大小(JS / CSS / Images)。因此,请考虑您的页面大小,如预算。例如,Hootesuite最近声明他们的主页现在有一个严格的页面大小预算 1 mb。没有例外。 Now check out their page. Pretty fast isn't it?
减少页面大小的轻松胜利包括删除未使用的JS或CSS文件,仅在需要时包括它们,并将静态图像更改为更小的向量。
图像加载是导致页面加载速度慢的一个重要原因。在启动页面背景中使用的大型5mb图像可以很容易地降低到200kb-400kb的尺寸,并且仍然具有足够高的质量,几乎与高分辨率原件无法区分。页面加载时间的差异将是巨大的。
您也应该对上传的图片执行相同操作。例如。如果用户为其横幅或头像上传了5mb图像,那么根据要显示的尺寸,以较低的文件大小/分辨率提供此上传的图像至关重要。 Carrierwave,Fog,结合rmagick或minimagic是与Amazon S3一起使用的流行技术,可实现更好的图像上传/调整大小。使用它们,您可以动态提供较小的图像分辨率,以适应用户的屏幕大小。然后,您可以使用媒体查询来确保移动设备获得较小的图像分辨率和图像分辨率。文件大小比使用Retina屏幕的桌面大。
如果您的网站处理大量图片或大型文件,那么您应该考虑使用Cloudfront之类的内容分发网络(CDN' s)来加快资产/图像加载时间。 CDN将您的资产文件分发到遍布全球的许多服务器,然后使用最靠近用户地理区域的服务器来为资产提供服务。除了更快的速度之外,CDN的另一个好处是它可以减少您自己服务器上的负载。
当静态资产被指纹识别时,当用户访问您的页面时,他们的浏览器将缓存这些资产的副本,这意味着不再需要为下一个请求重新加载它们。
如果在不使用 Rails方式的情况下包含其他javascript文件,那么请注意,如果javascript资源放在页面顶部,那么页面将在其加载时保持空白用户的浏览器尝试加载它们。如果您使用资产管道或使用javascript_include_tag
指定javascript文件来防止此问题,Rails会自动将javascript文件放在页面底部,但如果不是这样,请确保外部Javascript文件包含在页面底部。
在后端性能优化中,没有任何单一的性能增强可以接近匹配缓存提供的好处。缓存是推动任何Rails应用程序实现高可伸缩性的重要组成部分。良好实施的缓存机制极大地减少了您的服务器对低效查询的暴露,并且可以减少对现有非性能代码进行痛苦重构的需要。
例如,通过我上面提到的App2示例,在我们实现了一个简单的页面缓存之后,我们的 34秒页面加载时间下降到不到一秒 在制作中。 我们没有重构此代码的一行。
经常访问 的页面内容,但相对不经常更改最容易缓存并从缓存中获益最多。有多种方法可以在服务器端缓存,包括页面缓存和片段缓存。 Russian doll caching现在是Rails中受欢迎的片段缓存技术。 Here's a good place to start.
如果要将SQL用于数据库层,请确保在连接表上指定索引,以便更快地查找经常使用的大型关联。您必须在迁移期间明确添加它们indexing is not included by default in Rails.
使用关系(SQL)数据库的Rails应用程序的主要性能杀手是N+1 queries。如果您在日志中以类似于模式的方式在单个请求中看到数百个数据库读/写,那么您可能已经遇到了严重的N + 1查询问题。在开发过程中很容易错过N + 1个查询,但随着数据库的增长,可能会迅速削弱您的应用程序(我曾经处理了一个有12个N + 1查询的查询。在累积了大约1000行的生产数据之后,一些页面开始采用超过一分钟加载)。
Bullet是catching N+1 queries early as you develop your app.的绝佳宝石。在Rails应用中解析N + 1查询的简单方法是在必要时急切加载相关模型。例如。如果您要加载页面上每个帖子的所有评论,则Post.all
会更改为Post.includes(:comments).all
。
较新版本的Rails包含许多性能改进,可以加速您的应用程序(例如Turbolinks。)如果您仍在运行Rails 3.2.1,那么您需要升级到至少Rails 3.2 .18仅出于安全原因。
Ruby 2.1.x +包含比旧版Ruby更好的垃圾收集。到目前为止,有关人员升级的报告已找到notable performance increases from upgrading.
我可以推荐一些性能改进。没有更多信息,我可以提供很多帮助。
答案 1 :(得分:0)
仅索引正常访问的模型。这应该会给你带来显着的性能提升。