小红书在容器环境的 CD 实践

容器推出以来,给软件开发带来了极具传染性的振奋和创新,并获得了来自各个行业、各个领域的巨大的支持——从大企业到初创公司,从研发到各类 IT 人员等等。跨境知名电商小红书随着业务的铺开,线上部署单元的数量急剧增加,以 Jenkins 调用脚本进行文件推送的部署模式已经不能适应需求。本文作者介绍小红书如何以最小的投入,最低的开发量快速的实现容器化镜像部署,以及由此带来的收益。

小红书

图 1

小红书是一个从社区做起来的跨境电商。用户喜欢在我们的平台上发关于生活、健身、购物体验、旅游等相关帖子。目前我们已经有有 5 千万的用户,1 千万的图文,每日有 1 亿次笔记曝光,涉及彩妆、护肤、健身、旅游等等各种领域。

小红书是国内最早践行社区电商这个商业模式并获得市场认可的一家电商,我们从社区把流量引入电商,现在在电商平台的 SKU 已经上到了十万级。我们从社区里的用户创建的笔记生成相关的标签,关联相关商品,同时在商品页面也展示社区内的和这商品有关的用户笔记。

小红目前还处在创业阶段,我们的技术团队规模还不大,当然运维本身也是一个小团队,团队虽小,运维有关的方面却都得涉及。小公司资源有限,一个是人力资源有限,二是我们很多业务往前赶。在如何做好 CI/CD,怎么务实的落地方面,我们的策略就是开源优先,优先选择开源的产品,在开源的基础上,发现不满足需求的地方再自行开发。

之前的应用上线流程

图 2

如图 2 是之前的应用上线的过程,开发向运维提需求,需要多少台服务器,运维依据需求去做初始化并交付给开发。我们现在有一个运维平台,所有服务器的部署都是由这个平台来完成的,平台调用腾讯云 API 生成服务器,做环境初始化,配置监控和报警,交付给开发的是一个标准化好的服务器。

图 3

开发者拿到服务器准备线上发布时用 Jenkins 触发脚本的方式:用 Jenkins 的脚本做测试,执行代码推送。当需要新加一台服务器或者下线一台服务器,要去修改这个发布脚本。 发布流程大概是这样的:Jenkins 脚本先往 beta 环境发,开发者在 beta 环境里做自测,自测环境没有问题就全量发。

我们遇到不少的情况都是在开发者自测的时候没有问题,然后在线上发,线上都是全量发,结果就挂了。然后回退的时候,怎么做呢?我们只能整个流程跑一遍,开发者回退老代码,再跑一次 Jenkins 脚本,整个过程最长需要10来分钟,这段过程线上故障一直存在,所以这个效率挺低。

以上的做法其实是大多数公司的现状,但是对于我们已经不太能适应了,目前我们整个技术在做更迭,环境的复杂度越来越高,如果还是维持现有的代码上线模式,显然会有失控的风险,而且基于这样的基础架构要做例如自动容量管理等都是很难做到的。

问题 & 需求

首先,我们整个技术团队人数在增加,再加上技术栈在变。以前都是纯 Python 的技术环境,现在不同的团队在尝试 Java、Go、Node。还有就是我们在做微服务的改造,以前的单体应用正在加速拆分成各个微服务,所以应用的数量也增加很多。拆分微服务后,团队也变得更细分了;同时我们还在做前后端的拆分,原来很多 APP 的页面是后端渲染的,现在在做前后端的拆分,后端程序是 API,前端是展示页面,各种应用的依赖关系也变得越来越多。再加上电商每年大促销,扩容在现有模式也很耗时耗力。所以现在的模式基本上已经不太可行了,很难持续下去。

我们团队在两三个月以前就思考怎么解决这些问题,怎么把线上环境和代码发布做得更加好一点。基本上我们需要做这几点:

■重构“从代码到上线”的流程;

■支持 Canary 发布的策略,实现流量的细颗粒度管理;

■能快速回退;

■实践自动化测试,要有一个环境让自动化测试可以跑;

■要求服务器等资源管理透明化,不要让开发者关心应用跑在哪个服务器上,这对开发者没有意义,他只要关心开发就可以了。

■要能够方便的扩容、缩容。

方法

图 4

