Sin*_*aye 3 ruby apache performance ruby-on-rails
我正在接管Ruby on Rails网站,发现该网站存在巨大的性能问题。有时,该网站甚至没有加载。这对于该网站来说并不新鲜。
它位于具有2gb Ram的Rackspace服务器(第一代)上。
它使用Apache2和MySQL在Ubuntu Hardy上运行。RoR站点正在运行Ruby(1.8.7)和Rails(3.2.1)的旧版本。
根据top(移位m),Apache(res列)每个进程使用大约6mb至10mb。
它使用具有以下规格的prefork mpm:StartServers 2 MinSpareServers 2 MaxSpareServers 2 MaxClients 50 MaxRequestsPerChild 100
并将乘客设置为:PassengerMaxPoolSize 10
乘客内存统计数据显示,Rails平均使用大约40mb。
free -ml始终显示100mb至1500mb的可用内存。
旅客状态有时在等待全局队列中显示高达250,但通常在0到100之间变化。
我曾尝试过使用MaxClients和PoolSize,但最终该网站会变慢或在某个时候根本无法访问,但我认为当流量减少时,稍后可能会再次加载正常。
加载实际的Rails站点有时可能会花费很长时间,但是加载静态文件(图像,txt文件)可以很好地工作。尽管有时会达到甚至无法加载静态文件的地步。
是否有任何尝试使它起作用的指示?对于获得的流量(每月约25万次展示),服务器似乎适合该站点。
编辑:尽管我还是把它放在这里,但我还是回应了评论。
数据库大小约为1gb。垃圾邮件问题很多(新的帐户很明显是垃圾邮件,平均每天大约1k,垃圾邮件的发布/评论等)。到目前为止,Mysql-slow.log没有显示任何内容。
感谢所有的评论。我曾希望这仅仅是我成为Apache或Passenger服务器设置的白痴。我的下一步是开始调查代码和查询。
不知道太多,我只能给出更一般的建议。为了提高网站的性能,请记住性能黄金法则:
最终用户响应时间的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)
Run Code Online (Sandbox Code Playgroud)
App1和App2都遇到性能问题,但是App2的性能问题显然令人沮丧。 但是有了这些服务器日志,我知道我应该研究App1 clients/details.html.erb,而对于App2我绝对需要研究search/livesearch.js.haml。(我发现App2拥有未缓存的大量数据的大型N + 1查询-我稍后会介绍)
为了保持快速的加载时间,您需要减少页面资产(JS / CSS /图像)的数量/大小。因此,请像预算一样考虑您的页面大小。例如,Hootesuite最近宣布他们的主页现在的页面大小预算严格为1 mb。没有例外。现在查看他们的页面。是不是很快?
减少页面大小的简单优势包括剥离未使用的JS或CSS文件(仅在需要时包含它们),以及将静态图像更改为更小的矢量。
图像加载是页面加载时间缓慢的主要原因。初始页面背景中使用的5mb大图像可以轻松缩小到200kb-400kb,并且仍然具有足够高的质量,与高分辨率的原始图像几乎没有区别。页面加载时间的差异会很大。
您也应该对上传的图片执行相同的操作。例如,如果用户为自己的横幅或头像上传了5mb的图像,则至关重要的是,您将以较低的文件大小/分辨率提供此上载的图像,具体取决于将显示的大小。 Carrierwave,Fog和rmagick或minimagic结合使用是一种流行的技术,可与Amazon S3结合使用,以实现更好的图像上传/调整大小。有了它们,您可以动态提供较小的图像分辨率以适合用户的屏幕尺寸。然后,您可以使用媒体查询来确保为移动设备提供比具有Retina屏幕的台式机更小的图像分辨率和文件大小。
如果您的站点处理大量图像或大文件,则应考虑使用诸如Cloudfront之类的内容交付网络(CDN)来加快资产/图像加载时间。CDN将您的资产文件分布在世界各地的许多服务器上,然后使用最接近用户地理区域的服务器来提供资产。除了提高速度外,CDN的另一个好处是它可以减少您自己服务器上的负载。
当静态资产被指纹识别后,当用户访问您的页面时,他们的浏览器将缓存这些资产的副本,这意味着它们不再需要为下一个请求重新加载。
如果还包含其他未使用Rails方式的 javascript文件,请注意,如果将javascript资产放置在页面顶部,则当用户的浏览器尝试加载页面时,页面将保持空白。如果您使用资产管道或使用javascript_include_tag来指定javascript文件,Rails会自动将javascript文件放置在页面底部,以防止出现此问题,但是如果不是这种情况,请确保在页面底部包含外部Javascript文件。
在后端性能优化中,没有任何一项性能增强可与高速缓存所带来的好处相提并论。缓存是将任何Rails应用程序推向高度可扩展性的重要组成部分。良好实施的缓存机制可最大程度地减少服务器对低效率查询的影响,并减少对现有性能不佳的代码进行痛苦的重构的需求。
例如,在上面提到的我的App2示例中,实现了简单的页面缓存后,我们的34秒页面加载时间下降到生产中的不到一秒。 我们没有重构此代码的一行。
经常访问但相对不频繁更改的页面内容最容易缓存,并且从缓存中受益最大。在服务器端有多种缓存方式,包括页面缓存和片段缓存。现在,俄语娃娃缓存是Rails中最受欢迎的片段缓存技术。 这是一个不错的起点。
如果将SQL用于数据库层,请确保在联接表上指定索引,以便在频繁使用的大型关联上更快地查找。您必须在迁移期间明确添加它们,因为Rails默认不包括索引。
使用关系(SQL)数据库的Rails应用程序的主要性能杀手是N + 1查询。如果您在日志中以类似模式的方式看到单个请求的数百个数据库读/写,则很可能您已经遇到了严重的N + 1查询问题。N + 1查询在开发过程中很容易丢失,但是随着数据库的增长,它会迅速削弱您的应用程序(我曾经处理过具有十二个N + 1查询的。在仅累积约1000行生产数据之后,一些页面开始接管一个分钟加载)。
Bullet是在您开发应用程序时尽早捕获N + 1个查询的绝佳工具。 解决Rails应用中N + 1个查询的一种简单方法是急于在必要时加载关联的模型。例如Post.all,Post.includes(:comments).all如果要加载页面上每个帖子的所有评论,则更 改为。
较新版本的Rails包含许多性能改进,可以提高您的应用程序(例如Turbolinks)的速度。如果您仍在运行Rails 3.2.1,则仅出于安全性原因就需要至少升级到Rails 3.2.18。
与旧版Ruby相比,Ruby 2.1.x +包含更好的垃圾回收。到目前为止,有关人员升级的报告发现升级带来了显着的性能提升。
这些是我可以推荐的一些性能改进。没有更多信息,我将无济于事。