规模化敏捷需求协作

在敏捷开发中,我们用Product Backlog来承载需求的集合,里面包括需求的优先级以及排序等。进入迭代后用Sprint Backlog来表示迭代内的需求和任务。单个需求用User Story卡片来沟通。高效需求协作在团队规模较小时比较容易开展,但如果团队上了规模,多团队间怎么有效的进行需求沟通,怎么在多团队间进行高效的需求协作呢?以下分三种规模的敏捷团队进行探讨。 1.单团队敏捷 在单团队敏捷中,采用典型的端到端交付敏捷特性团队,整个团队可以完成从需求到产品开发上线等一系列事情。从需求协作的角度来说,一般会经历3个重要的会议: 1.Product Backlog Refinement工作坊 2.Sprint Planning 1 会议 3.Sprint Planning 2 会议 Product Backlog Refinement(PBR)工作坊,主要用于业务方,PO,用户,和团队一起了解下阶段业务目标,分析产品功能以支持业务目标,并对User Story进行拆分,组合,初步估算,同时对Product Backlog进行优先级排序 Sprint Planning 1 会议,PO和团队设定迭代目标,确定迭代内能完成多少User Story卡片,对卡片模糊部分进行再次澄清,对卡片进行再次估算和调整 Sprint Planning 2 会议,团队创建Sprint Backlog,并对迭代内要做的User Story卡片进行任务拆分,估算任务时间,同时领取任务(有些团队采用将Sprint Planning 1&2会议合并为一个会议) 会议发生时间线如图: 可以看出PBR会议在整个迭代期间多次进行,主要集中在迭代后期举行比较多,Sprint Planning会议一般集中在迭代第一天进行,但也有将Sprint Planning 1 会议在前一个迭代末进行,Sprint Planning 2在新迭代开始进行,这就是迭代内敏捷需求协作开展的活动。 2.多团队敏捷 随着市场增长,对产品功能需求增多,产品特性上线时间要求更急迫,单个团队无法满足市场对软件推出速度的期望,这时就需要建立多个敏捷团队并行迭代开发。而且多个团队之间的需求可能具有依赖关系,这时需求协作就比单个敏捷团队复杂一些。敏捷团队结构可以有多种变化。针对PO角色来说一般有3种团队结构。 最常见的一种是多个团队之间有主PO(CPO),每个团队内部有各自的团队PO(TPO)。 第一种PO组织方式-CPO和Team PO 在这种团队结构中,CPO负责整体Product Backlog的梳理,TPO负责迭代内需求的卡片的细化,为团队澄清需求,以及团队间依赖需求的协作沟通 第二种是多团队之间有主PO(CPO),团队内部不再安排团队PO(TPO)。 第二种PO组织方式-CPO 这种结构要求团队和CPO紧密协作,CPO负责整体Product Backlog的安排,同时团队经常参与Product Backlog Refinement和CPO一起进行Product Backlog的梳理。团队也需要经常和业务方进行沟通,了解产品业务目标,以及设计怎样的产品方案以满足业务目标。在这种组织结构下团队对产品方案有更多的设计决策权。 第三种是无主PO,团队里面有团队PO。 第三种PO组织方式-只有团队PO 这种方式并不推荐,但经常出现在采用敏捷的组织结构中,这个组织结构很容易造成团队各自为政,每个TPO只考虑自己团队的需求,需求依赖的团队间需求协作效率降低。容易出现A团队由于依赖B团队的一个需求,而产生等待现象。 不管是哪种团队结构,有个原则是一个产品只建立一个Product Backlog,而不管内部有多少个敏捷特性团队。这里容易出现的敏捷反模式是每个团队都有一个Product Backlog.试想一下针对一个产品每个团队都有自己的PB,就会出现每个团队只关心团队内的PBI,失去对产品全景的理解,同时对PBI的排序只会针对本团队需求进行局部排序优化,缺乏对整个产品需求优先级进行调整的灵活性。而第三种PO结构最容易出现每个团队一个PB,没有一个统一的PB,团队间为了对齐需求花费大量沟通协调成本。 在多团队敏捷中需求协作活动大致有如下几种: 1.总体Product Backlog Refinement工作坊 ...

October 25, 2020