我们一开始就考虑到容器化,一开始就是用 Kubernetes 的框架做容器化的管理。为什么是容器化?因为容器和微服务是一对“好朋友”,从开发环境到线上环境可以做到基本一致;为什么用 Kubernetes?这和运行环境和部署环境有关系,我们是腾讯云的重度用户,腾讯云有对 Kubernetes提供了非常到位的原生支持,所谓原生支持是指它有几个方面的实现:第一个是网络层面,我们知道 Kubernetes 在裸金属的环境下,要实现 Overlay 网络,或者有 SDN 网络的环境,而在腾讯云的环境里,它本身就是软件定义网络,所以它在网络上的实现可以做到在容器环境里和原生的网络一样的快,没有任何的性能牺牲。第二在腾讯云的环境里,负载均衡器和 Kubernetes 里的 service 可以捆绑,可以通过创建 Kubernetes 的 service 去维护云服务的 L4 负载均衡器。第三就是腾讯云的网盘可以被 Kubernetes 管理,实现 PVC 等,当然 Kubernetes 本身提供的特性是足够满足我们的需求的。

刚刚说了我们作为创业公司都是是以开源为主,在新的环境里应用了这样的一些开源技术(图 4),Jenkins、GitLab、Prometheus 和 Spinnaker。Jenkins 和 GitLab 应该都听说,大家都在用,Prometheus、Docker 也都是很主流的。

重点介绍两个比较新,但是现在相当火的开源技术:第一个叫 Traefik,在我们的环境里用来取代 Nginx 反向代理,Traefik 是用 Go 写的一个反向代理服务软件。第二是 Spinnaker,这是一个我个人认为非常优秀的开源的发布系统,它是由 Netflix 在去年开源的,是基于 Netflix 内部一直在使用的发布系统做的开源,可以说是 Netflix 在 CD 方面的最佳实践,整个社区非常活跃,它对 Kubernetes 的环境支持非常好。接下来我会重点介绍这两块东西。

Spinnaker

■Netflix 开源项目

■开放性和集成能力

■较强的 Pipeline 表达能力

■强大的表达式

■界面友好

■支持多种云平台

刚才介绍了 Spinnaker,它是一个开源项目,是 Netflix 的开源项目。Netflix 的开源项目在社区一直有着不错的口碑。它有开放式的集成能力,它原生就可以支持 Jenkins、GitLab 的整合,它还支持 Webhook,就是说在某一个环境里,如果后面的某个资源的控制组件,本身是个 API,那它就很容易整合到 Spinnaker 里。

再者它有比较强的 Pipeline 的能力,它的 Pipeline 可以复杂非常复杂,Pipeline 之间还可以关联,它还有很强的表达式功能,可以在任何的环节里用表达式来替代静态参数和值,在 Pipeline 开始的时候,生成的过程变量都可以被 Pipeline 每个 stage 调用。比如说这个 Pipeline 是什么时候开始的,触发时的参数是什么,某一个步骤是成功还是失败了,此次要部署的镜像是什么,线上目前是什么版本,这些都可以通过变量访问到。它还有一个比较友好的操作界面,重点的是支持多种云平台。目前支持 Kubernetes、OpenStack、亚马逊的容器云平台。

图 5

图 5 是 Spinnaker 的架构,是一个微服务的架构。这是一个微服务架构,里面包含用户界面 Deck,API 网关 Gate 等,API 网关是可以对外开放的,我们可以利用它和其它工具做一些深度整合,Rosco 是它做镜像构建的组件,我们也可以不用 Rosco 来做镜像构建,Orca 是它的核心,就是流程引擎。Echo 是通知系统,Igor 是用来集成 Jenkins 等 CI 系统的一个组件。Front52 是存储管理,Cloud driver 是它用来适配不同的云平台的,比如 Kubernetes 就有专门的 Cloud driver,也有亚马逊容器云的 Cloud driver。Fiat 是它一个鉴权的组件。

图 6

图 6 是它的界面。界面一眼看上去挺乱,实际上它还是有很好的逻辑性。这里每一个块都有三种颜色来表示 Kubernetes 的环境里的某个实例的当前状态。绿色是代表是活着的,右边是实例的信息。实例的 YML 配置,实例所在的集群,实例的状态和相关 event。

图 7

图 7 是 Pipeline 的界面。首先,我觉得这个界面很好看很清晰。二是 Pipeline 可以做得非常灵活,可以说执行了前几个步骤之后,等所有的步骤执行完了再执行某个步骤。这个步骤是某个用户做某个审批,再分别执行三个步骤其中的一个步骤,然后再执行某个环节。也可以说要发布还是回退,发布是走发布的流程,回退就是回退的流程。总之在这里,你所期待的 Pipeline 的功能都可以提供,如果实在不行,还有 Webhook 的模式让你方便的和外部系统做整合。

图 8

