CloudFoundry源码分析:Service框架(1)

本文主要介绍cloud foundry的service框架,主要内容包括(1)service_gateway的启动过程;(2)service_node的启动过程;以及几个重点流程分析包括(3)服务的注册和注销;(4)服务实例的生成、删除、绑定、解绑

1、service_gateway的启动过程

一个服务的启动过程从VCAP::Services::Base::Gateway(vcap_services_base/lib/base/gateway.rb)的实例化和start方法开始。比如mysql服务:

VCAP::Services::Mysql::Gateway.new.start

启动方法逻辑并不复杂,根据具体的服务生成一个VCAP::Services::Base::Provisioner实例,并以该实例为基础生成VCAP::Services::AsynchronousServiceGateway的实例,VCAP::Services::AsynchronousServiceGateway是sintra/base的子类,从而启动一个以sinatra框架的HTTP服务器,接受请求。

(1)实例化provisioner

VCAP::Services::Base::Provisioner的实例化过程包括VCAP::Services::Base::Base的initialize过程和VCAP::Services::Base::Provisioner的initialize过程。

1)连接nats服务器,连接成功之后,首先注册component组件提供状态查询功能,然后调用on_connect_node方法。

2)定期更新varz

3)定期检测service_nodes的状态是否过期

重点工作在on_connect_node方法,在该方法中

1)注册announce、node_handles、handles、update_service_handle事件

    %w[announce node_handles handles update_service_handle].each do |op|
      eval %[@node_nats.subscribe("#{service_name}.#{op}") { |msg, reply| on_#{op}(msg, reply) }]
    end

2)发布service node discover消息,通过service node向该gateway注册自己

    node_nats.publish("#{service_name}.discover")

(2)实例化VCAP::Services::AsynchronousServiceGateway

VCAP::Services::AsynchronousServiceGateway是Sinatra::Base的子类。

初始化过程主要在setup方法中

  def initialize(opts)
    super
    setup(opts)
  end
首先启动一个周期性的定时器向cloud controller发送heart beat信息,同时也是向cloud controller注册服务

  EM.add_periodic_timer(@hb_interval) { send_heartbeat }

然后通过Kernel实现系统退出时的回调:向cloud controller发送注销信息

  send_deactivation_notice
接着从cloud controller获取所有的handles(service_configs),委托provisioner更新状态

最后provisioner注册handle call back。
(3)启动HTTP服务

Service Gateway的HTTP接口可以参见VCAP::Services::AsynchronousServiceGateway,包括

post '/gateway/v1/configurations'

delete '/gateway/v1/configurations/:service_id'

post '/gateway/v1/configurations/:service_id/handles'

delete '/gateway/v1/configurations/:service_id/handles/:handle_id'


post "/gateway/v1/configurations/:service_id/snapshots"

get "/gateway/v1/configurations/:service_id/snapshots/:snapshot_id"

get "/gateway/v1/configurations/:service_id/snapshots"

put "/gateway/v1/configurations/:service_id/snapshots/:snapshot_id"

delete "/gateway/v1/configurations/:service_id/snapshots/:snapshot_id"

post "/gateway/v1/configurations/:service_id/serialized/url/snapshots/:snapshot_id"

get "/gateway/v1/configurations/:service_id/serialized/url/snapshots/:snapshot_id"

put "/gateway/v1/configurations/:service_id/serialized/url"

put "/gateway/v1/configurations/:service_id/serialized/data"

get "/gateway/v1/configurations/:service_id/jobs/:job_id"

post '/service/internal/v1/restore'

post '/service/internal/v1/recover'

post '/service/internal/v1/check_orphan'

delete '/service/internal/v1/purge_orphan'

post "/service/internal/v1/migration/:node_id/:instance_id/:action"

get "/service/internal/v1/migration/:node_id/instances"

2、service_node的启动过程

一个服务节点的启动过程从VCAP::Services::Base::NodeBin的实例化和start方法开始,比如mysql的节点

VCAP::Services::Mysql::NodeBin.new.start

服务节点的启动过程就是生成VCAP::Services::Base::Node 实例的过程

    EM.run do
      node = node_class.new(options)
      trap("INT") {shutdown(node)}
      trap("TERM") {shutdown(node)}
    end

VCAP::Services::Base::Node同VCAP::Services::Base::Provisioner一样是VCAP::Services::Base::Base的子类,除了读取配置、启动组件服务器之外,连接nats server,主要实现还是由on_connect_node方法中。

在on_connect_node中,node注册了一系列的nats主题

provision、unprovision、bind、unbind、restore、disable_instance、enable_instance、import_instance、update_instance、cleanupnfs_instance、purge_orphan

还有discover和check_orphan。

完成之后将发送send_node_announcement,通过nats消息告诉相应的service_gateway,这个节点可以提供服务了。

publish(reply || "#{service_name}.announce", Yajl::Encoder.encode(a))

3、服务注册与注销

Cloud Foundry平台支持的每种服务都有一个service gateway。service gateway通过HTTP主动向cloud controller发送POST请求完成服务的注册和注销。

Cloud clontroller接收服务注册和解除的uri为:#{@cld_ctrl_uri}/services/v1/offerings。

(1)注册:post #{@cld_ctrl_uri}/services/v1/offerings

Service gateway向Cloud Controller发送的信息包括服务的label、url、plans等。

标志性字段active=true,表示注册该服务。

    @svc_json     = {
      :label  => @service[:label],
      :url    => @service[:url],
      :plans  => @service[:plans],
      :cf_plan_id => @service[:cf_plan_id],
      :tags   => @service[:tags],
      :active => true,
      :description  => @service[:description],
      :plan_options => @service[:plan_options],
      :acls => @service[:acls],
      :timeout => @service[:timeout],
    }.to_json

(2)注销:

Service gateway向Cloud Controller发送的信息包括服务的label、url。

标志性字段active=false,表示注销该服务。

    @deact_json   = {
      :label  => @service[:label],
      :url    => @service[:url],
      :active => false
    }.to_json

4、服务实例的创建、删除、绑定和解绑

(1)创建service实例 post '/gateway/v1/configurations'

首先解析出要创建的service的基础信息,包括label(name 和 version)和plan

    req = VCAP::Services::Api::GatewayProvisionRequest.decode(request_body)

如果名称和版本号不匹配,则返回错误。

    name, version = VCAP::Services::Api::Util.parse_label(req.label)
    unless (name == @service[:name]) && (version == @service[:version])
      error_msg = ServiceError.new(ServiceError::UNKNOWN_LABEL).to_hash
      abort_request(error_msg)
    end

如果该服务名称和版本号匹配,则委托provisioner创建服务实例、

    @provisioner.provision_service(req) do |msg|

(2)删除服务实例 delete '/gateway/v1/configurations/:service_id'

根据参数service_id委托provisioner删除服务实例

 @provisioner.unprovision_service(params['service_id']) 

(3)绑定服务实例到某个应用上 post '/gateway/v1/configurations/:service_id/handles'

首先解析出绑定请求信息:req = VCAP::Services::Api::GatewayBindRequest.decode(request_body)

然后委托provisioner绑定实例

@provisioner.bind_instance(req.service_id, req.binding_options)

(4)解除绑定 delete '/gateway/v1/configurations/:service_id/handles/:handle_id'

同样解析出解绑信息后委托provision实例解绑

@provisioner.unbind_instance(req.service_id, req.handle_id, req.binding_options)

先写到这里吧。后面会接着写一篇专门用来理清cloud controller和service gateway以及service gateway和service node之间的信息交互。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值