为什么敏捷开发落地那么难?

最近项目组发版质量持续降低,生产事故接连不断,回家的路上陷入深思,明明几个月前还做的相当不错,质量稳步提升,虽不完美,但总算还在持续进步。到底什么原因导致现在的情况?随着思考不断深入,更多本质的问题浮到面上。(本文着重讨论开发,不涉及敏捷需求价值部分) 人的素养: 手工艺人制造商品,从设计,制作,检验,并摆上商铺进行销售往往都是一个人完成。逛街的时候会遇到现场制作的手工艺人,一道工序,接另一道工序,最后组合成可用的商品,其中并没有看到做出来的东西需要另一个人单独测试,才能摆上商铺才能销售。大家往往习惯于此,但为什么我们的软件制作(开发)需要单独一个人或一组人帮你验证(测试),你自己开发的东西?你自己开发出来的东西,为什么有如此多的缺陷,如果不经过别人的验证,甚至不敢摆上商铺销售(上线)? 优秀的软件工程师,完成一段代码,一个功能,无论从内在质量,还是外在质量都经得起推敲,甚至根本不用任何人帮助他验证,即可上线。他们在做自己功能的时候,会主动构建自动化测试,开发过程中不断重构自己代码,完成后还要经过自己多次验证,同时为了避免思维盲区,他们会采用结对编程或同行评审的方式再次验证功能的逻辑。然后和测试,产品一起看看还有没有遗漏的部分。完成上述事情,他们才认为开发完成。 平庸的…..(我觉得都不应该称为工程师),接到需求,不经思索就匆忙开始,写完代码,不做任何自动化验证,不做重构,简单测试功能(happy path),甚至happy path都没跑完,然后就扔给测试人员一堆垃圾代码,就让别人测试。这是软件开发吗?这就是中国当前大多数企业的开发现状。 我觉得这是人的素养问题,有涵养的人对自己的事都有高度的责任心,做任何事都抱着不麻烦别人的利他精神,自己的事情做到极致的工匠精神,自己的代码自己负责,需要他人协作也是借鉴他人思路,而不是假他人之手来做。和这样人相处整个团队都会处于正向上升,效率,质量都会不断进步。但是如果团队大量存在平庸的人,那么这个团队只能处于向下的循环,开发效率低下, 质量差,开发埋怨测试不够快,测试埋怨开发质量差,整个团队士气低下,几乎无可救药。 意识与技能 “功能都做不完,还写什么自动化测试,做什么重构?”,能力平庸的开发人员往往搬出这套说法告诉你,做这些浪费时间,影响交付。往往说这种话的人,从没写过自动化测试,重构是什么根本不了解。他们不知道CI,TDD,refactoring三件套实际是加速整个交付效率。这种人既没有良好的软件开发意识,同时也不具备基本的软件开发技能。在一个企业留下一堆垃圾代码,然后仓皇而逃,继续祸害下个企业。 这里企业并不是无辜的,只要“性价比高”就招进来,宁愿招一群能力平庸的人,也不愿高薪聘请少量的优秀工程师。软件在欧美是一个令人羡慕的行业,薪资常年Top5,engineer这个职位是被人尊敬的。但在这里廉价劳动力获得野蛮生长,真正的劣币驱逐良币。 磨刀不误砍柴工 我们有句谚语:“磨刀不误砍柴工”,这句话用在开发里面解释就是,如果我在加入一个新功能前,能有结构清晰的代码(重构完成),有良好的自动化测试守护,那么在加入新功能时就能加快速度。总体做完一个功能花费的时间比在一个内部质量差,且没有自动化守护的代码基上加入新功能花的时间更短。 重构+自动化测试+新功能+测试+修改bug所花费的时间 < 直接开发新功能+测试+修改bug的时间。 有时大家明明理解这个道理,却还是不愿意去做,是因为工作量的原因。敏捷期望团队提升协作,提升能力,达到提升效率。但很多组织在团队还没有提升的时候加大工作量。上个迭代完成60个点,下个迭代就要求完成80个点。导致团队明知道磨刀会加快速度,但却不愿意磨刀,直接去砍柴。结果越砍越慢,越慢越加班,越加班,越不愿磨刀,形成恶性循环。 管理文化 敏捷体系是建立在信任的基础上。有了信任才有了协作,不同性格的人才有发挥空间。敏捷强调管理者、团队关注未完成的事情。一旦管理者,团队不仅仅关注事情,还更关注人是否忙碌,这个直接破坏了敏捷的基础。这样每个人都处在微观管理下,协作变的不顺畅,团队无法自组织,更无法持续提升。 要让敏捷发展,管理层要有魄力信任个人,团队,让他们自主决定做哪些事,怎么协作,怎么提升,不到万不得已,不干涉团队的决定。这个对管理者能力是个极大的考验。 #绩效 还记得“绩效毁掉sony这个故事吗?”讲述sony公司在引入绩效考核后,大家都盯着kpi做事,有一个很有价值的事,产品老化测试,但由于耗时长,体现不出绩效,而无人问津,最后导致sony的产品质量急剧下降。 虽然不知道这个故事真假,不过绩效可以很轻易的破坏敏捷文化。敏捷文化很重要的一点就是协作,无论个人还是团队之间。如果一个组织过度注重绩效,人人都盯着绩效做事,凡事都问:“这个事对我绩效有什么帮助吗?”。那么会导致人与人之间,团队与团队之间协作困难。每个人和团队都在做局部优化,整体优化丢失,组织整体效率变的低下。 总结一下: 要开展敏捷,以下几点很重要: 需要高素养的人,技能可以学习,但高素养的人需要从小培养 开发中经常使用UT,TDD,refactoring,pair programming,code review 支持团队成长,合理化工作量,通过团队成长,效率提升来提升工作量 扁平组织架构,基于信任的管理 注重整体绩效,尽量基于团队,甚至多个团队进行整体绩效管理 看起来很简单,实际上每一条都很难,敏捷就是这样难。

