Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

介绍 • 关于我 • 谢⽂文威,薄荷科技 Co-founder,CTO,rubyist • 关于薄荷 • 互联⺴⽹网 + 健康公司,核⼼心系统完全基于 ruby 构建

Slide 3

Slide 3 text

ruby 应⽤用的演化 big app db app1 db app2 db app3 db 微服务化(SOA化)是解决系统复杂度的⼀一种有效⽅方法

Slide 4

Slide 4 text

薄荷 app 的例⼦子 薄荷 账户 购物 状态 记录 消息 ⾷食物 计划 按业务垂直划分,⾼高内聚、低耦合, 尽可能减少和简化服务间通信

Slide 5

Slide 5 text

服务间通信种类 • A 服务需要使⽤用 B 服务的⼀一些数据 》 共享数据库 • A 服务需要 B 服务提供某个计算结果 》 请求结果 • A 服务需要 B 服务处理⼀一项任务 》 请求任务处理 • A 服务发⽣生某件事,通知 B 和 C 进⾏行处理 》 订阅和通知

Slide 6

Slide 6 text

• 简单⾼高效 • 耦合度⾼高 • 适⽤用通信特别频繁或者 数据量特别⼤大的场合 共享数据库 app1 app2 db1 db2

Slide 7

Slide 7 text

共享数据库⽅方法 • ActiveRecord ⽀支持多数据库配置 • 可以使⽤用关联,不⽀支持 join,不⽀支持事务 • 测试数据最好使⽤用 factory_girl • 为避免数据混乱,只有⼀一个服务可写 • 如何共享模型 • gem model • git submodule

Slide 8

Slide 8 text

Http API Call • 服务边际简单清晰 • 同时适⽤用外部和内部 • 最常⻅见的通信⽅方式,服 务实现⽅方案成熟可靠 • 内部调⽤用性能不够好 app1 app2 request response

Slide 9

Slide 9 text

Http API 注意事项 • Http Client 选择 • 依赖,性能和并⾏行处理 • 访问安全控制,使⽤用 ip限制,token校 验等 • 避免调⽤用层次过深,超时机制

Slide 10

Slide 10 text

Http Client 参考:rubyhttp-clients-comparison

Slide 11

Slide 11 text

并⾏行 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,性能⾼高,⽀支持并⾏行请求

Slide 12

Slide 12 text

RPC • ⻓长连接,避免每次通信创 建⺴⽹网络连接,性能较好 • 对⽐比 http,消息协议更 ⾼高效 • 多种跨语⾔言 RPC ⽅方案, 如 thrift msgpack_rpc app1 app2 request response

Slide 13

Slide 13 text

RPC 管理 • 性能上有⼀一定优势,需要权衡其复杂度 • 复杂在于服务实现⽅方案和管理⽅方法 • 服务端并发模式 • ⾼高可⽤用⽅方案,可⽤用 HAProxy • 平滑部署

Slide 14

Slide 14 text

消息队列 • 传统消息队列系统 • Rabbit MQ / Active MQ … • 基于 redis 的轻量消息队列 • resque & sidekiq • sidekiq-postman app1 app2 MQ

Slide 15

Slide 15 text

消息队列分析 • 有效降低服务之间耦合度 • 通常⽤用于服务之间的异步任务处理(传统 MQ 有更丰富的 处理机制) • 传统 MQ ruby 服务实现⽅方案,参考 sneakers, hutch, rack-ampq,rack-rabbit

Slide 16

Slide 16 text

sidekiq-postman app1 sidekiq1 app2 sidekiq2 redis sidekiq postman ⼀一种基于sidekiq轻量消息队列解决⽅方法,
 简单实⽤用,我个⼈人写的 gem,即将开源

Slide 17

Slide 17 text

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])  

Slide 18

Slide 18 text

订阅和通知 • 传统消息队列系统 • redis pub/sub • 基于 sidekiq 的 pub/ sub — sidekiq-driver app1 app2 MQ

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

sidekiq-driver app1 app2 app3 driver publish consume consume subscribe subscribe ⼀一种基于sidekiq 轻量订阅和通知解决⽅方法,
 简单实⽤用,我个⼈人正在写的 gem,即将开源

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

招聘 ruby, web 前端,iOS ⾼高级⼯工程师 钱多,妹⼦子多,事情有意思 虚位以待!

Slide 23

Slide 23 text

Thank you & QA • ruby-china: vincent • mail: [email protected] • http://xiewenwei.github.com • 微信:booheeok

Slide 24

Slide 24 text

参考链接 • 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/