我对如何优化我的Ruby on Rails 3.1.3应用程序的Unicorn设置感兴趣。我目前正在高CPU超大型实例上生成14个工作进程,因为我的应用程序似乎在负载测试期间受CPU限制。在模拟负载测试中,每秒大约20个请求重放请求,我的实例上的所有8个核心都达到峰值,并且盒子负载峰值达到7-8。每个独角兽实例使用大约56-60%的CPU。
我很好奇我有什么方法可以优化它?我希望能够将每秒更多的请求汇集到这个大小的实例上。与所有其他I / O一样,内存完全正常。在测试期间,CPU正在变得瘫痪。
答案 0 :(得分:6)
如果你是CPU绑定的,你想要不再使用独角兽进程,否则你会使系统过载并减慢调度程序的速度。您可以使用ab在开发框上测试它。您会注意到2个独角兽将胜过20(数量取决于核心,但概念将成立)。
此规则的例外情况是您的IO绑定。在这种情况下,添加与内存一样多的独角兽。
一个好的性能技巧是将IO绑定请求路由到托管许多独角兽的不同应用服务器。例如,如果您有一个使用慢速SQL查询的请求,或者您正在等待外部请求,例如信用卡交易。如果使用nginx,请为IO绑定请求定义上游服务器,将这些URL转发到包含40个独角兽的盒子。 CPU绑定或非常快速的请求,转发到一个有8个独角兽的盒子(你说你有8个核心,但在aws上你可能想尝试4-6,因为他们的调度程序是超线控的并且已经很忙)。
此外,我不确定你是否可以指望aws为你提供可靠的CPU使用率,因为你获得了一个不明显百分比的百分比。
答案 1 :(得分:1)
首先,您可能不希望实例占45-60%cpu。在这种情况下,如果您遇到流量高峰,您的所有实例都会窒息。
接下来,14个Unicorn实例似乎很大。 Unicorn不使用线程。相反,每个进程都使用单个线程运行。如果能够处理它,Unicorn的主进程只会select
一个线程。因此,核心数量不是衡量Unicorn性能的指标。
更保守的设置可能会为每个实例使用4个左右的Unicorn进程,每秒可能会响应5-8个请求。然后,调整实例数,直到CPU使用率约为35%。这将确保在每秒20个请求压力情况下的稳定性。
最后,您可以使用God
获得更多精确的统计信息和详细信息。
答案 2 :(得分:1)
对于高CPU超大型实例,每秒20个请求非常低。代码可能存在问题。特定于独角兽的问题似乎不太可能发生。如果您有疑问,可以尝试使用其他应用服务器并确认它仍然存在。
在这种情况下,我会考虑的问题......
1 - 您是否在代码中执行CPU密集型操作 - 可能是应该真正存在于数据库中的内容。例如,如果你带回一个大的记录集并在ruby / rails中循环它以对其进行排序或执行其他操作,那么这将解释此级别的CPU瓶颈而不是数据库内的瓶颈。在这种情况下,建议是修改查询以执行更多操作并减轻rails的负担。例如,如果您在控制器中而不是通过sql对结果集进行排序,则会导致类似这样的问题。
2 - 与vanilla crud应用程序相比,您是否正在做任何不寻常的事情,例如访问共享资源,或者争用可能成为问题的任何事情?
3 - 您是否有任何可能会烧毁CPU的循环,尤其是在存在资源争用的情况下?
4 - 尝试解开相关控制器逻辑的各个部分。例如,如果您破解代码只返回静态hello world响应,它的扩展程度如何?我打赌突然麒麟会快速地快速下降。然后尝试添加部分代码,直到找到缓慢的来源。