cloud foundry之router源码分析

cloud foundry的源码解析一览(cloud controller,dea) 关于cloud foundry 的源码解析的文章很多,最近我也在研究这个东西,感觉内容比较多,也相对比较复杂,我在这里做一个整合,方便大家了解。 1.CloudController 了解整个Cloud Foundry需要熟悉的内容很多,但最核心的东西是nats和event-machine. 关于nats上一篇已经做了介绍,大家可参考基于Cloud Foundry的PaaS实践(二) Clo 阅读详情

前面的文章已经介绍了整个cloud foundry的源码的启动过程,这篇文章介绍一下router方面的细节,毕竟外界访问cloud foundry的入口就是router。。

首先来看router的启动:

/home/fjs/cloudfoundry/vcap/router/bin/router -c /home/fjs/cloudfoundry/.deployments/devbox/config/router.yml
接下来进入源码来看看。。。
config_path = ENV["CLOUD_FOUNDRY_CONFIG_PATH"] || File.join(File.dirname(__FILE__), '../config')
config_file = File.join(config_path, 'router.yml')
port, inet = nil, nil

options = OptionParser.new do |opts|
  opts.banner = 'Usage: router [OPTIONS]'
  opts.on("-p", "--port [ARG]", "Network port") do |opt|
    port = opt.to_i
  end
  opts.on("-i", "--interface [ARG]", "Network Interface") do |opt|
    inet = opt
  end
  opts.on("-c", "--config [ARG]", "Configuration File") do |opt|
    config_file = opt   #/home/fjs/cloudfoudnry/.deployments/devbox/config/router.yml
  end
  opts.on("-h", "--help", "Help") do
    puts opts
    exit
  end
end
options.parse!(ARGV.dup)

begin
  config = File.open(config_file) do |f|   #读取配置文件
    YAML.load(f)
  end
rescue => e
  puts "Could not read configuration file:  #{e}"
  exit
end

# Placeholder for Component reporting
config['config_file'] = File.expand_path(config_file)  #/home/fjs/cloudfoudnry/.deployments/devbox/config/router.yml

port = config['port'] unless port
inet = config['inet'] unless inet
首先是进行一些基本的配置,例如读取配置文件等等。。

然后会启动EVENTMACHINE,进行真正的启动。。。

在代码之前,先介绍一下router的大体设计。。。

router中会集成一个简单的服务器,通过Sinatra开发的,然后还会集成一个nginx服务器,外界的访问首先是到达nginx服务器,然后nginx会调用lua脚本,生成http请求发送到router自己的服务器,然后router会通过外界访问的host的值来找到相应的app的ip+port地址(指向对应的dea),然后再返回,然后nginx再代理到返回的地址就好了。。。

这样也就是先了router的功能。。。。类似于如下:



好了,大体的设计已经介绍完了,接下来进入代码吧:

 Router.server = Thin::Server.new(inet, port, RouterULSServer, :signals => false) if inet && port   #这个一般情况下不会使用
    Router.local_server = Thin::Server.new(fn, RouterULSServer, :signals => false) if fn #创建router的服务器,用来与nginx进行交互

    Router.server.start if Router.server    #启动服务器
    Router.local_server.start if Router.local_server
这里,一般情况下是监听一个本地的sock文件,这样就很容易实现nginx与router自己的服务器之间的通信:/tmp/router.sock

接下来是订阅一些消息,例如有新的app上线了,那么router需要登记它的名字和ip+port地址,

  Router.setup_listeners  #主要是订阅一些nats的消息
它的代码具体如下:
def setup_listeners
      #订阅app的注册消息
      NATS.subscribe('router.register') { |msg|
        msg_hash = Yajl::Parser.parse(msg, :symbolize_keys => true)
        return unless uris = msg_hash[:uris]
        uris.each { |uri| register_droplet(uri, msg_hash[:host], msg_hash[:port],
                                           msg_hash[:tags], msg_hash[:app]) }
      }
      #订阅一些app解注册的消息
      NATS.subscribe('router.unregister') { |msg|
        msg_hash = Yajl::Parser.parse(msg, :symbolize_keys => true)
        return unless uris = msg_hash[:uris]
        uris.each { |uri| unregister_droplet(uri, msg_hash[:host], msg_hash[:port]) }
      }
    end
router.register用于登记新的app,unregistered则是当有app下线的时候需要将其删除。。

