首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

可伸缩的高性能 Rails 应用程序开发和部署实践(3)

可伸缩的高性能 Rails 应用程序开发和部署实践(3)

使用 Starling 和 Workling 去异步执行 Rails 后台任务在进行 Web 应用开发时,每个 Web 请求都需要迅速的得到返回,这时候有些计算量比较大的操作可以放在后台去异步执行,比如大量的数据更新操作,只需要在 Web 应用中进行触发,然后在后台进行执行。而有些操作则需要定期去执行,比如数据的备份,一些数据的统计分析,图片的处理,邮件的发送等等。这些操作如果放在 Web 应用中即时返回显然是不合适的,而且也会带来机器的负载很严重,对于 Rails 应用程序来说,除了影响用户体验,这样的操作还会阻塞 Rails 服务器实例,从而带来整体性能的下降。对于这类操作,我们可以使用一个任务队列,将需要执行的操作依次入队,然后在后台再启动进程进队列中取出这些任务,并执行,队列可以使用数据库,Memcached, ActiveMQ 或者 Amazon SQS 来实现,而后端进程则可以使用 Rails 里面的 cronjob+script/runner 或者 BackgrounDRb 等等来操作。这里要介绍的解决方案则是采用 twitter 开发人员贡献出来的采用 Memcache 协议的 Starling 消息队列和 Workling 插件来进行实现。
Starling 是 twitter 开发团队从 twitter 项目抽象出来开源的 Rails 插件,虽然说 Starling 并不完全就是 twitter 的线上版本所用的插件,但我们也可以足以相信 Starling 的性能和应对高并发的处理能力。类似的插件还有 backgroundrb,background job, background_fu。backgroundrb 是使用 drb 实现队列的消息传递,但它还有一个问题,更新队列的时候,backgroundrb 使用的是悲观锁,在大访问量的情况下,这种情况是不容允许的。 background job 和 background_fu 则是基于数据库的消息队列,在大负载量的情况下数据库的性能也不容易得到保证。而 Starling 是基于 Memcached 协议的消息队列,效率更高,也更容易伸缩,通常你可以在每台应用服务器上都运行一个 Starling 服务器,并在同一台机器或者其它机器上去运行后台程序与之交互。
我们通过如下命令来安装 Starling:
清单 4. 安装 Starling
1
2
3
gem sources -a http://gems.github.com/
sudo gem install starling-starling
mkdir /var/spool/starling




在读取 Starling Server 时,我们需要 memcache-client,这个 gem 的 1.5.0 版本有一些问题,在 fiveruns-memcache-client 得到修正,这个 fiveruns-memcache-client gem 在 starling-starling gem 中是作为依赖项自动安装的。
安装完 Starling 之后,使用 sudo Starling -d -p 15151 这个命令来启动它,启动时用 -p 参数来指定所要使用的端口,一般加 -d 参数使它以 daemon 方式在后台运行:
为了明白 Starling 的机制和 Starling 究竟做了哪些工作,在启动了 Starling 之后,我们可以使用我们打开 irb 下面的程序来进行简单的测试:
进行简单的测试
清单 5. 测试 Starling
1
2
3
4
5
6
7
8
9
10
11
>> require 'starling'
=> true
>> Starling = Starling.new('127.0.0.1:15151)
=> MemCache: 1 servers, ns: nil, ro: false
>> Starling.set('test_queue', 123)
=> nil
>> loop { puts Starling.get('test_queue'); sleep 1 }
123
nil
nil
...




这里我们可以看到确实启动了 Server,然后我们向这里插入数据,我们用一个循环去访问这个队列,最后的输出便是我们想要的结果。
接下来我们安装 workling:
清单 6. 安装 workling
1
script/plugin install git://github.com/purzelrakete/workling.git




Workling 支持多种方式来进行后台任务操作,其中就包括上面已经安装的 Starling,安装好 Starling 后,我们需要在 Rails 应用程序中的 environment.rb 加上以下代码来配置 Workling 使用 Starling:
清单 7. 使用 workling
1
Workling::Remote.dispatcher = Workling::Remote::Runners::StarlingRunner.new




Workling 的配置文件在 workling.yml, 和其它 Rails 的配置文件类似,workling.yml 也可以针对不同产品模式进行不同的模式,这里仅列出 production 的配置。
清单 8. Workling 配置
1
2
3
4
5
6
production:
     listens_on:localhost:15151, localhost:15152, localhost:15153
     sleep_time: 2
     reset_time: 30
     memcache_options:
       namespace: myapp




listens_on 参数即为 workling_client 去访问的 Starling 启动的地址和端口,这里可以允许多个 Starling 地址,这就意味着你启动多个 Starling 服务器,而用一个 workling_client 去调用。sleep_time 即为 workling_client 去队列中取数据的等待时间,reset_time 则定义了如果出现 memcache 错误时,workling_client 等待去重建和服务器连接的时间。 在 memcache_options 的 namespace 参数则定义了所使用的命名空间,这在同一台服务器如果为不同的 Rails 应用启动同一个 Starling 服务器时是非常有用的。
用 script/workling_client start 脚本便可以启动 workling_client 进程,有时候我们觉得一个 workling_client 不够用,我们可以修改 script/workling_client start 来支持多个 workling_client 实例,这样每运行 script/workling_client start 一次都会新启动一个 workling_client 实例。
清单 9. 多 client 的 Workling 配置
1
2
3
4
5
6
7
8
9
10
options = {
:app_name   => "workling",
:ARGV       => ARGV,
:dir_mode   => :normal,
:dir        => File.join(File.dirname(__FILE__), '..', 'log'),
:log_output => true,
:multiple   => true,
:backtrace  => true,
:monitor    => true
}

返回列表