V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
AVOSCloud
V2EX  ›  分享发现

AVOS Cloud 实时通信服务架构:微服务和服务发现

  •  2
     
  •   AVOSCloud · 2014-08-19 17:27:37 +08:00 · 3202 次点击
    这是一个创建于 3777 天前的主题,其中的信息可能已经有所发展或是发生改变。
    「微服务」 (Microservice) 是今年特别热的一个概念,Martin Fowler 的文章 对微服务作了详细的介绍。简而言之,微服务鼓励用户把功能拆分以细粒度的服务接口暴露出来,并通过 REST 服务或轻量级消息队列集成。在微服务架构里,一个业务的实现,可能由不同的功能单元组合而实现。

    在 AVOS Cloud,我们提供数据存储、统计、实时通信等不同功能的服务,在实现上,这些功能需要共用基础设施,有的服务本身也根据业务性质的不同拆分功能模块,我们目前就是以这种「微服务」架构思路来实现拆分。有句话说,if you cannot split, you cannot scale.

    以实时通信服务为例,根据功能角色的不同,我们有这样一些模块:

    Push 服务:处理推送的订阅关系,触发推送
    长连接服务器:维持设备与服务的长连接
    Router:应用层的 lookup,负责分配合适的长连接服务器给新设备
    WatchDog:从多台长连接服务器收集运行和统计数据,对异常情况发起报警
    数据存储:群组数据,用户可以通过 API 访问
    HBase:消息记录存储

    模块间的集成,根据业务的特性分别使用 Slacker 远程调用框架和 Kestrel 消息队列。
    对于可能耗时较大的任务,我们通过 Kestrel 队列放到后台执行,避免阻塞前台服务,影响吞吐量。而另一些需要实时的集成,则使用 Slacker 远程调用实现多个进程间的通信。

    Slacker 是一个专门为 Clojure 语言设计的远程调用框架,利用 Slacker 你可以暴露一个 或多个 Clojure 的 namespace 供远程调用。在客户端,Slacker 利用 Clojure 宏 的特性,保持远程调用和本地调用的代码完全一致,这样本地和远程调用的切换只要更改一个 (require) 即可实现,把框架对业务代码的侵入降到最低。此外,Slacker 使用二进制序列化 nippy,在网络连接层面使用异步复用,同时在超时方面也做了良好的控制。

    以上的基础设施帮助我们良好地拆分模块,为下一步的扩展提供了可能。

    服务发现
    长连接服务器是实时通信的功能核心,它的瓶颈在内存和 CPU,可以通过增加部署来达到线性扩展。随着业务量的增加和硬件资源的整合,它可能会面临较频繁的部署变化,另外它也需要有能通过新增部署来快速平滑高峰压力的能力。基于 Pub/Sub 抽象 的消息队列对此有良好的支持,但这对我们以 RPC 为核心的集成方式提出了新的要求,依赖模块也能快速响应服务部署的变化:我们不可能在新增某个服务部署后修改每个依赖的配置再逐一重启。

    在这方面,我们利用了 Slacker Cluster 框架 。他的核心思想是在部署和服务间增加一层抽象:对于服务的消费者而言,只需声明自己所依赖的服务,而无需静态地了解进程的地址。

    所有的服务提供者将自己能够提供的服务注册在 Zookeeper 集群里,并将部署地址注册为 Ephemeral 节点。Ephemeral 节点在创建它的连接断后会自动删除,这样当一个部署下线后,它相应的节点也会自动删除。

    # Zookeeper 目录结构
    ls /slacker/example-cluster/namespaces/
    [my.serviceA, my.serviceB]

    ls /slacker/example-cluster/namespaces/my.serviceA
    [192.168.1.100:2104, 192.168.1.101:2014...]

    所有服务的客户端会 watch 自己感兴趣的 Zookeeper 节点,而部署变化时,所有的客户端都会得到通知,进而刷新服务列表,将流量引向新的节点。

    在实时通信服务中,Router 服务会通过这个 RPC 机制轮询所有在线的长连接服务器,记录他们实时的运行状态。所有的用户设备并非直接连接到固定的长连接服务器,而是先询问 Router,由后者分配一台压力较轻的实例。当有新的长连接服务器部署后,Router 收到通知,新的连接将优先连接这个新进程。此外,监控和数据收集的服务也会自动地把新实例加入管理范围。

    有了这样一套服务发现机制,我们就可以对整个架构中的任意模块随时增减部署,保证服务可以以健康的状态运行。未来,我们还会集成云主机的提供商的 API,来实现基础设施的自动化:当系统压力达到阀值时,云主机自动分配新的资源自动开机,jenkins 自动部署,加上现有的服务发现机制,实现 0 手工操作。这将是云服务运维的新篇。
    5 条回复    2014-08-19 18:30:48 +08:00
    anguslg
        1
    anguslg  
       2014-08-19 17:41:04 +08:00
    看到客户案例是百姓网,对百姓网恨之入骨的人果断没兴趣
    yanng
        2
    yanng  
       2014-08-19 17:47:24 +08:00
    avos有支付相关的功能吗?另外,目前使用avos服务的应用中,有没有完全没有后端服务器,业务又相对比较复杂的?
    AVOSCloud
        3
    AVOSCloud  
    OP
       2014-08-19 17:52:55 +08:00
    @yanng 暂时没有支付功能的,但我们的云代码基本可以解决你想要的功能。后面的问题不好说啊~
    yanng
        4
    yanng  
       2014-08-19 17:57:34 +08:00
    @AVOSCloud 为啥,你们网站上不是也有案例的吗。我在想如果都是比较简单的逻辑,或者只是使用了你们某一项服务,那还是需要服务端的,这样的话服务器都还是需要,那就不是那么牛了。 听说你们新开发了一个用docker的,是否意味着将来可以用go来写云代码部分?
    另外你们的网站很酷炫,但背景那些线条已经影响到文字内容了,而且在ipad上会导致浏览器崩溃。
    AVOSCloud
        5
    AVOSCloud  
    OP
       2014-08-19 18:30:48 +08:00
    @yanng 复杂度不好说是因为不知道什么逻辑才算复杂。但是基于云代码服务,基本上能实现任何想要的逻辑。我们的云代码目前仅支持 node.js, docker做资源隔离。 非常感谢您的反馈~_~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2560 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 11:33 · PVG 19:33 · LAX 03:33 · JFK 06:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.