接下来的代码是:

  @hello_message = { :id => @router_id, :version => Router::VERSION }.to_json.freeze

  # This will check on the state of the registered urls, do maintenance, etc..
  Router.setup_sweepers

  # Setup a start sweeper to make sure we have a consistent view of the world.
  EM.next_tick do
    # Announce our existence
    NATS.publish('router.start', @hello_message)

    # Don't let the messages pile up if we are in a reconnecting state
    EM.add_periodic_timer(START_SWEEPER) do
      unless NATS.client.reconnecting?
        NATS.publish('router.start', @hello_message)
      end
    end
  end
setup_sweepers主要是用于设置周期函数,用于更新一些实时的数据,例如http请求数量等等。。

然后又会设置周期函数,用于广播当前router的一些基本信息。。。。

然后我们来看router自己的服务器。。。。

  get "/" do
    uls_response = {}
    VCAP::Component.varz[:requests] += 1

    # Get request body
    request.body.rewind # in case someone already read the body
    body = request.body.read  #{"host":"fjs.vcap.me","stats":[{"response_latency":0,"request_tags":"BAh7BjoOY29tcG9uZW50SSIUQ2xvdWRDb250cm9sbGVyBjoGRVQ=","response_codes":{"responses_3xx":1},"response_samples":1}]}
    Router.log.debug "Request body: #{body}"
    
    # Parse request body
    uls_req = JSON.parse(body, :symbolize_keys => true)
    raise ParserError if uls_req.nil? || !uls_req.is_a?(Hash)
    stats, url = uls_req[ULS_STATS_UPDATE], uls_req[ULS_HOST_QUERY]   #url为当前app的http的请求的header的host字段的值
    sticky = uls_req[ULS_STICKY_SESSION]

    if stats then
      update_uls_stats(stats)
    end

    if url then
      # Lookup a droplet
      unless droplets = Router.lookup_droplet(url)
        Router.log.debug "No droplet registered for #{url}"
        raise Sinatra::NotFound
      end

      # Pick a droplet based on original backend addr or pick a droplet randomly
      #这里是为了区分instance的session
      if sticky
        _, host, port = Router.decrypt_session_cookie(sticky)
        droplet = check_original_droplet(droplets, host, port)
      end
      droplet ||= droplets[rand*droplets.size]
      Router.log.debug "Routing #{droplet[:url]} to #{droplet[:host]}:#{droplet[:port]}"

      # Update droplet stats
      update_droplet_stats(droplet)

      # Update active apps
      Router.add_active_app(droplet[:app]) if droplet[:app]

      # Get session cookie for droplet
      new_sticky = Router.get_session_cookie(droplet)

      uls_req_tags = Base64.encode64(Marshal.dump(droplet[:tags])).strip
      uls_response = {
        ULS_STICKY_SESSION => new_sticky,
        ULS_BACKEND_ADDR   => "#{droplet[:host]}:#{droplet[:port]}",
        ULS_REQUEST_TAGS   => uls_req_tags,
        ULS_ROUTER_IP      => Router.inet,
        ULS_APP_ID         => droplet[:app] || 0,
      }
    end

    uls_response.to_json
  end
代码其实还是很简单的,主要是接受经过lua脚本处理过然后nginx传过来的数据,然后router根据host的数据查找相应的app的信息,主要是找到访问这个app的ip+port地址,然后将它返回回去,这样nginx就可以直接通过这个地址来直接到dea来访问对应的app了。。。

另外还剩下的就是lua脚本和nginx的配置方面的东西了,其实很简单,稍微看看就能明白。。。

这样router的主要的东西就讲完了。。。通过这几天看cloud foundry的源码,发现其实cloud foundry的整个实现还是相对来说比较简单的了。。。。

国央企创新负责人如何通过平台实现科研成果的快速识别与转化?.docx 科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。 立即下载

相关推荐

PotPlayer自用皮肤

自用 PotPlayer 皮肤,仅微调了字体大小与颜色,是按个人习惯调整,未做适配性调整。

【Cloud Foundry】Could Foundry学习(三)——Router

在阅读的过程中有不论什么问题。欢迎一起交流 邮箱:1494713801@qq.com    QQ:1494713801     一、概述         Router组件在Cloud Foundry中是对全部进来的Request进行路由。         进入Router的request主要有两类:首先是来自VMCClient或者STS的管理型指令,这类request...

weixin_34326179的博客 196

2-shell及常用命令-续.pdf

2-shell及常用命令-续.pdf