图 8 是 Pipeline 步骤的类型。左上 Check Precondltions 前置条件满足的时候才执行某个步骤。例如当前面的第一次发布里所有的实例都存活的时候,才执行某个步骤。或者当前面的步骤达到了某个状态,再执行下一个步骤。deploy 是在 Kubernetes 环境里生成 Replication Set,可以在 deploy 里更新一个服务器组、禁用一个集群、把集群的容量往下降、往上升等等。也可以跑某一个脚本,这个脚本是在某一个容器里,有时候可能有这样的需求,比如说 Java 来说这个 Java 跑起来之后并不是马上能够接入流量,可能要到 Java 里跑一个 job,从数据库加载数据并做些初始化工作后,才可以开始承接流量。

图 9

Pipeline 表达式很厉害,它的表达式是用 Grovvy 来做,大家知道 Grovvy 是一个动态语言。凡是 Grovvy 能用的语法,在字符串的地方都可以用。所以,这些步骤中,可以说这个步骤参数是来自表达式。也可以说有条件的执行,生成环境的时候才做这样的东西。也可以有前置条件,当满足这个条件的时候,这个流程和 stage 可以继续走下去。

图 10

图 11

如图 10 是各种类型的表达式,从现在看起来,基本上我们各种需求都能满足了。Pipeline 可以自动触发(图 11),可以每天、每周、每月、每年,某一天的时候被自动触发,做一个自动发布等等,也可以在镜像有新 tag 推送到镜像仓库时,Pipeline 去做发布。

Spinnaker 和 Kubernetes 的关系

图 12

Spinnaker 和 Kubernetes 有什么关系?它有很多概念是一对一的,Spinnaker 有一个叫 Account的,Account 对应到 Kubernetes 是 Kubernetes Cluster,我们的环境里现在有三个 Kubernetes 的 Cluster,分别对应到开发、测试和生产,它也是对应到 Spinnaker 的 三个 Account;Instance 对应到 Kubernetes 里是 Pod,一个 Pod 就是一个运行的单元;还有有 Server Group,这个 Server Group 对应的是 Replica Set 或者是 Deepionment。然后是 Load Balance,在 Spinnaker 里称之为 Load Balance 的东西在 Kubernetes 里就是 Service。

Traefik

图 13

Traefik 亮点:

■配置热加载,无需重启

■自带熔断功能

-traefik.backend.circuitbreaker:NetworkErrorRatio() > 0.5

■动态权重的轮询策略

-traefik.backend.loadbalancer.method:drr

为什么我们用 Traefik 而不用 Nginx 做反向代理呢?首先 Traefik 是一个配置热加载,用 Nginx 时更新路由规则则是做后端服务器的上线、下线都需要重载,但 Traefik 不需要。Traefik 自带熔断功能,可以定义后端某个实例错误率超过比如 50% 的时候,主动熔断它,请求再也不发给它了。还有动态的负载均衡策略,它会记录 5 秒钟之内所有后端实例对请求的响应时间或连接数,如果某个后端实例响应特别慢,那接下来的 5 秒钟就会将这个后端的权重降低直到它恢复到正常性能,这个过程是在不断的调整中,这是我们需要的功能。因为上了容器之后,我们很难保证一个应用的所有实例都部署在相同处理能力的节点上,云服务商采购服务器也是按批量来的,每一批不可能完全一致,很难去保证所有的节点性能都是一致的。

图 14

图 14 是 Traefik 自带的界面。我们定义的规则,后端实例的情况都可以实时的展现。

为什么在 Kubernetes 环境里选择了 Traefik?

■Kubernetes 集群中的 Ingress Controller

■动态加载 Ingress 更新路由规则

■根据 Service 的定义动态更新后端 Pod

■根据 Pod 的 Liveness 检查结果动态调整可用 Pod

■请求直接发送到 Pod

Traefik 和 Kubernetes 有什么关系呢?为什么在 Kubernetes 环境里选择了 Traefik?Traefik 在 Kubernetes 是以 Ingress Controller 存在,大家知道 Kubernetes 到 1.4 之后就引进了 Ingress 的概念。Kubernetes 原来只有一个 Service 来实现服务发现和负载均衡,service 是四层的负载均衡,它做不到基于规则的转发。在 Kubernetes 里 Ingress 是属于七层 HTTP 的实现,当然 Kubernetes 本身不去做七层的负载均衡,它是通过 Ingress Controller 实现的,Traefik 在 Kubernetes 里就是一种 Ingress Controller。它可以动态加载 Kubernetes 里的 Ingress 所定义的路由规则,Ingress 里也定义了一个路由规则所对应的 Service,而 Service 又和具体的 Pod 相关,Traefik 据此可以将请求直接发送给目标 Pod,而无需通过 Service 所维护的 iptables 来做转发。Pod列表是根据 Pod 的 Liveness 和 Readiness 状态做动态的调整。

