乘客托管的 Rails 应用程序*痛苦地*慢,但服务器是野兽
Posted
技术标签:
【中文标题】乘客托管的 Rails 应用程序*痛苦地*慢,但服务器是野兽【英文标题】:Passenger hosted Rails app *painfully* slow, but the server is a beast 【发布时间】:2011-01-13 02:56:36 【问题描述】:我一直在努力部署一个相对较大的 Rails 应用程序(Rails 2.3.5),最近进行了一些负载测试,我们发现该站点的吞吐量远低于预期的流量水平。
我们在标准的 32 位服务器、3GB 内存和 Centos 上运行,我们运行 Ruby Enterprise Edition(最新版本)、Passenger(最新版本)和 nginx(最新版本)——当只有一两个用户时该站点运行良好(如您所料),但是当我们尝试将负载增加到约 50 个并发请求时,它会完全死机。 (Apache Bench 报告 ~2.3 req/sec,这是可怕的)
我们正在运行 RPM 并试图确定负载问题出在哪里,但它在 Rails、SQL 和 Memcached 中分布得相当均匀,因此我们或多或少地在优化代码库。
出于绝望,我们启动了一个大型 EC2 实例(Ubuntu 9.10、7.5GB RAM、2 个计算单元/核心)并设置了与原始服务器相同的配置,尽管资源更多,但我们仍然看到可悲的结果.
因此,在花了太多时间尝试优化、使用缓存配置等之后,我决定测试一些 mongrels 的吞吐量,并且 ta-da,它们的性能比乘客好得多。
目前的配置是通过 Nginx 代理 15 个 Mongrel,我们似乎满足了我们的负载要求只是,但这还不足以让我对上线感到满意......我在想什么是否有人知道导致这种情况的一些可能原因...?
我对乘客/nginx 的配置是:
Nginx 工作人员:尝试了 1 到 10 个,但通常是三个。 乘客最大池大小:10 - 30(是的,这些数字相当高) 乘客全局排队:尝试开启和关闭。 NGinx GZip 开启:是值得注意的是,我们已将 nginx 最大客户端主体大小增加到 200m 以允许上传大文件。
无论如何建议都会真的感谢,虽然杂种工作正常,但它改变了我们做事的方式很多,我真的更喜欢使用Passenger - 此外,它不应该这样做吗更简单,性能更好?
【问题讨论】:
仅供参考,解释如下:不同之处在于,杂种生成应用程序的分离实例,因此每个应用程序都有自己的 sql 池,而乘客从单个预初始化的应用程序生成器(即快得多)所以它共享你的 sql 池。 感谢您的解释 - 一旦我们测试了对池的更改(好吧,一旦我阅读了建议),我就变得非常非常清楚 - 正如明智的人经常说的那样,有时你只需要另一个一双眼睛;) 您可能需要修改您的标题,因为这已解决为与 nginx 无关。如果您将 sql 池大小设置得太小,每次部署乘客都会发生这种情况。 @hurikhan77: Phusion 团队的成员claims pools are not shared amongst apps。 @twelve17 现在在 Passenger4 中可能会有所不同。但通常它是这样的(这意味着不在应用程序之间共享,而是在每个应用程序的实例之间共享):池连接被打开,进程分叉(打开的 FD 成为共享),因此池与每个实例共享 【参考方案1】:也许你的 sql pool 太小了?这从本质上限制了应用程序中数据库工作负载的并行性,一旦您将工作放在应用程序堆栈上,这反过来又会增加大量负载...
【讨论】:
哇,我不敢相信我没有想到这一点 - 我们将游泳池提升到更高的数字(是否有“太高”之类的东西?是 50 太高了吗?)和区别是惊人的。非常感谢您的建议 您需要的不会超过您的乘客池大小...也许可以提供 4 或 5 个额外的缓冲区。 这取决于你的内存大小和你的应用程序使用了多少。它应该填充这样的内容:“poolsize * process_size 这就是我们说的database.yml中的'pool'参数吧? +1 通过将池大小加倍以匹配乘客最大池大小,我的应用程序的速度得到了提高【参考方案2】:作为第一步,我将在您的环境中部署一个最小的“Hello World”类型的 Rails 应用程序,并查看您获得的吞吐量。这样做至少会告诉你问题是出在环境还是在应用程序的某个地方。
【讨论】:
以上是关于乘客托管的 Rails 应用程序*痛苦地*慢,但服务器是野兽的主要内容,如果未能解决你的问题,请参考以下文章
如何将远程(用户)IP 从 nginx 传递到托管在 google 容器引擎上的 Rails?
Rails + Elastic Beanstalk + Passenger:更改乘客配置