CloudFoundry源码分析:Router

Router的实现主要由两部分组成: 一个是lib/router/router.rb,主要作用和nats服务器交互,管理router表。一个是lib/router/router_uls_server.rb,主要是处理各种外部请求。 Router Router(lib/router/router.rb)主要通过注册事件和nats服务器交互,处理其他模块发布的信息,并统计一些运行信息。 rout

Tony的专栏 1300

Anaconda详细安装及使用教程(带图文)

Anacond的介绍 Anaconda指的是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。因为包含了大量的科学包,Anaconda的下载文件比较大(约531 MB),如果只需要某些包,或者需要节省带宽或存储空间,也可以使用Miniconda这个较小的发行版(仅包含conda和Python)。 Conda是一个开源的包、环境管理器,可以用于...

代码帮 186万+

【Godot4自学手册】第一节配置Godot运行环境

Godot是一款自由开源、由社区驱动的 2D 和 3D 游戏引擎!它是一款功能丰富的跨平台游戏引擎,可以通过统一的界面创建 2D 和 3D 游戏。它提供了一套全面的通用工具,因此用户可以专注于制作游戏,而无需重新发明轮子。游戏可以一键导出到多个平台,包括主流的桌面平台(Linux、macOS、Windows)、移动平台(Android、iOS)、基于 Web 的平台以及主机平台。

zhaoyang314的博客 5983

cloud foundry源码启动(1)