July 2, 2020

敏捷文档真的轻了吗?

在日常辅导团队的过程中有一个问题是大家问的比较多,直观上理解有些困难,更别说实际的使用。“敏捷需要文档吗?”这个问题,在一个组织对于不同的角色,同一个角色但不同开发背景的人,答案都不一样。这篇文章想由浅入深的对敏捷开发需要的文档进行讨论。 简单的答案是“需要”。 敏捷开发和瀑布流程对文档的要求 我们知道敏捷开发和瀑布流程在开发周期时间上明显不同,一个是迭代开发,迭代周期(1~4周),一个是阶段-门限开发,周期(1~n月),在交付一个可运行的小功能上两种开发方式需要的时间明显不同。敏捷只需要几周,瀑布则需要按月来交付。这个周期时间的不同会导致在文档上花的时间的不同。 如上图我们说敏捷开发是轻文档,而瀑布是重文档式的流程。 重量级文档流程 先来说重量级文档,在瀑布流程下,我们被要求从商业分析,市场分析,产品需求收集,产品设计,开发分析,开发,UT,测试,集成测试,系统测试,到发布这些阶段,对应于商业需求文档(BRD), 市场需求文档(MRD),产品需求文档(PRD),概要设计(HLS),详细设计(LLS),测试策略,测试计划,测试用例,测试报告,整个开发流程大概需要这些文档。Winston W. Royce(瀑布流程发明者,1970年发表)认为开发流程和制造业的流程相似,如果在每个阶段我们都做好充分的分析设计,那么整个项目最终是不会有很大偏差的。 到这里我们要回答两个问题: 这个理论正确吗? 1970发明的方法还适用于现在的市场环境,商业环境和研发技术吗? 这个理论正确吗?在不考虑任何成本的情况下,花更多的时间在每个阶段可以提升每个阶段的正确性。在后续任何阶段发现错误,都可以回到最初的阶段。比如在测试阶段发现前面有个功能的设计错误了,那么完全可以回到产品需求收集阶段进行修改,同时进行相应文档变更,PRD,HLS,LLS,测试用例变更。那么这个理论正确吗?在不考虑任何成本的情况下,这个理论可行。但如果考虑成本呢? 我们在一个产品或项目构建的早期,能想清楚所有要解决的用户问题,所有的功能,所有的技术依赖吗? 经验说明根本不可能,不然变更控制委员会(CCB)设立来做什么?就是变更太多控制不住,需要一群人来控制。 我们的业务,领域知识是随着产品不断的开发过程中,不断学习获得的,如果前期在缺乏大量产品知识的时候,我们要进行大量的需求设计,这时期会产生大量的低质量需求,大量错误的假设导致后期的返工。 1970发明的方法还适用于现在的市场环境,商业环境和研发技术吗? 大家回想一下1970年代的产品与技术,那个时候以科研系统为主流,unix系统在那时诞生,使用汇编和C语言为主要编程语言。那个时候市场竞争并不激烈,计算机还没有用于个人。所以在70年代左右开发的系统复杂,昂贵,而且没有多少市场竞争,开发一套系统往往耗时几年。这个时候开发一套系统成本很高,周期很长,使用重文档的流程开发,产生的浪费,往往被高成本,长时间的交付掩盖住了。 到了现在个人市场,商业市场都有了长足的发展,交付周期被缩短到了几周,甚至于每天上线多次。重文档的流程弊端凸显,要么根本就无法完成这些文档,要么对文档进行大量的裁剪,要么文档落后代码几公里再也无法同步。在快速高效的开发流程里写出这些高质量的文档变得不可能,也不必要,因为这些文档从一开始价值就不高。重文档流程的组织在商业交付上越来越慢,最后深陷泥潭,被新型的独角兽企业一遍又一遍的冲击,最后不得不转型开发流程寻求突破。 敏捷开发中的文档 敏捷文化在90年代后期开始逐渐重塑了整个软件行业。以重视反馈,减少浪费,团队协作为核心,整个开发文档也遵循其核心价值。 那么在敏捷中我们怎么写文档,才能高效,高质量,低成本的完成我们的交付呢? 关于需求文档: 之前说到在前期业务人员,市场人员,产品经理会输出BRD,MRD,PRD,这些文档的目的和价值是什么呢? 这些文档的核心目的是帮助组织的业务目标和产品对齐,在敏捷里面不仅希望目标对齐,同时还希望最大化使用这些文档,通过这些文档实现以下目的: 业务目标和产品目标对齐 理解的一致性 文档和代码保持一致 自动化验收系统 这样可以最大化的提升文档的价值,文档用于业务人员,产品经理,开发人员,测试人员理解一致,文档和代码始终一致可以实时反应代码情况,同时文档又用于产品交付的自动化验收。 用户故事 敏捷里面提倡使用用户故事来描述需求,通过用户故事团队随时讨论,澄清需求,同时通过用户故事的验收标准(AC),帮助开发团队各角色明确需求的验收范围。 通过用户故事的INVEST原则,帮助我们提高交付效率,理解需求价值。 用户故事的INVEST原则 实例化需求 敏捷里面提出了实例化需求的一组模式,帮助达到上述的目标,在实例化需求里面提倡: 产品要从商业目标去得到需求的范围,要理解需求背后的"why"“who”,理解商业用户期望的结果是什么 需求是协作产生的,通过工作坊商业干系人,领域专家,开发团队一起完成需求的梳理和澄清 使用实例来描述需求,开发团队和商业用户一起识别系统的关键实例 精炼实例,实例需要呈现用户的需要,避免过多的实现细节 实例化需求实现自动化验收 前面几点还是比较容易理解,主要第5点很多产品经理觉得不可思议了,我写的需求还可以变为自动化验收测试系统?是的,现在有很多支持实例化需求的平台,如: Concordion,FitNesse. Concordion实例化需求: 自动化验收框架: 这里不具体讲解实例化需求验收部分,这个以后专题讲解。 关于设计文档: 说了需求部分,那么开发设计部分呢?以前的HLS,LLS怎么更有价值,减少浪费呢? 敏捷里面认为: 代码的设计体现在代码自动化测试里面,这样代码的设计通过自动化测试代码实现,这时测试代码和实现代码保持一致,通过测试反应方法设计意图,反应功能设计的意图。 领域模型,领域的知识用领域模型反映,通过领域模型实现开发人员和领域专家理解一致性 通过富文本注释实现,代码不仅要自注释,而且通过图文并茂的富文本注释体现设计思路 关于测试文档: 在测试方面,提倡代码质量集体负责,测试人员并不是最后的守门员,而是作为测试专家,把测试方面的技能传递给开发人员,让开发人员对自己的功能充分测试,并完成自动化单元测试,自动化验收测试。最后测试文档变成了一个一个的自动化测试用例代码。 总结: 在如今要求高效率,高质量快速交付的环境下,敏捷的轻量级文档流程,并不是真的“轻”了,而是聚焦于消灭成本高,浪费高,价值低的文档,通过自动化的方式提升文档的价值。作为产品,开发,测试的人员更需要锻炼基本功,提升整个交付过程的效率和质量。

