话说上次 @luikore 在 RubyConf China 2013 上面演讲提到 Ruby China 在用 Puma 来跑是穿越了!其实之前我和他提到有个 Puma 在跑的应用是另外一个网站。
到今天才切换到 Puma 是因为据之前的测试,Puma 在部署过程有许多小问题,不如 Unicorn 那么稳妥。
SIGUSR2
的方式重启; 于是我就换上了,据今天跑了一下午来看,速度和稳定性不比 Unicorn 差。
之前 Unicorn 在 Ruby China 上面跑了 8 个进程左右 (共 1.5 G 左右)
UPDATE! 2015 年据长期使用来看,Unicorn 和 Puma 的内存消耗,性能都是差不多的。
之前和 @luikore 讨教过关于 Ruby App Server 方面的进程、线程的细节,总结一下我的理解,有错的地方还望指正
threadsafe!
(Rails 4 默认开启)不然 Rails 调用的 Rack::Lock 将导致 Thread 无效 (参考文章)#3 楼 @jiang_plus 上面我有提到啊,之前由于 Unicorn 是单线程多进程模式,进程数量等于并发数量,所以开到了 8 个为高访问的情况准备。而现在 Puma 的多线程模式直接少了 6 个 Ruby 进程。
不过 Puma 用 MRI 跑多线程的模式是否能达到 Unicorn 8 个进程的效果这个还得验证,只是据目前情况来看(Rails log 里面的请求响应时间)和以前没有区别
之前看到 GitLab 用 Puma,我就跟着用了,当时好像是 Puma 2.1.0 之后的确有出现 start 提示要删除 sock 文件的问题,然后看各位大伙都推荐 unicorn、rainbows 什么的,加上 GitLab 又换回 unicorn,所以我又回到 unicorn 了…… 不过这次听了分享说 Puma 很好,所以,计划又一次回到 puma 体验一把
用 Heroku 上的小应用尝试了一下,ab 测试的Requests per second
没有明显变化。看来和 unicorn 相比主要是内存上的优势?
@huacnlee 原来 8 个进程,现在 puma 两个进程,怀疑能否达到原来的请求数量,毕竟 thread 只是在 IO 的时候有作用,反而如果很多请求 (假设 CPU 计算比较多) 进入 thread 反而互相影响,导致进入 thread 的 request 响应时间比以前还要长,如果按照 puma 也起 8 个进程来看消耗的内存也不一定比 unicorn 少
我以为 Unicorn 已经可以达到不中断部属了?http://rubyist.marsz.tw/blog/2013-06-03/unicorn-rails-and-capistrano/
我能问下吗?我不太懂。。。看 lz 说的,ruby 才 8 个进程?能高并发?并发能多高?我看 php 好像都是 128,256 个进程的。。。(fastcgi 的方式跑)。交流学习,勿喷。
Puma 在 MRI 上面只是对 IO 的地方实现多线程了,其他的东西由于 GIL 的原因同一时间只能有一个 Thread 在跑;只有用 JRuby 才能实现完全多线程化;
MRI Ruby 的线程,在 IO 的时候,会自动释放 GIL,只有 JRuby 和 Rubinius 这种无 GIL 的 Ruby 实现,才能实现多线程「并行」,你说的多线程化是指「并行」吧。单 MRI Ruby 的话,多线程依旧可以「并发」。
看过一篇文章,同时使用两个 server,redirect 慢的 IO 多的 request 到 puma,其他的 redirect 到 unicorn
#25 楼 @zj0713001 GitLab 当时换回 unicorn,估计也是当时 puma 不成熟 #17 楼 @JeskTop 我觉得 passenger 装起来很方便,但升级时就比较蛋疼……
之前 robin 发过一个服务器的帖子 http://ruby-china.org/topics/10832 ,有空还打算试试 rainbow 呢,现在业界风向又回到 puma 了吗?
Fetching: puma-2.6.0.gem (100%)
Temporarily enhancing PATH to include DevKit...
Building native extensions. This could take a while...
ERROR: Error installing puma:
ERROR: Failed to build gem native extension.
g:/RailsInstaller/Ruby2.0.0/bin/ruby.exe extconf.rb
creating Makefile
make
generating puma_http11-i386-mingw32.def
compiling http11_parser.c
ext/http11/http11_parser.rl: In function 'puma_parser_execute':
ext/http11/http11_parser.rl:111:3: warning: comparison between signed and unsigned integer expressions
compiling io_buffer.c
io_buffer.c: In function 'buf_to_str':
io_buffer.c:119:3: warning: pointer targets in passing argument 1 of 'rb_str_new' differ in signedness
g:/RailsInstaller/Ruby2.0.0/include/ruby-2.0.0/ruby/intern.h:668:7: note: expected 'const char *' but argument is
compiling mini_ssl.c
In file included from mini_ssl.c:3:0:
g:/RailsInstaller/Ruby2.0.0/include/ruby-2.0.0/ruby/backward/rubyio.h:2:2: warning: #warning use "ruby/io.h" inst
mini_ssl.c:4:25: fatal error: openssl/bio.h: No such file or directory
compilation terminated.
make: *** [mini_ssl.o] Error 1
Gem files will remain installed in g:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/puma-2.6.0 for inspection
Results logged to g:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/puma-2.6.0/ext/puma_http11/gem_make.out
GitLab5.4 切换到 unicorn,然后 GitLab6(2013-8-20 发布) 又切换回到 unicorn 了。看这里 貌似在 MRI 环境下 puma 多线程会有很严重的内存泄露,而且 CPU100% 很高。
We switched from Puma in GitLab 5.4 to unicorn in GitLab 6.0.
why switch back to Unicorn again?
Puma caused 100% CPU and greater memory leaks when running mult-ithreaded on systems with many concurrent users. That's because people used MRI. You MUST use JRuby or Rubynius when using Puma. Or else the world breaks apart.
Mathieu adds in the comments:
Yes, Unicorn is better (but more memory-eager) on MRI setups. Puma is better on Rubinius & JRuby, that's all.
They can't force people to use other implementations of the Ruby Runtime, so they just fell back to the best setup for most setups :) –
今天把一个 Discourse 项目换用 puma 跑了,内存由 1.8G 降到了 400 多 mb,速度也有明显上升…… 4 worker , 8:32 运行之前: 运行时:
#51 楼 @QueXuQ 你说 discourse 还是 rails 项目部署 puma?
Discourse 部分我再优化优化过几天给官方 PR,rails 部署参考:http://tommy.chheng.com/2013/01/23/deploying-a-rails-app-on-nginxpuma-with-capistrano/
只不过这篇文章用的 capistano2,升级到三需要大幅修改…puma 配置文件看官方https://github.com/puma/puma 下的 README 和 Example 下的 config.rb,写得很清楚
看 ruby-china 的源码也可以学习一下
#52 楼 @cassiuschen 哦。说的是 puma。以前安装 passenger 都对照着 passenger 和 nginx 的教程来配置,现在 puma 网上看不到如何连同 nginx 的配置,所有才问问。 那就单独先装好 nginx,然后在根据 puma remadme 的 config 就可以了。等我试试看。
@huacnlee 好像有段时间没上了 rubychina 是用的 Nginx + Puma 吗,咋 Capistrano 没见到 Nginx 相关的部署代码
#56 楼 @u1360749170 不过前几天用 puma 跑 discourse 之后,把 puma 的配置信息 pr 给 discourse 官方,结果对方似乎很介意把负载平衡从 nginx 迁移到 puma,于是就拒绝了 merge……