Gem Ruby China 已经正式换成 Puma 来跑了!

huacnlee for Ruby China · 2013年10月29日 · 最后由 StephenZzz 回复于 2019年06月12日 · 33166 次阅读
本帖已被管理员设置为精华贴

话说上次 @luikore 在 RubyConf China 2013 上面演讲提到 Ruby China 在用 Puma 来跑是穿越了!其实之前我和他提到有个 Puma 在跑的应用是另外一个网站。

到今天才切换到 Puma 是因为据之前的测试,Puma 在部署过程有许多小问题,不如 Unicorn 那么稳妥。

但是最近 Puma 2.6.0 发布以后,明显好多了:

  • 多进程模式,并且也有 Copy on Write 机制;
  • Capistrano 部署脚本集成
  • 重启连接不断开(不会出现 Nginx 502)
  • 支持 SIGUSR2 的方式重启;

于是我就换上了,据今天跑了一下午来看,速度和稳定性不比 Unicorn 差。

之前 Unicorn 在 Ruby China 上面跑了 8 个进程左右 (共 1.5 G 左右)

目前 Puma 的状况:

  • MRI Ruby 2.0, Rails 4
  • 2 4 进程(由于有了线程暂时两个进程就够用了),400M 内存耗费
  • 8 - 32 个线程

UPDATE! 2015 年据长期使用来看,Unicorn 和 Puma 的内存消耗,性能都是差不多的。


Puma 以及 Rails 跑多线程应用的细节

之前和 @luikore 讨教过关于 Ruby App Server 方面的进程、线程的细节,总结一下我的理解,有错的地方还望指正

  1. Puma 的多线程在 MRI 上面只是对有 IO 的地方才有效果,其他的东西由于 GIL 的原因同一时间只能有一个 Thread 在跑;只有用 JRuby 才能实现完全多线程化;
  2. 用 Puma 得开启 threadsafe! (Rails 4 默认开启)不然 Rails 调用的 Rack::Lock 将导致 Thread 无效 (参考文章)
  3. 当用 JRuby 跑 Puma 的时候,进程数量应该设置成和 CPU 核数一样;
  4. Puma -t 参数指定的每个进程的线程数量;
  5. 由于 MRI 只能调用一个核,所以,和 Unicorn 一样,Puma 的进程数量应设成与 CPU 核数一样,以便能充分利用资源,如果数量超过核数,反而会由于进程抢占资源过程的开销带来性能损耗;

以后我也试试。

果断跟风

分享中提到 Puma 的优势是比 Unicorn 省很多内存,目前有体现这个优势吗

#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/

#15 楼 @lulalala 确实已经可以了啊

passenger 一直都可以不中断部署所有一直用,但是很多人推 unicorn,还搞不懂原因。现在想试用 puma 看看。

内存优势,因为 Copy on Write 机制 吗?

关注一下~

我能问下吗?我不太懂。。。看 lz 说的,ruby 才 8 个进程?能高并发?并发能多高?我看 php 好像都是 128,256 个进程的。。。(fastcgi 的方式跑)。交流学习,勿喷。

@huacnlee

Puma 在 MRI 上面只是对 IO 的地方实现多线程了,其他的东西由于 GIL 的原因同一时间只能有一个 Thread 在跑;只有用 JRuby 才能实现完全多线程化;

MRI Ruby 的线程,在 IO 的时候,会自动释放 GIL,只有 JRuby 和 Rubinius 这种无 GIL 的 Ruby 实现,才能实现多线程「并行」,你说的多线程化是指「并行」吧。单 MRI Ruby 的话,多线程依旧可以「并发」。

@huacnlee thread_num = CPU_core_number - 1?

关注,有空试试

#22 楼 @shawnyu Puma 进程数量考虑和 CPU Core 一样。线程数量可根据负载情况来看,比如从 4 个 Unicorn 进程转过来,可以考虑 1 个 puma 进程 4 个线程或者 2 个 puma 进程 2 个线程,当然也可以先直接使用 puma 默认的 16 个线程。

#8 楼 @imlcl 我的 gitlab 已经切到 puma 了 从日志来看没有太大差别 但是内存省了 50%

重启时会不会内存泄露 cpu 飙升,或者直接起不起来?在 puma 2.0 的时候碰见过这两个 bug,至今心有余悸。

看过一篇文章,同时使用两个 server,redirect 慢的 IO 多的 request 到 puma,其他的 redirect 到 unicorn

#25 楼 @zj0713001 GitLab 当时换回 unicorn,估计也是当时 puma 不成熟 #17 楼 @JeskTop 我觉得 passenger 装起来很方便,但升级时就比较蛋疼……

感谢楼主分享!

捎带问一句,楼主有没有做过 rainbows 和 Rails 4 的搭配测试?感觉如何?

30 楼 已删除

#26 楼 @iamroody 我觉得这个 Bug 在 Thin 上更常见…

之前 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

好像缓存 CacheStore 貌似都不支持 connection pool,在多线程状态下会不会出现性能问题

#34 楼 @yakczh 似乎是缺少 openssl 的头文件,最好在 msys 里编译安装一个

#25 楼 @zj0713001 多线程自然省内存。

期待 jruby + torquebox

啥时候换成 JRuby 或 Rubinius 跑跑

哦。rubychina 都 rails4 了啊?好前卫~!

我们用 GitLab 的时候没发现 Puma 省多少内存,可能是默认配置的原因。。

继续观望一段时间

之前也出现过 Puma 内存吃的很紧的情况,可能现在 2.6.0 好了点,之前部署问题多多~

留言回帖都很快,赞一个。

为什么没有人用 thin 呢?好像都没人提及这个哦

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 运行之前: 运行时:

#50 楼 @cassiuschen 哥们,有教程不,我也打算上 puma 了。

#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 就可以了。等我试试看。

#53 楼 @QueXuQ 嗯…nginx 部署大同小异,因为都是靠 socket 连接,passager 我没用过,以前 thin 的多 worker 是多次允许 thin server,生成多个 sock,然后在 nginx 里负载均衡,puma 只有一个 sock,内部负载均衡

@huacnlee 好像有段时间没上了 rubychina 是用的 Nginx + Puma 吗,咋 Capistrano 没见到 Nginx 相关的部署代码

#50 楼 @cassiuschen 不错,我的新项目将果断跑 Puma

#56 楼 @u1360749170 不过前几天用 puma 跑 discourse 之后,把 puma 的配置信息 pr 给 discourse 官方,结果对方似乎很介意把负载平衡从 nginx 迁移到 puma,于是就拒绝了 merge……

匿名 #59 2013年11月24日

#55 楼 @feitian124 capistrano v2 的有现成文件可以引用

#50 楼 @cassiuschen 你原来使用的是什么?thin 还是 passager

#60 楼 @todaynet 没用过 passager……唯一一次用 Passager+Apache 结果内存溢出,我阿里云整台服务器崩溃……上面部署的 php 什么的全宕机来着……后来不敢再使用 passager 了……

redmine 也用 puma 跑一下试试,虽然并发量不是很大

64 楼 已删除

类似于 python 下 flask 的东西么?

Great. 我现在也在用了。你的研究成果,解决了我一些疑问。

好东西

嘛,刚刚学 ruby。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号