June 8, 2020

规模化敏捷思考

敏捷 XP和scrum作为敏捷开发里面最重要的两种思想,相辅相成的发展了20多个年头。要了解这两种方式的本质,要先了解发明人。XP的发明人Kent Beck来自美国的软件工程师,TDD(测试驱动开发)的推崇者。在软件领域最出名的是他的Junit单元测试框架。Jeff Sutherland和Ken Schwaber共同发展了scrum的敏捷理念。Jeff Sutherland毕业于西点,11年的军旅生涯里面当了医生,随后涉及到IT领域. Ken Schwaber软件工程师,产品和工业的咨询。 在这里我们可以了解到Kect Beck更偏向于技术,所以在XP里面除了价值,原则外,更看重各种开发的实践。而scrum则更偏向于人,团队,流程。所以我们采用的敏捷一般是XP和scrum的混合方式。既有XP里面的开发实践,也有scrum的关于人,团队,流程的框架。这两种理念相辅相成,共同发展,形成了今天的敏捷。 小规模的敏捷 在90年代末期,没有现在的云计算,没有大数据,没有docker,k8s。受限于当时的软件技术和规模。XP和scrum在当时的环境下不管从价值观,原则和可以落地的工程实践,都比当时普遍采用的瀑布开发方式好上太多。在2000年后敏捷开发方式开始一步一步成为主流的开发方式。后来持续集成,持续交付,精益开发,用户故事地图,实例化需求的发展进一步加强了敏捷的各个部分。 在当时的背景下,采用组织架构的重新划分,以及架构的持续演进,就可以从component team,变化为feature team. 在feature team里面,团队之间依赖少。所以一个个独立的团队自己采用XP和scrum方式进行持续改进。整个组织的交付效率和质量得益于不断提升的单个团队。 唯一的不变就是变化,这句话时刻提醒着我们。随着时间推移,软件的规模越来越大,SaaS,PaaS,大数据,中台化等技术和组织架构的变化。使得小而美的敏捷团队遇到了前所未有的挑战。 规模化的敏捷 软件规模变得越来越大后,遇到的首要问题是团队间需求的依赖问题。一个完整的具有用户价值的功能现在无法由一个团队完成。有时需求会横跨3,4个团队,甚至7,8个团队。团队间就像以前的component team一样依赖起来。整个开发的过程变得臃肿,反应变慢,反馈周期变长。这样敏捷团队的价值观和原则被现实打破。怎么才能短,快的交付有价值的需求,得到反馈,使敏捷的价值重现。所以后来出现了规模化敏捷的思考,就是基于现状找到可以解决的方法。不管从safe,还是less,或者Scrum@Scale,其实本质就是解决两个核心问题。 第一个问题就是:需求怎么对齐,其实也就是依赖团队间目标怎么对齐,怎么协同开发? 第二个问题就是:随着软件规模扩大,团队,团队人数怎么扩张? 针对第一个问题的本质是,如果无法解决团队间开发依赖问题,那么通过在依赖团队间建立统一的product backlog和统一迭代起止时间的方式进行缓解。统一的product backlog可以解决团队之间需求排序优先级的问题,再加上团队之间迭代的起止时间变得一致性,提升沟通,联调的效率,降低协作的成本。 针对第二个问题,还是考虑到团队人数开始变多,沟通渠道变宽,团队整体的透明性,沟通效率变差,团队变得迟缓。所以通过保持小而美的团队,通过一层层把小团队聚合起来,形成更大规模的团队群。上层团队之间的协作依靠团队代表成员(PO代表,scrum master代表,技术代表,测试代表等)进行沟通协作,来提升沟通效率。 当软件规模更大后,所有的规模化方法都是解决协作的问题,沟通效率问题,解决这类问题本身会产生更多的成本(相较于以前的小规模敏捷团队) 所以当组织达到一定规模化,进行敏捷的方式要进行相应的调整,根据每个组织的独特性一般有以下几点: 优先解决团队开发的依赖 通过统一product backlog 统一团队迭代进行依赖缓解(比如集中多个团队的sprint plan) scrum of scrums, scrum of scrums of scrums(或者其他方法用于同步团队间的进度) 集体团队回顾(持续改进团队依赖问题) 持续交付基础设施的完善 说了那么多,其实规模化敏捷也属于一直在探索的道路上,在这条遍布荆棘的道路上,一定要坚持敏捷的价值观和原则,找寻到适合自己组织和团队的方法。