新学期开始了,又要开始搞cloud foundry了。。。首先从cloud foundry源码的启动过程搞起: cloud foundry的启动入口文件是vcap_dev文件,它的主要作用的就是初始化一些基本的参数,最后则是由vcap文件来真正的启动cloud foundry的各个部分。 好了,我们就来分析vcap_dev文件的执行过程吧(这里用的各项都是默认的参数): options["n

fjs的专栏 1705

谷歌DreamFusion使用方法及实例详解

DreamFusion 是谷歌提出的基于文本生成3D模型的突破性技术,无需3D训练数据,通过2D扩散模型(如Imagen)与NeRF(神经辐射场)结合实现。以下为使用社区开源实现(如。)的详细步骤及实例。

主攻大数据 人工智能 物联网 安全 低空经济等方向。mtsc 、gtest特邀分享嘉宾 1042

Cloud Foundry 源码解析一览(warden)

warden是其核心部分的资源管理容器,完成了各种资源分配的事情。 代码位置在:https://github.com/cloudfoundry/warden 这一部分也是我最想了解细节的地方,因为在一个paas平台中,资源的隔离才是最有价值的部分。 基础知识 rv= unshare(CLONE_NEWNS); unshare这个调用,可以把挂载的文件系统设置成只在新的挂载命名空间(mou

kent45的专栏 1687

告别Modern Standby噩梦:Win11睡眠断网冻结的根源剖析与S3睡眠回归实战

本文深入剖析了Windows 11中Modern Standby(现代待机)模式导致睡眠后断网、系统冻结等问题的根源,指出其与硬件驱动、后台活动的兼容性矛盾。文章提供了通过修改注册表键值强制系统回归稳定S3睡眠状态的详细实战步骤,帮助用户彻底解决睡眠故障,实现可靠的远程访问与挂机任务。

weixin_29210727的博客 605

大模型量化方法总结

本文主要对大模型量化方法进行了总结,希望对学习大语言模型的同学们有所帮助。 文章目录 1. 前言 2. 模型精度 3. 量化方法 3.1 方法一 3.2 方法二 3.3 方法三

herosunly的博客 1万+

Cloud Foundry新版router源码分析

调整格式太费力了,这里直接粘帖过来了,原文我写在自己的博客上了:http://lory-yang.com/2012/08/06/cloud_foundry_router/。 Cloud Foundry在几个月前改进了它的router,我们可以在新版cloudfoundry解密中看到它的介绍: 上个版本中。Router作为一个nginx脚本存在。所以的请求都必须经过Ruby代码,然后

cherry_sun的专栏 4431

直方图均衡化原理及matlab和opencv实现代码

详细分析了直方图均衡化的数学原理,配有matlab和opencv实现代码

qq_21603315的博客 4777

cloudfoundry之router源码分析

cloud foundry之router源码分析 1      router目录结构 2      router组件的启动 每个组件启动都需要经过下列命令 exec_cmd("#{ruby_binary} #{vcap_launch} #{command} #{vcap_components["components"].join(" ")} -c #{deployment_conf

ximenghappy的专栏 3527

国自然基金申请书撰写新思路:如何合理利用AI提高本子竞争力?

最后给大家推荐的400多所高校教师都在用的AI平台——高级学术版专业应用平台,集成了国际主流学术应用,以及ChatGPT、Claude、Gemini、Grok等Al大模型的高级版本平台,还有,可以辅助大家高效完成科研和学术写作任务,当然撰写硕博论文,课题、职称论文、国社科、国自然基金本子也是手拿把掐。创新点、技术路线、前期基础,但是我们也可以把写好的初稿交给AI,让它扮演资深研究员,帮我们精炼表述、优化段落结构,并揪出可能被评审追问的逻辑漏洞。,我们需要的是让它帮我们理清楚思路,而不是让它替我们完成内容。

智能AI让学术科研更容易 664

基于改进Unet的多场景水果图像分割与分类研究

本文针对复杂场景下的水果图像分割问题,提出了一种改进Unet模型。通过构建包含8类水果、3种成熟度及多种干扰场景的数据集,采用ResNet50与MobileNetV3作为骨干网络,并在跳跃连接层集成CBAM注意力机制。实验表明,改进模型在测试集上达到91.6%的mIoU,推理速度提升23%,特别在重叠水果和低光照场景表现突出。研究为农业视觉检测提供了有效解决方案。

AI的内部世界的博客 303

Cloud Foundry中collector组件的源码分析

在Cloud Foundry中有一个叫collector的组件,该组件的功能是通过消息总线发现在Cloud Foundry中注册过的各个组件的信息,然后通过varz和healthz接口来查询它们的信息,最后再将各个组件收集过来的数据发送到指定的存储位置。 本文从collector的功能出发,主要讲述以上三个功能的源码实现。

木精灵的技术博客 3424

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Cloud Foundry中gorouter源码分析

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

rznice的专栏 1977

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Cloud Foundry技术全貌及核心组件分析

本文在从架构组成、核心模块功能、源代码分析等角度来全面剖析Cloud Foundry,同时会结合各行业的典型案例来讲解Cloud Foudry在具体应用场景中的表现。 架构设计及核心组件 从总体上看,Cloud Foundry的架构如图1所示。 图1 Cloud Foundry架构图 经过一年多的发展,Cloud Foundry的组件增加了很多。但核...

weixin_33709219的博客 362

CloudFoundry源码分析:DEA

DEA(Droplet Execution Agent),主要流程都在agent.rb文件中实现。 由于CloudFoundry平台是以NATS为中心的,只要弄清楚了这个组件能够处理的NATS消息,也就清楚了这个组件的基本流程。DEA也不例外。 Agent主要注册了以下几种事件,下面分别介绍这些方法的实现流程 。 NATS.subscribe('dea.s

Tony的专栏 1461

CloudFoundry组件之间通信NATS MESSAGES

Cloud Foundry是业界领先的开源PaaS平台,它的内核采用Ruby开发。设计上使用以NATS消息系统为核心的松耦合组件架构,强调以NATS消息系统为核心的松耦合组件架构所带来的弹性。 NATS 一个轻量级的 发布-订阅, 分布式队列消息系统,基于EventMachine开发。 本文重点将列出CF系统中,都有哪些 "NATS MESSAGES",并且对其功能做简单介绍。

restkuan的专栏 1660

从CloudFoundry源代码看vcap安装过程

本文仅关注dev_setup子目录,通过阅读本文及源代码,你能够大致了解运用dev_setup是如何实现对CF的布暑及启动的。 bin/vcap_dev_setup parse options, sudo, bundle clear, ruby, gem, proxy, wget, config, chef, rake, git (准备最基本环境。可手动安装,不碍事) ---- lib/

restkuan的专栏 1213

Cloudfoundry中查看router中所有路由信息

我们知道在CloudFoundry中,router是入口,那么它就要保存所有的域名和ip的对应关系,如何查看各个app和内部组件的真实ip:port呢?   登陆部署gorouter的机器,netstat -ant | grep 8082,gorouter默认会启动8082和80端口,如果你之前修改过就grep你修改之后的端口,看到8082在监听了吧,e.g. 127.0.0.1:8082,...

By Ulric Qin 497
上一篇: cloud foundry的消息中间件nats用法
下一篇: cloud foundry之dea组件源码分析
fjs_cloud
博客等级 码龄15年 248粉丝 192原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值