导读
首先,所谓的深入解读比较标题党了哈:)只是给大家分享一下我的理解,希望共同进步
我们以一个问题开篇,主要介绍代码结构、接口交互、主要逻辑,最后稍微总结一下,希望能把你讲明白:)
背景问题
思考这么一个问题:paas是多租户的,每个app都希望有自己的域名,比如miui.com、miliao.com、xiaomi.com,为了提高可用性,每个app一般都会有多个instance。OK,想象一下,一个http request过来了,请求的是miui.com(至于怎么过来的CloudFoundry是不管的,自己可以做个cname之类的),CloudFoundry应该如何处理呢?
- 针对这个域名的请求最终应该打到某个instance上,so,应该有个地方来保存路由信息,可不能让miui.com的请求打到miliao.com的instance上去
- 既然有个路由表,那某个instance挂掉的时候或者扩容新增instance的时候,希望能够动态更新这个路由表
- http协议本身是无状态的,如果一会请求instance a,一会请求instance b,就会存在session一致性问题,我们可以用一个简单的策略解决,达到这样的效果:上次这个用户请求打到哪个instance我们记录下来,下次仍使其打到这个instance上;第一次请求就随便喽,不过要有负载均衡的效果
- app不光是http协议提供服务的,还有websocket的、tcp的呢,怎么整?
OK,gorouter就是来解决以上问题的,他保存了一张路由表在内存中,他来做转发,所有的请求都从router节点走,所以性能是个需要注意的问题,cf1.0中使用nginx+lua+ruby来搞效果不是很好,当然,还有一个更普遍的问题,可用性问题:) so,一般来讲,在CloudFoundry平台中,gorouter是部署多个的,前面加一层LVS
代码结构
gorouter的代码地址:https://github.com/cloudfoundry/gorouter,分了不少目录,我们简述一下各个目录的功能,可以认为是代码模块的划分了
- common 通用代码,比如获取本机IP:LocalIP,生成UUID:GenerateUUID,通用组件struct定义:VcapComponent(gorouter设计成一个Component),/healthz接口返回的内容,http权限校验逻辑等等
- config 故名思议,就是处理配置的,通过这个package可以读取gorouter的配置文件
- example_config 里面只是一个配置文件,样例,yaml格式的
- log 这个package是用来打印log的
- proxy 最重要的package,gorouter作为路由节点主要就是干proxy这个事情的,里边定义了如何处理http请求,如何处理websocket请求,如何处理tcp请求
- register 各个app来更新路由表的时候通过这个这个package中的Register和UnRegister方法处理
- route 这个package里是一些数据结构,存储路由表相关信息
- router main函数所在的位置
- stats 保存了一些状态信息,貌似是存储了访问量比较大的app列表,还定义了一个数据结构heap,没仔细看
- test目录没看,谁让他起这么个名字呢
- util 工具性package,只有一个方法,写pid文件
- varz 统计状态并存放到相应数据结构里,比如多少BadRequest,多少BadGatway之类的,/varz接口 会返回这里保存的信息
接口交互
gorouter提供了三个http接口,可以这么调用查看:
# 查看路由表信息的 curl http://router:routerPass@routerIp:routerPort/routes # 健康检查接口 curl http://router:routerPass@routerIp:routerPort/healthz # 状态信息查看接口 curl http://router:routerPass@routerIp:routerPort/varz
上面的router:routerPass分别是在配置文件中配置的user和pass,routerPort就是你配置的port,默认是8082,这个端口提供的接口都是管理性质的接口
gorouter还会同时启动一个http server来监听80端口,处理终端用户的访问请求,最新版本的gorouter直接使用了golang内置的net/http,之前版本还自己定义了蛮多东西
主要逻辑
CloudFoundry内部组件之间通信主要通过NATS来完成,NATS是一个轻量级的基于pub-sub机制的分布式消息队列系统,它负责衔接各组件。
gorouter启动的时候,会往router.start这个channel发送一条消息,之后就是周期性发送了,周期时间由配置项 publish_start_message_interval 指定,发送的消息内容是json格式,定义如下:
type RouterStart struct { Id string `json:"id"` Hosts []string `json:"hosts"` MinimumRegisterIntervalInSeconds int `json:"minimumRegisterIntervalInSeconds"` }
表示说:hi,各位同仁,我是gorouter,我启动了,我的地址是xx,你们有人要注册路由么?如果有需要的话每隔一段时间要给我发一条消息哈
gorouter会订阅router.register,这是各个组件注册路由信息的channel
还会订阅router.unregister,如果有组件想unregister,就发消息到这个channel;另外,如果一个组件长时间(droplet_stale_threshold)不发消息给router.register,router也会把对应的instance从路由表摘掉,router会经常性来做测试,测试周期是:prune_stale_droplets_interval
gorouter已经启动运行一段时间了,一个新的组件加入了,比如dea,他不知道gorouter的地址,怎么办?dea可以给router.greet这个channel发消息,gorouter会订阅这个channel,收到消息之后router会回复一个消息,消息内容跟发往router.start的内容一样,这样dea就获取到gorouter的地址了
OK,通过以上通信,router填充好了本机的路由表信息,开工,接收外部请求:)
router会监控80端口,http协议,一个request过来,router的主要处理逻辑:
1、找到对应的instance,之前提到的session一致性问题就是在这里解决的,cookie中如果有之前的instanceId,就用对应的这个instance,否则就从app对应的Endpoint(保存了instance相关信息)池中随机选取一个
2、判断是否是TcpUpgrade,判断依据:http header中Connection字段的value是upgreade,Upgrade字段的value是tcp,如果是,就用tcp的方式来handle,否则继续
3、判断是否是WebSocketUpgrade,判断依据:http header中Connection字段的value是upgreade,Upgrade字段的value是websocket,如果是,就用websocket的方式来handle,否则继续
4、走到这,说明是个纯粹的http请求,handle it即可
总结一下,起一个web server来监听80端口,拿到一个http request,判断是否是upgrade,如果是就升级为websocket连接或tcp连接,否则就是纯粹的http连接。如果读者了解websocket,对这种处理方式应该感觉很亲切,但是这个所谓的tcp方式有用么?后端rpc接口根本没法用这种方式暴露……反正目前我是没看到有啥用处哈,纯粹就是为了扩展,防止一个类似websocket这种协议出现吧
总结
1、用NATS这种通信方式来链接各个组件,非常松耦合,因为路由表信息没必要严格做到数据一致性,这样一来,router很轻易的部署多个实例,大家都监听相同的channel就都可以得到路由信息了,很方便
2、新版本扩展性更好,所有依赖于http协议的通信方式都可以解决,比如websocket
3、后端rpc模块如何提供服务目前没法解决,感觉可以仅仅把router里的路由信息作为name service来用,业务代码从此处获取原始接口提供方,即多个rpc instance,然后程序内部自己failover,自己去call。没有想到好方法,如果你有的话欢迎交流哦:)
gorouter作为CloudFoundry平台的入口,承载了所有的流量,虽然是个很重要的模块,不过逻辑比较简单,先写这么多,有问题可以留言讨论~:)
参考资料
Cloud Foundry中gorouter源码分析:http://blog.csdn.net/shlazww/article/details/11974411
gorouter源码地址:https://github.com/cloudfoundry/gorouter
NATS:http://limengyun.com/cloudfoundry/nats.html
相关推荐
在CloudFoundryv1版本中,router作为路由节点,转发所有进入CloudFoundry的请求。由于开发语言为ruby,故router接受并处理并发请求的能力受到语言层的限制。虽然在v1版本中,router曾经有过一定的优化,采用lua脚本...
Cloud Foundry是一个开源的平台即服务(PaaS)系统,由Pivotal Software维护,用于构建、部署和管理云...深入研究这些资料,将有助于全面理解Cloud Foundry的最新进展,从而更好地利用这一强大的平台来驱动业务创新。
从如何快速开始使用Cloud Foundry,到深入了解其内部架构和扩展性,书中都提供了系统的说明和指导。 在Cloud Foundry平台上,应用容器化是其一大特色,这意味着应用被打包成标准化的容器,以便能够在任何支持Cloud ...
Spring Cloud为Cloud Foundry中的服务提供了注册与发现机制,通过Spring Cloud Config Server,应用程序可以在运行时动态获取或更新配置信息,使得环境适应性和灵活性大大提升。 Cloud Foundry的健康检查机制与...
本话题主要围绕Cloud Foundry的合作伙伴策略及其在实际应用中的成功案例进行深入探讨。 首先,"喻勇_Cloud Foundry合作伙伴战略和案例分享.ppt"可能涵盖了Cloud Foundry如何与全球范围内的技术提供商、系统集成商和...
在Cloud Foundry生态系统中,开发者可以利用开源的Apache 2.0许可证获取代码,并在GitHub上进行托管。VMware鼓励第三方不仅在自己的CloudFoundry.com平台上部署应用,还可以创建私有云或公共云平台,提供更多的特性...
在探讨“Cloud Foundry中Ruby的应用”这一主题时,我们首先需要深入了解Cloud Foundry与Ruby在现代软件开发和云计算环境中的角色与价值。 ### Cloud Foundry:一个革命性的PaaS平台 Cloud Foundry是一个开放源代码...
【标题】"cloudfoundry-runtime-0.8.4_Java8_cloud_" 指的是一个针对 Cloud Foundry 运行时环境的特定版本,这个版本是为 Java 8 语言定制的。Cloud Foundry 是一个开源的平台即服务(PaaS)系统,允许开发者构建、...
Cloudfoundry
Get started with Cloud Foundry, the leading Platform as a Service (PaaS) that’s dramatically changing how developers, operations practitioners, and especially DevOps teams deploy applications and ...
综上所述,基于CloudFoundry的PaaS云平台的设计与实现,不仅需要深入理解和分析CloudFoundry的技术架构和组件,还需要在实际构建过程中,根据自身的需求进行定制开发。CloudFoundry通过其开放性和对多种语言框架的...
CloudFoundry开源云计算平台简介rar,提供“CloudFoundry开源云计算平台简介”免费资料下载,主要包括Cloud Foundry的概述、Cloud Foundry的架构、使用Cloud Foundry部署应用等内容,可供学习使用。
6. **Droplets**:CloudFoundry中的应用被封装成Droplets,这是运行时环境的容器,包含应用代码及其依赖。 7. **BOSH**:用于部署和管理CloudFoundry的工具,支持跨多个云环境的基础设施管理和更新。 8. **Diego**...
微服务在Cloud Foundry中的应用,可以使开发者快速地部署和运行微服务架构的应用程序,并利用Cloud Foundry提供的各种服务和功能。 Cloud Foundry的主要特点包括开放源代码、支持多种编程语言和框架、以及与企业...
根据给定的信息,本文将深入探讨“Cloud Foundry的弹性设计”,主要围绕以下几个方面进行解析:Cloud Foundry产品概述、架构剖析以及其中的关键模块(如NATS、Router和Warden Container)。 ### Cloud Foundry产品...