华为云用户手册
-
组件和依赖管理 在构建或运行软件时,软件的一部分要依赖于另一部分,就产生了依赖关系,而更好的管理项目中有依赖关系的组件和库文件,就成了配置管理中重要的一环。 在软件项目中,有适当的管理依赖的方法,其中比较常见有几种:一种是应用版本控制库对依赖进行管理;一种是显式的声明他们,例如应用Maven进行项目的构建;还有一种是使用依赖管理工具,管理自己的依赖库。 在CodeArts中你可以针对自己的项目情况,灵活的使用这些方法。关于应用版本控制库和显式声明来管理依赖的方式在此不做详细说明,我们主要看看如何通过CodeArts,更便捷的管理项目的依赖。 私有依赖库 CodeArts提供企业级的私有依赖库,用户可以将项目内部依赖的私有依赖组件放到私有依赖库中进行管理,并可对仓库进行多种配置。 依赖包的上传方式有三种: 在私有依赖库中单击“上传”按钮即可上传依赖包。 通过CodeArts编译构建任务,添加配置Maven私有依赖库步骤,直接将构建生成的依赖包归档到私有依赖库中。 通过修改本地的配置文件信息,实现本地构建后直接将组件上传至CodeArts的私有依赖库中进行管理。 可从依赖库中直接生成配置信息,通过复制或下载配置文件直接替换的方式,修改本地配置信息。 想要了解详细的私有依赖库操作方法,请见快速上手私有依赖库。
-
编译构建:一站式的持续集成,快速灵活地构建软件包 在高度分散和异构化的IT运维环境下,开发部与运维部应达成以下共识: 开发部跟运维部应该紧密合作,建立共同的目标和共同解决问题的机制。 开发的工作与运维的工作应该解耦,运维更多是将IT运维任务转变为自助、自动化服务,把基础架构的配置能力交给开发,因为没有人比我们更清楚应用的运行环境。 保证每个环境(开发调测环境、测试环境、QA环境、生产环境)都保持一致,避免因为环境不一致导致的各种问题。后面统一使用Docker的方式将应用与环境统一打包到镜像保持环境一致。 持续不断的对应用进行验证,确保应用总是处于可部署的状态并建立持续反馈回路,防止问题代码进入生产环境。
-
DevOps:来谁领风骚 实际上,从本质上讲,DevOps不只是一种技术或方案,它更多的是文化,它重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作,以提高整个软件开发生命周期的效率以及质量。因此,谁拥有更多的开发者,谁更加了解开发者,谁就能更加准确的掌握开发者的需求,引领软件工程能力的趋势,也能做出更加接地气的产品,谁更新迭代的速度更快,谁就越有可能在未来的长跑中获胜。 虽然从此次调查结果来看,国外厂商的DevOps产品仍然处于领先地位,但我们相信,在以华为云为代表的国内厂商的共同努力下,我国的软件工程能力将会得到显著的提升,我国的DevOps产品的能力也会得到迅速的提高,从而帮助中国企业落地DevOps,推动中国企业从DevOps的初始级和基础级的阶段,向全面级、优秀级、卓越级转变,全方位的促进国内软件产业发展,打造软件产业发展新模式,推动中国软件产业不断向前发展。
-
DevOps:想说爱你不容易 虽然众多企业都期望DevOps能够给它们带来更高效的交付效率、提升客户满意度、创造更多的商业价值,但成功实践DevOps依然是一个难题。在报告中,实际能够真正成功实施DevOps的企业仅有31.65%,另外,还有接近四成(41.13%)的企业居然不清楚自己是否成功实施DevOps,这不得不说是一个令人感到意外的结果。 当我们认真研究当前中国企业的DevOps现状时,就会明白这个结果也在情理之中。虽然国内应用DevOps的众多,DevOps已经在国内逐步落地实践,但大部分企业仍然位于DevOps能力成熟度初始级和基础级,其比例高达7成。 在DevOps的细分领域,例如DevOps的敏捷开发管理成熟度方面,同样是近七成企业仍然处在基础级和全面级,仅有1.83%的企业处于卓越级。而且虽然大多数企业普遍采取了敏捷开发方法以提升研发效率,但敏捷开发技术普及率有待提升,研发管理流程严谨性不足。同样,在应用设计方面和安全风险管理方面,多数企业也是位于初始级和基础级。同时,在持续交付方面,企业的自动化测试整体覆盖率普遍偏低;在技术运营方面,企业整体运营能力有待提高,缺乏对潜在风险的管理。 再加上企业中有近7成的研发人员DevOps经验少于1年,在这样的情况下,得到上述的调查结果也就不足为奇了。 总之,从报告来看,目前国内大多数企业的DevOps应用还是处在初始级和基础级的阶段,需要向全面级、优秀级、卓越级转变。
-
DevOps:企业迈向敏捷之钥 DevOps的出现,源于在传统模式下的开发和运维在组织上的分离而造成的管理混乱,开发要不断的迭代新版本上线新功能,但是运维关注的是稳定,这两种需求实际上是矛盾的。但DevOps旨在打破这道混乱之墙,让开发、运维、测试协同作战,提高研发效率,实现高效交付,解决传统模式下的运维之痛。 事实证明,DevOps确实能够较好的解决开发和运维之间的混乱问题,提升研发效率,实现高效交付。在近期中国信通院(CAICT)发布的《中国DevOps现状调查报告(2019年)》(以下简称报告)中,超八成企业表示,通过采用DevOps中的核心工程实践“持续交付”获得了研发效率的显著提升。同时调查发现,具备清晰、明确变更管理系统的组织,平均变更前置时间(即从代码被成功提交到成功运行在生产环境平均需要的时间),即通常意义上的交付时间也相对较短。 正是因为DevOps能够给企业带来的诸多益处,目前DevOps已经成为企业软件研发的主流,被众多企业所采用。报告显示,超半数企业使用DevOps的敏捷工程实践管理开发项目,近6成企业选择编码规范、单元测试和持续集成。
-
一体化DevOps:DevOps的潜力股 虽然国外老牌传统工具JIRA仍然以52.13%的市占率高居DevOps工具选择之首,但与云结合的DevOps工具的发展势头良好,国内厂商也在其中占据了一席之地,特别是在软件开发一体化管理领域,排名前两位的分别是国内公有云大厂华为云CodeArts与阿里云效,分别占据16.46%与10.98%的市场份额。尽管从整体上来看,软件开发一体化的DevOps平台目前在市场中的占有率仍然偏低,但从未来发展的趋势来看,与云结合的一体化DevOps将是未来DevOps平台发展的一个重要方向,这从报告中的企业广泛选择云以及与云计算有着紧密联系的微服务架构和容器可以得到很好地佐证。 而在这个领域,之所以中国厂商能够占据领先的地位,和两家厂商在中国公有云市场的强势发展是分不开的。特别是华为云DevOps之所以能够成为报告中唯一占据一个首位的DevOps工具,首先应该得益于华为30多年软件研发的沉淀,这些在多年软件研发中积累的丰富经验,使得华为深知开发者到底需要怎样的DevOps工具,在这样的理念上推出的CodeArts,受到企业和开发者的青睐,自然就是水到渠成的事情了。其次,华为云CodeArts针对需求变动频繁、开发测试环境复杂、多版本分支维护困难、无法有效监控进度和质量等开发者研发中的普遍痛点,使开发人员实现软件研发过程可视、可控、可度量,还可以实现一键式部署,解决开发者在应用部署方面的挑战。而云端代码检查、自动化测试管理和APP测试功能,能够显著避免代码出错情况的发生,分布式代码托管功能更是为开发者的代码提供了一个可靠的“家园”。第三,华为云CodeArts不仅对外服务,其本身就孵化于华为内部的软件研发能力中心,至今还在为内部所有软件研发人员服务,在可用、可靠、安全性方面都经过了实践应用的检验。这些优点汇聚起来,得到这样的结果也就在情理之中了。
-
DevOps:工具技术如何选 要实现企业DevOps从初始级、基础级向全面级、优秀级、卓越级转变,除了企业要增强对于DevOps的重视度之外,选择合适的DevOps工具和技术显得至关重要。从报告中显示,近九成的企业会选择云来助力DevOps实践落地,这是因为,DevOps就是在开发和部署周期中设计开发人员需要的环境的自动化,以减少开发人员的等待时间,并允许开发人员在代码基础上获得更多的迭代。考虑到这些环境一直处于变化状态,云计算是DevOps的天然盟友,在云计算的支撑下企业能够立即启动支持开发和部署过程中涉及的各种环境所需的资源以实施DevOps。 同时,在易用性、可伸缩性和性能方面有着卓越表现的微服务,成为了企业软件开发较受欢迎的架构,而微服务和DevOps有着非常密切的联系。微服务在具有众多优势外也带来了实施上的复杂性,整个系统由单一应用拆分为多个服务,微服务之间存在较强的依赖关系,服务之间如何协作如何处理就变得非常复杂。由于微服务是一个网状分布的,有很多服务需要维护和管理,对它进行部署维护和监控管理的时候就比较复杂。因此使用微服务,第一步是要构建一个一体化的DevOps平台。DevOps包含了持续集成与持续发布、服务依赖关系管理、服务的发现与负载均衡,以及集中化监控管理,这些都是微服务生态系统所必不可少的工具和实践。 近几年火热的容器技术也被誉为是DevOps的天作之合,它的出现使DevOps落地实践相对容易,而保持跨环境的一致性和灵活的可移植性是企业选择容器的主要因素。 这些调查结果表明,大多数企业在DevOps实践过程中,基于云计算、微服务、容器给企业带来的诸多益处,都会选择云+微服务+容器的方式来具体落地DevOps。在具体的工具选择上,国外厂商的产品仍然占据大半江山,JIRA在需求和需求管理领域拔得头筹、Gitlab位居代码管理首位。
-
用户故事地图的结构 每个用户故事地图代表一个完整的用户故事: 地图的核心是一条从左到右的时间线。 时间线的上部放置最大粒度的内容(可以理解为Epic)。 时间线的下部的第一行放置二级粒度内容(可以理解为Backlog Item),并在每个一级粒度下按照从左到右的优先级进行放置。 每个二级粒度内容的下面,自上而下放置三级粒度内容(可以理解为Task)。 最终绘制出来一个完整的端到端的用户故事。 这样的用户故事地图构建体验中,很强烈感受的是:大家专注、目标明确,讨论完成的故事非常完整。
-
创建用户故事地图(User Story Mapping)的8个步骤 召集到3-5名对产品非常熟悉的人员参与。3-5人听上去像是个魔法数字,实际上是的。因为更少的人意味着你无法获得足够的建议,而更多人则会因为讨论和协调降低会议效率。 使用静默头脑风暴模式,让每个人在便签纸上写下自己认为重要的“所要做的事情”,也就是用户任务(User Tasks)。每个人都用同样颜色的便签来书写自己的用户任务描述,这个阶段不要互相讨论。一旦大家都基本完成了准备,让每个人轮流大声读出自己的内容,并把便签纸全部放置在桌面上。这时如果出现重复的内容就可以省略掉: 根据产品规模,这个过程可能需要3-10分钟的时间,你可以观察大家的行为来判断是否需要停止。 基本上每张便签都会以一个动词开头,如:发送邮件、创建联系人、添加用户等。 这些便签组成了一级用户故事,也称为用户任务(User Tasks),它们组成了用户故事地图上的 "行走的骨骼" (The walking skeleton)部分。 这时可以提示参与者:我们只用了很少的时间就完成了需求的收集过程,而且有些内容你可能没有想到,而其他人帮你想到了。 然后,让大家将桌面上所有的便签进行分组,将类似的任务分为一组,其它的类似: 这个过程最好也采用静默模式进行,因为这样做会更快。如果发现重复的内容,就略过。 基本上分组会很容易完成。 这时同样观察每个人的行为,判断大家是否已经做完,基本上这个过程需要2-5分钟。 选择另外一个颜色的便签,对每个组进行命名,并贴在每组便签的上部。 对这些分好组的便签进行排序,一般按照用户完成操作的顺序,从左到右摆放: 如果大家无法决定顺序,那么顺序可能没有那么重要(明显)。 这一组便签,Jeff Patton称为用户活动 (User Activities) 这时你的地图应该类似于: A1 A2 A3 用户活动 T1,T2,T3 T4,T5,T6 T7,T8,T9 用户任务 现在,按照 "行走的骨骼" 用户活动这行开始讲述用户故事,确保你没有遗漏任何用户活动和用户任务。这时一般由组织者进行讲述,其他人提出意见,甚至可以让最终用户来参与讨论。 这时,我们已经完成了用户故事地图的基本框架,可以在每个用户任务下面添加更加细节的用户故事(User Stories)了。此时仍然建议使用静默头脑风暴的模式来进行第一轮用户故事的产生,同时借助如Persona和Scenario等方式协助完成这个过程。一旦你完成了用户故事的创建,就可以开始划定发布计划(Releases)了: 一般在第一个发布中只选择每个用户任务的2-3个用户故事,这对于帮助大家排定优先级和范围将很有帮助。 基本上不必使用用户故事的标准句法(As a ...)来书写这些故事,因为每张便签都处于地图的特定位置,很容易识别其所处的场景和角色。 最后,针对第一个发布的所有用户故事进行分解,确保我们的第一个发布越小越好,基本上需要保证在1-2个迭代后就可以发布产品的第一个版本。
-
用户故事可视化——起床故事 讨论一个最简单的场景:早上起床出门,作为第一个用户故事地图。 每个人都非常熟悉这个场景,但是当我们开始讨论的时候,有两个问题开始浮现: 每个人习惯不同,如何统一我们的故事? 从起床到出门要经历几个不同的阶段,到底应该如何确定阶段? 第一个问题其实是“用户故事”要解决的首要问题:这个场景的角色(Person)是谁? 第二个问题其实就是确认需求粒度的过程。 在敏捷需求分析过程中,对Person的确认非常关键,如何统一思路并让大家可以在讨论某个场景的时候可以聚焦到特定的Person上,是经常遇到的问题。讨论中经常会跑题:原本在谈Person A,结果讨论到另外一个Person B了。 在讨论中,首先将Person的定义通过卡片贴在时间线的左侧,这个很小的动作,却让团队的成员可以非常专注于当前Person的场景讨论,效率很高。 粒度方面,经常有人问Backlog Item的粒度如何确定?过去的回答是,从实现的角度来考虑,比如:控制在2-3天的工作量上。其实这是个非常不靠谱的建议,因为在讨论需求的过程中还无法确认是否要做,更谈不上评估工作量。 这就暴露了Scrum的一个最主要的问题,Backlog解决的是在Story确认以后如何进行开发过程规划的问题,而对Story该如何产生、如何设计的问题,并没有给出很好的解决办法。我们往往把Story当成需求来看,而实际上敏捷使用Story来描述需求的目的是为了协助团队进行讨论,以便最终确认需求(也就是Specification)。 用户故事地图的作用就是将User Story的简单描述:As a .... I want to ... so that ...,用可视化的方式展现在团队面前,让团队可以仔细梳理、讨论、确认这个Story包含的内容,最终产出Specification进行开发。
-
用户故事地图规范 第2个步骤中的便签表示用户任务(User Tasks),也就是下图中的绿色便签。 第3-4个步骤中的便签表示用户活动(User Activies),也就是下图中的蓝色便签。 Jeff称这两行的内容为 “行走的骨骼(walking skeleton)”和“主干(backbone)”。 用户故事(User Stories),也就是黄色便签在每个用户任务下自上而下排列,便于我们确定优先级 一般来说用户会按照从左到右的顺序来使用你的系统(用户故事地图)。
-
用户故事地图样例 下图是一个蛋糕制作及心得分享系统的用户故事地图: 第三行所包含的内容就是“大家在电子邮件系统所要做的事情”,包括:注册、配置信息、发布、下单、支付等。 第二行对这些事情进行了分组。 与一般用户故事地图不同的是,这张图当中增加了第一行的角色划分,以使整个流程更加清晰明了。 黄色的便签的第一行包含了最小化的用户故事,如:“蛋糕小白”的注册只包括手机注册和验证码登录,其他如微信绑定则不在此行,放入更靠下的便签中。 在黄色便签上,可以贴上更小的蓝色和橘黄色便签,以表示不同的状态,比如:蓝色代表完成,橘黄色代表进行中(WIP),这样你就可以看到项目的进展。 现在如果我们专注于从左到右完成第一行的黄色便签,就可以确保很快发布一款包含了最基本功能的蛋糕制作及心得分享系统,这样就可以验证我们的系统整体架构可行。同时也可以帮助我们对系统的功能进行端到端的测试,确保我们可以从用户处获取到反馈,知道我们是否解决了它们的问题(提供了商业价值)。注意:在第一行没有包含“心得分享”这一功能,因为并不一定要完成所有用户任务的开发。
-
影响地图的分层 是否可以将影响地图分层? 答案是可以而且合理的。 建议计划两次会议:第一次定义预期的业务目标和度量,第二次来制作一张地图。第一步是确定使命,而一个战略目标往往太大,无法快速见效,需要拆分成可短期达成的战术目标。根据优先级排序的战术目标,逐次进行影响地图分析,期间动态调整更新,定期决定是否需要继续。 因此可以有两层的影响地图:"一份针对整体产品愿景,一份针对中期交付。" 同时,通过分层,也可以有效的控制参与两个会议的人员组成。高阶的领导者未必需要参加所有的影响地图活动,尤其是战术影响地图会议。
-
如何防止思维蔓延,地图扩张 先发散再收敛 实战练习中,我们40多人分成6组,分别绘制自己的影响地图;实际场景中,如果每组都基于同一个目标,绘制出来的地图会各具特色而发散,最终需要引导将发散的地图进行收敛,在此过程中,会发现更好的实现方式或是新的假设导出,最终得到成型的影响地图。 分层和拆分时,掌握80/20原则,不求面面俱到,只需要涉及最关键重要的因素。考虑到大部分团队会使用物理板+即时贴的方式进行影响地图的设计,因此,原本因为物理空间受限以及可读性原因存在的物理白板的弊端,反而可以作为细化程度的一个有效限制原则(正如著名的两个披萨原则):以物理墙/白板为影响地图的最大边界。 相对于我们通常关心的业务功能/营销活动,即影响地图的第四层What,我们更应该把注意力放在前三层目标、角色和影响上,尤其是角色和影响上,关注点如此,优先级排序也是如此;先不要关注在What即自己要做什么事情上,这往往会让我们陷入执行的细节,埋头做事,而忽略了事情的初衷。 多数的路径最终不会被执行,是否需要保存? 首先,要避免过早陷入过多的细节,未来一切都是未知的,所有的结论都是基于当前的假设。所以,维护一份完整的地图,试图将所有想法都归纳在地图上,是没必要的。 其次,要遵循目标导向原则,避免在那些对整体目标没有作用的影响上花费过多的时间。整理出来的路径,当然可以保留下来,作为下一次影响地图的部分输入。 此外,需要注意的是,What包含交付内容、软件功能和组织的活动,如果交付的所有条目都是技术性,也许要重新审视影响地图,尤其是角色Who与影响How两部分,并非所有的目标都是需要通过产品功能达成,更多情况下,也许一个简单的营销活动就可以快速实现目标。
-
什么时间结束 影响地图会议何时结束 “当关键想法已经出现在地图上。” 当团队已经达成目标,并且确定最快/小路径,暂时也想不出更好的替代方案时,就可以结束。 建议设定严格的timebox,一旦出现时间点超时,或者是由于团队陷入太过细节的讨论,或是没有找对合适的人,例如缺乏合适的决策者,也许是业务决策者,也许是技术决策者。 影响地图何时失效 如同计划,在制定出来的那一刻也许影响地图就已经失效,因此需要适时调整(注意是适时,未必是实时)。 影响地图更像是迭代计划,每个影响达成,进行反馈评估,对影响地图的内容以及优先级进行调整;一旦目标达成,也许这张影响地图就完成了使命。
-
影响地图的特点 结构性:从业务目标到交付的结构化梳理和挖掘的方法,目标--角色--影响--交付物。 整体性:连接目标和具体交付物之间的树状逻辑图谱。 协作性:利益相关人一起沟通讨论协作,把隐藏在个人头脑中的默认的思维逻辑挖掘共享出来。 动态性:动态调整、迭代演进、经验证的学习。 可视化:统一共享的视图,结构清晰易读。 影响地图将各个部门/角色不同的视角、不同的思维逻辑、不同的前提假设,通过可视化和协作的方式进行梳理、澄清和导出。通过连接交付内容、影响和目标,影响地图显示了之所以去做某个功能的因果链,同时也可视化了各利益相关人做出的假设。这些假设包括:业务交付的目标、涉及目标干系人、试图达到的影响。同时,影响地图沟通了两个层面的因果关系假设: 交付会带来角色行为的变化,产生影响。 一旦影响达成,相关的角色会对整体目标产生贡献。
-
如何创建和收集故事? 通常有几种方式进行用户故事的创建和收集,其中前两种是最经常采纳的: 用户访谈 故事编写工作坊 问卷调查 观察 用户访谈的关键是找到真正的用户,所以用户访谈之前是用户画像,也就是找到Who的过程。 “你们的确开发了我所说的功能,但它并不是我真正想要的”,用户往往不知道或很难准确表达自己想要的,所以沟通需要频繁,需要拿着不同阶段的产物进行确认。说者无心,听者有意,会不会是自己主观臆断?说者有心,听者无意,会不会遗漏关键字?同理心说起来容易,做起来很难。 用户故事编写工作坊是捕获需求最有效的方式,原则是:数量优先而不是质量优先,鼓励大家输出,而不要去评判某个故事的好坏;深度优先而不是广度优先,先把一条路走通,而不要中途跳到岔路上。用户最可能做什么?可能会犯什么错误?会有什么困惑?会需要什么信息?在工作坊里最好用贴纸,便于交互,随后再整理到工具平台上。 观察用户真实使用产品的机会是难能可贵的,你会发现用户永远不会按照你设计的方式使用产品。
-
有关用户故事的一些零散建议 需求要有时间点。多问一句“什么时候需要?”,你往往会发现对方其实心里没数,ASAP不是一个好答案,越快越好只能说明不信任。尽管会有顾虑,我依然会如实说“这个功能与一个月之后的某个活动相关,在此之前实现即可,但需要预留给我一周的时间进行验证和修复”。 进行故事优先级排序时,需要考虑成本,一个重要的需求,有可能因为成本过高而延后,另一种方法是对其进行拆分。 不要着急给用户故事添加细节,遵循Kent Beck提出的最后责任时刻原则(Last Responsible Moment),团队要等到开始实现软件特性前才写下特性的具体细节,优先级排序,近期、中期、长期需求的详略程度。 纸质卡片、贴纸,还是电子工具? 在需求收集和引导的前期,例如需求编写工作坊,建议采用纸质卡片,便于交互,并且卡片的有限文字空间保证了我们不会过早进入细节。 当需求收集告一段落,统一将需求录入到CodeArts平台,需求不只是Card一个维度,多方位的信息需要有工具平台来支撑和记录。同时平台也提供了团队成员之间的协同,CodeArts团队异地的协同场景就是基于CodeArts平台进行的。
-
如何识别用户故事的坏味道(BadSmell) 如同低质量的代码会有Bad Smell,用户故事也一样会有坏味道: 几十页上百项需求堆在Product Backlog里。 提交的需求,自始至终没人和你沟通,某一天突然发现需求被实现了。 排在Product Backlog中段和后段的用户故事太过详尽。 大家依赖Product Backlog电子系统,而不是面对面进行沟通。 用户故事长得像需求规格说明书。 说不出故事的目标用户以及带来的价值。 很难为众多故事排优先级(不是高中低,而是唯一顺序)。 故事之间牵一发而动全身。 如果你发现上面任意一条出现在你的项目中,那说明你的用户故事还需要改进。
-
非功能性需求以及技术类需求 非功能性需求(Non Functional Requirement)往往是决定产品或项目成败的关键,却往往容易被忽视。当非功能性需求欠缺太多,就背负了技术债务,需要通过定期的技术类活动进行清理。 典型的非功能性需求包括:性能、可移植性、可扩展性、可用性、易用性、可维护性、可重用性、可操作性、安全性、容量等。 技术类需求的例子包括:重构、搭建持续交付流水线、测试自动化活动、环境的维护与搭建、架构改造等。 目前CodeArts没有预置非功能性需求和技术类需求作为单独的工作项类型,不希望工作项类型过于膨胀而增加了使用的复杂性。 通过新增字段可以标识不同类型的需求,更好的方式则是采用Tag标签。善用标签和过滤器的结合,可以实现非常强大的功能,关于过滤器的使用技巧,我们可以单开一个主题来讨论。
-
前言 秉承吃狗粮的文化,CodeArts团队在践行精益敏捷DevOps的同时,也在使用CodeArts工具进行实践落地。 需要说明的是: 本文中提到的实践方式,CodeArts团队在践行,所以具有一定的示范性。 不具备普适性,每个团队都应该根据自己团队的业务特性、团队成熟度、流程以及对方法论的解读,来进行落地实现。 里面有很多优化的空间,并没有最好的实践,只有适合的实践。 通常而言,软件开发起始于需求收集与分析,所以本文从需求谈起。 传统的瀑布研发模式基于三个假设: 用户准确的知道自己想要什么。 开发人员能够完全理解用户在说什么。 需求在研发过程中不会发生变化。 但事实上这三个前提假设都不存在,需求沟通之后做出来的产品,往往与需求大相径庭。
-
我们遵循Ron Jeffries提出的原则 关于用户故事,Ron Jeffries用3个C来描述它: Card(卡片):我们在用户故事编写工作坊中使用贴纸或卡片编写,随后录入到CodeArts成为工作项,展现方式可以是卡片、列表或树状结构。卡片代表需求而不是记录需求,详尽的需求内容可以用其他文档表述。 Conversation(讨论):讨论的过程建议是面对面的,如果与CodeArts的成员一样,分布在不同地域,可以通过电话或IM工具(华为内部用eSpace,可以聊天,也可以语音、视频)进行,将重要的结论写在工作项提供的讨论功能中。简单的讨论可以直接通过工作项的讨论进行,但需要牢记的是,文字的讨论永远无法取代面对面或是电话的沟通。 Confirmation(确认):用户故事并不具备契约性质,达成协议的验证要点是测试的依据,用来验证用户故事是否符合用户的期望。在用户故事编写工作坊中,验证信息可以写在故事卡片的背面,随后录入工作项。针对每一个测试要点都应该变成完整的测试用例,测试用例会与需求进行关联,由此完美的将3C结合在一起。 在CodeArts中的用户故事: 卡片是用户故事的展现形式,我们会切换到迭代视图的卡片模式,通过拖动卡片完成状态更新。 讨论是沟通的方式,不要让讨论的内容蒸发掉,讨论过程中最大的浪费就是大量的信息随后被遗失掉了。我们通常在Story工作项的评论中记录讨论结果,或是直接在评论中进行讨论,并用@通知他人。 确认是验收方式,验收信息可以填写在描述信息中,也可以在项目设置中在Story工作项的模板中添加一个属性字段完成,具体实现方式不一,并且实现起来非常灵活,所以并未做进预置的项目模板中。 一个用户故事工作项,事实上是一个需求的入口,以条目化或是卡片的形式展现,同时可以进行多方位的关联。 由验收信息生成的测试用例,会关联到工作项的“关联用例”中。 在对话和沟通的过程中会产生的有用信息,可以通过Wiki(知识共享)、Docman(文档协同)来保存,并且可以关联到Story工作项。 可以将现有的文件添加为工作项的附件。
-
Automation自动化系统 自动化在DevOps中的作用不言而喻,这部分的主线一般由各种类型的Build系统来实现,如:Jenkins、Team City、Travis CI、CC等等。只有这些还不够,为了能够完成应用从开发环境到生产环境的迁移,我们还必须处理如编译、自动化测试、依赖恢复、容器构建、打包、编排等很多操作,因此还需要配置如Junit、Xunit、FitNesse、Selenium、NuGet、NPM、JMeter等许多其它的工具来实现。但这些工具只是在自动化系统中实现某一部分的功能,一般都需要由Build系统来驱动,并依赖于SCM中所提供的各种代码来实现的。 因此我们现在通常选择华为云CodeArts这样能帮助团队完成DevOps端到端打通全流程的工具。在华为云CodeArts中提供了敏捷需求管理、配置管理、测试计划、部署、以及自动化流水线的DevOps端到端服务。通过CodeArts,用户可以一站式完成所有开发工作。
-
SCM配置管理系统 配置管理是DevOps最底层的基础设施。无论是Configuration As Code,还是Infrastructure As Code,强调的都是用管理代码的方式来管理环境。将环境版本化,无论对于快速创建,还是可稳定的重复创建这些DevOps的基本要求来说,都是最重要的基础。 配置管理系统有GIT、SVN、Mercurial、GitHub、Bitbucket等。对于DevOps实施来说,选择哪种SCM的一个重要考虑点,就是后续的Automation和Cloud这两个环节中的其它工具对这些工具的集成情况如何。作为近年来比较受欢迎的Git来说,这一切都不是问题,是最好的选择。 SCM中所放置的内容又可以再分成2个层次,分别为: AppCode:即应用代码。 EnvCode:即环境相关的代码,这部分内容又可以进一步细化成环境配置(Config)和配置数据(ConfigData)。 环境配置:指那些针对当前应用基本上固定的环境配置。 环境数据:指那些需要在部署的同时根据情况调整的数据,如:配置文件,开发、测试、生产环境的地址等。
-
Cloud 云 云服务的出现应该是催生DevOps的重要因素,没有云服务所提供的弹性、自服务等特性,很多DevOps的理念只能停留在纸面上。 对于DevOps实施来说,我们需要了解的就是各种云所提供的API,因为无论是自动化系统还是前面的SCM的产出,最终都需要调用这些API来完成最终应用部署。 在华为云CodeArts中,我们可以通过CodeArts直接调用华为云的其他公有云服务,例如弹性 云服务器ECS 、云容器引擎CCE、 容器镜像服务 SWR等,并可通过这些云服务帮助用户完成丰富多样的产品需求。 通过编译构建任务的配置,将Docker镜像直接上传至SWR镜像仓库。 通过调用E CS 服务,直接将构建好的软件包部署到云主机中。
-
持续交付与持续部署 每个团队都应该根据自己的需求做出选择。我们不应该关注形式,而应该关注结果:部署应该是无风险、按需进行的一键式操作。 持续交付 持续交付(CD) 是指,所有开发人员都在主干上进行小批量工作,或者在短时间存在的特性分支上工作,并且定期向主干合并,同时始终让主干保持可发布状态,并能做到在正常的工作时段里按需进行一键式发布。开发人员在引入任何回归错误时(包括缺陷、性能问题、安全问题、可用性问题等),都能快速得到反馈。一旦发现这类问题,就立即加以解决,从而保持主干始终处于可部署状态。 ( Wikipedia: Continuous delivery (CD) is a software engineering approach in which teams produce software in short cycles, ensuring that the software can be reliably released at any time. ) 持续交付是持续集成的延伸,将集成后的代码部署到类生产环境,确保可以以可持续的方式快速向客户发布新的更改。如果代码没有问题,可以继续手动部署到生产环境中。 持续部署 持续部署是指,在持续交付的基础上,由开发人员或运维人员自助式的定期向生产环境部署优质的构建版本,这通常意味着每天每人至少做一次生产环境部署,甚至每当开发人员提交代码变更时,就触发一次自动化部署。 持续交付是持续部署的前提,就像持续集成是持续交付的前提条件一样。持续部署则是在持续交付的基础上,把部署到生产环境的过程自动化。 持续部署更适用于交付线上的Web服务,而持续交付适用于几乎任何对质量、交付速度和结果的可预测性有要求的低风险部署和发布场景,包括嵌入式系统、商用现货产品和移动应用。这意味着除了自动化测试之外,还可以自动完成发布过程,并且可以通过单击按钮随时部署应用程序。 从理论上讲,通过持续交付,可以决定每日,每周,每两周发布一次,或者满足您业务需求的任何频率。 但是,如果真的想获得持续交付的好处:应该尽早部署到生产环境,以确保可以小批次发布,在发生问题时可以轻松排除故障。
-
云原生Cloud Native的“纹身” Native的意思是辅助、原生,DevOps与Cloud Native背后共同的东西是文化。DevOps不仅是我们的工作内容,更是工作方法,同时也在形成一种工作的文化。 华为Cloud Native转型之路,也是把文化赋予华为的研究过程的纹身过程。这是基于DevOps的精髓和支柱。 华为在云端领域的DevOps是云的基座,云渗透在ICT的很多领域,目前华为云推出一百多个云上的服务。在云的基座上,TATO所代表的内容是:T代表Team(团队),A是Architecture(架构),T是Tools(工具),O是Operations(运维)。 DevOps实践的第一步是来自于人的思想和观念的转变、科学的变化,科学的背后是思想和理论的变化,文化需要人在思想上做出改变,也需要人去承载这种思想改变。华为CodeArts转型经历了几个阶段,最初华为以盒子类的通信设备为主,盒子是以前大规模的软件开发过程,软件都是上亿行甚至几亿行代码的软件,要求可靠、稳定,每一款通信设备都有很长的研发周期。
-
华为公司管理过程的变化 《科技想要什么》一书中,将科技比作生物。生物是在不断进化,伴随着科技生物的进化,科技生物的研发方法也在不断的进化。华为公司在过去三十年,从小型做硬件、做CT通信产品的公司,成为跨ICT公司,研发理念和思想上也在不断变化。经历了初步的CMM持续交付、持续集成到敏捷、DevOps,直到最新的进化状态CodeArts。下图是华为公司在过去三十年研发能力和研发方法以及研发的工具进化的过程。
-
DevOps敏捷测试之道 本文主要以华为云的演变历程为案例,从工具角度为大家简要讲解敏捷转型过程中测试人员及测试团队都会经历哪些转变。 在2008年左右的时候,华为的项目还是采用传统的交付方式,例如在年初开始一个项目,在项目立项之初就会把客户的需求全部收集好,包括一些用户的反馈,并把需求做了全年的排序。年中的时候发布产品给用户,两个月之后再出一个补丁,最终年底出一个正式的版本。当时版本交付的节奏还是比较慢的,但是对质量要求比较强。因为产品发布给客户以后,下一个补丁需要两个月,如果用户在这个期间发现产品问题,他们只能再等两个月,而在这期间如果用户不接受我们的产品,会导致项目前功尽弃,所以就对产品的质量有严格的要求。 在2008年到2011年期间,产品逐渐向敏捷方向发展,这时有一部分研发工具平台已经陆陆续续转到云上去了,一些测试类的工具也需要转型。之前产品的交付是半年、两个月发一次,转型之后变成一个月,甚至两周发一次,但这时的转变并不彻底,与客户的交付过程仍然存在一些问题。 在2011年到2014年,华为全面把工具向平台化、服务化方向转型,这个时候一些商业模式才发生了根本性的变化,也就是说当需求上云了以后,用户才更加快速的介入进来。以前的项目是,每年年初接一次需求,而上云之后是时刻反馈需求,基于云平台,把一些功能快速的开发出来,然后频繁的和用户去商量,听取客户意见,牵引产品做快速迭代,这种交付方法使得交付周期一下变快了,之前是半年交付一次,现在是一周、两周,更有甚者,可能一两天就把功能发布出去了。从需求的角度来说发生了巨大变化,基本做到了小步快跑,快速试错。 需求变化了,产品的架构也发生了变化。CS的时候产品是单点的架构,后来慢慢转型到了SOA,到现在微服务的架构。第一轮敏捷升级,华为把业务部门和研发部门合到一起,在DevOps微服务转型的时候,把运营和运维合到一起。 然而需求变化了,架构变化了,团队也变了,这就导致了项目在过程中遗留了很多债务。从测试角度来说,这些债务主要有这么几类。第一类就是人。团队和个人、各个角色对测试的意识是不同的。比如说全功能团队对开发很重视,因为项目必须要交付产品,但是对测试方面不重视。所以测试人员自己会觉得是否自身发展到了瓶颈,没有办法再朝着测试的方向继续发展。测试人员最开始有些专项的能力,包括行动可靠性等等,他们会写一些自动化的脚本,拥有一些自动化的能力,但是在转型的过程中,他们会面临一些自动化的开发工具,需要对接自动化平台,需要有一定的开发能力,这对测试人员的自身素质提出了更高的要求。而对开发人员来说,首先是质量意识不足,第二是对于大部分开发人员来说白盒测试用例会写,但是黑盒测试用例不会写。另一方面开发在转型的过程中往往忽视了敏捷价值观,他们的思想还停留在传统的开发思想,开发做开发的事,质量跟我无关。这些其实并不是技能的问题,更多的还是思想意识上的欠缺。除了人的意识之外,前面还提到了技能意识,流程意识,例如过度依赖黑盒功能测试,我们在流程里面对测试的保障就是依赖黑盒子,结果测试、前端的UI测试,认为做到这些就能保证质量。还有一些问题,例如迭代速度很快,测试时间留得很少,所有工作量的评估只评估开发完的事情,没有评估从开发到测试,乃至上线的时间点。环境本身也有问题,测试环境部署时间比较长,测试人员在α、β生产各个节点上面做部署,然后做验证,使得部署耗费了很多时间。 下面让我们再看看测试,测试最重要的是要做什么。这里有两个关键的焦点: 第一点,测试就是一个质量活动,做测试就是要保证质量。 第二点,业务价值。测试要围绕业务价值去做,而不是说一个测试上来之后,就把测试相关的关系点、关联点全部做一遍。 让我们来看几个例子:例如现在正在做一个线上支付的功能,对这个功能最关心的方面肯定是安全,所以相关的测试用例关键点就应该围绕安全大做文章,一定把安全保证好。再比如,现在要做一个线上商城,面向用户是老百姓,不仅要让年轻人会用,也要让妈妈、婆婆都会用,那么就要关注易用性。除此之外,在双十一、双十二要举办促销活动,那就还需要关注性能。所以测试也要求瞄准了产品本身的业务价值,确定产品的目标,相应的制定质量关键点,制订相关的测试策略,然后实践落地。落地之后还要基于一些不良的效果不断的进行反馈、循环,校验整体的测试过程是否达到预期结果。这就是我们的测试焦点。 自动化测试金字塔 从这个金字塔可以看出在测试方面每一个环节的自动化能力和投入,在最底层单元测试方面,这个金字塔不代表测试用例的数量,而更应该关心单元测试的质量。例如项目中有一个非常重要的模块,要保证重要模块对应的覆盖率要达到标准。所以单元测试的重点不是在用例的数量上,一定要关心它本身的质量。在金字塔越底层做的事情,发现问题并将其解决的成本越低。而越向上一层,解决成本越高,效率也会越低。例如在界面测试层面发现了问题,对问题的定位要从界面到网络、模块A、模块B等等,需要涉及很多工作人员做问题定位。如果在单元测试层面发现问题,那么就是模块本身的问题了。对于金字塔里面所有基于代码、到单元测试、接口测试、界面测试、UI,还要尽量做到自动化。提交一行代码,能够自动把整个测试流程走遍,出去喝一杯咖啡之后,回来看到所有的测试结果在开发者眼前呈现。 常规安全与弹性安全 在我们常规的设想中,通常是哪个地方不安全,就一定要把所有不安全的因素找出来,清除掉。这是常规的做法,也就是Safety-Ⅰ的小天平,指针在绿色一边是安全,在红色一边不安全。第一个做法是把不安全的红色因素一一剔除,这是一种非常理想的方法,但在实际工作中是不可能把整个系统中不安全的因子全部识别到的,这其中涉及能力、架构等各方面的原因。因而在此基础上演变出了弹性安全,就是通过场景模拟的方式将不安全因素尽量展现出来,从而基于这种不安全场景,给出快速的修复方案弥补这个不安全因素,从用户角度来讲是感知不到的。从产品来讲,它的商业目的和质量目的都可以达到,这就是所谓的弹性安全,即便发生了错误,能够及时快速的修复漏洞或者自我修复,达到正常工作的目的。 测试左移和测试右移 左移就是前移,尽量把活动向前移。例如BDD行为开发,基于场景直接设计出符合这个场景的用例,来匹配这个设计;契约测试,服务和服务本身之间有耦合,我们可以通过契约测试解耦,以防导致问题。 测试右移是指要把测试活动的覆盖范围尽量向后蔓延。我们现在的测试只进行到了版本发布之前,测好之后发布一个软件包,而测试右移就要求我们要把软件包发布到生产环境,以及到线上运营环节,都要去做测试。 在这两个方面也有一些相应的实践,例如线上拨测,主动线上监控用户的一些行为,并从行为轨迹里面快速捕捉相应的问题,主动推送给相关的责任人,让他去关注并且解决。所以线上的过程可以通过一些测试手段,不断的反馈给真正的开发人员,让他知道当前产品的整体表现,开发人员就会快速的针对产品作出应对方案。 不同时期的测试策略 前面讲了这么多的测试活动,那么是否这个团队组建之初,就要把整个自动化测试的能力构建起来呢?其实这也是一个过程,下面从软件的成熟周期的角度,看一下如何构建测试自动化的能力。 在软件初期探索阶段,产品是一个不确定的状态,从前端的风格和整体的布局到后端的API都时刻在变化当中,而且变化比较频繁,因为自动化用例的生命周期比较短,所以在这个时候创建一些自动化测试用例是不太划算的。而这个时间段产品,往往特性是可控制的,只有几个测试,所以可以以手动为主,不考虑自动化,让产品能够快速识别错误点,让用户能用起来。 到了产品扩张阶段,用户认可产品,这时候会出现两个现象。第一是用户量增长,第二是需求数量增长。这时候必须要考虑自动化。因为在这个阶段每一次迭代的全量验证成本会越来越大,而交付的速度也会越来越快。我们不可能每一轮上线的时候都做全部的测试,这时候旧的模块就需要自动化用例去保证。 到提取阶段,产品已经到了需求的饱和期,产品的利益增长也到了饱和期,这时候要严格控制产品需求,自动化用例的职责变成守护,不允许变动引入额外的风险点、大的特性变动,导致对成熟的用户造成攻击。 团队规模对测试建设的影响 如果说团队规模在5个人以下,团队处于探索阶段,这时质量活动可以仅仅局限于测试的自组织阶段,只是做一些基础类测试管理活动,把缺陷管理起来,做一些回归测试。在这个阶段主要是建立一个测试管理的流程和机制,并没有接触到自动化测试。 随着项目的进一步扩大,逐渐增长到5-10人的团队规模,这时测试工作量突然增加,可能会有专门的测试人员进来,这个测试人员就会去和开发人员进行串联,把需求转化成自动化测试的用例,搭建持续集成,逐步演进一些测试手段。这个阶段已经开始做一些自动化的尝试。 团队进一步增大,一个人可能搞不定工作量的时候,会招聘更多的测试人员,成立专门的测试团队,这个团队就从自动化测试转向测试自动化,把更多的管理工作做进来。在这个管理过程中,我们会做一些产品的对接,包括开发专门的工具,实现自动化的整体能力,不仅仅是自动化执行了。 经过上面几个演进周期之后,测试团队具备了很多的测试自动化经验,这个时候可以进行面向云化的转型,现在很多团队都在进行DevOps转型,最关心的方面就是组建DevOps的全功能团队。那么之前转型的这些人在做什么?原有10-15人的测试专项团队做什么?在这个阶段团队要把测试专项能力向服务化能力转型。这时候测试专员就会在团队创建初期进行赋能,包括测试工程搭建,早期的测试用例怎么写,标准化模板的编制,针对非功能性测试的专项能力的赋能,所有团队进行测试流程的评审,包括测试策略、测试计划、测试用例的评审,再看一下整个团队里面流程上还有哪些改进的。从各个方面整个专项测试团队向服务化进行转型,帮助所有团队完成自动化转型。 在这里要澄清一个理念,就是测试自动化。测试自动化的目的是减少手工测试和手工操作。测试自动化不仅仅包括自动化测试执行,还包括其他所有可以减人力投入的活动,例如自动化环境创建、自动化部署、自动化监控、自动化数据分析等。刚才讲了很多自动化测试,这是测试的执行部分,例如把一些测试执行的人工测试手段做成自动化测试,但是测试自动化不仅仅是只是执行,还包括了从环境的获取到生成测试数据、执行自动化测试,最终生成结果。如果有问题,会自动推送给相关的人,对应的组织解决。自动生成测试报告,测试人员直接拿到测试结果。 契约测试的价值 团队之间一定要引入契约测试,这描述起来比较简单,它既是一种测试技术,也是一种测试规范。例如有两个服务分别是服务A和服务B,服务A依赖服务B的结构。这时签订一个契约,服务A基于这个Mock开发自己的业务逻辑,服务B基于测试来保证给A提供的结构是可用的,最终两个服务可以独立上线,A和B可以做远调。这就好像我们生活中的螺母和螺丝,它们分别由A和B厂商制造,但是他们会遵循一些契约,保证螺丝的长度、宽度、对应的型号和间距都会对应标准,最终两个厂商生产的螺丝和螺母能够正常工作,严丝合缝的合在一起。这就是契约测试的价值。 下面我们来看看在CodeArts中的几个实践。针对CodeArts,团队内部有几个专项的试点。第一是视角,测试本身不仅仅是某个细节功能点的测试,还要基于场景做测试用例,而且在必要的情况下,会有一些专门的人去对这些场景做手工测试,检验是否有问题。CodeArts本身就是打造开发者一站式的云上开发平台,提供整套的工具链,所以CodeArts团队内部追寻的DevOps下的开发实践就是狗粮文化,自己的狗粮自己吃,所有的测试活动、软件开发活动都在CodeArts里面进行,这样开发人员既是开发人员又是测试人员,他自己的思维会一直在转变,不断的打磨自己的产品,最终使产品精益求精。还有一个实践是分层自动化,CodeArts团队把所有的自动化专项流程打散,放到流水线里面,在编码或者再向前的环节,做一些安全的分析,在编码过程中做编码检视,还有单元测试用例来保证单元测试本身的用例指标。在后面的阶段,还有华为云的代码静态检查,会预先识别代码里面的规范,包括隐含的内存,通过对语句的分析能够找到问题,进行拦截。在部署到Alpha、Beta测试阶段,用CodeArts的 API服务 构造一些针对可靠性和安全的测试用例。针对生产环境的在线测试,进行在线拨测,还有后台的主动检测手段,包括前端、后端接口的检测。以及用户业务流下面关键分支上的日志,有异常日志要记录下来,然后基于日志进行分析,这些在使用过程中也会给我们进行一些质量的反馈。 最后,简单介绍一下华为云的测试服务。华为云的测试服务最开始是对内部的,有很多的测试工具。做到一定程度,也积累了很多的测试经验之后,对外发布了一些比较好的实践所带来的工具,例如现在已经上线的CodeArts的测试计划和 移动应用测试 以及解决方案,包括整体测试流程管理、测试的用例和需求双向可追溯,能够看到这个需求的测试状态;提供相应的自动化的能力,例如对安卓和IOS的测试,将软件包放在后台,对它进行系统化的兼容性测试,检测是否有兼容性的问题,能够涵概多少用户;接口测试,能够涵盖接口一层的自动化测试,APITest可以让开发人员投入到写测试用例,你可以通过鼠标加一些必要的参数进行编排,可以通过接口把场景构造出来;性能测试,模拟一些大并发的场景,会提供多种加压策略,能够实现在测试过程中对于用户的吞吐量、响应时间、负载能力,进行整体的分析。测试总览还提供完全可视化的看板,能够提供测试用例执行的情况汇总,帮助团队迅速掌握当前项目的需求和用例执行情况。 小结:本文结合华为云CodeArts团队内部近几年的测试能力发展的角度简单剖析了项目团队在DevOps转型过程中会遇到的问题,以及需要提升的能力。希望通过本文的解读能为各位在DevOps转型中迷失的从事测试工作的朋友们带来一定的启发。 父主题: 持续测试与反馈
-
CodeArts前端DevOps实践 本文主要以CodeArts产品自身为背景,简要介绍一些在前端性能优化方面的优秀实践方法和常见问题。 在开始本文的内容之前,先简单介绍一下华为云CodeArts。CodeArts是华为云一站式云端DevOps平台。简单来说,就是在云端提供了从需求到运维的端到端DevOps工具链。CodeArts的目的是为研发团队提高研发效率,降低研发成本。 本文的主题是前端的性能优化,而性能优化的解决过程与一个希腊神话故事十分类似。这个故事讲述一个名叫西西弗斯的国王,由于犯了错误,被惩罚在一座山坡上不停的推石头。这位国王不停推石头的过程,与我们持续的进行性能优化的过程很像,而石头就是我们要不停优化的问题,发现有问题又要重新来,或者一步一步来。几乎所有大型网站在做性能优化的时候,可能都是在重复的推那个大石头。 我们为什么要做性能优化?下面让我们来看几个数据: 第一,40%的用户如果在一个网站加载时长超过三秒之后就会离开这个网站。 第二,用户转换率和网站的响应时间进行关联的结果基本是,响应时间越高,性能越差,转换率越低。 之前在知乎上有一个很出名的讨论,有个人分享他把网站的响应时间从10秒提高到2秒,效率提高500%的心得和过程。当时很多人评论他讲得好,但还有更多人批判这个问题,原因就是为什么你最初能够容忍一个响应时间为10秒的产品上线?其实很多团队都存在这样的问题,每天聚焦在做优化的事情,反而忽略了第一次的10秒是怎么产生的。就好像西西弗斯的那个故事里的大石头,它为什么会出现?比如突然有一天我们被告知,用户说网站性能太差,无法承载响应的需求,这个时候团队内部才决定痛定思痛,好好做网站性能优化的事情。第一步往往是对网站进行分析,看能否找到其中的问题是什么。然后通过这些问题逐步去分析,并且做大量的技术验证,去定位并确定问题,这一步帮助我们知道这个石头是怎么来的。在这个阶段,让我们来看看有哪些好的实践。 首先,尽量利用一些第三方的平台工具,例如谷歌的Page Speed和YSlow、Lighthouse。这些工具提供了很多关于单一应用的检查项。用好第三方平台工具,能够快速对你的网站进行检验,去发现这里是否有问题,然后给我们某一个维度的检查报告。我们不能也全部依赖于工具的检验结果,也需要基于业务本身去一个一个验证,得出一个优化的结论,每一环验证好打上勾,最终的结果呈现出性能的提升。我们在提升的过程中往往发现,很多问题是规范方面的不足,这时就需要思考为什么在开发过程当中会犯这样的低级错误。 基于前面的过程,团队往往会组合出适合自己的工具链。但当我们一次次的开始推我们的这个大石头时,会发现石头特别大、特别累。于是我们希望前端工作人员能够安静独立的尽快解决这个事,不被打扰;我们会想团队要求能否少点需求,在这各阶段大家都停一下,一起把这个任务过了,让网站得到一些提升。 我们可能经过一个月的攻关,确保每个团队把自己的工作做好了,发上线了,客户得到了好的反馈,网站性能提升了,团队很高兴终于把这个石头推向山顶。但是过一两个月,又有人说页面速度变慢了,有些模块的响应速度完全不能忍受。问题的来源可能很多,我们的开发人员要专注于交付,项目进程中会出现人员的变动,很多之前在项目中积累的好实践会丢失掉。然而这些问题是无法避免的,可性能的提升也是刻不容缓的,难道团队要每隔一两个月就要做一次这样的攻关,又去推一遍超级大的石头吗? 在CodeArts的开发过程中也出现过这样的问题,而CodeArts团队针对这个问题的思考是不推这个石头了,为什么一定要积累到这么庞大的问题,而不是把石头敲碎,每次带一点呢。于是CodeArts开始基于这个角度思考如何进行性能优化,不要做任何专项的改进,而是把问题敲碎,放在每一个迭代当中。 回到开始,我们想一下之前要做的性能优化的事情,简单来说可以分为两个部分。第一个部分是固化的部分,包括CDN的建设、所有Web上的容器设置。CodeArts使用的是前端的Angular框架,关于Angular框架本身的演进与优化,再到基于业务实践自己抽取的或者实现的主权库以及公共的部分,我们把它看做是固化的部分。固化的意思是说在组织过一次集中的攻关之后,经验和效果很容易被传承下来。它的改动不涉及业务,所以它的变化频率本身比较低,而且一般这种公共的东西会有专门的架构师去看护。对于这部分内容,做了一部分优化之后就会有很好的效果。这其中还有网站劣化的部分,有可能每一个特性就是100到几百毫秒的差别,但是一个不注意,积累到一定程度之后,就会出现我们最开始所说的10秒页面。对于这部分问题CodeArts前端团队会怎么做?这就要回到DevOps的三步法,从左到右的流动,从右到左的反馈,以及持续学习的迭代。 这里的关键是第二步,从CodeArts面临的问题角度来看,就是我们怎么知道产品的每一个服务,每一个页面在什么时候开始发生了性能的劣化,就像那个石头一样是慢慢长大的。我们能否在每天,每个月,每个迭代随时发现它的变化,然后把石头敲碎,前提就是能否及时得到反馈。如果团队自身都不知道产品的性能是怎么样,靠外界,靠用户,靠其他人了解,到那个时候一看,石头就已经非常庞大了。所以核心的第一点是反馈,那么如何建立这个反馈? 第一,要有主动、实时的、前端定制化的监控。这里有几个非常关键的方面: 前端定制化。这种监控手段非常多,有各种各样的监控工具,大部分的实现原理是源于浏览器的关键节点。CodeArts本身基于开源的项目做了定制化的监控,一是将浏览器里面所有关于监控的指标细化了。 按照框架的要求,定义一些对产品要求更适合的指标,并且监控数据是实时的,并不是采样。监控的数据会提供给开发人员,每一个前端的开发人员会隔几天观察一下页面服务的现状表现如何,监控生成的结果一目了然,会帮助他们知道问题是由于网络还是由于基础框架、业务写法、效率、接口,通过前端主动化、定制化的监控,可以快速识别,且降低交付成本。 第二部分是被动的例行的性能验收。CodeArts团队会从测试验收的维度思考问题,有的团队确实疏忽了,或者初期没有建立起主动的意识,就需要靠被动的性能验收去给团队展示,让大家知道网站目前的情况,看到每一个页面发生的变化。 有了这两个主动的和被动的监控数据存在,让整个前端团队能够掌控到网站在性能上的实时变化,知道现在发生了什么问题,哪一块是我们的弱点,哪一块需要我们的开发人员去注意,哪一块需要公共架构成员去关注,这些都是非常重要的需要可视化的东西。 建立了相关的 数据可视化 以后,要怎么推行它?正如上文所说,要避免以前的那种专项的运动,因此要把每一次的性能优化放在每一个迭代,实际上影射的就是DevOps的第三步,每一个小迭代的快速优化和快速学习。这并不是一个技术活,这个问题的解决不依赖于某个技术手段或工具,因此这才是最麻烦的问题,它要求参与的每一个人有这方面的意识,提供了自动化工具和监控的可视化数据,但是不去实施,那么前面所做的所有努力就都白费了。针对这个问题最好的解决办法就是沟通,每一次的站会、周会,整个团队上下要有一个沟通的机制。在团队内部建立起良好的沟通氛围,所有数据可视化,且进行展示,团队的成员可以自发认领,且对于任务不惩罚,多主动激励,培养团队成员的主观能动性,在一次一次迭代过程中,让大家能够主动的去承担,去找到这些问题。最后很关键的一点是及时的激励或及时的反馈,每一个迭代都要看到客观数据的变化。因为前面已经建立了主动的和被动的监控数据,每次的迭代中你做的努力,或者你的松懈,会直接在下一周,或者下一个迭代会议里面产生相应的数据变化。这种可视化的反馈数据会产生及时的激励,让团队看到付出的所有努力都是值得的,那些主动思考问题、解决问题的团队一定会在可视化中脱颖而出,而不愿意改的问题一定会被放大出来。 最后回到原点,上文中一直吐槽西西弗斯,但换一个角度看他,还有一部分非常值得我们去学习的地方,就是一直向上不停歇,无论怎样,他永远在那个死循环里面推石头,也像CodeArts的精神,就像迭代一样,不断提升自己。一千个读者眼中有一千个哈姆雷特,希望本文中基于CodeArts分享的所有前端性能优化,以及实践上的尝试,能给各位开发者带来一定的启发,也希望文中提到的内容也能够为你日常的工作和实践提供帮助。 父主题: DevOps概览
共100000条
- 1
- ...
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
- 1000
- 1001
- 1002
- 1003
- 1004
- 1005
- 1006
- 1007
- 1008
- 1009
- 1010
- 1011
- 1012
- 1013
- 1014
- 1015
- 1016
- 1017
- 1018
- 1019
- 1020
- 1021
- 1022
- 1023
- 1024
- 1025
- 1026
- 1027
- 1028
- 1029
- 1030
- 1031
- 1032
- 1033
- 1034
- 1035
- 1036
- 1037
- 1038
- 1039
- 1040
- 1041
- 1042
- 1043
- 1044
- 1045
- 1046
- 1047
- 1048
- 1049
- 1050
- 1051
- 1052
- 1053
- 1054
- 1055
- 1056
- 1057
- 1058
- 1059
- 1060
- 1061
- 1062
- 1063
- 1064
- 1065
- 1066
- 1067
- 1068
- 1069
- 1070
- 1071
- 1072
- 1073
- 1074
- 1075
- 1076
- 1077
- 1078
- 1079
- 1080
- 1081
- 1082
- 1083
- 1084
- 1085
- 1086
- 1087
- 1088
- 1089
- 1090
- 1091
- 1092
- 1093
- 1094
- 1095
- 1096
- 1097
- 1098
- 1099
- 1100
- 1101
- 1102
- 1103
- 1104
- 1105
- 1106
- 1107
- 1108
- 1109
- 1110
- 1111
- 1112
- 1113
- 1114
- 1115
- 1116
- 1117
- 1118
- 1119
- 1120
- 1121
- 1122
- 1123
- 1124
- 1125
- 1126
- 1127
- 1128
- 1129
- 1130
- 1131
- 1132
- 1133
- 1134
- 1135
- 1136
- 1137
- 1138
- 1139
- 1140
- 1141
- 1142
- 1143
- 1144
- 1145
- 1146
- 1147
- 1148
- 1149
- 1150
- 1151
- 1152
- 1153
- 1154
- 1155
- 1156
- 1157
- 1158
- 1159
- 1160
- 1161
- 1162
- 1163
- 1164
- 1165
- 1166
- 1167
- 1168
- 1169
- 1170
- 1171
- 1172
- 1173
- 1174
- 1175
- 1176
- 1177
- 1178
- 1179
- 1180
- 1181
- 1182
- 1183
- 1184
- 1185
- 1186
- 1187
- 1188
- 1189
- 1190
- 1191
- 1192
- 1193
- 1194
- 1195
- 1196
- 1197
- 1198
- 1199
- 1200
- 1201
- 1202
- 1203
- 1204
- 1205
- 1206
- 1207
- 1208
- 1209
- 1210
- 1211
- 1212
- 1213
- 1214
- 1215
- 1216
- 1217
- 1218
- 1219
- 1220
- 1221
- 1222
- 1223
- 1224
- 1225
- 1226
- 1227
- 1228
- 1229
- 1230
- 1231
- 1232
- 1233
- 1234
- 1235
- 1236
- 1237
- 1238
- 1239
- 1240
- 1241
- 1242
- 1243
- 1244
- 1245
- 1246
- 1247
- 1248
- 1249
- 1250
- 1251
- 1252
- 1253
- 1254
- 1255
- 1256
- 1257
- 1258
- 1259
- 1260
- 1261
- ...
- 1262
- 1263
- 1264
- 1265
- 1266
- 1267
- 1268
- 1269
- 1270
- 1271
- 1272
- 1273
- 1274
- 1275
- 1276
- 1277
- 1278
- 1279
- 1280
- 1281
- 1282
- 1283
- 1284
- 1285
- 1286
- 1287
- 1288
- 1289
- 1290
- 1291
- 1292
- 1293
- 1294
- 1295
- 1296
- 1297
- 1298
- 1299
- 1300
- 1301
- 1302
- 1303
- 1304
- 1305
- 1306
- 1307
- 1308
- 1309
- 1310
- 1311
- 1312
- 1313
- 1314
- 1315
- 1316
- 1317
- 1318
- 1319
- 1320
- 1321
- 1322
- 1323
- 1324
- 1325
- 1326
- 1327
- 1328
- 1329
- 1330
- 1331
- 1332
- 1333
- 1334
- 1335
- 1336
- 1337
- 1338
- 1339
- 1340
- 1341
- 1342
- 1343
- 1344
- 1345
- 1346
- 1347
- 1348
- 1349
- 1350
- 1351
- 1352
- 1353
- 1354
- 1355
- 1356
- 1357
- 1358
- 1359
- 1360
- 1361
- 1362
- 1363
- 1364
- 1365
- 1366
- 1367
- 1368
- 1369
- 1370
- 1371
- 1372
- 1373
- 1374
- 1375
- 1376
- 1377
- 1378
- 1379
- 1380
- 1381
- 1382
- 1383
- 1384
- 1385
- 1386
- 1387
- 1388
- 1389
- 1390
- 1391
- 1392
- 1393
- 1394
- 1395
- 1396
- 1397
- 1398
- 1399
- 1400
- 1401
- 1402
- 1403
- 1404
- 1405
- 1406
- 1407
- 1408
- 1409
- 1410
- 1411
- 1412
- 1413
- 1414
- 1415
- 1416
- 1417
- 1418
- 1419
- 1420
- 1421
- 1422
- 1423
- 1424
- 1425
- 1426
- 1427
- 1428
- 1429
- 1430
- 1431
- 1432
- 1433
- 1434
- 1435
- 1436
- 1437
- 1438
- 1439
- 1440
- 1441
- 1442
- 1443
- 1444
- 1445
- 1446
- 1447
- 1448
- 1449
- 1450
- 1451
- 1452
- 1453
- 1454
- 1455
- 1456
- 1457
- 1458
- 1459
- 1460
- 1461
- 1462
- 1463
- 1464
- 1465
- 1466
- 1467
- 1468
- 1469
- 1470
- 1471
- 1472
- 1473
- 1474
- 1475
- 1476
- 1477
- 1478
- 1479
- 1480
- 1481
- 1482
- 1483
- 1484
- 1485
- 1486
- 1487
- 1488
- 1489
- 1490
- 1491
- 1492
- 1493
- 1494
- 1495
- 1496
- 1497
- 1498
- 1499
- 1500
- 1501
- 1502
- 1503
- 1504
- 1505
- 1506
- 1507
- 1508
- 1509
- 1510
- 1511
- 1512
- 1513
- 1514
- 1515
- 1516
- 1517
- 1518
- 1519
- 1520
- 1521
- 1522
- 1523
- 1524
- 1525
- 1526
- 1527
- 1528
- 1529
- 1530
- 1531
- 1532
- 1533
- 1534
- 1535
- 1536
- 1537
- 1538
- 1539
- 1540
- 1541
- 1542
- 1543
- 1544
- 1545
- 1546
- 1547
- 1548
- 1549
- 1550
- 1551
- 1552
- 1553
- 1554
- 1555
- 1556
- 1557
- 1558
- 1559
- 1560
- 1561
- 1562
- 1563
- 1564
- 1565
- 1566
- 1567
- 1568
- 1569
- 1570
- 1571
- 1572
- 1573
- 1574
- 1575
- 1576
- 1577
- 1578
- 1579
- 1580
- 1581
- 1582
- 1583
- 1584
- 1585
- 1586
- 1587
- 1588
- 1589
- 1590
- 1591
- 1592
- 1593
- 1594
- 1595
- 1596
- 1597
- 1598
- 1599
- 1600
- 1601
- 1602
- 1603
- 1604
- 1605
- 1606
- 1607
- 1608
- 1609
- 1610
- 1611
- 1612
- 1613
- 1614
- 1615
- 1616
- 1617
- 1618
- 1619
- 1620
- 1621
- 1622
- 1623
- 1624
- 1625
- 1626
- 1627
- 1628
- 1629
- 1630
- 1631
- 1632
- 1633
- 1634
- 1635
- 1636
- 1637
- 1638
- 1639
- 1640
- 1641
- 1642
- 1643
- 1644
- 1645
- 1646
- 1647
- 1648
- 1649
- 1650
- 1651
- 1652
- 1653
- 1654
- 1655
- 1656
- 1657
- 1658
- 1659
- 1660
- 1661
- 1662
- 1663
- 1664
- 1665
- 1666
- 1667
- 1668
- 1669
- 1670
- 1671
- 1672
- 1673
- 1674
- 1675
- 1676
- 1677
- 1678
- 1679
- 1680
- 1681
- 1682
- 1683
- 1684
- 1685
- 1686
- 1687
- 1688
- 1689
- 1690
- 1691
- 1692
- 1693
- 1694
- 1695
- 1696
- 1697
- 1698
- 1699
- 1700
- 1701
- 1702
- 1703
- 1704
- 1705
- 1706
- 1707
- 1708
- 1709
- 1710
- 1711
- 1712
- 1713
- 1714
- 1715
- 1716
- 1717
- 1718
- 1719
- 1720
- 1721
- 1722
- 1723
- 1724
- 1725
- 1726
- 1727
- 1728
- 1729
- 1730
- 1731
- 1732
- 1733
- 1734
- 1735
- 1736
- 1737
- 1738
- 1739
- 1740
- 1741
- 1742
- 1743
- 1744
- 1745
- 1746
- 1747
- 1748
- 1749
- 1750
- 1751
- 1752
- 1753
- 1754
- 1755
- 1756
- 1757
- 1758
- 1759
- 1760
- 1761
- 1762
- 1763
- 1764
- 1765
- 1766
- 1767
- 1768
- 1769
- 1770
- 1771
- 1772
- 1773
- 1774
- 1775
- 1776
- 1777
- 1778
- 1779
- 1780
- 1781
- 1782
- 1783
- 1784
- 1785
- 1786
- 1787
- 1788
- 1789
- 1790
- 1791
- 1792
- 1793
- 1794
- 1795
- 1796
- 1797
- 1798
- 1799
- 1800
- 1801
- 1802
- 1803
- 1804
- 1805
- 1806
- 1807
- 1808
- 1809
- 1810
- 1811
- 1812
- 1813
- 1814
- 1815
- 1816
- 1817
- 1818
- 1819
- 1820
- 1821
- 1822
- 1823
- 1824
- 1825
- 1826
- 1827
- 1828
- 1829
- 1830
- 1831
- 1832
- 1833
- 1834
- 1835
- 1836
- 1837
- 1838
- 1839
- 1840
- 1841
- 1842
- 1843
- 1844
- 1845
- 1846
- 1847
- 1848
- 1849
- 1850
- 1851
- 1852
- 1853
- 1854
- 1855
- 1856
- 1857
- 1858
- 1859
- 1860
- 1861
- 1862
- 1863
- 1864
- 1865
- 1866
- 1867
- 1868
- 1869
- 1870
- 1871
- 1872
- 1873
- 1874
- 1875
- 1876
- 1877
- 1878
- 1879
- 1880
- 1881
- 1882
- 1883
- 1884
- 1885
- 1886
- 1887
- 1888
- 1889
- 1890
- 1891
- 1892
- 1893
- 1894
- 1895
- 1896
- 1897
- 1898
- 1899
- 1900
- 1901
- 1902
- 1903
- 1904
- 1905
- 1906
- 1907
- 1908
- 1909
- 1910
- 1911
- 1912
- 1913
- 1914
- 1915
- 1916
- 1917
- 1918
- 1919
- 1920
- 1921
- 1922
- 1923
- 1924
- 1925
- 1926
- 1927
- 1928
- 1929
- 1930
- 1931
- 1932
- 1933
- 1934
- 1935
- 1936
- 1937
- 1938
- 1939
- 1940
- 1941
- 1942
- 1943
- 1944
- 1945
- 1946
- 1947
- 1948
- 1949
- 1950
- 1951
- 1952
- 1953
- 1954
- 1955
- 1956
- 1957
- 1958
- 1959
- 1960
- 1961
- 1962
- 1963
- 1964
- 1965
- 1966
- 1967
- 1968
- 1969
- 1970
- 1971
- 1972
- 1973
- 1974
- 1975
- 1976
- 1977
- 1978
- 1979
- 1980
- 1981
- 1982
- 1983
- 1984
- 1985
- 1986
- 1987
- 1988
- 1989
- 1990
- 1991
- 1992
- 1993
- 1994
- 1995
- 1996
- 1997
- 1998
- 1999
- 2000
- 2001
- 2002
- 2003
- 2004
- 2005
- 2006
- 2007
- 2008
- 2009
- 2010
- 2011
- 2012
- 2013
- 2014
- 2015
- 2016
- 2017
- 2018
- 2019
- 2020
- 2021
- 2022
- 2023
- 2024
- 2025
- 2026
- 2027
- 2028
- 2029
- 2030
- 2031
- 2032
- 2033
- 2034
- 2035
- 2036
- 2037
- 2038
- 2039
- 2040
- 2041
- 2042
- 2043
- 2044
- 2045
- 2046
- 2047
- 2048
- 2049
- 2050
- 2051
- 2052
- 2053
- 2054
- 2055
- 2056
- 2057
- 2058
- 2059
- 2060
- 2061
- 2062
- 2063
- 2064
- 2065
- 2066
- 2067
- 2068
- 2069
- 2070
- 2071
- 2072
- 2073
- 2074
- 2075
- 2076
- 2077
- 2078
- 2079
- 2080
- 2081
- 2082
- 2083
- 2084
- 2085
- 2086
- 2087
- 2088
- 2089
- 2090
- 2091
- 2092
- 2093
- 2094
- 2095
- 2096
- 2097
- 2098
- 2099
- 2100
- 2101
- 2102
- 2103
- 2104
- 2105
- 2106
- 2107
- 2108
- 2109
- 2110
- 2111
- 2112
- 2113
- 2114
- 2115
- 2116
- 2117
- 2118
- 2119
- 2120
- 2121
- 2122
- 2123
- 2124
- 2125
- 2126
- 2127
- 2128
- 2129
- 2130
- 2131
- 2132
- 2133
- 2134
- 2135
- 2136
- 2137
- 2138
- 2139
- 2140
- 2141
- 2142
- 2143
- 2144
- 2145
- 2146
- 2147
- 2148
- 2149
- 2150
- 2151
- 2152
- 2153
- 2154
- 2155
- 2156
- 2157
- 2158
- 2159
- 2160
- 2161
- 2162
- 2163
- 2164
- 2165
- 2166
- 2167
- 2168
- 2169
- 2170
- 2171
- 2172
- 2173
- 2174
- 2175
- 2176
- 2177
- 2178
- 2179
- 2180
- 2181
- 2182
- 2183
- 2184
- 2185
- 2186
- 2187
- 2188
- 2189
- 2190
- 2191
- 2192
- 2193
- 2194
- 2195
- 2196
- 2197
- 2198
- 2199
- 2200
- 2201
- 2202
- 2203
- 2204
- 2205
- 2206
- 2207
- 2208
- 2209
- 2210
- 2211
- 2212
- 2213
- 2214
- 2215
- 2216
- 2217
- 2218
- 2219
- 2220
- 2221
- 2222
- 2223
- 2224
- 2225
- 2226
- 2227
- 2228
- 2229
- 2230
- 2231
- 2232
- 2233
- 2234
- 2235
- 2236
- 2237
- 2238
- 2239
- 2240
- 2241
- 2242
- 2243
- 2244
- 2245
- 2246
- 2247
- 2248
- 2249
- 2250
- 2251
- 2252
- 2253
- 2254
- 2255
- 2256
- 2257
- 2258
- 2259
- 2260
- 2261
- 2262
- 2263
- 2264
- 2265
- 2266
- 2267
- 2268
- 2269
- 2270
- 2271
- 2272
- 2273
- 2274
- 2275
- 2276
- 2277
- 2278
- 2279
- 2280
- 2281
- 2282
- 2283
- 2284
- 2285
- 2286
- 2287
- 2288
- 2289
- 2290
- 2291
- 2292
- 2293
- 2294
- 2295
- 2296
- 2297
- 2298
- 2299
- 2300
- 2301
- 2302
- 2303
- 2304
- 2305
- 2306
- 2307
- 2308
- 2309
- 2310
- 2311
- 2312
- 2313
- 2314
- 2315
- 2316
- 2317
- 2318
- 2319
- 2320
- 2321
- 2322
- 2323
- 2324
- 2325
- 2326
- 2327
- 2328
- 2329
- 2330
- 2331
- 2332
- 2333
- 2334
- 2335
- 2336
- 2337
- 2338
- 2339
- 2340
- 2341
- 2342
- 2343
- 2344
- 2345
- 2346
- 2347
- 2348
- 2349
- 2350
- 2351
- 2352
- 2353
- 2354
- 2355
- 2356
- 2357
- 2358
- 2359
- 2360
- 2361
- 2362
- 2363
- 2364
- 2365
- 2366
- 2367
- 2368
- 2369
- 2370
- 2371
- 2372
- 2373
- 2374
- 2375
- 2376
- 2377
- 2378
- 2379
- 2380
- 2381
- 2382
- 2383
- 2384
- 2385
- 2386
- 2387
- 2388
- 2389
- 2390
- 2391
- 2392
- 2393
- 2394
- 2395
- 2396
- 2397
- 2398
- 2399
- 2400
- 2401
- 2402
- 2403
- 2404
- 2405
- 2406
- 2407
- 2408
- 2409
- 2410
- 2411
- 2412
- 2413
- 2414
- 2415
- 2416
- 2417
- 2418
- 2419
- 2420
- 2421
- 2422
- 2423
- 2424
- 2425
- 2426
- 2427
- 2428
- 2429
- 2430
- 2431
- 2432
- 2433
- 2434
- 2435
- 2436
- 2437
- 2438
- 2439
- 2440
- 2441
- 2442
- 2443
- 2444
- 2445
- 2446
- 2447
- 2448
- 2449
- 2450
- 2451
- 2452
- 2453
- 2454
- 2455
- 2456
- 2457
- 2458
- 2459
- 2460
- 2461
- 2462
- 2463
- 2464
- 2465
- 2466
- 2467
- 2468
- 2469
- 2470
- 2471
- 2472
- 2473
- 2474
- 2475
- 2476
- 2477
- 2478
- 2479
- 2480
- 2481
- 2482
- 2483
- 2484
- 2485
- 2486
- 2487
- 2488
- 2489
- 2490
- 2491
- 2492
- 2493
- 2494
- 2495
- 2496
- 2497
- 2498
- 2499
- 2500
- 2501
- 2502
- 2503
- 2504
- 2505
- 2506
- 2507
- 2508
- 2509
- 2510
- 2511
- 2512
- 2513
- 2514
- 2515
- 2516
- 2517
- 2518
- 2519
- 2520
- 2521
- 2522
- 2523
- 2524
- 2525
- 2526
- 2527
- 2528
- 2529
- 2530
- 2531
- 2532
- 2533
- 2534
- 2535
- 2536
- 2537
- 2538
- 2539
- 2540
- 2541
- 2542
- 2543
- 2544
- 2545
- 2546
- 2547
- 2548
- 2549
- 2550
- 2551
- 2552
- 2553
- 2554
- 2555
- 2556
- 2557
- 2558
- 2559
- 2560
- 2561
- 2562
- 2563
- 2564
- 2565
- 2566
- 2567
- 2568
- 2569
- 2570
- 2571
- 2572
- 2573
- 2574
- 2575
- 2576
- 2577
- 2578
- 2579
- 2580
- 2581
- 2582
- 2583
- 2584
- 2585
- 2586
- 2587
- 2588
- 2589
- 2590
- 2591
- 2592
- 2593
- 2594
- 2595
- 2596
- 2597
- 2598
- 2599
- 2600
- 2601
- 2602
- 2603
- 2604
- 2605
- 2606
- 2607
- 2608
- 2609
- 2610
- 2611
- 2612
- 2613
- 2614
- 2615
- 2616
- 2617
- 2618
- 2619
- 2620
- 2621
- 2622
- 2623
- 2624
- 2625
- 2626
- 2627
- 2628
- 2629
- 2630
- 2631
- 2632
- 2633
- 2634
- 2635
- 2636
- 2637
- 2638
- 2639
- 2640
- 2641
- 2642
- 2643
- 2644
- 2645
- 2646
- 2647
- 2648
- 2649
- 2650
- 2651
- 2652
- 2653
- 2654
- 2655
- 2656
- 2657
- 2658
- 2659
- 2660
- 2661
- 2662
- 2663
- 2664
- 2665
- 2666
- 2667
- 2668
- 2669
- 2670
- 2671
- 2672
- 2673
- 2674
- 2675
- 2676
- 2677
- 2678
- 2679
- 2680
- 2681
- 2682
- 2683
- 2684
- 2685
- 2686
- 2687
- 2688
- 2689
- 2690
- 2691
- 2692
- 2693
- 2694
- 2695
- 2696
- 2697
- 2698
- 2699
- 2700
- 2701
- 2702
- 2703
- 2704
- 2705
- 2706
- 2707
- 2708
- 2709
- 2710
- 2711
- 2712
- 2713
- 2714
- 2715
- 2716
- 2717
- 2718
- 2719
- 2720
- 2721
- 2722
- 2723
- 2724
- 2725
- 2726
- 2727
- 2728
- 2729
- 2730
- 2731
- 2732
- 2733
- 2734
- 2735
- 2736
- 2737
- 2738
- 2739
- 2740
- 2741
- 2742
- 2743
- 2744
- 2745
- 2746
- 2747
- 2748
- 2749
- 2750
- 2751
- 2752
- 2753
- 2754
- 2755
- 2756
- 2757
- 2758
- 2759
- 2760
- 2761
- 2762
- 2763
- 2764
- 2765
- 2766
- 2767
- 2768
- 2769
- 2770
- 2771
- 2772
- 2773
- 2774
- 2775
- 2776
- 2777
- 2778
- 2779
- 2780
- 2781
- 2782
- 2783
- 2784
- 2785
- 2786
- 2787
- 2788
- 2789
- 2790
- 2791
- 2792
- 2793
- 2794
- 2795
- 2796
- 2797
- 2798
- 2799
- 2800
- 2801
- 2802
- 2803
- 2804
- 2805
- 2806
- 2807
- 2808
- 2809
- 2810
- 2811
- 2812
- 2813
- 2814
- 2815
- 2816
- 2817
- 2818
- 2819
- 2820
- 2821
- 2822
- 2823
- 2824
- 2825
- 2826
- 2827
- 2828
- 2829
- 2830
- 2831
- 2832
- 2833
- 2834
- 2835
- 2836
- 2837
- 2838
- 2839
- 2840
- 2841
- 2842
- 2843
- 2844
- 2845
- 2846
- 2847
- 2848
- 2849
- 2850
- 2851
- 2852
- 2853
- 2854
- 2855
- 2856
- 2857
- 2858
- 2859
- 2860
- 2861
- 2862
- 2863
- 2864
- 2865
- 2866
- 2867
- 2868
- 2869
- 2870
- 2871
- 2872
- 2873
- 2874
- 2875
- 2876
- 2877
- 2878
- 2879
- 2880
- 2881
- 2882
- 2883
- 2884
- 2885
- 2886
- 2887
- 2888
- 2889
- 2890
- 2891
- 2892
- 2893
- 2894
- 2895
- 2896
- 2897
- 2898
- 2899
- 2900
- 2901
- 2902
- 2903
- 2904
- 2905
- 2906
- 2907
- 2908
- 2909
- 2910
- 2911
- 2912
- 2913
- 2914
- 2915
- 2916
- 2917
- 2918
- 2919
- 2920
- 2921
- 2922
- 2923
- 2924
- 2925
- 2926
- 2927
- 2928
- 2929
- 2930
- 2931
- 2932
- 2933
- 2934
- 2935
- 2936
- 2937
- 2938
- 2939
- 2940
- 2941
- 2942
- 2943
- 2944
- 2945
- 2946
- 2947
- 2948
- 2949
- 2950
- 2951
- 2952
- 2953
- 2954
- 2955
- 2956
- 2957
- 2958
- 2959
- 2960
- 2961
- 2962
- 2963
- 2964
- 2965
- 2966
- 2967
- 2968
- 2969
- 2970
- 2971
- 2972
- 2973
- 2974
- 2975
- 2976
- 2977
- 2978
- 2979
- 2980
- 2981
- 2982
- 2983
- 2984
- 2985
- 2986
- 2987
- 2988
- 2989
- 2990
- 2991
- 2992
- 2993
- 2994
- 2995
- 2996
- 2997
- 2998
- 2999
- 3000
- 3001
- 3002
- 3003
- 3004
- 3005
- 3006
- 3007
- 3008
- 3009
- 3010
- 3011
- 3012
- 3013
- 3014
- 3015
- 3016
- 3017
- 3018
- 3019
- 3020
- 3021
- 3022
- 3023
- 3024
- 3025
- 3026
- 3027
- 3028
- 3029
- 3030
- 3031
- 3032
- 3033
- 3034
- 3035
- 3036
- 3037
- 3038
- 3039
- 3040
- 3041
- 3042
- 3043
- 3044
- 3045
- 3046
- 3047
- 3048
- 3049
- 3050
- 3051
- 3052
- 3053
- 3054
- 3055
- 3056
- 3057
- 3058
- 3059
- 3060
- 3061
- 3062
- 3063
- 3064
- 3065
- 3066
- 3067
- 3068
- 3069
- 3070
- 3071
- 3072
- 3073
- 3074
- 3075
- 3076
- 3077
- 3078
- 3079
- 3080
- 3081
- 3082
- 3083
- 3084
- 3085
- 3086
- 3087
- 3088
- 3089
- 3090
- 3091
- 3092
- 3093
- 3094
- 3095
- 3096
- 3097
- 3098
- 3099
- 3100
- 3101
- 3102
- 3103
- 3104
- 3105
- 3106
- 3107
- 3108
- 3109
- 3110
- 3111
- 3112
- 3113
- 3114
- 3115
- 3116
- 3117
- 3118
- 3119
- 3120
- 3121
- 3122
- 3123
- 3124
- 3125
- 3126
- 3127
- 3128
- 3129
- 3130
- 3131
- 3132
- 3133
- 3134
- 3135
- 3136
- 3137
- 3138
- 3139
- 3140
- 3141
- 3142
- 3143
- 3144
- 3145
- 3146
- 3147
- 3148
- 3149
- 3150
- 3151
- 3152
- 3153
- 3154
- 3155
- 3156
- 3157
- 3158
- 3159
- 3160
- 3161
- 3162
- 3163
- 3164
- 3165
- 3166
- 3167
- 3168
- 3169
- 3170
- 3171
- 3172
- 3173
- 3174
- 3175
- 3176
- 3177
- 3178
- 3179
- 3180
- 3181
- 3182
- 3183
- 3184
- 3185
- 3186
- 3187
- 3188
- 3189
- 3190
- 3191
- 3192
- 3193
- 3194
- 3195
- 3196
- 3197
- 3198
- 3199
- 3200
- 3201
- 3202
- 3203
- 3204
- 3205
- 3206
- 3207
- 3208
- 3209
- 3210
- 3211
- 3212
- 3213
- 3214
- 3215
- 3216
- 3217
- 3218
- 3219
- 3220
- 3221
- 3222
- 3223
- 3224
- 3225
- 3226
- 3227
- 3228
- 3229
- 3230
- 3231
- 3232
- 3233
- 3234
- 3235
- 3236
- 3237
- 3238
- 3239
- 3240
- 3241
- 3242
- 3243
- 3244
- 3245
- 3246
- 3247
- 3248
- 3249
- 3250
- 3251
- 3252
- 3253
- 3254
- 3255
- 3256
- 3257
- 3258
- 3259
- 3260
- 3261
- 3262
- 3263
- 3264
- 3265
- 3266
- 3267
- 3268
- 3269
- 3270
- 3271
- 3272
- 3273
- 3274
- 3275
- 3276
- 3277
- 3278
- 3279
- 3280
- 3281
- 3282
- 3283
- 3284
- 3285
- 3286
- 3287
- 3288
- 3289
- 3290
- 3291
- 3292
- 3293
- 3294
- 3295
- 3296
- 3297
- 3298
- 3299
- 3300
- 3301
- 3302
- 3303
- 3304
- 3305
- 3306
- 3307
- 3308
- 3309
- 3310
- 3311
- 3312
- 3313
- 3314
- 3315
- 3316
- 3317
- 3318
- 3319
- 3320
- 3321
- 3322
- 3323
- 3324
- 3325
- 3326
- 3327
- 3328
- 3329
- 3330
- 3331
- 3332
- 3333
- 3333
推荐文章