图 15

图 15 是新发布的一个流程或者是开发的流程。我们有三个环节:一个是开发阶段,一个是集成测试,一个是上线。

开发阶段,开发者在迭代开始时生成一个 Feature 分支,以后的每次更新都将这个 Feature 分支推送到 GitLab 。GitLab 里配置的 Webhook 触发一个 Jenkins job,这个 job 做单元测试和镜像构建,构建成一个 Feature 分支的镜像,给这个镜像一个特定的 tag。生成新的镜像之后,触发 Spinnaker 的部署,这个部署只在开发环境里。

开发者怎么访问刚刚部署的开发环境呢?如果这是个 HTTP 应用,假设应用叫做 APP1,而分支名称叫 A,那开发者就通过 APP1-A.dev.xiaohongshu.com 就可以访问到 Feature A 的代码。在整个周期里可以不断的迭代,最后开发者觉得完成了这个 Feature 了,就可以推送到 release。一旦把代码推往 release 就触发另一个构建,基本上和前面的过程差不多。最后会有一个自动化的测试,基本上是由测试团队提供的自动化测试的工具,用 Spinnaker 调用它,看结果是什么样。

如果今天很有信心了,决定往生产发了,可以在 Git 上生成一个 tag,比如这个 tag 是 0.1.1,今天要发 0.1.1 版了,同样也会触发一个镜像的构建。这三个不同的阶段构建的镜像 tag 不一样,每生成一个新 tag, Spinnaker 会根据 tag 的命名规则触发不同的 Pipeline,做不同环境的部署。

Canary

最重要的是我们有一个 Canary 的发布过程,我们在 Spinnaker 的基础上,开发了一套 Canary 的机制。Canary 和 Beta 差不多,但 Canary 是真实引入流量,它把线上用户分为两组:一是稳定版的流量用户;二是 Canary 版的用户,他们会率先使用新版本,我们的具体策略是先给公司、先给我们自己办公室的人来用,这个灰度如果没问题了,用户反馈 OK,看看监控数据也觉得没有问题,再按照 1%-10%-20%-50%-100% 的阶段随机挑选线上用户继续灰度,在这整个过程都有监控数据可以看, 任何时候如果有异常都可以通过 Spinnaker 进行回退。

图 16

这个是 Canary 的示意图,线上用户被分成两组,大部分用户访问老版本,特定用户通过负载均衡转发到特定的版本里,后台有监控数据方便去比较两个版本之间的差异。

图 17

这是我们在容器环境里实现的 Canary 的架构(图 17),用户请求从前面进来,首先打到 Traefik,如果没有做 Canary 的过程,Traefik 是直接把请求打到组实例。如果要发布一个新的版本,有一个 HTTP 的 API 控制 project service,决定把什么样的流量可以打到这个里面版本。我们的策略可能是把办公室用户,可以通过 IP 看到 IP,或者把线上的安卓用户,或者线上 1% 的安卓用户打给它,这些都是可以定义的。

图 18

如图 18 所示是线上真实的部署流程。首先是要设置一个 Canary 策略,这个策略可以指定完全随机还是根据用户的特定来源。比如说是一个办公室用户,或者所有上海的用户等等,然后去调整参数,是 1% 的上海用户,还是所有的上海用户。然后开始部署服务。接下来把这个 Canary 实例做扩展,在流量进来之前,实例的容量一定要先准备好。进来之后把流量做重新定向,把流量从原来直接打给后端的 Pod 改成打到 Canary 代理服务上,由 Canary 代理服务根据策略和用户来源做进一步的流量分发。整个过程不断的迭代,有 1% 的线上用户开始慢慢到到 100%。在达到 100% 后,就采用红黑的策略替换掉所有旧版本:先把所有的新版本实例生成出来,等所有的新版本通过健康检查,都在线了,旧的版本再批量下线,这样完成一个灰度。如果中途发现问题不能继续,马上就可以回退,所谓的回退就是把 把流量打回到线上版本去。

图 19

图上(图 19)是我们的 Canary 策略。这是我们自己实现的一套东西。图中的例子是把来自指定网段一半的 iPhone 用户进行 Canary。用户分组的维度还可以有其它规则,现在我们支持的是完全随机/特定 IP/特定设备类型,这些规则可以组合起来。

我们的用户分组是有一致性保证的,一旦为某个用户分组了,那在当前灰度期间,这个用户的分组不会变,否则会影响用户体验。

下一步打算

■ACA——自动灰度分析

■自动容量管理

