大约1年之前,我们发现当时的架构有些不合理了。尤其是Hub,它上面承担了太多的任务。Hub要接收新的处理请求,处理并推动构建日志,它要同步用户信息到Github,它要通知用户构建是否成功。它跟一大群外部API打交道,全部都是在一个进程中处理。
Hub需要继续演化,但它却不太可能自由扩展。Hub只能以单进程的方式运行,也因此成为我们最有可能发生的单点错误。
Github API是一个有趣的例子。我们是Github API的重度用户,依靠这些API我们的构建任务才能执行。无论是获取构建配置信息,更新构建状态,还是同步用户数据,都离不开这些API。
回顾历史,当这些API中的某一个不可用,hub就会停止当天正在处理的任务,而转移到下一个任务上。所以,当Github API不可用时,我们的很多构建都会失败。
我们对这些API赋予了很多信任,当然现在也一样,但是说到底,这些是我们不能掌控的资源。这些资源不是我们自己来维护,而是由另外的一个团队,在另外的网络系统中,有他们自身的弱点。
我们过去没有这样想。过去我们总是把这些资源当做我们可以信赖的朋友,以为他们随时都会响应我们的请求。
我们错了。
一年之前,这些API无声无息的对某个功能做了修改。这个一个虽然没有文档说明,但是我们非常依赖的功能。这个功能就是这么消无声息的被修改了,于是导致了我们这边的问题。
结果,我们的系统完全乱套了。原因很简单,我们把Github API当做了自己的朋友,我们耐心的等待这些API回应我们的请求。每一次新的提交,我们都等了很长的时间,每次都有几分钟。
我们的超时设置太宽松了。因为这个原因,当对Github API的请求最终超时时,我们的系统也已经发生错误。那天晚上我们花了很长的时间处理这个问题。
即便是小问题,当某个时刻凑到一块了,也能够破坏一个系统。
我们开始隔离这些API请求,设置更短的超时时间。为了保证我们不会因为Github方面的中断而导致构建失败,我们同样加了重试机制。为了保证我们能够更好的处理外部的异常,我们的每一次重试都会依次延长过期时间。
你应该接受那些在你控制之外的外部API随时可能失败的现实。如果你不能将这些失败完全隔离,你就有必要考虑如果去处理他们。
如何去处理每一个单点错误场景是基于商业上的考虑。我们可以承受一个构建出异常吗?当然,这不是世界末日。如果因为外部系统的问题,我们能够让数百个构建出现异常嘛?我们不能,因为无论什么原因,这些构建异常够影响到了我们的客户。
Travis CI最初是一个好心的家伙。它总是很乐观地认为每一件事情总会正确的工作。
很不幸,那不是事实。每一件事在任何时刻都可能导致混乱,但是我们的代码却从来没考虑过这一点。我们做过很多努力,现在我们仍然在努力,去改变这种情况,去提高我们的代码处理外部API或者系统内部异常的能力。
回到我们的系统,hub承担的任务很容易导致异常,所以我们将其分割成很多的小应用。每个小应用都有其自身的目的和承担的任务。
做好任务隔离,这样我们就能更轻松的扩展系统。大部分任务都是直接的从上到下运行的。
现在我们有了三个进程;处理新的提交,处理构建通知,和处理构建日志。
突然之间,我们有了新的问题。
虽然我们的应用已经分割开了,但是他们都依赖一个叫做travis-core的核心。核心包括数量很多的Travis CI所有部分的商业逻辑。这可真是一个big ball of mud。
对核心的依赖意味着核心代码的改动可能影响到所有应用。我们的应用是按照各自的任务进行划分,但是我们的代码不是。
我们现在还在为最早的架构设计而支付学费。如果你增加功能,或是修改代码,对公用部分的一点点改变都可能带来问题。
为了保证所有应用的代码都可以正常工作,当travis-core做了修改,我们需要部署所有应用去验证。
任务并不仅仅意味着你必须从代码的角度将其分隔。任务本身也同样需要物理分隔。
复杂的依赖影响了部署,同样,它也影响了你交付新代码、新功能的能力。
我们慢慢的将代码的依赖变小,真正的从代码隔离开每个应用间的任务。幸运的是,代码本身已经有很好的隔离程度了,所以这个过程显得容易多了。
有一个应用需要特别关注,因为它是我们做扩展最大的挑战。
相关推荐
开源项目-travis-ci-travis-ci.zip,[travis CI]: Go 1.10 is parsed as 1.1 if not passed as strings
hello-travis-ci:Travis CI教程,主要介绍如何使用Travis CI的检验代码功能和代码审查功能。 Travis CI的教程主要介绍如何使用Travis CI的检查代码功能和Code Review功能
后台的Travis CI插件 特征 列出Travis CI构建 触发生成 如何将Travis-ci项目依赖项添加到Backstage应用程序 如果您有不带此插件的后台应用程序,请按照以下说明进行添加: 在backstage/packages/app项目中,将该...
使用travis CI自动打包APK,并上传到fir,整个步骤执行成功的打印日志,帮助学习者分析错误问题。
haskell-ci:Travis CI和Appveyor模板,用于测试Haskell应用程序并发布二进制发行版
travis-minikube:在Travis CI上运行minikube
Drupal / Travis CI 演示 该项目将在 GitHub 上演示基本的 Drupal/Travis-CI 集成。 目前展示的功能: 通过 Ansible 和/或 git 安装 Drupal 和 drush。 Drupal 核心测试通过 drush(simpletest 和 PHPUnit)运行...
travis.rb, Travis CI客户端( ruby 和库) Travis客户 Travis包含一个 命令行 客户端和一个 ruby 库插件,与 Travis CI服务接口。 无论你是使用 travis-ci.org, travis-ci.com 还是任何定制 Travis CI设置,你
用户可以设置默认值并将逻辑直接包含在Travis::Config类中,也可以将其扩展到例如Travis::Logs::Config 。 例如 require 'travis/config' module Travis class Config < Hashr define host : 'travis-ci.org'...
字符串化-travis-徽章 从对象生成 Travis CI 徽章。使用安装npm i stringify-travis-badge --save用法 var travis = require ( 'stringify-travis-badge' ) ;travis ( 'assemble' , 'verb' ) ;//=> [![Build Status]...
该Ember插件为您提供了实用程序,用于检索任何公共Travis CI回购的构建状态,以及可根据返回的状态显示动态内容的组件。 构建状态会缓存在应用程序会话中,以避免不必要的API调用。 内容 安装 ember install ember...
从2020-11-25开始,我的项目不再使用Travis CI。 相反,我在GitHub Actions中使用 。 保持此仓库8年后,我很高兴通过接力棒。 如果您愿意并有能力支付Travis CI,您可能仍然会发现此回购很有用。 你可以分叉。 有...
Travis CI Webhook 简单的Webhook即可验证Travis CI通知并运行命令
从参数列表或对象生成 Travis CI URL。 使用安装 npm i stringify-travis-url --save 用法 var travis = require ( 'stringify-travis-url' ) ; travis ( 'jonschlinkert' , 'micromatch' ) ; //=> '...
Travis CI monorepo演示 该存储库是有关使用构建Monorepo项目的实验。 如果您对其他CI选项感兴趣,请确保签出我的。 这个怎么运作? 它利用Travis矩阵功能,在.travis.yml我们在.travis.yml为不同项目位置定义...
Travis CI对流星包运行速度测试的支持,已通过以下测试茉莉花,但也应与摩卡咖啡搭配使用。 指示 执行以下步骤,将travis ci测试添加到您的项目中: 将.travis-example.yml复制到您的软件包目录,将其重命名为....
tox-travis, Travis CI无缝集成 毒理检测Travis和 Travis Tox Travis是一个毒性测试插件可以简化毒物检测和Travis之间的设置。用法配置 python 版本以在 .travis.yml 中测试,并使用pip安装 tox-t
Travis API 警告!!!!! Master分支仅适用于.com。 如果您想为.org部署更改,请使用org-only分支 要求 您需要以下软件包才能使travis-api正常工作: PostgreSQL 9.3或更高版本 邦德勒 雷迪斯 可选: RabbitMQ...
Travis CI ember Web客户端运行应用该应用程序是使用开发的。 它需要安装了npm的nodejs。 为了运行该应用程序,您需要使用以下命令安装依赖项: npm ci然后全局安装ember-cli,以便可以访问ember命令: npm install ...
Travis CI cron触发器该项目允许定期触发构建,例如测试刮板。 在Travis,他们最终将实现cron(ref: ),同时,我希望这会有所帮助:)技术上该项目由两部分组成: 一个Django网络应用程序(在运行),允许用户将新的...