Ruby的多线程应用服务器介绍
随着Rails4.0的发布,Ruby的Web开发社区开始进入多线程的时代了:
从Ruby1.9开始,多线程已经是native thread了,尽管有GIL全局锁的存在,但是对于IO并发来说,已经可以实现并行处理了。
Rails4.0开始,默认打开了多线程运行模式,将推动整个Ruby的Web开发社区迁移到多线程Web模式。
多线程服务器的模型,相比传统多进程服务器模型,可以非常有效的提高IO并发的吞吐量。我现在开发Web应用,已经全部改用多线程了,我写过一个相关的文档介绍:Web并发模型粗浅探讨,有哪些Ruby的应用服务器可以良好的支持多线程呢?
Rainbows
rainbows和unicorn是同一个作者Eric Wong开发的,rainbows和unicorn非常像,他们之间的主要区别就是:unicorn是多进程服务器,rainbows是多线程服务器,此外基本用法,配置都一样的,本身rainbows就是基于unicorn开发的。
unicorn现在被广泛的使用在很多负载非常高的生产环境中,rainbows也和unicorn同样非常稳定。由于Ruby1.9的GIL,多线程并发只能有效使用1颗CPU内核,因此在多核服务器上,需要运行多个rainbows进程。一般来说,服务器有多少CPU内核,就启动多少个rainbows worker进程。每个rainbows进程里面再启动多个线程,因此理想情况下,能够同时处理的IO并发请求数量等于 “进程数” × “线程数”,看一个例子:
rainbows.rb,注意以下3项配置:
use :ThreadPool # 使用线程池模式,进程启动的时候创建好线程数worker_processes 4# 创建多少个进程worker_connections 64# 每个进程创建多少个线程
以上面的配置为例,如果你在一台4核服务器上面部署应用,希望尽量使用服务器资源,那么可以创建4个进程,每个进程创建64个线程,因此整个服务器IO并发处理能力是256个执行线程,这比传统的多进程模式要高得多。
控制rainbows服务器的shell脚本很容易写:rainbows.sh,rainbows和unicorn一样,都是通过给进程发送信号来控制服务器的。
以上的配置启动以后,会有5个rainbows进程:1个master控制进程,4个worker工作进程。master进程负责加载应用程序代码,创建和销毁worker进程,分发请求;worker进程负责处理请求。这个master-workers的工作模式和nginx是一样的。你还可以通过给master进程发送信号,让master进程创建更多worker进程,或者减少worker进程,还可以实现“平滑的重启”,即在不中断web请求服务的同时,重新启动进程,加载新的应用代码,这一点通过: rainbowsctl reload
就可以实现。
此外如果你使用的是Ruby2.0,还可以在rainbows.rb
里面打开 copy on write 特性,如下:
preload_apptrueGC.respond_to?(:copy_on_write_friendly=) andGC.copy_on_write_friendly = true
可以让多个进程共享加载应用程序框架和库的内存空间,节省很多物理内存。
总之对于大型多线程Ruby Web应用,推荐使用rainbows,我使用下来感觉也很不错。
Puma
我在相当长一段时间都不怎么关注puma,因为puma是个单进程多线程服务器,没有cluster模式,不太适合真实有负载的环境,对于多核服务器,启动多进程跑cluster是必须的。但是最近Puma升级到2.0版本以后,也支持了多进程cluster模式,而且也是master-workers的方式,类似nginx和rainbows,请看配置文件:puma.rb
workers 0# 指定创建多少个worker进程,如果0则不打开cluster模式threads 0, 16# 最少线程和最多线程,可根据请求量在这个范围自动伸缩
通过workers设置进程数,通过threads设置线程数,最大IO并发请求量等于进程数乘以最大线程数。Puma比较有意思的地方在于:
通过workers设置,可以在单进程和多进程cluster模式之间自动切换,如果是0,则不启动master进程,只有一个单进程,如果workers不是0,则启动1个master和多个workers。而且master进程不会加载应用代码,master进程占有内存非常少,当然这个的代价就是如果启动workers进程很多,启动时间会很长。
线程可以根据请求量自动在min和max之间伸缩,对于较少的请求,启动的线程数少,可以节省资源。
此外puma也支持“平滑的重启”,也提供了很多有趣的状态控制方式,请看puma.sh Puma启动的时候可以设置一个状态文件,它会把进程的运行状态写进去,方便你控制进程的运行。
Rainbows or Puma
我对Rainbows和Puma做了一些简单的性能压力测试,测试结果表明两者之间的性能差异非常小,Rainbows稍稍胜出。使用哪个,更多取决于个人偏好。我觉得大型应用使用Rainbows更好一些,希望节省服务器资源的小型应用更适合用Puma。这是因为:
Rainbows基于unicorn的代码,稳定性得到了大量高负载应用的考验。
Rainbows提供了很多通过信号控制进程的手段,方便系统管理员干预应用服务器运行。
在单进程模式下Puma只有1个工作进程,单Rainbows仍然会启动master-worker模式,因此Puma的单进程更节省内存。
Puma的线程可以根据请求自动伸缩,对于请求量小的应用,比较节省资源。
Zbatery
zbatery也是unicorn和rainbows的作者Eric Wong开发的,配置文件可以直接用rainbows的,它是rainbows的简化版本,只支持单进程多线程,没有master进程,信号支持的也不完整,而且很久没有升级过了。比较正规的生产环境可能就不太适合了。但zbatery的好处是特别节省内存,比单进程的puma还要节省很多内存,如果你想在一个VPS上跑很多web应用,每个web应用流量都很小,那用zbatery到非常合适。
建议继续学习:
- 每个程序员都应该学习使用Python或Ruby (阅读:16343)
- 我的PHP,Python和Ruby之路 (阅读:11919)
- 浅析C++多线程内存模型 (阅读:7185)
- C++ 多线程编程总结 (阅读:6863)
- 多线程队列的算法优化 (阅读:6590)
- Ruby 和 Python (阅读:5763)
- 程序中的“多线程” (阅读:5786)
- 为什么我们要从 NodeJS 迁移到 Ruby on Rails (阅读:5471)
- php多线程扩展 (阅读:4348)
- 为什么在多线程程序中要慎用volatile关键字? (阅读:4068)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:robbin的自言自语 来源: robbin的自言自语
- 标签: Ruby 多线程
- 发布时间:2013-05-14 22:28:48
- [2754] 前端必须熟悉的10个CSS3属性
- [201] QR码分析
- [68] Oracle MTS模式下 进程地址与会话信
- [67] 如何拿下简短的域名
- [67] Twitter/微博客的学习摘要
- [66] 【社会化设计】自我(self)部分――欢迎区
- [63] Go Reflect 性能
- [61] android 开发入门
- [57] IOS安全–浅谈关于IOS加固的几种方法
- [57] 流程管理与用户研究