下一步我们打算做两件事情:第一,我们想做自动灰度分析,叫 ACA,现在 AIOps 概念很热门,我个人认为自动灰度分析可以说是一个具体的 AIOps 落地。在灰度的过程中,人肉判断新版本是否正常,其实如果日志采集够完整的话,这个判断可以由机器来做,机器根据所有数据来为新版本做评分,然后发布系统根据评分结果自动继续发布或者终止发布并回退。第二,再往下可以做自动的容量管理,当然是基于 Kubernetes 的基础上,做自动容量管理,以便更好的善用计算资源。

最后总结一下:一个好的 CD 系统应该能够控制发布带来的风险;我们在人力资源有限的情况下倾向于采用开源的方法解决问题,如果开源不满足的话,我们再开发一些适配的功能。

用 Spinnaker 构建更安全,低风险的部署环境

Spinnaker 是 Netflix 开源的持续交付平台。Netflix 的服务运行在超过100000个 AWS 云实例上,Spinnaker 用于部署超过95%的 AWS 云实例。

Spinnaker 主要用于降低新部署带来的风险,Netflix 公司并不希望一个新的 Push 影响到主体服务的运作,建立一个新的微服务很简单,难点是不断升级和维护拥有数百万用户的微服务,当出现问题时,还需要快速的回滚,在这篇文章中,将重点介绍 Spinnaker 提供的一些技术和工具。

更加方便的回滚

Spinnaker 最简单的保护措施是在通过红黑(也称为蓝/绿)部署策略部署服务时启用简单回滚。

在 Spinnaker 中创建新的集群时,只需选择 “red/black”部署策略:

这个操作将保持 Spinnaker 中的最后一个集群可用,但是被禁用(即没有流量)。

如果上线时发生什么事情(事故)需要将代码回滚到上一个可用的版本,只需在侧栏中选择 Rollback 操作即可:

回滚对话框将询问你要回滚到哪个禁用的集群:

使用红/黑部署策略可以让回到最后一个已知的可用的版本,如果部署失败或出现问题是可以撤销的。

限制并发执行

Spinnaker 中另一个限制部署风险的策略是它能够限制 Pipeline 的执行。

默认的 Pipeline 一般会修改和部署相同的自动生成的备用的 Pipeline。

Spinnaker 可以配置一次只运行一个 Pipeline:

启用 NOT_STARTED 标志后,只要已经有一个正在运行的 Pipeline,任何新的 Pipeline 都将处于同一个状态,一旦这条 Pipeline 完成,等待的 Pipeline 将启动。

执行部署

我们可以限制 Spinnaker 中特定阶段的执行时间。

限制一个阶段的执行时间有两种可能的用途:

1)只有当有人能够手动干预时

2)在服务器不是采取高峰流量时。

Netflix 在一天中对流量的需求往往是周期性的。人们一般时在晚上下班后回家观看视频。Netflix 确保在流量高峰时间不会触发部署动作。为了让部署过程更加透明,Netflix 将一个名为 SPS(每秒部署,下面会介绍)的度量合并到部署报表中,并突出显示与此度量相关的部署窗口。

禁用Pipeline

如果给定的 Pipeline 产生不正确的输出,或者由于其他系统问题而不能运行,则可以禁用该 Pipeline。

禁用的 Pipeline 将不会自动触发,并且会导致触发它的任何父 Pipeline 失败。

禁用的 Pipeline 不能手动触发,直到再次启用的时候。

检查先决条件

Spinnaker 提供了一个名为 Check Preconditions 的阶段,如果不符合某些要求,将会停止 Pipeline。

第一种形式是检查一个集群的大小:

第二种形式允许指定一个灵活的程序化表达式,称为 Pipeline 表达式。

可以通过运行 Jenkins Job 或 Docker 容器来执行更复杂的检查(例如冒烟测试),这两个阶段在 Spinnaker 中都得到很好的支持。

任何 Spinnarker 阶段可以通过配置 Conditional On Expression 使其成为可选项。这允许添加可由 Pipeline 参数控制的可选阶段,并提供额外的自动质量关卡。

手动判断

Spinnaker 提供了一个 Manual Judgment 的选项,确保运维工程师或 QA 可以轻松完成需要人工的步骤。

当一个 Pipeline 到达人工判断阶段时,它会停下来等待负责人进来并点击 Continue。这可以在需要时进行额外的验证。

手动判断阶段使用 Spinnaker 内置的现有通知机制,因此可以向需要批准流水线的用户发送电子邮件,SMS 或 Slack 通知。

我们也可以指定判断条件。判断条件可以用来决定管道的下一个步骤。在上面的例子中,如果用户选择了输入 Continue,那么后面的步骤将会运行。

