分享

给Cloud Foundry添加自定义服务

问题导读:
1、Cloud Foundry如何提供可扩展性?
2、Cloud Foundry服务架构有哪些?





上一篇博客介绍了Cloud Foundry系统服务的工作方式,看到两个重要组件:Service Gateway,Service Node。其实这只是服务的冰山一角,Cloud Foundry为了提供服务的可扩展性、管理性,架构设计得非常灵活,见下图:
22.png

Cloud Foundry服务架构

概括为三点:

Service Gateway向外暴露RproEST API;
Service主要有两大组件:Service Gateway和Service Node;
Service Gate与Service Gateway间通过NATS通信。
首先是CloudController与Service Gateway间的REST API。这里有双向,共六组API需要实现:
22.jpg

当然,因为CloudFoundry有一些安全配置项来限制Service,所以还需要在cloud_controller.yml里配置令牌,这部份参考:

向开源软件 Cloud Foundry 添加系统服务中文文档

至此,我们可以宣布一个Service已经开发完成,Service可以被发现,可以进行创建、绑定、解绑、删除等操作。但是上面那一坨东西还没搞呢,可惜CloudFoundry中文的文档到此就没了。其实剩下的部份称作Reference implementation:

Service Gateway处理命令及控制Service;
Service Node是Service运行的虚拟机,它可以动态扩展;
当有一个创建命令来到Service Gateway,它会进行负载均衡,选择一个低负载的Service Node进行创建;
Service Gateway与Service Node可以互相发现,并且通过NATS进行通信。而通信内容不在CloudFoundry规范里面,可以自定义。
有点复杂,如何让开发者可以遵循以上Reference实现呢?熟悉设计模式的朋友肯定能想到模板模式。CloudFoundry提供了一系列基类帮助开发,如果没有什么特别需求,可以直接继承基类放法即可。甚至上面我们提到的六个REST API都不需要我们来实现 ,因为我们所有的Service都需要实现上面六个API,所以VCAP::Services::Base::Gateway已经帮我们做好了,它会解析配置文件后通过asynchronous service gateway.rb提供出那六个API,我们可以直接继承使用这个基类。所以我们真正代码需要写的类有:

provisioner.rb:在接到asynchronous service gateway的调用后它会向NATS发消息,让Service Node执行相对应的操作。一般来说VCAP::Services::Base::Provisioner已经做了绝大部份工作,除非我们需要高级功能,否则直接使用基类即可;
node.rb: 这个类是运行在Service Node的。如果我们继承了VCAP::Services::Base::Node,当Service Node从NATS收到消息后就会触发相应的行为,这里有相应的抽象方法等待我们去实现,譬如provision,unprovision,bind,unbind等等。这里真正操作你提供的服务;
common.rb: 这个可以就一行代码,告诉别人Service的名字;
error.rb: 一般继承VCAP::Services::Base::Error::ServiceError,定义了一些错误消息。
我们可以看到上面那张复杂的架构图经过Cloud Foundry的封装,我们只需要简单的实现几个真正干活的方法即可,另外还能从Cloud Foundry所提供的大量钩子方法来进一步定义服务。

在Service里面,有一些高级功能,例如:Snapshot等,它们的激活与否可以绑定到一个plan。plan在这里的意思是指这个服务的SLA,譬如是收费用户、免费用户、金牌用户等等。我们可针对不同的Level来决定是否对他们开启这项功能。我们可以参考MySQL服务的定义:
  1. plan_management:
  2.    plans:
  3.    free:
  4.       low_water: 10
  5.       high_water: 180
  6.       lifecycle:
  7.         snapshot:
  8.          quota: 5
  9.         serialization: enable
  10.         job: enable
复制代码


我们可以看到MySQL的免费用户也是支持snapshot, serialization和job功能的。我们可以看看snapshot功能的实现,由于Cloud Foundry提供了大量的Base实现,所以实现起来比你想象的要简单得多。我们以创建Snapshot为例,在VCAP::Services::Mysql::Provisioner内,除了继承了VCAP::Services::Base::Provisioner外,还snapshot, serialization和job相关的方法,我们只看创建snapshot的方法:
  1.   def create_snapshot_job
  2.       VCAP::Services::Mysql::Snapshot::CreateSnapshotJob
  3.   end
复制代码


然后去看VCAP::Services::Mysql::Snapshot::CreateSnapshotJob,位置在mysql/lib/job/mysql_snapshot.rb中,
  1. class CreateSnapshotJob < BaseCreateSnapshotJob
  2.    include VCAP::Services::Mysql::Util
  3.    include Common
  4.    def execute
  5.       ...
  6.    end
  7. end
复制代码



看到这应该很明白了吧,snapshot相关的其他方法也是使用类似实现。更多的细节,笔者推荐可以参考下MySQL的实现,这个服务算是Cloud Foundry里面比较早规范的实现,参考价值很高。

另外,Cloud Foundry的服务在一直发展,还有很多值得讨论的话题,例如目前服务模块也引入了warden,使每个租户的服务不影响,同时也不受别的服务影响,这些话题应该可在《深入Cloud Foundry》专栏文章里面针对Service的专文中看到,笔者也会在其他文章里探讨一下。

没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条