V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
niuer
V2EX  ›  程序员

[七牛弯区课堂] Ruby 服务间通信模式

  •  
  •   niuer · 2015-04-09 17:00:43 +08:00 · 2257 次点击
    这是一个创建于 3546 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Ruby是计算机语言中的绅士,如果要用一个词来形容,那一定是优雅,有这么一位Rubyist,他的座右铭是“写优雅的程序,做一个优雅的人”,他是来自七牛小伙伴“薄荷”的Co-founder兼CTO谢文威(英文名Vincent)。薄荷的核心系统完全基于Ruby构建,关于Ruby服务间通信模式,他在“七牛弯区课堂”给Ruby爱好者们做了一次分享。

    上图是薄荷App服务划分的例子,各子系统(服务)间需要进行各种通信,主要通信种类如下。

    一、A服务需要使用B服务的一些数据 共享数据库

    应用场景:用户的年龄、性别、身高和体重等数据存储在账号子系统中,其它子系统经常需要使用这些数据。

    处理方式:共享数据库

    App2直接建立连接访问 App1的数据库。这种方式的优点是性能较好,避免了接口处理和消息封装种种开销,适用于通信特别频繁或者数据量特别大的场合。薄荷的账号和会话数据即采取这种方案。但是,该方式导致服务间有很强的耦合,App2对App1的数据结构有紧密的依赖,导致App1的实现难以变更。

    共享数据库方法:

    ActiveRecord支持多数据库配置有一些注意的事项:
    可以使用关联,不支持join,不支持事务
    测试数据最好使用factory_girl
    为避免数据混乱,只有一个服务可写

    共享模型使用
    gem model
    git submodule

    二、A服务需要B服务提供某个计算结果 请求结果(同步)

    应用场景:计算预算热量需要使用复杂的数学模型,它放在记录子系统中实现,别的系统需要用到相关的数据时,通过一种通信机制拿到计算结果。

    处理方式:HttpAPI Call和RPC

    1)Http API Call

    这是最常见的一种通信方式,服务实现方案成熟可靠,具有服务边际简单清晰的特点,同时适用于外部和内部,但内部调用性能不够好。

    使用Http API注意事项
    访问安全控制,使用ip限制,token校验等
    避免调用层次过深,超时机制
    Http Client选择(Http Client特别多,主要分为以下几类)

    薄荷目前typhoeus和faraday用的较多,原因是:typhoeus底层基于curl,性能比较好,并且支持并行,用异步API的方式,比较可靠,不用担心多线程问题。

    2)RPC(Remote Procedure Call)

    主要特点:
    长连接,避免每次通信创建网络连接,性能较好
    对http、消息协议更高效
    多种跨语言RPC方案,如thriftmsgpack_rpc
    RPC管理
    性能上有一定优势,需要权衡其复杂度,复杂度在于服务实现方案和管理方法。
    服务端并发模式
    高可用方案,可用HAProxy
    平滑部署

    RPC的用法比较少见,更多地用于跨多语言的团队,当公司使用多种语言且需要很好地整合时,RPC则是一种比较成熟的方案。

    三、A服务需要B服务处理一项任务 请求任务处理(异步)

    应用场景:在购物模块里面,一个订单发生支付后,需要给用户推送一些信息,比如发短信、邮件和手机推送等。发送消息可能需要比较长的时间才能完成,请求方不需要等待处理结果。

    处理方式:消息队列

    1)传统消息队列系统RabbitMQ/Active MQ
    MQ可以有降低服务之间耦合度,通常用于服务之间的异步处理(传统MQ有更丰富的处理机制),传统MQ ruby服务实现方案,可以参考sneakers, hutch, rack-ampq, rack-rabbit。
    2)在单个应用内部常常使用基于redis的轻量消息队列
    resque&sidekiq
    3)sidekiq-postman

    它是Vincent写的一个gem,基于sidekiq轻量消息队列解决方法,简单实用,可以跨应用请求sidekiq任务处理,以下是其核心代码:

    四、A服务发生某件事,通知B和C进行处理 订阅和通知

    应用场景:比如账号基本信息,基于性能考虑,在子系统中存储了用户名副本。当用户名在账户子系统中发生变化时,需要通知其它子系统更新。

    处理方式:消息队列

    Sidekiq-driver 是Vincent正在写的基于sidekiq轻量订阅和通知解决方法的gem,大家可以尽情期待这个项目的开源。

    • [七牛弯区课堂] 是七牛为广大开发者提供的技术实践分享课堂,后续将定期邀请各技术社区的专家进行分享。以上内容即是Ruby China社区在“七牛弯区课堂”的处女作。欢迎各技术社区的小伙伴来 [七牛弯区课堂] 分享实践心得,也感谢各位为技术社区所贡献的力量。*
    2 条回复    2015-04-10 16:49:43 +08:00
    zjgsamuel
        1
    zjgsamuel  
       2015-04-09 17:09:43 +08:00
    那么七牛弯区课堂 的地址呢?
    anjianshi
        2
    anjianshi  
       2015-04-10 16:49:43 +08:00
    弯区课堂是直男误入的意思吗? XD
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1301 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 17:38 · PVG 01:38 · LAX 09:38 · JFK 12:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.