通过流水线触发器自动清理

Spinnaker 允许用一条 Pipeline 的结果调用另外的 Pipeline,这样做的一个用途是自动将应用程序的状态恢复到已知的良好状态。

这可以通过设置 Pipeline 自动触发器来完成,该触发器只会运行另一个失败或被取消的 Pipeline。

流量监控

如果不小心摧毁了最后一个好的集群,导致流量中断。流量监控来确保总是提供可用的集群。

在应用程序的配置中设置了一个流量监控。它会告诉你哪些集群将被保护。

现在,当 Pipeline 或人为销毁或禁用受保护群集中的最后一个集群时,他们将看到下面的错误消息或其 Pipeline 执行失败:

自动金丝雀分析

Netflix 采用的先进技术之一是自动金丝雀分析(ACA)。在 ACA 中,实时流量被发送到基线和金丝雀集群对,以查看它们发出的指标是否满足可接受的偏差。ACA 非常擅长捕捉传统单元测试或集成测试无法跟踪的问题。

在 Spinnaker 中建立 Canary 分析阶段非常简单:

首先,定义基线(当前)群集和金丝雀(新代码)群集。

然后选择金丝雀分析的细节并定义可接受的分数,然后运行 Pipeline:

Spinnaker 将启动每个基线和金丝雀集群的一个新实例,并将每 x 分钟产生一个 Canary 得分(在例子中为15)。

成功的金丝雀

金丝雀得分

在 Spinnaker 添加金丝雀分析之前,不同的团队会以不同的方式做金丝雀。 有些会启动新的集群,其他则会重新利用其生产集群中的现有指标。通过 Spinnaker 处理 ACA 的部署,Spinnaker 的用户能够专注于他们需要捕获的分析和指标。还可以确保基线/金丝雀集群提供了最佳的一组可比较的指标。

Canary Analysis 只是一个简单的阶段,可以插入到 Pipeline 中,Spinnaker 鼓励使用这种技术,代码失败的 ACA 是不会进一步部署的。

自动的“Chaos”测试

Chaos 实验

Netflix 的“Chaos Engineering”工程是一个相对较新的实践。这个想法是运行自动控制的实验,确保能够达到预期的回退行为。

Spinnaker 与“Chaos”自动化平台(ChAP)集成,以确保使用“Chaos Engineering”工程实践创建的测试案例作为部署和验证 Pipeline 的一部分运行:

在 Spinnaker 中运行 ChAP 就是要确保”失败转移”行为作为部署过程的一部分进行测试。这种持续不断的测试对于那些本来就处于休眠状态的系统性弱点是至关重要的。

Chaos Monkey

Chaos Monkey V2 与 Spinnaker 深度整合,并支持使用 Spinnaker API。

Spinnaker 还通过托管它的配置来帮助 Chaos Monkey,如果用户没有做好准备,用户可以选择退出这个野蛮的状态。

通过启用 Chaos Monkey,可以确保代码对实例的故障转移具有适应性。其中插入在 Netflix 中做更大规模的故障转移测试,以确保 Netflix 可以生存在 Chaos Monkey 中。

Scrum中story point的预估

一、什么是story point

Story point,翻译成中文即为故事点。
故事点是Scrum团队使用的一种随机度量方式,用来度量实现一个故事需要付出的工作量”,还可能是“故事点数的估算混合了对于开发特性所要付出的努力、开发复杂度、个中风险以及类似东西。
我们也可以理解为可以用story point来衡量一个issue的难度或工作量。

二、story point的预估

估计story point常用的两个标准如下,在这里我主要以Fibonacci为例讲解。

  • Fibonacci: 0, ½, 1, 2, 3, 5, 8, 13, 21,34, 55, 89
  • Power of 2: 0, 1, 2, 4, 8, 16, 32, 64,128

story point虽然可以分为12个等级,但我们在现实中一般只采用0、1、2、3、5、8、13这七个等级。如果在预估中发现超过13的,我们一般把任务进行分割,分割为两部分,循环该步骤,直至所有point都小于等于13。

一开始我们选取之前预估为3的Issue来跟要预估的Issue进行比较,如果两个工作量差不多,设置该Issue的story point为3,如果工作量略少,则为2,更少的话则设置为1,如果该Issue不需要完成的则设置为0,该情况一般不会出现。
同理可得,如果工作量较大,相应的设置为5/8/13。

基于JIRA的Scrum敏捷开发的项目管理

Scrum敏捷开发的关键字就是增量、迭代,他更重视项目团队之间的现场沟通,不向传统瀑布式开发那样需要万事具备,才开始开发,Scrum在大方向和小故事点确认好了后,团队就可以开动了。

