`
alanland
  • 浏览: 635796 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

深入Cloud Foundry(下)

阅读更多

这是下半部分。

原文链接: http://qing.weibo.com/tj/88ca09aa33000975.html

原文作者:EMC中国研究院高级研究员  彭麟

 

续与回顾

本文第一部分介绍了CloudFoundry的整体架构,并在最后花了一点篇幅简介CloudFoundry的代码组织情况,以便于读者自己去研究源代码。笔者认为开源项目最大的好处在于:当你读懂源代码、理解总体架构后,能够成竹在胸,并吸收为己用(有点类似武侠小说中的“北冥神功”)。“为己用”就是本篇要说的内容:我们使用CloudFoundry搭建自己的私有PaaS平台。

在介绍CloudFoundry之前,先说明一下,VMware在企业云应用平台的产品线上,有另外一款产品,叫做VMwarevFabric Cloud Application Platfor[1],这和Cloud Foundry属于两个产品,分别由两批团队开发。相比较来说,选择vFabric会更令人省心省力,毕竟作为商业产品,完善很多,而且发展已久,和STS[2]深度整合。如果企业以应用为目的,不希望开发上面耗费太多人力物力,不妨考虑一下;如果选择Hard模式,打算以CloudFoundry为基础搭建私有云,那就开始吧!

第二部份 基于CloudFoundry的私有云实践 

 一、安装配置CloudFoundry

本文内容所提到的CloudFoundry版本较早,,所以不可能一直紧跟着CloudFoundry的更新,造成有些内容并不是针对最新代码库,虽然我会比较新代码库来写这篇文章,但是请一定不要把本文当作按部就班的安装说明书。

去年10月份开始,CloudFoundry的主代码vcap里面新增加了个目录叫做dev_setup,Cloud Foundry大方地公开了他们的部署代码,这样大大简化了我们把CloudFoundry部署在自建数据中心的难度。如之前Figo在VMwareCloud Forum提到的一样,CloudFoundry官方用Chef[3]作为部署工具 。Chef是OrchestrationEngine的一种,可以自动化管理、部署复杂的云环境。工作过程大概就是我们需要写一系列的“recipes”,这些“recipes”描述我们需要把我们的服务器部署成什么(Apache,Mysql还是Hadoop?),然后Chef可以自己执行这些配置。现在数据中心变得越来越庞大,原来那种通过自己写脚本完成自动部署的IT管理方式日渐不堪重负,帮助管理、部署数据中心服务器集群的中间件变得越来越重要,我们统称这类型工具为OrchestrationEngine.

回到正题,如果使用了新版的CloudFoundry,可以参考dev_setup目录和dev_setup/deployments目录下面的两个README文件。基本上使用提供的脚本来部署不同的CloudFoundry组件就是一条命令的事情。

但是既然我们命题为深入CloudFoundry,那就必须深入地了解整个CloudFoundry的部署过程。 在这之前让我们先回顾第一部分里面的CloudFoundry总体架构图:

 

 

深入Cloud Foundry(下)
Figure 1 CloudFoundry 总体架构图

 

从图1中可以看出两点:

1、  CloudFoundry是完全模块化的设计,每个模块单独存在、运转。CloudFoundry是基于Ruby开发的,那每个部分可以认为拿来即可运行,不存在编译等过程;

2、  我们需要配置换的应该是图中的箭头部分。换句话说就是如何把每个模块连接起来,使其成为一个完整的、分布式的系统。这点就是我们现在要做的事情。

如果你是用:

深入Cloud Foundry(下)
 

安装的CloudFoundry,那你的系统里面就应该包含了所有的子模块。

 

DEA, Health_Manager, Router这三个模块,代码结构比较接近:都有一个bin目录,毫无疑问里面就是可执行文件,但是打开着个文件会发现它只是个简单的link,真正的执行文件在lib下面,有对应的rb文件;而这几个模块的根目录下面都有一个config目录,里面有以模块命名的yml文件,这就是他们的配置文件。

而cloud_controller模块,之前已经说过它是个典型的RoR项目,里面的文件结构有点复杂,文件有点多,但是还是能找到config/cloud_controller.yml这个文件的;

 

接着就是service模块,这里会看到很多似曾相识的子目录,比如mysql,redis, rabbit, mongodb。专业人士一看就知道是不同的服务,每个服务一个文件夹,点进这些目录看,又看到熟悉的结构了,比如bin,config, lib,很简单,和前面的DEA,Router等模块的结构一样。但是打开bin后,发现执行文件有点多,有个gateway,还有个node。(如果你是新的代码库,可能还看到个backup,顾名思义就是配置service备份工作的,不难理解,这里就不叙述了)

 

我们来聊聊Service模块的gateway和node。Gateway在一个servicenode里面负责处理restfulapi的相关事情,负责读入并初始化messagebus。Node是service的具体执行者,包括响应message,与底层service的交互等等。但是从配置文件来说,因为gateway负责解析初始化messagebus,所以与messagebus相关的配置信息反而放在了xxx_gateway.yml里面;而xxx_node.yml则是一些关于底层配置的信息,拿mysql_node.yml来说,就是一些max_long_query,max_long_tx这些信息。

 

如果我们要架构分布式的云环境,不应该选择在一台服务器里面安装所有的模块,下面简单介绍下做法:

 

通过研究源代码,我们知道CloudFoundry的主安装文件vcap_setup里是可以选择安装哪些组件的。所以安装全部组件应该是install这个脚本搞的鬼,我们去看看install[4]里面做了什么?

 

通过略读install脚本,发现它不难理解,且每一个步骤都有一个echo来说明。它分别做了以下动作:

1、  检测是否是Linux或者MacOS环境;

2、  安装依赖包;

3、  安装并启动RVM;

4、  安装Ruby;

5、  下载vcap;

6、  安装配置vcap;

7、  重启Nginx;

8、  安装Bundler。

 

其中注意这一行命令:

 

深入Cloud Foundry(下)

 

这里面的参数–a与-s。在vcap_setup的comments里面有如下定义,

 

深入Cloud Foundry(下)
 

 

 

也就是说,install脚本为了省去安装时的提问过程,剥夺了我们的自主选择权!那么解决方法就简单了——把这句改了,然后执行install,我们应该能看到安装脚本询问要不要安装Router?要不要安装CloudController?同样的,因为去掉了-s参数,所以在安装过程中会提示需要安装的Service类型。

下面是我们实验室中服务器的具体配置图,

 

 

深入Cloud Foundry(下)

 

Figure 2 Cloud Foundry 在ELC 实验室中的部署图

 

首先,我们手上没有硬件LoadBalancer,而且为了节约ip资源,我们决定只用一个外部ip,使用桥接,然后用Ngnix来做loadbalancer,所有的requests会转向4台Router。

 

我建议Router宜多一点,因为CloudFoundry当前的设计,Router的资源会很紧张,但是如第一部分说到那样,这问题会在以后的版本改善。目前还是多加点Router服务器吧。

 

然后CloudController我们用了3台,并且这三台也同时兼了Health_Manager的功能,因为CloudController主管的是控制流,资源占用不会太大。我一开始也觉得CloudController会很耗资源,因为从上一部分的工作描述来看,它负责的工作还是比较多的,但实际应用下来,结果和笔者想的相差很远。这部分需要的资源其实并不多,可能因为我们不是经常需要启动/关闭/删除instance。

 

后面是一个单独的数据库服务器。在生产环境里用的是postgresql,用其他也是可以的,在cloud_controller.yml里面修改就好。这是整套系统的单点,我也一度担心过,但据说CloudFoundry.com用的也是单点数据库,没存在太大问题。据说CloudFoundry在设计的时候已经注意到这里的数据流量问题。

 

接着是5台服务器用于Health-Manger,其中3台与CloudController公用。因为我希望多检测一点数据,用于后面的管理,所以在这里狠下了心。

 

DEA模块,也是5台服务器。这里算是app的主场,建议根据资源需求动态增加,CloudFoundry有很好的扩展性设计,如果某一模块吃不消了,都可以动态添加。

 

Service模块,同样给了5台。我们目前只用到Mysql,Postgresql和MongoDB。同样按照项目需要来加。其他Service暂时还没用上。

 

接着就是贯穿这套系统的MessageBus模块。CloudFoundry的所有模块都需要指定到这个MessageBus。它是基于NATS的,轻量级,很好用,但是有个问题是不支持HA/HP集群,也就是说无法配成多台Messagebus hosts。这部份据说正在开发,而既然CloudFoundry.com都能应付得了,我们私有云,一台server,应该足矣!

 

后面我们选几个模块看看具体的配置修改:

1. /etc/nginx/nginx.conf

前面说到,我们用一台nginx来作为loadbalancer。我们整个服务器集群用的是虚拟机,这台虚拟机配双网卡,分别设为privatenetwork和vmnetwork,两网卡间采用桥接。这台服务器有双ip:10.32.105.165和192.168.1.178。我们进入这台机器,选择Nginx的一个原因是,只要安装CloudFoundry,因为Router组件是基于Nginx的,所以都会安装这个HttpServer,减少了我的工作。配置Nginx没什么特殊之处,我用了最简单的方法,设置一个upstream,采用RR来均衡负载。

 
深入Cloud Foundry(下)
然后设置location的proxy_pass到这个upstream:
 
深入Cloud Foundry(下)
 
Ngnix用作loadbalancer的做法很多,而且可以引入权重算法等,大家按需使用。
2. Router.yml

Load balancer出来的request就会流到Router组件,Router.yml的配置相当简单:

 

 

深入Cloud Foundry(下)

 

唯一需要改的只有mbus,就是把mbus指到我们的mbus服务器去。

3. cloud_controller.yml

Cloud_controller.yml看起来相当复杂,我们可以选择需要的配置修改:

深入Cloud Foundry(下)
 
这三行属于api的URI信息。external_uri比较重要,请在DNS里面绑定这个域名到LoadBalancer的外部ip地址(如果没有的话,需要访问的client要配置hosts文件,绑定LoadBalancer和这个域名)。我们的配置是在DNS绑定好api.elc.com和10.32.105.165。

 

深入Cloud Foundry(下)
 

 

按照配置文件里面的介绍,说这个可以不修改,默认为nil,我配置成了CloudController的ServerIp,用起来没出问题。

 

接着有两个重要的配置:

 

深入Cloud Foundry(下)
 

 

这两个目录是关于用户上传的apps(在Cloud Foundry里叫做Droplets),以及相关资源的目录。上一部分说到,在CloudController的当前实现,是采用一个NFS来存储这些Droplets,使它全局唯一。所以我们在此之前,需要建立一个NFS,并且每个安装Cloud_Controller的服务器把这个NFSmount到/var/vcap/shared下。这点非常非常重要,否则会出现上文说的启动失败问题!

 

接下去,我们需要配一个,所有CloudFoundry组件都要配置的内容,mbus:

深入Cloud Foundry(下)
 

 

后面有很长的一段是关于Rails的环境配置,这里就不啰嗦这些内容了。再往后,有一些单个账户资源限制问题,可以留意一下:

深入Cloud Foundry(下)
 
这里如果对于内部使用可以适当放宽一下。配置文件里的其他内容,可以根据自己的需要来订制修改。

 

4. health_manager.yml

接下去就该配置health_manager.yml。一开始看到的就是两个所有模块都要修改的内容,local_route和mbus:

 

深入Cloud Foundry(下)
 

 

 

Local_route还是填本机的ip,mbus填的都一样,就是mbus服务器的ip和端口。

然后,从本文第一部分所描述的health_manager的职责可知道,该模块和CloudController数据库有交互,所以需要配置database_enviroment信息。这部份需要和CloudController吻合。

 

health_manager.yml还有一些关于healthcheck频率等的配置,这部份可以选择不用修改。如果需要具体定制,可以参考yml文件中的comments。

5. DEA.yml

一如既往地需要修改local_route和mbus。

深入Cloud Foundry(下)
 

这里有一个配置需要注意一下:

深入Cloud Foundry(下)
 

DEA模块会自己host一个thin服务器用来处理发送到以下URL的请求,让用户可以直接访问到app的files。

 

深入Cloud Foundry(下)
 

 

 

换句话说,如果需要自己开发一些应用对app进行文件级管理的话,可以通过上面这个URL。另外,这个URL也是我们访问app文件的一个选择。或者我们可以从CloudContorller的API进入也是可以的,后面关于如何管理我们搭建的私有云时,会讨论到这个话题:

深入Cloud Foundry(下)
 

除此之外,其它配置如果没有特殊要求,可以保持默认。

6. Service层配置

在Service层,每种service的配置都略有不同,但是大同小异,需要修改的地方也不多。在这里,我举Mysql为例子。和所有的Service一样,mysql分为了两个配置文件(最新版本会多一个backup,共三个):mysql_gateway.yml和mysql_node.yml。

 

对于mysql_gateway.yml,需要改的,只有:

host: 192.168.1.193

mbus: nats:// 192.168.1.177:4222

 

对于mysql_node.yml,这里比较多的是mysql调优参数,按照需要修改。但同样有两处需要修改:

Ip_route: 192.168.1.193

mbus: nats:// 192.168.1.177:4222

 

到此为止,所有的安装配置完成。如果一切顺利的话,重新启动component后,CloudFoundry应该就可以用了。再强调一次,这篇博客并不是一个可按部就班的安装指南。CloudFoundry在一直发展,代码变动很大。如果不指定某一版本,很难保证所写就一定适合。我觉得更多的应该是在通读本文第一部分后,对CloudFoundry的整体架构有个了解,然后前面的描述可以看作是一些可具体理解CloudFoundry的切入点。通过去修改配置文件,保证系统如第一部份描述那样来运转。

 

CloudFoundry的架构并不复杂,其主要思想就是messagebus的配置,使异构的、分布式的组件可以互相通信合作。我浏览了下CloudFoundry的最新代码,很多新增配置配置是控制component如何运转的配置,保持默认状态即可。如果大家在配置过程中有什么问题,很欢迎直接@我的微博(@Layne_Peng)进行讨论,我会尽量帮忙。

二、下一步?

要搭建一个完整的私有云系统,还有很多缺少的地方,譬如下层的IaaS如何集成?如果CloudFoundry一个组件负载过高,应该如何扩容?能否做到自动化?如何检测、管理CloudFoundry的服务器集群?这些都是需要解决的问题。

 

首先,CloudFoundry是与底层IaaS无关的,我们可以用vSphere或者OpenStack来作为IaaS方案。为了实现云计算的可伸缩性,IaaS层需要提供如下两个功能:

1、  当CloudFoundry某些组件的发出性能警报,或者到达我们设定的某些指标时,我们需要用IaaS创建部署该组件的虚拟机,并把它启动加入CloudFoundry集群中(由OrchestrationEngine来做);

2、  当某些组件有大量资源盈余,而物理资源出现紧张情况的时候,IaaS需要删除虚拟机,把计算资源归还到资源库;

3、  IaaS需要提供虚拟机的注册、存储、查找、导入、启动等功能。

而OrchestrationEngine在我们Lab中负责把由IaaS导入并已经启动的虚拟机,按照前面章节介绍的“安装配置CloudFoundry”配置好,以保证新加入的虚拟机资源可以被CloudFoundry使用。

 

我们的私有云有了IaaS和PaaS,有了自动化管理工具(也就是OrchestrationEngine),但中间还缺少监控管理工具。有了监控管理工具,我们才可以知道现在CloudFoundry每个服务器的资源使用情况,才可以向IaaS请求计算资源。这一块要做得非常完善并不容易,但是我们可以按照我们的需要,去做一些必需的。实现自己的监管工具,第一件要做的事就是认识CloudFoundry提供的API,以便我们获得PaaS的运行信息。

 

前面多次提及,CloudFoundry的管理是由CloudController负责,并对外提供RestfulAPI,供VMC和STS使用。另外,CloudController是典型的RoR项目,所以我们需要的一切API都可以在vcap/cloud_controller/Router.rb文件找到。

 

打开Router.rb文件,我们可以发现这里基本可以得到部署在CloudFoundry上apps和services所有信息,包括app的统计信息、app的crashlogs、service node所提供的服务、servicenode的资源情况等等。再配合Linux本身的一些基本命令,我们可以知道服务器节点的资源情况。

 

另外,我们在Router.rb还能发现以下API,

 

深入Cloud Foundry(下)

 

 

通过它们,我们可以拿到每个apps的所有file文件。也就是说,我们可以拿到Webserver(假设是Java的instance,那WebServer就是Tomcat)的logfiles。通过分析这些logfiles,我们可以得到目前部署在我们PaaS上的app运行情况。

 

这里面的话题很多,可以发挥的地方也很大。我是先分析Router.rb可以提供哪些信息,然后觉得哪些比较有价值,可以联系到我们业务的哪些需要,来设计的。分析这些API的比较好办法就是直接Query这些API,然后看看返回数据。

 

我用的是Chrome浏览器,只需要装个AdvancedREST client插件,我们就可以直接访问这些RestAPI了。访问大部份CloudFoundry的RestfulAPI,都首先需要拿到授权Token,我这里直接用http://api.cloudfoundry.com为例。

 

我们用VMC的时候,先需要把Target设定为http://api.cloudfoundry.com,这一步其实就是给VMC设定了Restful的访问BaseURL,属于本地操作。

 

第二步就是执行login,并输入email和password,我们可以通过研究VMC的源代码,或者直接看VCap源代码,得知,这个login其实是发向:

 

post   'users/*email/tokens'       => 'user_tokens#create',   :as => :create_token

 

所以,我们可以用AdvancedREST client往上面的URL发送POST请求,并把email和password的JSON格式放到Body里面,

 

深入Cloud Foundry(下)
 

 

 

从服务器返回了一串Token,这就是我们需要拿到的授权Token,后面的所有操作都需要用到。

 

接着我们就可以慢慢尝试CloudController能为我们提供什么信息了。举个最简单的例子,我想看当前email账户下的所有apps列表,只需要把以上的Token放到请求的header里面,并把name设为AUTHORIZATION,然后GET  http:// api.cloudfoundry.com/apps:

 

深入Cloud Foundry(下)
 

 

返回信息就是该账户下所有的apps列表:

 

深入Cloud Foundry(下)

 

 

从这里可以得到这个用户的apps的一些基本情况,包括appname、url、所使用的技术、instance数目、资源情况等等。

 

再举一个简单的例子,如果我想做一个Portal列出部署在我的PaaS里面的所有应用,这个API或许可以派上用场。

 

开发一个完善的PaaS不是我们研究院的主要任务,而且搭建一个私有云需要大量的开发量,我只是简单实现了一小部分。如果真打算搭建私有云平台,要做的工作还有很多。譬如ActiveState就基于CloudFoundry,做了一个商业版的PaaS,叫做Stackato[5],它们也是在Monitor和Manage上面做了很多工作,值得参考一下。

结束语

上下两部分的深入CloudFoundry到这里就写完了。虽然命名为深入,其实很多地方只是简单带过,对CloudFoundry的分析也只到架构一层,还有很多内容可以挖掘,譬如开发自己的Runtime,嵌入新的Service等等,以后如果必要,我可以再写文章聊聊相关内容。第二部分简单介绍了CloudFoundry的安装,以及我们实验室里面的使用,希望对大家有帮助。

 

Cloud Foundry作为业内第一个开源的PaaS,我觉得它给我们打开了一扇研究云计算环境下平台架构设计的窗户,我相信围绕它的周边开发会有一片很大的空间可以让开源界进入,这篇文章只不过是抛砖引玉。


分享到:
评论

相关推荐

    CloudFoundry技术全貌及核心组件分析

    为了便于大家了解和深入研究首个开源PaaS平台——CloudFoundry,《程序员》杂志携手CloudFoundry社区开设了“深入CloudFoundry”专栏,旨在从架构组成、核心模块功能、源代码分析等角度来全面剖析CloudFoundry,同时...

    Foundry在企业融合云平台中的应用.pdf

    演讲者在CCTC2017中国云计算技术大会上做了主题为《区块链技术的回顾与展望》的演讲,就Cloudfoundry架构及功能介绍,基于Cloudfoundry的平台架构介绍,基于Cloudfoundry的功能扩展做了深入分析。

    cloud-cf-furnitureshop-documentation:在SAP Cloud Platform Cloud Foundry环境上创建云本机应用程序的分步文档

    SAP Cloud Platform Cloud Foundry环境简介是一种开源的平台即服务(PaaS)技术,具有广泛的行业支持。 提供了开源Cloud Foundry技术的优势,以及多种差异化的企业级特性和功能。 Cloud Foundry的一项关键设计原则是...

    CloudFoundryonCloud开源PaaS集成技术实现.pdf

    高级技术专家 高磊在2017云栖大会·北京峰会中做了题为《Cloud Foundry on Cloud-- 开源PaaS集成技术实现》的分享,就PaaS的介绍,Cloud Foundry Components,Cloud Foundry在阿里云的应用等方面的内容做了深入的分析...

    portal-custom-tile:门户服务中的自定义图块(SAP Cloud Foundry)

    build 之后,可以启动CDS服务器npm run cds:watch 现在,第一个自定义图块或第二个自定义图块都可以通过UI5工具提供: npm run ui5:serve:tile1 npm run ui5:serve:tile2构建并部署到您的Cloud Foundry空间npm run ...

    java开发家具系统源码-2019-Q2-CAP-documentation:云应用编程模型实践指南

    本实践会议的目的是让您更深入地了解在 . SAP Cloud Platform Cloud Foundry 环境简介 是一种具有广泛行业支持的开源平台即服务 (PaaS) 技术。 提供开源 Cloud Foundry 技术的优势以及多个差异化的企业级特性和功能...

    springCloud

    Spring Cloud简介 Spring Cloud包含了多个子项目(针对分布式系统中涉及的多个不同开源产品),比如:Spring Cloud Config、Spring Cloud Netflix、Spring Cloud0 CloudFoundry、Spring Cloud AWS、Spring Cloud ...

    大话微服务与DevOps

    导读:本次分享围绕作者这些年在OpenStack、Kubernetes、Microservice、DevOps、Cloudfoundry、ELK等云计算相关领域及技术的实践,从微服务和DevOps两方面着手,旨在为两者的落地提供一个快速可行路径。针对这“说说...

    pcf-workshop-devops:DevOps 的 PCF 研讨会

    Cloud Foundry平台上的DevOps目标部署和配置微服务和UI,利用平台对微服务进行监控和管理,并进行零停机的蓝绿部署。先决条件Java SDK 1.7+ 来自Git 来自 Cloud Foundry CLI 从关键网络服务帐户。 在此处创建免费的...

    cf-docs:一个光线充足的文档地方

    Cloud Foundry开源文档的新网站是 。 有新的文档库。 有关现在如何发布文档的详细信息,请参阅库上自述。 现在,开源文档分为多个存储库: :基础概念和体系结构指南。 :针对开发人员将应用程序推送到Cloud ...

    物联网摇动:使用IBM Cloud的示例演示应用程序:Watson IoTMQTTNode-RED + MessageHub + IBM Cloud Functions + Cloudant

    IBM Cloud IoT和无服务器演示 该演示最初在使用,以演示...注:我将假设您可以按照IBM Cloud文档来创建各种服务以及推送/创建CloudFoundry应用程序。 现有的示例和旅程中有许多很棒的资源,如果您遇到困难,可以参考。

    Docker源码分析-孙宏亮

    读研期间活跃在PaaS和Docker开源社区,对Cloud Foundry有深入研究和丰富实践,擅长底层平台代码分析,对分布式平台的架构有一定经验,撰写了大量有深度的技术博客。2014年末以合伙人身份加入DaoCloud团队,致力于...

    经典SEO内容知识

    Cloud Foundry征文赢取小米手机 应用+API=奥迪?笔记本?ipad3? 深入了解更多数据库前沿技术 更多 Office 2013发布RTM版本 预计明年春季正式发布 刚收购就开源 Twitter开源A/B测试应用Clutch.io

    worldwindjava源码-FinalPaper:这是乔治亚格威内特学院ITEC软件开发顶点课程的期末论文

    我们将通过深入研究到目前为止确定的一些利弊进行跟进,并为读者留下一个更全面的视角,让您能够决定自己和当前的利弊是否大于利弊/ 或您的组织。 让我们开始吧! Go 编程语言是由在 Google 工作的三位绅士(至今仍...

    Spring Boot实战 ,丁雪丰 (译者) 中文版

    8.3.1 部署到Cloud Foundry 150 8.3.2 部署到Heroku 153 8.4 小结 155 附录A Spring Boot开发者工具 157 附录B Spring Boot起步依赖 163 附录C 配置属性 169 附录D Spring Boot依赖 202

    spring boot实战.pdf高清无水印

    8.3.1 部署到Cloud Foundry 150 8.3.2 部署到Heroku 153 8.4 小结 155 附录A Spring Boot开发者工具 157 附录B Spring Boot起步依赖 163 附录C 配置属性 169 附录D Spring Boot依赖 202

    springBoot实战4.0 高清版

    8.3.1 部署到 Cloud Foundry ............... 150 8.3.2 部署到 Heroku ........................... 153 8.4 小结 ....................................................... 155 附录 A Spring Boot 开发者工具 .....

    SpringBoot实战(第4版)

    8.3.1 部署到 Cloud Foundry ............... 150 8.3.2 部署到 Heroku ........................... 153 8.4 小结 ....................................................... 155 附录 A Spring Boot 开发者工具......

Global site tag (gtag.js) - Google Analytics