Ruby 服务间通信模式

Ruby 服务间通信模式

1. 共享数据库:共享数据和模型
2. 请求结果(同步)Http API & RPC
3. 请求任务处理(异步):消息队列
4. 订阅和通知:消息队列

26631f3b69f8975167d9475014494b06?s=128

Vincent Xie

March 30, 2015
Tweet

Transcript

  1. ruby 服务间通信模式 薄荷 vincent 2015.3.29

  2. 介绍 • 关于我 • 谢⽂文威,薄荷科技 Co-founder,CTO,rubyist • 关于薄荷 • 互联⺴⽹网

    + 健康公司,核⼼心系统完全基于 ruby 构建
  3. ruby 应⽤用的演化 big app db app1 db app2 db app3

    db 微服务化(SOA化)是解决系统复杂度的⼀一种有效⽅方法
  4. 薄荷 app 的例⼦子 薄荷 账户 购物 状态 记录 消息 ⾷食物

    计划 按业务垂直划分,⾼高内聚、低耦合, 尽可能减少和简化服务间通信
  5. 服务间通信种类 • A 服务需要使⽤用 B 服务的⼀一些数据 》 共享数据库 • A

    服务需要 B 服务提供某个计算结果 》 请求结果 • A 服务需要 B 服务处理⼀一项任务 》 请求任务处理 • A 服务发⽣生某件事,通知 B 和 C 进⾏行处理 》 订阅和通知
  6. • 简单⾼高效 • 耦合度⾼高 • 适⽤用通信特别频繁或者 数据量特别⼤大的场合 共享数据库 app1 app2

    db1 db2
  7. 共享数据库⽅方法 • ActiveRecord ⽀支持多数据库配置 • 可以使⽤用关联,不⽀支持 join,不⽀支持事务 • 测试数据最好使⽤用 factory_girl

    • 为避免数据混乱,只有⼀一个服务可写 • 如何共享模型 • gem model • git submodule
  8. Http API Call • 服务边际简单清晰 • 同时适⽤用外部和内部 • 最常⻅见的通信⽅方式,服 务实现⽅方案成熟可靠

    • 内部调⽤用性能不够好 app1 app2 request response
  9. Http API 注意事项 • Http Client 选择 • 依赖,性能和并⾏行处理 •

    访问安全控制,使⽤用 ip限制,token校 验等 • 避免调⽤用层次过深,超时机制
  10. Http Client 参考:rubyhttp-clients-comparison

  11. 并⾏行 http request require  'typhoeus'   require  'typhoeus/adapters/faraday'   response1,

     response2  =  nil   conn  =  Faraday.new(:url  =>  "http://coolness.com")  do  |faraday|      faraday.adapter  :typhoeus   end   conn.in_parallel  do      response1  =  conn.get('/one')      response2  =  conn.get('/two')      #  these  will  return  nil  here  since  the      #  requests  haven't  been  completed      response1.body      response2.body   end net/http, excon, parton and more typhoeus 基于 libcurl,性能⾼高,⽀支持并⾏行请求
  12. RPC • ⻓长连接,避免每次通信创 建⺴⽹网络连接,性能较好 • 对⽐比 http,消息协议更 ⾼高效 • 多种跨语⾔言

    RPC ⽅方案, 如 thrift msgpack_rpc app1 app2 request response
  13. RPC 管理 • 性能上有⼀一定优势,需要权衡其复杂度 • 复杂在于服务实现⽅方案和管理⽅方法 • 服务端并发模式 • ⾼高可⽤用⽅方案,可⽤用

    HAProxy • 平滑部署
  14. 消息队列 • 传统消息队列系统 • Rabbit MQ / Active MQ …

    • 基于 redis 的轻量消息队列 • resque & sidekiq • sidekiq-postman app1 app2 MQ
  15. 消息队列分析 • 有效降低服务之间耦合度 • 通常⽤用于服务之间的异步任务处理(传统 MQ 有更丰富的 处理机制) • 传统

    MQ ruby 服务实现⽅方案,参考 sneakers, hutch, rack-ampq,rack-rabbit
  16. sidekiq-postman app1 sidekiq1 app2 sidekiq2 redis sidekiq postman ⼀一种基于sidekiq轻量消息队列解决⽅方法,
 简单实⽤用,我个⼈人写的

    gem,即将开源
  17. sidekiq-postman 核⼼心代码            #  deliver  job

                 def  deliver(worker,  arguments,  options={})                  msg  =  {  'class'  =>  worker,                                    'args'  =>  arguments,                                    'jid'  =>  SecureRandom.hex(12),                                    'retry'  =>  options[:retry]  ||  true,                                    'enqueued_at'  =>  Time.now.to_f                  }                  redis_connection.lpush("#{@namespace}:queue:default",  JSON.dump(msg))              end   Sidekiq::Postman.deliver("rd",  
    "PushHisWeightsToQqWorker",  [user.user_key])  
  18. 订阅和通知 • 传统消息队列系统 • redis pub/sub • 基于 sidekiq 的

    pub/ sub — sidekiq-driver app1 app2 MQ
  19. 订阅和通知 • 有效反转消息发布者的 依赖⽅方向 • 进⼀一步降低系统耦合度, 更⽅方便扩展 • 中间⼈人⾓角⾊色必须存在 app1

    app2 MQ app2 … consume publish
  20. sidekiq-driver app1 app2 app3 driver publish consume consume subscribe subscribe

    ⼀一种基于sidekiq 轻量订阅和通知解决⽅方法,
 简单实⽤用,我个⼈人正在写的 gem,即将开源
  21. 常⻅见通信模式总结 • 1. 共享数据库:共享数据和模型 • 2. 请求结果(同步):Http API,RPC • 3.

    请求任务处理(异步):消息队列 • 4. 订阅和通知:消息队列
  22. 招聘 ruby, web 前端,iOS ⾼高级⼯工程师 钱多,妹⼦子多,事情有意思 虚位以待!

  23. Thank you & QA • ruby-china: vincent • mail: ok@boohee.com

    • http://xiewenwei.github.com • 微信:booheeok
  24. 参考链接 • www.slideshare.net/HiroshiNakamura/rubyhttp-clients-comparison • https://thrift.apache.org/ • https://github.com/msgpack-rpc/msgpack-rpc • https://github.com/jondot/sneakers •

    https://github.com/gocardless/hutch • https://github.com/rack-amqp/rack-amqp • http://codeincomplete.com/posts/2014/9/4/introducing_rackrabbit/