Scrum的团队一般都不大,一Scrum团队人数一般在10人左右,主要角色有:

product owner(产品负责人)、scrum master(团队负责人)、scrum team(开发/测试团队)。

  • Product owner :需求方,提出需求,能对功能流程、业务流程拍板的人。
  • Scrum master :团队负责人,负责解决团队各类问题,领导项目的人。
  • Scrum team :项目执行人员,一般指项目具体开发和测试的人员。

Scrum开发的步骤:

步骤一:头脑风暴

如果product owner对产品需求非常清楚,就可以省略这个步骤;开发遵守“先紧后松”原则,必须先把需求了解清楚;这里product owner可以召集技术团队/用户群体对其需求进行公开征求意见,最后输出一个产品建议表。

步骤二:product owner对产品建议表进行筛选并做减法,提炼最核心的需求。

在确定了需求后,由scrum master进行输出prd(product requirement document),这里就和传统的瀑布模式一样了,该有的文档都必须有,必须由scrum master和product owner确定好需求,包括业务逻辑、功能流程等。

步骤三:工作量估算

把任务量化,包括原型、logo设计、ui设计、前端开发等,尽量把每个工作分解到最小任务量,最小任务量标准为工作小时不能超过16小时,然后估算总体项目时间。

把每个任务都贴在白板上面,白板上分三部分:

(1)to do-待完成(2)in progress-进展中(3)done-完成

步骤四:Sprint

经过讨论后,已经把任务量化到需要具体完成的时间,然后把n个任务按照开发的重要度,组合成n个sprint(冲刺),每次执行一个sprint。

  • Sprint:每个sprint都是独立的,一般先做主要功能,再到次要功能,再到小功能,最后的sprint一般是修复bugs。)
  • Sprint:因为任务都被量化了,每天工作了多少小时,完成了多少任务量,通过每天的例会scrum master就非常清楚,并且在time burn down chart(时间燃尽表)进行表示,我们就可以直观看到任务的进度了,而且是具体到多少小时。
  • Sprint:在burn down chart里面,不管任务是否按时完成都必须记录。
  • Bugs:每个sprint都必须测试,尽量大家一起测试,如果太多bugs就开一个sprint来修复bugs。
  • 站会:每天要做的是,要开standing meeting,因为大家的时间都是非常紧张的,一般是站着开的,时间不要长,10分钟左右为宜。会议必问开发团队每个人三个问题:(1)今天做了什么(2)明天打算做什么(3)遇到什么困难
  • scrum master要解决开发团队的困难,让项目快速进展下去;每周一次周会,product owner最好在场;每个月一次月会,product owner最好在场,指出产品开发是否在product owner期待范围内;如此重复下去,直到开发完成。

(时间燃尽表:scrum的精华,通过该表格可以可视化任务的时间进度,从图中可以看到,day1是整个任务的总共时间,每天按照任务完成度更新剩余时间,或者增加时间(例如发现一个技术难点、团队成员请假等要增加开发时间))。

步骤五:评估

product owner和其团队/用户会对产品进行评估,可能还会有各种不满意的地方,不过product owner要求需要改的地方还是要改的,建立一个bugs sprint,把产品做到product owner最想要为止。

补充说明

  • SCRUM也有其自身的先天缺点,就是对团队要求高,团队成员有能力且相互信任度高,不会相互推卸责任。
  • 新团队使用该方法,起初会有各种问题,需要多多磨合。

 

基于JIRA的Scrum的项目管理

准备工作:

1、在上面的第三步时需要做工作拆分及工作量估算,会得到一个类似下面的项目计划表,JIRA的Scrum项目管理也是基于此表

p_w_picpath

2、团队中所有成员必须已经在JIRA中建立用户,并可以正常登陆

p_w_picpath

正式JIRA中建立Scrum开发项目

一、建立一个Scrum的BoardsScrum的团队

p_w_picpath

p_w_picpath

p_w_picpath

p_w_picpath

p_w_picpath

这是新建好的Boards,同时也建好了项目。

p_w_picpath

p_w_picpath
二、开发项目常规管理

p_w_picpath

1、项目编辑

p_w_picpath

p_w_picpath

2、版本开发周期设置

p_w_picpath

3、添加软件开发的功能模块

p_w_picpath

4、修改工作流

p_w_picpath

p_w_picpath

默认工作流太简单,没有QA等功能,需要重新建立工作流,或者增加一个工作流:

p_w_picpath

p_w_picpath