April 27, 2020

golang-NSQ讲明白

版本 golang – 1.12.4 nsq-1.1.0.linux-amd64.go1.10.3.tar.gz 什么是NSQ 一句话讲NSQ是一个简单队列,类似于java经常使用的activeMQ或者RocketMQ,一般在同步分离成异步,发送消息和接受消息解耦的地方使用到。 NSQ有以下特性: 支持拓扑的高可用性和避免单点故障(SPOFs)。 更强的消息递交保证 为单次处理绑定着内存的足迹(通过把一些持久话的消息放入磁盘) 对生产者和消费者的配置进行极大的简化 提供直接的升级路径 提升效率 NSQ组成 NSQ由三个组件组成: nsqd 用于接收消息,排队消息,投递消息,我们的客户端(生产者,消费者)主要和它打交道 nsqlookupd 管理nsqd,nsqadmin拓扑信息。 我们的客户端(消费者)询问此组件来发现nsqd等 nsqadmin web UI 查询各种NSQ组件的信息,消息信息 NSQ使用步骤 启动nsqlookupd组件 启动nsqd并向nsqlookupd注册 启动nsqadmin并向nsqlookupd注册 生产者推送一个message到其中一个nsqd,并将此消息设置到一个topic里面 消费者向nsqlookupd询问指定topic的消息,nsqlookupd把有此topic的nsqd地址给到消费者 消费者建立channel和topic之间的订阅关系,通过channel向nsqd获取指定topic里面的消息 nsqd向所有订阅该topic的channel推送message, 然后其中一个消费者可以通过其中一个channel获取该topic的message 注意第4点,生产者为什么没有从nsqlookupd注册中心去寻找可以推送消息的nsqd呢?因为nsq的设计理念是将nsqd本地化,也就是说生产者直接推送消息到local-nsqd。这点和RocketMQ的设计理念不一样,RocketMQ的NameServer和nsqlookupd类似,但是设计上RocketMQ生产者会访问NameServer去寻找可用的MQ推送消息。 启动,注册过程: 生产者,消费者: 这就是nsq一个完整的使用流程,下面分别从客户端和代码两个方面介绍详细怎么使用 客户端使用 启动nsqlookup $ nsqlookupd 在另一个shell启动一个nsqd,并在lookupd注册,注意-broadcast-address一定是消费者可以访问的地址 $ nsqd --lookupd-tcp-address=127.0.0.1:4160 -broadcast-address="x.x.x.x" -tcp-address="0.0.0.0:4150" 启动nsqadmin,并在lookupd注册: $ nsqadmin --lookupd-http-address=127.0.0.1:4161 生产者生产一个message,并创建该消息的topic $ curl -d 'hello world 1' 'http://127.0.0.1:4151/pub?topic=test' 消费者通过lookupd查找对应的topic的nsq并绑定topic和channel,通过channel接受该topic的message $ nsq_to_file --topic=test --output-dir=/tmp --lookupd-http-address=127.0.0.1:4161 生产者生产更多消息 $ curl -d 'hello world 2' 'http://127.0.0.1:4151/pub?topic=test' $ curl -d 'hello world 3' 'http://127.0.0.1:4151/pub?topic=test' 可以打开nsaadmin查看所有详情http://127.0.0.1:4171/ ,同时也可以查看/tmp下面接收并写入的message (test.*.log) ...

June 24, 2019