Cloud Foundry中gorouter源码分析

        在Cloud Foundry v1版本中,router作为路由节点,转发所有进入Cloud Foundry的请求。由于开发语言为ruby,故router接受并处理并发请求的能力受到语言层的限制。虽然在v1版本中,router曾经有过一定的优化,采用lua脚本代替原先的ruby脚本,由lua来分析请求,使得一部分请求不再经过ruby代码,而直接去DEA访问应用,但是,一旦router暴露在大量的访问请求下,性能依旧是不尽如人意。


        为了提高Cloud Foundry router的可用性,Cloud Foundry开源社区不久前推出了gorouter。gorouter采用现阶段比较新颖的go作为编程语言,并重新设计了原有的组件架构。由于go语言本身的特性,gorouter处理并发请求的能力大大超过了router,甚至在同种实验环境下,性能是原先router的20倍左右。


        由于gorouter的高性能,笔者也抱着期待的心态去接触go,当然还有gorouter。本文不会从go语言语法的角度入手gorouter,所以有一些go语言的基础再来看本文,是有必要的。本文主要是对gorouter的源码的简单解读,另外还包含一些笔者对gorouter的看法。


gorouter的程序组织形式


        首先,先从gorouter的程序组织形式入手,可见下图:


        以下简单介绍其中一些重要文件的功能:

        common:common意指通用,所以该文件夹中也是一些比较通识的概念定义,比如varz,healthz,component等,以及关于项目过程的一些基本操作定义。

        config:顾名思义,该文件夹中的文件为gorouter组件的配置文件。

        log:定义gorouter的log形式定义。

        proxy:作为一个代理处理外界进入Cloud Foundry的所有请求。

        registry:处理组件或者DEA中应用到gorouter来注册uri的事件,另外还负责请求访问应用时查找应用真实IP,port。

        route:主要定义在rigistry中需要使用到的三个数据结构:endpoint,pool和uris。

        router:程序的主入口,main函数所在处。

        stats:主要负责一些应用记录的状态,还有一些其他零碎的东西,比如定义一个堆。

        util:其中一般是工具源码,在这里只负责给gorouter进程写pid这件事。

        varz:主要涉及varz信息的处理,其实就是gorouter组件状态的查阅。

        router.go: 主要定义了router的数据结构,及其实例初始化的过程,还有最终运行的流程。


gorouter的功能


        gorouter的功能主要可以分为三个部分:负责接收Cloud Foundry内部组件及应用uri注册以及注销的请求,负责转发所有外部对Cloud Foundry的访问请求,负责提供gorouter作为一个组件的状态监控。


接受uri注册及注销请求


        当Cloud Foundry内一个组件需要提供HTTP服务的时候,那么这个组件则必须将自己的uri和IP一起注册到gorouter处,典型的有,Cloud Foundry中Service Gateway与Cloud Controller通过HTTP建立连接的,另外Cloud Controller也需要对外提供HTTP服务,所以这些组件必须在gorouter中进行注册,以便可以顺利通信或访问。


        除了平台级的组件uri注册,最常见的是应用级的应用uri注册,也就是在Cloud Foundry中新部署应用时,应用所在的DEA会向gorouter发送一个uri,IP和port的注册请求。gorouter收到这个请求后,会添加该记录,并保证可以解析外部的URL访问形式。当然,反过来,当一个应用被删除的时候,为了不浪费Cloud Foundry内部的uri资源,Cloud Foundry会将该uri从gorouter中注销,随即gorouter在节点处删除这条记录。


转发对Cloud Foundry的访问请求


        gorouter接受到的访问请求大致可以分为三种:外部请求有:用户对应用的访问请求,用户对Cloud Foundry内部资源的管理请求;内部的请求有:内部组件之间通过HTTP的各类通信。


       虽然说请求的类型可以分为三种,但是gorouter对于这些请求的操作都是一致的,找到相应的uri,提取出相应的IP和port,然后进行转发。需要注意的是,在原先版本的router中,router只能接收HTTP请求,然而现在gorouter中,已经考虑了TCP连接,以及websocket。


提供组件监控


        Cloud Foundry都有自己的状态监控,可以通过HTTP访问。这主要是每个组件在启动的时候,都作为一个component向Cloud Foundry进行注册,注册的时候带有很多关于自身组件的信息,同时也启动了一个HTTP server。


gorouter的初始化及启动流程


Router对象实例的创建与初始化


        gorouter的启动过程主要在router.go文件中,在该文件中,首先定义创建一个Router实例的操作并进行初始化,另外还定义了Router实例的开始运行所做的操作。

        在router.go文件中,首先需要是Router结构体的定义:

type Router struct {
	config     *config.Config
	……
}
        随后又定义了Router实例的初始化:

func NewRouter(c *config.Config) *Router {
	router := &Router{
		config: c,
	}
        ……
	return router
}
        还有就是定义了Router实例开始运行时所做的操作:

func (router *Router) Run() {
        ……
}
        查看源码可以发现Router结构体有以下几个属性:

  • config:负责传入gorouter所需要的配置信息
  • proxy:一个代理对象,负责完成请求的转发
  • mbusClient:作为gorouter中的nats_client,负责与Cloud Foundry的消息中间件NATS通信
  • registry:作为gorouter中的注册模块,完成Cloud Foundry中注册或注销请求的处理
  • varz:处理gorouter自身作为一个组件的状态监控
  • component:gorouter作为一个组件的信息,将自身的信息存入该component对象

       在初始化Router对象实例的时候,都是通过传入的config文件中的配置文件来完成初始化。首先通过创建一个Router实例,并初始化该实例的配置信息:


                
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值