这个流程比较适合Scrum项目使用,大概流程如下:建立好每个故事或子任务后,它们都处于 TO DO状态,团队成员登陆JIRA,可以看到分配给自己的任务,团队成员选择一个优先要做的任务,并把当前任务更改为IN Progress,如果遇到难题进行不下去了,就把这个任务状态改为Blocked,当哪天又可以解决的时候,再把当前任务状态改为In Progress,如果任务顺利完成,就把当前任务改成Ready For QA状态,等待进行软件测试,如果测试通过没有问题,QA就把这个任务状态改为DONE,此时这个任务就完成了。如果测试中有问题,QA会重新把任务状态改为IN PROGRESS状态,并分配处理人为开发者,同时备注问题原因,由开发者处理问题后重新提交Ready For QA。当整个Sprint都测试通过没问题,这个SPrint就结束了,但如果后来集成测试中还有问题,或者任务有了小的要求修改,相关任务,需要REOPENED,重新开始TO DO去一个新的循环。

p_w_picpath

返回项目管理中

p_w_picpath

三、Scrum敏捷开发设置

1、基本设置完成后,返回可以看到功能已经全部具备,下面开始添加Story、Task了

p_w_picpath

2、建立大一些的用户故事——Epics

p_w_picpath

p_w_picpath

p_w_picpath

以下设置是需要先在第一个Sprint的Planning Meeting上已经确定了Story和细分的Story Point 。

p_w_picpath

p_w_picpath

3、建立第一个Sprint,并重命名,方便识别

p_w_picpath

p_w_picpath

4、建立story(即Scrum开发中所说的Story,如果还有子任务,这个story可以不指定经办人)

p_w_picpath

p_w_picpath

p_w_picpath

p_w_picpath

选择Stroy输入Estimate(预估天数)及子任务

p_w_picpath

p_w_picpath

 

录完了所有的story后,下面按照计划表录入子任务

p_w_picpath

指定每个子任务的经办人

p_w_picpath

如此方法,建立完成所有的子任务

p_w_picpath

5、开始Sprint

p_w_picpath

设置第一个Sprint的开始及结束时间

p_w_picpath

有了活动Sprint,Active Sprint项目才能有内容。

p_w_picpath

在Active Sprint项目中增加Ready For QA列,用于过程测试动作的显示。

p_w_picpath

p_w_picpath

p_w_picpath

p_w_picpath

p_w_picpath

6、设置管理面板(为了方便看到整个项目进度情况及分配 给我的任务,可以根据需要专门定制管理面板)

p_w_picpath

p_w_picpath

增加一个新面板,并应用给所有人

p_w_picpath

p_w_picpath

p_w_picpath

通过增加小工具来增加工具

p_w_picpath

p_w_picpath

修改及移动已有的小工具

p_w_picpath

p_w_picpath

创建完成的面板,在用户一登陆时就会看到这个

p_w_picpath

项目中的6大功能板块:

一、Backlog(查看Epics-大故事,Task-小故事,Sub-Tasks-故事点。)

p_w_picpath

二、Active Sprints(查看进行中的Sprint的进展情况:To Do/In Progress/Done)

p_w_picpath

三、Releases(版本发布情况)

p_w_picpath

四、报表(各类统计报表)

p_w_picpath

五、Issues(问题列表)

p_w_picpath

六、模块(每个模块中的问题数量)

p_w_picpath

 

————————————————————————————————————————————————————————————————————————————————

说明:JIRA中可以建立项目的类型(上例是建立Boards时系统自动建立的软件项目,是默认的第一个项目类型)

p_w_picpath

软件类:

1、Scrum软件开发

p_w_picpath

 

2、看板软件开发

p_w_picpath

3、基本软件开发

p_w_picpath

业务类:

4、任务管理

p_w_picpath

5、项目管理

p_w_picpath

6、过程管理

p_w_picpath

Centos 字体安装

第一步:查看安装了那些字体  命令:fc-list :lang=zh

安装方法:

1、先从你本机 C:\Windows\Fonts 拷贝或者网络上下载你想要安装的字体文件(*.ttf文件)(把*.ttc重命名为*.ttf)

到/usr/share/fonts/chinese/TrueType 目录下(如果系统中没有此目录,则自行mkdir创建,亦可重命名为自己喜欢的文件夹名)

2、修改字体文件的权限,使root用户以外的用户也可以使用

# cd /usr/share/fonts/chinese/TrueType
# chmod 755 *.ttf

3、建立字体缓存

# mkfontscale (如果提示 mkfontscale: command not found,需自行安装 # yum install mkfontscale )
# mkfontdir
# fc-cache -fv (如果提示 fc-cache: command not found,则需要安装# yum install fontconfig )
4、重启计算机(似乎必须重启才会有效)
# reboot