如何理解持续集成与持续交付,持续交付,持续部署

【译】持续交付--自动化发布流程 - 简书
【译】持续交付--自动化发布流程
标签(空格分隔): 翻译
原文地址:
对于很多开发者来说,发布版本的那天都会陷入巨大的压力。发布过程中总是有些风险,比如出现某些莫名其妙的问题,或者是产品里又被发现了某个bug。在我上一家公司,我们采取的是手动发布版本,过程基本都是人工去做的,因此,特别容易出现问题。在发布当天,DevOps(译者:看百度百科是怎么描述的职责)部门会加载二进制的运行文件,然后做用户验收测试。如果所有的测试都成功,软件就会复制到服务器上,进行冒烟测,一般来说,还会进行一次前一版本的用户验收测试。下面列举出通常都会遇到的问题:
当我们因为一个问题回退发布的情况里,有2/3都是由于演示环境和生产环境配置有不同导致的;
发布的过程非常的缓慢,一个新功能要发布到用户手里总是需要非常长的时候。发布过程总是需要好几天甚至好几周。
漫长的发布流程以及跑完用户验收测试,还有另一个副作用:就是开发者总是不能及时的拿到用户反馈。当反馈到达的时候,他们可能正在开发另一个功能。这样一来,就可能会导致额外的问题,因为他们可能已经记不住那些代码怎么写的了,再改的时候就很容易出错,由于合并不同的分支,往往还会引入新的问题
简单的说,手动和没有固定的发布流程绝不是好的选择,发布那天总会承受很大的压力。在我们的案子里,如果发布不是很频繁,团队也还不够成熟时,这样的方式是可以接受的。为了改进和自动化发布流程,有一种软件工程的方法叫持续交付。
持续交付使得发布新的功能更快更稳定。同时可以让开发者更及时的收到反馈。我们开发一套软件,可以在任何时候自动安全的部署到产品上。这就确保了发布里的每一次改动,都会发布到类似真实产品环境上,并且可以运行大量的自动化测试。按照的理论,如果你做到以下的了,那么就称得上是持续交付:
业务的负责人随时都可以要求发布当前的开发版本部署到生产环境上。所有的人甚至都不需要眨下眼,一点不会感到惊慌。
持续交付,是持续集成(CI)的一个重要的先决条件。持续集成要求任何新的改动都可以快速的集成到主分支上,整个项目一直都处于开发状态中。通常来说,它是这么工作的:一旦有改动发布到github上,就会重新编译部署。整个应用都会按照所要求的配置去编译,一系列单元以及集成测试都会重新运行。如果测试失败,团队会停止工作直到修复了问题。没有了持续集成,集成很容易就变成梦魇。当我启动一个新的项目的时候,如何持续集成会是我考虑的首要事情。我看到过很多的案例,整个团队都不想关注那些出了问题的编译。这通常都发生在持续集成过程已经变成了巨大多毛的怪兽的时候。这也有违持续集成的首要目标:出了问题的版本决不能被忽视,团队的首要任务就应该是去修它们。为了确保这件事,持续集成的过程应该尽可能的短,好使,简单。如果测试的运行会占用过多的时间,不可靠也不能帮助定位问题,那么团队就会不去尝试修改问题版本,甚至互相推诿责任,说是别的团队弄坏了版本。持续集成主要是在关注开发团队。持续集成里也可能会有手动去发布版本的过程。在我们做过的案例里,也有手动的拷贝二进制文件和对应的配置文件到演示和生产环境里的。与之相反的是,持续交付会将整个发布流程自动化。为了达到这一目标,我们使用了一条流水线,这条流水线有非常清晰的阶段和对应的过程。
一条持续交付的流水线是让你的新版本发布出去的流程的集中体现。按照 Martin Fowler的理论:
在自动化你的编译和测试环境过程里一个很大的挑战是,你想要编译的更快,以便你可以快速的得到用户的反馈,但是综合测试需要运转很长的时间。部署流程会想办法把发布分解成很多个阶段。早期阶段会找出绝大多数能找出那些很快就可以被发现的问题,较晚的阶段则专注于找到会慢一些的问题。部署流水线是持续交付的核心部分。
一个典型的持续交付过程如下:
持续交付流程图
决定这条持续交付流水线成功与否的部分就是验收测试,验收测试位于这条流水线的较靠后的阶段,也就是“更多靠摸索”的阶段。他们确定软件能满足用户的需求和指标。验收测试不应暴露内部系统的细节,应该就像对待黑盒一样对待。我们的验收测试会由模拟一个真正的用户会输入的内容,接受并验证系统的输出并验证这些输出是否符合预期。
在持续交付的流水线上,从一个阶段转到下一个阶段可以使手动,也可以是自动的。手动并不意味着把内容拷贝复制到下一个流程中。它只是意味着,操作人员需要标记一下,表示现在的阶段已经完成,可以转交到下一个阶段了,而这个过程通常会需要手动的按一下按钮。
持续交付的流水线能在确定了交付流程之后被定型下来。没有所谓的标准答案:一个流程总会和另一个看上不太一样。举个例子,在一个有很多独立组件的SOA项目里,我们觉得一个为所有的组件制定一个流程是最好的方案。而另一个项目要求给每一个组件都制定独立的流程,而整合到一起之后的流程,可以参考下图。
集成后的流程
实现一个好的持续交付流程是一个让人沮丧的任务,但是一旦完成好了,会产生巨大的好处。在我看来,最好的方式就是仔细研究你的部署过程,理解所有的依赖关系,从一些比较小而且简单的地方开始入手。
持续交付VS持续部署
持续交付中,总需要有人最终去确定把产品部署到生产环境中。一个典型就是,发布的软件发生了一些变动之后或者是在固定的日子。
而持续部署比持续交付则更进一步:每一次改变,只要通过了自动化测试就会自动的部署到生产环境。持续部署可能不适用于所有的项目,即使理论上听上去很棒,但是我可以肯定,我目前还没有在商业项目里尝试过这种方式。Yassal Sundman的博客上有一副图,是比较持续交付和持续部署的过程:
持续交付VS持续部署
对于持续交付的工具我没有特别的个人偏好。最近我开始在使用AWS的CodePipeline(和AWS的CodeDeply类似)去自动化AWS云上的交付流程,我对此这个工具非常满意。966,690 六月 独立访问用户
语言 & 开发
架构 & 设计
文化 & 方法
您目前处于:
持续交付模式
持续交付模式
日. 估计阅读时间:
不到一分钟
道AI风控、Serverless架构、EB级存储引擎,尽在!
相关厂商内容
相关赞助商
ArchSummit深圳-8日,深圳&华侨城洲际酒店,
更重要的是,这样做没有锁定的风险。跟选择版本控制系统不同,你可以使用多种持续交付工具,而且可以互相之间自由切换。QA团队从开发人员那里拉出构建版本使用一种工具,向准备服务器推送时使用另一种工具,这样的事情也有所耳闻。
在基线场景中,我们要以有限的资源找出公司中的模式。像由3到4人构成的IT部门,常常兼做开发和系统管理。这样规模的团队常常支持中小型业务,特别是不以技术为主业务的公司。大型公司也有可能这样组织,把人分成多个、很可能是互相独立的小组,各小组之间也没有交互。
在真正开始进行持续交付之前,需要做一些必要的设置工作。首先,最重要的是要有版本控制系统,以及与之匹配的构建服务器。这第一台构建服务器将会是你的持续集成服务器,它要保证每次签入动作都能成功构建。一般来说,你需要一个&现成&的构建服务器担当此任。能够监控签入动作还要自动初始化构建,要想手工开发这样的东西,真正操作起来常常要比听起来难得多。即使可以在版本控制系统中加入触发机制,完成诸如失败构建通知这样的功能也不值得花太多功夫。
即使在资源有限的作坊式公司,交付准备服务器(staging server)也是持续交付的必要组成部分。交付准备服务器应该尽可能模拟出生产环境。&你有多少预算&常常是首要问题。如果你的生产环境有价值几十万美元的数据库服务器,很可能你无法负担搭建一个同样的交付准备服务器。而且可能你也不想这么做。
在模拟生产环境时,有一个常见错误:过高匹配硬件环境。假如你的生产环境每秒处理100个请求,如果为交付准备服务器购买同样硬件,但测试时每秒只执行几个请求,你的结果就是有问题的。理想情况下,为了模拟生产环境请求,你还应该购买并设置负载服务器,但这么做成本太高,而且耗费时间。对于这种规模的团队,降低交付准备服务器处理能力是更佳策略。
另一个常常忽略的需求,是构建的版本化。必须有某种唯一的识别机制,保证可以区分开每个构建和其他构建版本。如果针对单一的公共主干代码,简单的时间戳或是自增长版本号也就够了。本文后面会讨论更复杂的场景。
有了上面列出来的部件,现在你的环境应该跟下面的图很像:
构建服务器编译代码,交付准备服务器等候接收构建结果,有了这二者之后,下一步就是决定你的部署策略。小团队有两种选择:&签入时交付&和&定时交付&。
签入时交付
&签入时交付&策略的优势在于马上产生的满足感。根据代码库的规模,从签入新功能代码到能够在交付准备服务器上测试,一两分钟就够了。
这种方式的主要问题在于:交付准备服务器会被蹂躏得不稳定。很多时候,我见到有人试图测试某个功能,突然新的版本推到交付准备服务器上了,破坏了正在运行的测试。更糟糕的是:交付准备服务器常常作为演示服务器使用,在某些重要的演示时,很可能出现严重的后果。
代码混乱是另一个问题。比如,如果三次签入在很短的时间内先后进行,那么可能触发三个构建、交付周期,实际上只有最后一次才是必要的。极端情况,这会带来很大混乱,交付部署环境将无法有充足的时间展示自己的功用。不过,大多数构建服务器都有选项,可以延迟构建的开始,或是在给定时间间隔内避免多次构建。
定期交付策略更易于预测。所有人都知道交付何时启动,并可以规划自己的代码签入是在交付之前还是之后进行。典型做法是一天构建/交付一次或两次。
每日构建的缺点在于,它会给工作环境带来不必要的压力。开发人员会发现自己要赶着在构建截止时间之前完成一次签入。在每日深夜构建,这时开发人员应该不在工作,可以减轻压力,但也意味着除非到第二天,他们无法执行第二层测试。
当我们开始使用&每日构建&这样的词汇时,很容易忘记我们实际上不是在谈论构建。我们真正在谈论的,是完整的构建、交付周期。有了持续集成,如果构建失败,你马上就能知道。接下来是要修复问题,还是要回滚签入,就很简单了;只要规划好的交付完成了,软件就已经准备好部署到生产环境。
部署到生产环境
该场景的假设是:实在没人能够完成任何特定版本前要做的大量测试工作。只要交付准备服务器上的检查完成,构建版本就会直接提送到生产环境中。但即使如此,也有多种选项,各有其妥协之处。
从交付准备阶段提送
将经过验证的构建版本从交付准备服务器直接提送,是常见的选择。其优势在于高度确定性。理论上,测试一个版本的构建、然后错误地部署另一个版本,这样的事情不可能发生。写脚本把文件从交付准备服务器拷贝到生产环境,也很容易。
但像很多事情一样,理论跟现实总是有差距的。有了到交付准备服务器的自动化推送,很可能出现这样的情况:测试完成,去倒一杯咖啡,回来后工作针对的构建版本可能就完全不同了。更糟糕的情况是:构建代理会开始覆盖交付准备服务器上的文件,而这时这些文件正在推送到生产环境服务器上。
从构建服务器提送
将构建版本从构建服务器直接提送是更好的选择。这可以消除我上面提到的那种方式中的多种时间冲突。而且,人们更容易知道被推送的是哪个版本。
这种方法也有弱点:人们很容易选择错误的版本推送到生产环境中。
重新构建并推送
第三种选择是为持续集成服务器创建新的构建选项,其中包括推送到生产环境这一步。我提醒大家要小心这种方式。虽然理论上重新构建的代码与你测试的代码没有区别,但还是有某些东西增加了出错的可能性。
另一个问题是:这让你可以选择多种编译选项。如果你可以选择,你可能希望在交付准备服务器上使用调试构建版本,在生产环境上使用发布构建版本。如果有些行为在两个构建配置中有变化,这会产生灾难性后果。
虽然使用持续集成服务器做配置很容易,但我再次强调:我不推荐人们选择这种方式。
场景2:加入QA
如果QA加入进来,事情就变得非常复杂了。因为你现在必须处理跨团队的沟通和规划,你需要更多的构建环境,还有更具意义的所有制感觉。
一旦QA加入,你可能需要至少3个非生产环境服务器。在某些特定条件下,代码变更从一台服务器提送到下一台服务器。
这是功能代码签入后,构建版本到达的第一台服务器。被称为&集成环境&,是因为签入功能代码会与其他功能代码完全集成。用来现场检查一个构建版本是否适于提供给QA。这个环境中允许不稳定,但是不允许构建版本停留太长时间。
这是QA团队完成自己大部分工作的地方,根据需要会从集成环境更新代码。
交付准备环境
交付准备环境现在完全用作演示和在构建进入生产环境前的最后检查。任何构建版本到了这个环境,都应该是牢固可靠的。交付准备环境也许可以连接到生产环境资源,比如数据库和文件系统,但不是必须这么做。
QA交付选项
从构建服务器向集成环境交付代码,可以使用基线场景中提到的多种方式之一。从集成到QA环境就需要动动脑子,因为涉及多个团队。下面是我看到的一些成功模式。
开发者发起
在&开发者发起&模式中,开发人员决定何时进行编译检查和把构建版本提送给QA。说得难听一点,当QA完全&服从&开发人员时,可以使用该模式。可能第一眼看上去,这对开发人员来说还挺好,实际上常常阴暗着某种问题。比如:如果发生某个质量上的问题,QA人员可能要等很长时间,等着阻碍他们工作的bug得到解决。
极端情况下,需要设置自动提送机制,定时自动提送到QA环境。
这是更适合大部分团队的典型方式。开发人员仍然参与,他们需要在集成环境中检查他们的构建,然后确定构建版本是否可以提送。
在这种方式下,QA准备好测试新功能时,他们会拉过来&已知正常&的最新构建版本。通常是QA经理完成该工作,一般来说他对于QA人员的需要最了解。虽说如此,有些QA团队允许所有成员提取新构建版本。
Test Runner启动
对于想真心做好自动化测试的公司来说,这才是目标。构建版本到达集成服务器后,整个自动化测试套件就开始运行。如果全部通过,构建版本会自动提送到QA。跟其他自动化交付方式一样,可以采取签入时方式或定时方式。
不要低估这种方式需要投入的成本。不仅需要有完整的测试套件,所有的测试必须还都能通过。构建服务器无法区分测试失败是由于新功能出问题,还是说有些问题需要留待将来解决。
变通方式,是把测试拆分成必须通过(must-pass)的项目和临时项目。测试从临时项目开始,特别是在TDD风格编程中用到的测试。只要测试验证正确、有用,代码也可以通过这些测试,就转而处理必须通过的项目。构建服务器不会运行临时测试,但是会看重必须通过的测试项目的结果。
交付准备/生产环境交付选项
在持续交付思想指导下,QA对于接收到的给定构建版本,只有两个选项:构建要么失败,要么提送到交付准备服务器。QA不会一边处理一个可用的构建版本,同时等待某些功能完成
这的确提出一个问题:如何定义某个构建版本是&可用的&?任何可以安全放到生产环境的构建版本,都是可用的构建版本。如果其中有未完成的功能,但这些功能可以以as-is方式工作,那么构建就可以往前提送。除非某个失败的功能会影响应用在生产环境中的使用,构建版本就不能停滞在QA这里。
进入交付准备服务器后,构建版本在下个发布周期中就要提送到生产环境。尽管持续部署到生产环境很难完全实现,还是经常听到成功的每周、甚至每日部署。关键点在于:一旦一个某件版本证明没有问题,就需要快速移动到生产环境,这样团队就可以聚焦于下一系列要开发的功能。如果构建版本停留在交付准备阶段长达几周乃至几个月,就会造成无尽的问题。
把QA环境和交付准备环境分开,是为了推进工作流。只要一个构建版本提送到交付准备服务器,下一个构建版本就会从集成服务器拉过来。这样一来,交付准备服务器就总会有一个稳定的环境,供利益相关者和其他第三方查看演示版本,同时QA仍有自己可以工作的环境。如果把服务器的职责混合起来,当环境锁定时,QA的工作就必须要停下来。
配置相关问题
一旦有了多个环境之后,配置文件就会成为严重的问题。举个例子,交付准备服务器必须配置正确,避免发生诸如发送测试邮件给所有用户,或是通过正式支付网关下订单等问题。我曾与一个刚入门的开发人员一起工作,他当时试图通过一个配置错误的测试服务器购买几百万美元的债券。(幸运的是,每张债券的价格比实际价格高,因为订单没有成功购买。)
出现这种状况,因为生产环境的配置保存在版本控制系统中,并与应用一起部署。这么做,是要防止出现非生产环境的配置放在版本控制系统中,然后被部署到生产环境服务器上的状况。
要避免上述问题,有个出人意料的解决方法:不要让构建代理的网络账号对配置文件有写权限。这样,如果有人不相信签入了配置文件,部署将会失败,错误就可以得到纠正。
不过这么做也有自己的问题。用这种方法,只要文件中的配置需要修改,就必须手工操作。如果失败了,将会使得环境出现问题,从而带来风险,因为数据更新随时可能发生。
关注点分离和配置文件
&关注点分离&这个词常常用来说明正确的设计决策应该怎么做,如果认真思考谁应该负责做什么,这种方法也是很有帮助的。比如,负责生产环境技术支持的人不关心开发人员选择注入哪种日志记录框架。然而,他们关心数据库连接串和警告发送的邮件地址。
我推荐下面这些类型的配置文件。
环境设置:与特定环境相关的值,必须按照服务器分开设置。只有某些重要事件发生时,才会需要改动它们,比如新数据库或新文件服务器上线。
代码作为配置:类似于驱动依赖注入框架的XML文件。虽然看起来像配置文件,但除开发人员外任何人都不应该碰它们。这些文件必须要放在版本控制系统中,而且应该把服务器上的文件标记为只读。
微调配置:这些配置与环境无关,但也许生产环境支持人员需要访问。可能包括比如批量上传批次限制、或是web页面请求超时设置等。
这三种配置中,微调配置需要付出最多精力以保证正确。理想状态下,应该有缺省配置放在文件中,并保存于版本控制系统,并可以根据特定服务器修改出多个文件,并且不必控制这些文件的版本。
配置和培训
避免增加不必要的配置设置,有一个技巧:要求为每个配置项提供文档和培训。如果不花时间教给生产环境支持人员何时、为何调整某些值,他们就无法完成这些工作,这些值就成为无法配置的摆设。
场景3:使用SOA的多个团队
使用SOA时,通常采取多团队方式。比如,一个团队构建数据库和服务,另一个团队处理UI,这种情况很常见。有时,两个团队的工作会非常紧密,相关团队成员会常常互相交换。有时,团队可能来自地球两边的不同公司。不管他们怎么切分,基本的模式相同。
如场景2,服务团队需要一个地方来测试构建版本,这样他们不会对团队之外造成负面影响。同时,UI开发人员需要一台可信的服务器,能够一直保持稳定,否则他们就无法完成自己的工作。因此,除了我们前面提到的单一团队场景,有必要加入&开发环境&。
不考虑UI集成阶段,我们看到的顺序与场景2相同。交付选项相同,附加条件是只有UI团队参与在这个流程中。UI团队对于构建版本质量的意见比服务团队的意见重要。
开发交付选项
何时以及如何将代码交付给开发环境,是很多紧张情势的来源。有问题的构建版本到了QA环境,QA团队只要让其失败,然后就可以转向其他任务,比如为新功能准备测试,或是改进回归测试。要是有问题的构建版本到了开发环境,整个UI团队就会发现自己无法工作了。因此,虽然QA交付中的多种交付模式都可以运作,基于自动化测试的方式目前是最成功的模式。
说明:谁编写集成测试?
处理分离的服务层时,提供服务和消费服务的团队都要编写自动化测试,这很重要。提供服务层的团队最了解服务层内部机制,因此能编写出别人不知道、或是了解其重要性的测试。
不过,这不能成为消费服务的团队不写测试的接口。他们的测试覆盖的场景不仅服务开发者想不到,而且能测试他们对于服务层的理解。比如:UI开发人员会假定某个给定调用永远不会返回null或负值。测试过UI使用的所有参数组合后,他们就可以确保自己的假设没有问题。
如果你的公司有QA工程师保佑,而不仅仅是只有QA分析人员,他们会发现自己也要针对服务层开发自动化测试。这常常与自动化UI测试连在一起,特别是动作结果不需要通过用户界面验证的时候。
场景4:采用并行功能开发的多个团队
这种情况很棘手。目前,前面提到的各个场景都假定只有一个单独的开发主干。一旦开始处理多个开发团队针对同一代码库并行开发,就必须决定何时、如何将功能代码从团队分支转移到基本开发主干中。下面两种模型是我见过的成功范例。
功能推送模型
在该模型中,不管何时,只要确定没有问题,每个团队都会把自己的变更推送到主干中。该模型的优点在于:团队可以自给自足。
该模型中最常用的策略是:在本地合并及测试。只要测试通过,修改的部分就可以推送到主分支。
该模型最大的风险是缺乏原子合并。很可能某个团队修改了某个函数的名字或签名,而另一个团队正在加入新的文件使用了同一个函数。如果两个更改同时签入,构建版本就会失败,而且版本控制系统不会报告任何冲突。
锁定-合并-推送
该方式需要版本控制系统支持锁定。推送新的构建版本时,主干应该是锁定的。新的功能要在本地与主干合并,完成冒烟测试,然后推送到主干。虽然合并的问题可以在锁定时解决,任何测试的失败必须马上把锁释放掉。
功能拉模型
该模型中,团队永远不能发布他们的变更。相反,变更控制团队的人负责将功能拉入到主干中。这样一来,QA团队就只会接收到他们准备好测试的变更。
功能拉模型需要高级的版本控制系统,支持集成工作项跟踪。仅仅给变更打上任务号是不够的,成员必须要说明&将功能X合并入分支Y&,并让版本控制系统识别所有需要的变更。这可以手工完成,但是会耗费很长时间,而且很容易出错。
对于简单的合并,变更控制工程师可以自己一个人搞定。复杂的合并,特别是团队们没有定期更新自己分支的情况下,需要开发相关功能的团队协助合并工作。
不管功能特性如何进入主干,结构都是一样的。每个团队都有自己的集成环境,他们会不断发布,就像基线场景一样。这些团队特定的集成环境向通用集成环境导入代码,然后就走正常流程了。
修正补丁(hot fix)如何处理?
所有这些场景中,我们都没有提到修正补丁的概念。这是有意为之,如果遵循持续交付的思想和理念,是没有所谓的修正补丁的。一旦变更进入集成环境,它们就会很快进入生产环境。在这个理论下,不需要修正补丁,只有正常的bug修复,其优先级偶尔会超过功能特性的开发。
然而,现实世界不是完全由理论指导的。功能常常会停滞在QA阶段,其时间超过预期,要么是质量问题,或者仅仅是因为它们的规模。与之类似,生产部署也可能延迟,因为业务需要,比如合同强制要求,或是早已公之于众的特定日期升级计划。类似事件发生时,修正补丁就有必要了。此时,最佳方案是抛开流程,完成工作优先。不要让形式成为公司和客户不必要的负担。一旦尘埃落定,危机解决,就可以开始研究问题发生的根本原因了。
持续交付的目标,不是要让修正补丁更易于处理,而是要制定出编码和测试的标准,消除对修正补丁的需要。每次流程失败的时候,就是你学习如何改进代码标准和测试实践的机会,避免重大bug再次发生。同样地,这也能为你提供理由,检查日程表制定方针中的缺陷,看看是什么导致流程的停滞和问题。如果无法同时在这两方面聚焦,你就永远不能保证所有的bug修复都可以通过严格控制的流程。
简而言之,持续改进是任何形式的持续交付的根本组件。
Jonathan Allen从2006年开始就为InfoQ撰写新闻报道,目前是.NET领域的首席编辑。如果您希望为InfoQ编写新闻或是有价值的文章,请通过联系他。
查看英文原文:
给InfoQ中文站投稿或者参与内容翻译工作,请邮件至。也欢迎大家加入到中与我们的编辑和其他读者朋友交流。
Author Contacted
告诉我们您的想法
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
赞助商链接
InfoQ每周精要
订阅InfoQ每周精要,加入拥有25万多名资深开发者的庞大技术社区。
架构 & 设计
文化 & 方法
<及所有内容,版权所有 &#169;
C4Media Inc.
服务器由 提供, 我们最信赖的ISP伙伴。
北京创新网媒广告有限公司
京ICP备号-7
找回密码....
InfoQ账号使用的E-mail
关注你最喜爱的话题和作者
快速浏览网站内你所感兴趣话题的精选内容。
内容自由定制
选择想要阅读的主题和喜爱的作者定制自己的新闻源。
设置通知机制以获取内容更新对您而言是否重要
注意:如果要修改您的邮箱,我们将会发送确认邮件到您原来的邮箱。
使用现有的公司名称
修改公司名称为:
公司性质:
使用现有的公司性质
修改公司性质为:
使用现有的公司规模
修改公司规模为:
使用现在的国家
使用现在的省份
Subscribe to our newsletter?
Subscribe to our industry email notices?
我们发现您在使用ad blocker。
我们理解您使用ad blocker的初衷,但为了保证InfoQ能够继续以免费方式为您服务,我们需要您的支持。InfoQ绝不会在未经您许可的情况下将您的数据提供给第三方。我们仅将其用于向读者发送相关广告内容。请您将InfoQ添加至白名单,感谢您的理解与支持。

我要回帖

更多关于 docker 持续集成部署 的文章

 

随机推荐