sidekiq在 Plain Ruby 项目中的使用

来源:互联网 发布:远程桌面数据加密错误 编辑:程序博客网 时间:2024/05/02 04:45

在高并发的场景下,使用异步队列可以解决慢io阻塞的问题,当用户请求到达时,先把消息塞在队列中,然后快速返回, 后台任务再从队列中取出消息慢慢处理。 sidekiq 就是一个用ruby实现的,底层使用redis,的一个异步队列。 


在rails工程中, 请参考 https://github.com/mperham/sidekiq/wiki/Getting-Started   很详细, 在这不过多讨论。 


Goliath 是一个高效的ruby web框架,在 rest full的接口场景下,既能满足效率的要求(上千请求每秒),又开发简单, (建议使用1.0.4版本, 1.0.3版本有一个crash的bug,需要打补丁)。 在这我们来讨论 goliath 这种纯ruby的环境下 sidekiq的使用问题。 



sidekiq的 examples 目录下有一个 por.rb  的文件, 这个就是纯ruby环境下 sidekiq的队列。 

require 'sidekiq'Sidekiq.configure_client do |config|  config.redis = { :namespace => 'x', :size => 1 }endSidekiq.configure_server do |config|  config.redis = { :namespace => 'x' }endclass PlainOldRuby  include Sidekiq::Worker  def perform(how_hard="super hard", how_long=1)    puts "Workin' #{how_hard}"  endend


启动命令  

# RACK_ENV=production bundle exec sidekiq -r ./por.rb -d -L log/sidekiq.log  -c 10  

-c 参数可以指定在一个进程中开启多少个并发, 在任务重的情况下可以考虑多开几个, (但要注意 并发数要小于 数据库连接池的连接数量,否则会导致数据库连接失败,应为并发多,db的连接数不够用)


在goliath代码中, 比如 webapi.rb 中 

class Webapi < Goliath::API  def response(env)    path = env[Goliath::Request::REQUEST_PATH]    case path    when /^\/webapi\/weixin\//        PlainOldRubyWorker.perform_async("test")    #  收到用户的请求,然后异步调用,把消息 塞到 sidekiq的异步队列中    end     [200,{},""]   end end

以上代码是最常见的使用场景, 但有一个问题,随着por中 class 越来越多,sidekiq的并发数量上升, class 任务之间会产生干扰, 一旦某个任务存在性能问题,会导致并发资源都被占用,所以需要一种资源隔离的策略, 重要的任务单独创建一个sidekiq进程。 

对上面的por.rb 文件做改造 

class NotifyWorker  include Sidekiq::Worker  sidekiq_options queue: :notify_worker, retry: 3, backtrace: true    #  这 指定队列的 名称, 重试次数   def perform( openid, msg , msgdata={})    ...    logger.info "-->send to #{openid} ,  #{succ}"  endend

启动命令    -q  参数,当前进程的工作队列,这样就与其他队列隔离开了。 

# RACK_ENV=production bundle exec sidekiq -r ./por.rb -d -L log/sidekiq.log -c 4 -q  notify_worker


注意 por.rb  修改后,  sidekiq 进程 和 goliath进程都需要重启才能生效。 



测试结果如下 :

启动2个 sidekiq  分别指定不同的队列参数 ;

RACK_ENV=production bundle exec sidekiq -r ./por.rb -d -L log/sidekiq.log -c 1 -q  callback_worker
RACK_ENV=production bundle exec sidekiq -r ./por.rb -d -L log/sidekiq.log -c 2 -q  notify_worker


root     23881  0.0  3.0 753132 62644 ?        Sl   16:51   0:02 sidekiq 2.17.1 [0 of 1 busy]

root     23997  0.1  3.3 822924 67788 ?        Sl   16:52   0:02 sidekiq 2.17.1 [0 of 2 busy]


监控 sidekiq的日志输出 

在进程 23881 上处理  callback_worker 任务 

2014-08-12T09:37:06Z 23881 TID-ovw9yoy70 EventCallbackWorker JID-ce334f112b6374b8fc47cde1 INFO: start

在进程 23997 上处理 notify队列相关的任务 

2014-08-12T09:37:07Z 23997 TID-owpks93e0 NotifyWorker JID-b0239ffa243b559dfba1be18 INFO: start


以上,可以达到隔离sidekiq任务的方法。  




0 0
原创粉丝点击