This commit is contained in:
louzefeng
2024-07-11 05:50:32 +00:00
parent bf99793fd0
commit d3828a7aee
6071 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,149 @@
<audio id="audio" title="35 | 版本发布:软件上线只是新的开始" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/8b/51/8bde1335e4db9e29b29dd23bd7fcc451.mp3"></audio>
你好,我是宝玉。上一章我们学习了软件测试篇,今天,我们将从版本发布这个话题开始,进入到运行维护篇的学习。
说到版本发布对于很多开发人员来说觉得是一件很简单的事情就是将程序编译打包部署但实际发布的时候却经常出现发布错版本的问题或者是发布前修改了一点代码导致上线出现Bug的情况发生。
而版本发布对于很多项目管理者来说又是一个很纠结的事情觉得还有很多功能没完成很多Bug还没改完害怕用户负面评价结果时间一拖再拖迟迟无法上线。
所以今天我将带你一起学习一下如何做好版本发布,保障好发布产品的质量。
## 关于软件版本
在讨论这个话题之前我们需要了解“版本”的含义。也许你已经知道版本的含义但是这里还是有必要明确一下因为在不同的语境下版本的含义也有所不同。比如产品经理会对开发人员说“这个功能我们会放到下个版本中实现”开发人员会对测试人员说“这个Bug在昨天的版本中已经修复了”。
这里产品经理说的“版本”是指特定功能集合,开发人员说的“版本”是指某一次程序的构建结果。也就是说对软件版本来说,包含两部分含义,一部分代表特定功能集合,一部分代表某一次特定的代码构建结果。
为了明确标识软件版本,需要对版本进行编号。目前业界在软件版本的命名上,通常会采用以下方式:
>
主版本号 . 子版本号.[.修正版本号.[构建版本号]]
比如说1.2.1、2.0、3.0.1 build-123。
其中主版本号和子版本号用来标识功能变化小的功能变化增加子版本号大的功能变化增加主版本号。修正版本号则表示功能不变化的情况下修复Bug而构建版本号表示一次新的构建这个通常由编译程序自动生成。
团队中对版本有了清晰的定义和良好的版本编号在讨论版本时你就可以根据版本号清楚地知道应该有哪些功能属于哪一次的构建结果。在修复Bug或者增加功能时开发人员也能清楚地知道代码应该加入哪个版本。在验证Bug时测试人员就可以知道应该在哪个版本中验证Bug有没有被修复。
## 版本发布前,做好版本发布的规划
回到前面的问题,为什么有的项目管理者会在发布前感觉没准备好,害怕上线发布呢?根源上,他们还是对于功能和质量没有信心,担心发布后获得负面的评价。
而实际上并不代表你需要完成所有的功能或者没有任何Bug有一个完美的版本才能上线。毕竟追求完美是没有止境的这世界上也不存在完美的软件很多著名的软件比如Windows、Office、iOS都免不了在发布后还要打补丁。
这里的关键在于,**要在用户(或客户)的心理预期和你软件的实际情况之间,达到一种平衡,让软件的功能和质量,满足好用户的预期。**
要合理管理好用户的预期,达到好的发布效果,就需要在版本发布前先做好版本发布的规划。
那么,版本的发布规划,是指规划哪些内容呢?
**首先是规划好要发布的功能。**在发布前,搞清楚哪些是用户必须要有的功能,哪些是用户可以没有的功能。对于必须要有的功能,那么要保证软件中有这个功能才能发布,对于不是必需的功能,可以以后再逐步完善。
有一个经典的案例就是第一代的iPhone复制粘贴的功能都没有但是在用户界面和触屏设计上做的非常好一样取得了极大的成功。
然后是定义好发布的质量标准。在发布前,搞清楚你的用户对质量的容忍度如何,对哪些功能的质量要求高,对哪些功能的质量要求没那么高。对于那些用户在意的功能,要具有较高的发布标准,反之,则可以有较低的质量标准。
举例来说,像微博这种社交类应用软件,界面布局存在一点问题,用户是可以接受的,但是如果撰写内容的时候,因程序异常导致辛辛苦苦写的内容丢失,用户是比较难以忍受的。
**再有就是要设计好发布的策略。**考虑好是直接发布给所有用户?还是先让一部分用户试用?比如说可以先让内部用户使用,内部用户对软件质量问题容忍度是很高的,还可以帮助发现很多问题。
让一部分用户使用Beta版也是一个好的发布策略当用户知道你的软件还是Beta版的时候要求会比较低一点可以接受一些不那么严重的Bug。 还有就是采用灰度测试的发布策略,让一小部分用户先用新功能,如果没发现什么问题,再继续扩大使用的用户规模,如果有问题,也只是影响少量用户。
像Gmail在最初的几年一直是Beta版本测试。还有像苹果的iOS用户也可以选择安装最新的Beta版本可以先体验新功能但是必须忍受系统的不稳定。
**最后,就是有一个综合性的版本发布计划。**在确定了要发布的功能、定义好了质量标准、设计好了发布策略,就可以制定一个综合性的版本发布计划了,确定好发布的时间点。
这个发布计划,不只是项目内部成员,还需要和项目之外利益相关方,比如客户、市场运营人员,大家一起确定最终的发布计划。
在对版本的发布做好规划后,就不用再纠结于该不该发布,该什么时候发布的问题。
有功能没完成没关系关键要看这个功能是不是必须要有有Bug没有修复完成是不是影响发布要看这些Bug是不是影响发布的质量标准还可以采用一些像Beta版、小规模用户试用的发布策略降低用户对功能和质量的预期。
## 规范好发布流程,保障发布质量
在规划好发布的版本后,要发布版本似乎是一件很简单的事,就是将源代码编码、部署。
但发布版本,可能并不是像你想的那么容易,这其中有几个需要注意的问题。
首先是必须保证要编译部署的是正确的版本。虽然一般来说,开发人员不会犯这样的错误,但是如果发布了错误的版本,后果可能很严重,所以要引起足够重视。比如说当年拼多多造成了几千万损失的薅羊毛事件,就是错误发布了一个测试用的无门槛券,导致被大量滥用。
然后要保证版本稳定可靠。如果你有开发经验的话应该知道开发软件一个常识就是每一次对代码的修改都可能导致新的Bug产生。如果你的代码库在发布之前还一直在增加新的功能或者是不停地修复Bug那么质量是难以稳定下来的。
再就是要在发布失败后能回滚。没有谁能保证程序发布后没有严重问题,所以最保险的办法就是要在部署后,如果发现发布的版本出现严重问题,就应该对程序进行回滚操作,恢复到部署之前的状态。即使有些不可逆的升级,也需要事先做好应对措施,比如发布公告,停止服务,尽快修复。
针对这些问题已经有些好的实践比如说代码冻结、Bug分级、回归测试等可以降低发布风险保障发布产品的质量。在《[12 | 流程和规范:红绿灯不是约束,而是用来提高效率](http://time.geekbang.org/column/article/87129)》这篇文章中,我也提到了:**流程和规范能将好的实践标准化流程化,让大家可以共享经验。**所以在版本发布上,我们也可以制定合理的流程,来应用这些好的实践,保证发布的质量。
那么一般大厂都是什么样的发布流程呢?下面这个流程可以作为一个参考。
- 在发布之前要做代码冻结。
什么是代码冻结呢就是在发布之前对于要发布的版本在源代码管理工具中专门创建一个release分支然后对于这个分支的代码冻结功能的修改不接受新功能的增加甚至重要性不高的Bug都不修改只修复重要的Bug。
由于严格的控制代码的修改,这样可以让版本的质量逐步趋于稳定。
- 对代码冻结后发现的Bug要分级
在代码冻结后可能还存在一些Bug测试的过程中也会新增一些Bug。代码冻结的原则就是尽可能减少代码的修改避免引起不稳定。所以对于这些Bug要有一个简单的分级是否在发布前修改还是留在发布后再修改。
至于如何对一个Bug分级这需要项目负责人和产品负责人一起确认。
- 每次修复Bug后发布新的候选版本
进入代码冻结后开发人员还需要对一些Bug进行修复每一次修复完Bug后就要生成一个新的候选发布版本比如说1.1 RC1、1.1 RC2。
关于生成发布版本,现在比较流行的做法是和持续集成系统整合,完全自动化。也就是在自动化测试通过之后,会自动构建,生成各个环境的发布版本。这样好处是,可以避免人为失误导致的错误,另外程序的配置管理做好了的话,只要测试环境的版本在测试环境测试没问题,那么就可以认为在生产环境的版本也是正常的。
自动化构建,生成发布版本并不复杂,各个语言都有成熟的方案,如果你还不了解的话,可以通过搜索引擎搜索关键字:“[对应平台] 自动打包”例如搜索“iOS 自动打包”、“iOS build automation”这样的关键字。
其中稍微有点麻烦的就是如何应用不同环境下的不同配置,比如说测试环境连测试环境服务器,生产环境连生产环境服务器。有关程序配置管理部分,可以参考这篇文章:《[大型项目程序配置管理演化之路](http://insights.thoughtworkers.org/large-project-configuration-management/)》
- 每次部署新的候选发布版本后,要做回归测试
在每次开发人员部署新的候选发布版本到测试环境后还需要做一次回归测试。也就是说在Bug修复完对主要流程要重新测试一遍同时还要对之前确认过的Bug再确认一遍以确保Bug确实修复了并且没有引入新的Bug。
如果当前候选发布版本达到版本发布的质量标准后,就可以准备发布了。
- 申请上线发布
上线发布是一件很严谨的事,所以在正式上线发布前,通常还需要有一个申请和审批的流程。审批的主要目的是要有人或者有部门统筹对所有的上线发布有一个全面的了解和控制,避免上线过于随意导致问题,避免和其他部门的上线冲突。
- 部署发布
如果已经实现了自动化,部署发布应该是非常简单的一步。如果还没有自动化部署发布,也需要事先将详细的操作步骤写下来,避免部署发布时发生纰漏,这样在实际部署发布时,按照事先写好的步骤操作就不容易出现错误。
- 上线后的测试
项目上线后测试人员需要马上对已经上线的版本做一个主要功能的测试以确保线上运行正常。如果做好了数据监控还同时要对一些关键数据进行监控例如服务器CPU利用率、内存占用率、服务出错率等数据。
如果万一发现版本上线后出现问题需要考虑按照事先准备好的回滚方案进行回滚操作尽量将损失降到最低。通常不到万不得已不建议马上对问题打补丁进行修复。因为哪怕很小的代码修改都可能会引入新的Bug。而重新做一遍回归测试耗时会比较长。
以上就是版本发布的一个常见流程,你也可以基于这个流程制定适合你项目的流程,让你的版本发布更加稳定可靠。
## 软件上线只是新的开始
当你的软件上线后,这不代表你的项目就结束了,可能这才只是新的开始。
用户在使用你的产品的时候可能会遇到一些Bug或者是有一些建议所以需要给用户反馈的渠道让用户可以有途径对于Bug或者功能去反馈。通过收集用户的反馈可以进一步完善你的软件产品。
只是靠用户主动反馈问题还是不够的需要主动的对发布的版本进行监控比如说要收集App Crash的Log、监控服务器资源占用情况、监控API出错的比例、监控网页响应的速度等数据。当发现数据异常时很可能说明发布的版本是有问题的需要及时的应对回滚版本或者发布新的更新补丁。
有关线上监控和报警的内容,将会在后续我们课程《[38 | 日志管理:如何借助工具快速发现和定位产品问题 ](https://time.geekbang.org/column/article/97682)》中带你继续学习。
不管怎么样,软件成功上线了都是一件值得祝贺的事情,同时也是时候回顾总结一下整个项目过程了,关于这一点,我也会在后续专栏文章《[39 | 项目总结:做好项目复盘,把经验变成能力](https://time.geekbang.org/column/article/98141)》中跟你一起探讨如何做好项目总结复盘,把经验变成能力。
## 总结
今天带你一起学习了版本发布的相关知识。做好版本发布,关键在于版本发布前做好版本发布的规划,以及采用一个科学的发布流程。
版本规划其实就是通过合理的规划尽可能的让软件的功能和质量满足好用户的预期。所以一方面要尽可能提供应有的功能和保证质量另一方面也可以通过合理的发布策略例如beta测试降低用户预期。
通过规范的发布流程可以确保要发布的版本正确以及发布质量的稳定。流程的关键在于发布前要对代码冻结避免发布前频繁修改代码引入新的Bug同时在每次修复Bug后要做回归测试保证Bug被修复以及没有引入新的Bug上线后还要对线上版本再一次测试确保没有问题。整个流程中一些手工部署发布的操作应该尽可能自动化。
最后,软件上线只是新的开始,还需要收集用户的反馈,对线上服务进行监控和预警,对整个版本的开发过程进行总结回顾。
## 课后思考
你在发布版本前,会做哪些准备工作?你的发布流程是什么样的?通过对这篇文章的学习,你觉得有哪些可以改进的地方?或者你觉得有什么更好的方案可以分享的?欢迎在留言区与我分享讨论。
感谢阅读,如果你觉得这篇文章对你有一些启发,也欢迎把它分享给你的朋友。

View File

@@ -0,0 +1,145 @@
<audio id="audio" title="36 | DevOps工程师到底要做什么事情" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/97/f7/971800a9fe907b4beed06482c05f53f7.mp3"></audio>
你好我是宝玉。这些年有关DevOps的概念很火大家都在讨论DevOps有人说DevOps就是自动化运维有人说DevOps是流程和管理还有人说DevOps是一种文化。以前的运维工程师也纷纷变成了DevOps工程师。
今天我将带你一起了解一下究竟什么是DevOpsDevOps到底要做什么事情
## 传统的运维模式以及面临的挑战
在传统的瀑布模型开发中,软件生命周期中的运行维护这部分工作通常是交给运维工程师来完成的。
当开发人员完成编码,测试人员测试验收通过后,到了要发布的时候,就会将程序交给运维人员部署发布到生产环境。
<img src="https://static001.geekbang.org/resource/image/2b/e0/2b3c01636b37728e5684d9bbc5e383e0.png" alt=""><br>
(图片来源:[The Product Managers Guide to Continuous Delivery and DevOps](http://www.mindtheproduct.com/2016/02/what-the-hell-are-ci-cd-and-devops-a-cheatsheet-for-the-rest-of-us/)
除了程序的部署更新传统运维工程师最重要的职责就是保障线上服务的稳定运行。对服务器24小时监控有意外情况发生时需要及时处理和解决。
除此之外,还有日常的更新维护,比如说安装升级操作系统、安装更新应用软件,更新数据库、配置文件等。
早些年这种运维模式运行的很好,但随着这些年互联网发展,有两个主要的因素对传统的运维模式产生了很大挑战。
第一,服务器规模快速增长和虚拟化技术的高速发展。
早些年一般的企业服务器数量都不会太多运维工作以手工为主自动化为辅。几个人几十台服务器即使用手动方式管理也不会太困难。但随着这些年技术的快速发展大型互联网公司的服务器数量越来越庞大而中小公司都开始往云服务上迁移基于Docker这样的虚拟化技术来搭建在线服务的基础架构。
服务器规模的增加和虚拟化技术的使用,就意味着以前的手动方式或者半自动的方式难以为继,需要更多的自动化和基于容器技术或者相关工具的二次开发。对于运维的工作来说,运维人员也需要更多的开发能力。
第二,高频的部署发布。
传统的软件部署频率不高,一般几天甚至几个月才部署发布一次,同时每一次的部署发布,也可能会导致系统的不稳定。而敏捷开发和持续交付的概念兴起后,更新的频率越来越高,每周甚至每天都会有若干次的更新部署。
高频部署带来的挑战,首先就是会引起开发和运维之间的冲突,因为开发想要快速更新部署,而对于运维来说,每次更新部署会导致系统不稳定,最好是不更新,可以让系统维持在稳定的状态。另一个挑战就是想要快速的部署发布,也意味着运维要有更高的自动化能力。
为了解决这些挑战DevOps 出现了,它帮助解决开发和运维之间的沟通协作问题,提升运维开发和自动化能力。
## 什么是DevOps
**DevOps可以理解为一种开发Development和运维Operations一起紧密协作的工作方式从而可以更快更可靠的构建、测试和发布软件。**
DevOps并不意味着开发一定要懂运维技术运维要懂开发技术而是说两个工种要更紧密的协作有共同的目标更快更可靠的构建、测试和发布软件。
这就意味着,对于运维来说,不再抵触开发的频繁更新部署,会帮助搭建自动化部署平台,提供自动化部署工具;对于开发来说,不再认为运维的工作和开发没关系,开发人员会邀请运维人员参与架构设计,帮助运维实现自动化脚本开发。
那么当你的团队采用DevOps的方式工作的话会带来哪些好处呢
- **整个软件的构建、测试和发布过程高度自动化**
DevOps一个很重要的基础就是自动化通过对自动化的应用是最简单有效的打破开发和运维之间壁垒的方式。
因为应用自动化后,对于运维人员来说,自动化的交付流程,减少了繁重的手工操作,自动化测试可以有效对产品质量提供很好的保障。对于开发人员来说,可以方便高频率地进行部署。
如果你的团队还没有开始实施自动化,可以先从持续交付开始,具体可以参考我们专栏在《[26 | 持续交付:如何做到随时发布新版本到生产环境?](http://time.geekbang.org/column/article/92587)》中的介绍。
- **信息更加透明和易于测量**
在传统的开发和运维合作模式中,开发和运维之间的信息不是那么的透明。对于开发来说,不了解程序在服务器上运行的情况,对于运维来说,程序就是个黑盒子,无法对程序内部进行监控,出现问题只能重启或者回滚。
当采用DevOps的工作方式信息更加透明通过日志和工具数据也可以被更好测量。比如说
- 可以直观看到开发到部署需要多少时间,哪个环节可以改进?
- 当前服务运行情况如何每分钟访问数多少API出错率多少
- 当前用户数多少,有多少新增用户?
这些数据,不仅可以帮助运维更好地预警,或者是帮助开发更好地优化程序,还可以帮助业务团队更好地了解服务的运营情况。
- **培养跨职能协作的文化**
DevOps的核心文化是不同职能工种之间的紧密协作的文化。其实不仅限于开发和运维之间就像我们之前在《[32 | 软件测试:什么样的公司需要专职测试?](http://time.geekbang.org/column/article/94941)》)中讨论的,开发和测试之间也一样离不开紧密的协作。
如果你的团队是在真正地实践DevOps的工作方式就会积极拥抱这样的跨职能协作的文化在日常工作中包容错误、对事不对人能对项目的开发流程持续改进鼓励创新。
有关DevOps也有一些不错的文章有兴趣的话可以进一步阅读《[DevOps 前世今生 | mPaaS 线上直播 CodeHub #1 回顾](http://juejin.im/post/5c98372c6fb9a070f2377ff6)》《[孙宇聪来自Google的DevOps理念及实践](http://mp.weixin.qq.com/s?spm=a2c4e.11153940.blogcont582942.6.67ba14b5SRgVNt&amp;__biz=MzI3MzEzMDI1OQ==&amp;mid=2651819931&amp;idx=1&amp;sn=0a4d940b122f65ac910ef9f0175c5bad&amp;chksm=f0dcd9e7c7ab50f11b0b2395a293e8ac6ee807e843d77fa54ba677c8f0bcf6ab1db2d1110458&amp;scene=0#rd)》和《[关于 DevOps ,咱们聊的可能不是一回事](http://www.jianshu.com/p/645bb1283a77)》。
DevOps看起来很美好也许你迫不及待想去实施但DevOps这种工作方式的建立也不是一下子能完成的上面提到的这些带来的好处相应的也是你要去遵守的DevOps原则**自动化、信息透明可测量、构建协作文化。**
这也意味着:
- 你需要去构建自动化部署的系统,从构建、测试到部署实现高度的自动化;
- 建立数据监控的系统,让信息透明可测量;
- 最后要形成跨职能协作的文化。
看起来很难但也不需要有压力因为要实践DevOps不需要你改变开发模式瀑布模型或者敏捷开发都可以实施不需要靠管理层推动也不一定要让开发人员去学习运维知识或者运维去学习开发知识。而是通过了解DevOps的核心价值也就是跨职能之间紧密协作更快更可靠地构建、测试和发布软件一点一点地做出改变。
## DevOps工程师到底要做什么事情
在了解了什么是DevOps后我们再来看看基于DevOps的实践DevOps工程师到底要做什么事情
对于DevOps工程师的定义其实是有争议的因为有人认为DevOps是一种团队工作的方式而不是一种职业。也有人认为DevOps工程师是一种职位用来帮助团队形成DevOps工作方式的职位。
在这里我们没必要陷入这种争论而是从DevOps实践的角度来看看DevOps工程师要做什么事情可以帮助团队来实践DevOps的工作方式。至于是Dev来做这些事情还是Ops来做这些事情还是一起协作来做这些事情并不是最重要的。
**首先DevOps工程师要帮助团队建立基于持续集成和持续交付工作流程。**
关于持续集成和持续交付,不仅仅是工具的使用,同时还是基于工具之上的一整套的交付工作流程。
这套工作流程已经是业界公认的好的实践,但在很多中小团队普及率还不高,主要的难点之一是搭建比较复杂,可能还涉及二次开发;另一个是不知道该怎么建立这样的流程。
对于这样的工具和流程的建设最初的时候就是需要有专门的人专门的时间去建立也是DevOps工程师首先要去解决的问题。
**其次,要建立一套基于日志的监控报警的系统,以及故障响应的流程。**
对于线上系统,应急响应非常重要,要在故障发生后,第一时间作出响应,及时恢复生产,避免更大损失。而要做到这一点,同样离不开工具和流程的支持。
需要能建立一套基于日志的监控报警的系统,将应用程序还有运行环境的各项数据监控起来,设置报警的阈值。当数据异常,超出阈值,就马上触发报警,然后进入应急响应的流程。
对于应急响应流程,首先应该能第一时间通知最合适的人去处理,比如负责这个服务值班的开发人员,然后对于怎么第一时间恢复应该有准备,涉及跨部门协作也应该有相应的配合流程;最后对于故障应该有总结,避免类似情况再次发生。
有关监控和日志分析,我还会在我们专栏后续文章《 监控和日志分析:如何借助工具快速发现和定位产品问题 ?》中有更多介绍。
**然后,要构建基于云计算和虚拟化技术的基础设施。**
虽然并非每一个软件项目都是基于云计算或虚拟化技术来搭建的,但云计算和虚拟化技术方面的技术,其实是横跨开发和运维的,可能对于大部分开发和运维来说,都只了解其中一部分知识,这就需要有人能同时懂软件开发和云计算或虚拟化技术,或者一起协作,才能搭建出真正适合云计算或虚拟化技术的架构。
构建出来基于云计算和虚拟化技术的基础设施后对于开发人员来说只要通过API或脚本即可搭建应用对于运维来说也只要通过脚本和工具即可管理。
这其实也是DevOps中的“[基础设施即代码](http://insights.thoughtworks.cn/nfrastructure-as-code/)”的概念。
**最后要形成DevOps的文化。**
DevOps最核心的本质就是工作方式和协作的文化而这样的文化需要有人引领一点点去形成。
DevOps工程师要帮助开发和运维相互理解对方的工作帮助开发和运维在一起协作时多沟通相互学习。出现问题不指责而是分析原因共同承担责任找出改进的方案。
这些就是DevOps工程师要做的事情本质上还是DevOps的几条基本原则自动化、信息透明可测量、构建协作文化。不需要有DevOps工程师的头衔基于DevOps的原则去做事情就可以算的上是DevOps工程师。
## 总结
今天我带你一起学习了当前热门的DevOps概念DevOps可以理解为一种开发和运维一起紧密协作的工作方式从而可以更快更可靠地构建、测试和发布软件。DevOps的主要原则就是自动化、信息透明可测量、构建协作文化。
DevOps工程师要做的事情就是帮助团队来实践DevOps的工作方式。具体可以帮助团队
- 建立基于持续集成和持续交付工作流程;
- 建立基于日志的监控报警的系统,以及故障响应的流程;
- 构建基于云计算和虚拟化技术的基础设施;
- 形成DevOps的文化。
DevOps工程师做的事情就是帮助团队基于DevOps原则来做事让团队形成紧密协作的工作方式更快更可靠的构建、测试和发布软件。
## 课后思考
你所在团队是否是DevOps的工作方式一起紧密协作有没有什么值得改进的地方可以怎么改进你认为的DevOps团队应该是什么样子的欢迎在留言区与我分享讨论。
感谢阅读,如果你觉得这篇文章对你有一些启发,也欢迎把它分享给你的朋友。
<img src="https!%5B://static001.g%5D(https://static001.geekbang.org/resource/image/78/9c/788180c8c6dd9b69b2784d2a780a239c.jpg)eekbang.org/resource/image/78/9c/788180c8c6dd9b69b2784d2a780a239c.jpg" alt="">

View File

@@ -0,0 +1,157 @@
<audio id="audio" title="37 | 遇到线上故障,你和高手的差距在哪里?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/75/90/75ceed7a33c73014874201c8890e8790.mp3"></audio>
你好,我是宝玉。在软件上线后,发生线上故障是一个常见的问题,但怎样对线上的故障进行处理,却很能反映出新手和高手程序员的差距。对于团队来说,如何应对线上故障,也同样能反映出线上运维水平的高低。
今天,我将带你一起分析一下,新手和高手在应对故障时有什么不同?大厂在处理线上故障时,有哪些可以学习借鉴的地方。
## 遇到线上故障,新手和高手的差距在哪里?
在这里,我把新手在处理线上故障遇到的一些常见问题列一下,同时,我们也一起分析下,高手是怎么处理这些问题的。
#### 新手遇到复杂的线上故障,不知道该怎么下手
对于线上故障有的很简单从界面或者错误日志上可以直观地看到问题在哪从而也好找到方法去解决。但有的故障却没办法直观地看出原因比如说内存一直在涨CPU居高不下遇到这种复杂的故障通常新手就不知道该怎么下手了。
而对高手来说会在实践中总结一套自己解决问题的步骤遇到问题会按照解决问题的步骤有条不紊地去分析和解决。比如说caoz的这篇《[出了bug怎么办](http://mp.weixin.qq.com/s?__biz=MzI0MjA1Mjg2Ng==&amp;mid=2649867038&amp;idx=1&amp;sn=8924a2a7b51f57f983b24445812f29c5&amp;chksm=f1075973c670d06547a8f7ad6eb687bfd78fb32894321b5519c1e982b4f7d31d23bb3a2e9fbc&amp;scene=0#rd)》,就充分体现了一个高手的水平。)通常通过下面这样的步骤:
- 第一步,评估影响范围;
- 第二步,试图重现问题;
- 第三步,临时方案和终极方案;
- 第四步,风险评估及持续优化。
如果你还记得专栏文章《[28 | 软件工程师的核心竞争力是什么?(下)](http://time.geekbang.org/column/article/93185)》里的内容,就会发现,其实这本质就是一种解决问题的能力。一步步分析、解决和预防问题。
从新手到高手,可以从借鉴像这样的方法开始,然后在实践中不断总结经验,形成一套自己的分析问题、解决问题的方法。
#### 新手遇到线上故障会想着马上修复Bug
当发现Bug后尤其是自己的Bug很多开发人员马上就想到了Bug的修复方案迫不及待就要去写代码打补丁了。然而这样做的问题就是匆忙之间打补丁如果没有经过充分的测试可能会引入新的Bug甚至是更严重的Bug。如果要充分测试那么意味着时间会比较长而线上故障的时间越长可能意味着损失也越大。
而对于高手来说会首先对故障进行评级看对用户的影响范围如果是核心业务大面积影响用户那么当务之急是恢复生产然后再考虑如何去修复Bug。
恢复生产并不一定需要修复Bug可以用一些临时性的方案比如说回滚系统到上一个稳定的版本重启服务看是否能恢复正常。当然在恢复之前还要尽可能保留当时的日志、故障场景的截图、内存的Dump把当前内存数据保存的静态文件等信息用来后续查找故障原因使用。
遇到线上故障新手需要时刻牢记恢复生产、降低损失是第一要务修复Bug是其次的。
#### 新手遇到线上故障不知道如何快速定位到Bug在哪
在临时恢复业务后还是需要找到Bug在哪后续才能从根本上解决。对于比较复杂的线上故障新手通常不知道从哪里下手看日志看代码都看不出所以然而高手却总能快速地定位到Bug在哪。
高手快速定位Bug在哪关键在于通过有效的手段逐步缩小问题范围直到找到Bug在哪里。
比如说一种常见手段就是先重现Bug因为有了重现的步骤就等于将问题的范围缩小到重现Bug的这几步操作相关的代码上就很容易发现问题在哪。
还有一种手段就是分析错误日志,通过错误日志,可以马上定位到错误在哪里。所以对于平时写程序,无论是客户端还是服务端,注意收集错误日志是非常重要的,可以帮助你在排查问题的时候节约不少时间。
还有一些不能重现的Bug则不是那么容易发现其实也可以按照缩小问题范围的思路来定位。
比如说Bug是在最近一次部署后发现的并且回滚部署后就恢复了正常那么就说明问题很可能是由于这一次部署和上一次部署之间的代码变更导致的如果代码变更不多就可以通过分析变更的代码来定位。
像内存泄漏或者CPU高的问题一般就可以通过分析内存Dump文件分析当前是哪些线程占用资源多线程运行的代码是什么哪些变量占用资源多。从而可以缩小范围快速发现问题在哪。
排除法也是一种缩小范围的方法,尤其是在架构比较复杂的情况,一次用户请求的操作可能经过多个服务,如果配合日志,那么可以对一个请求经过的每一个服务都进行日志分析,对于正常的服务可以逐一排除,直到找到出问题的环节,从而可以缩小问题范围。
所以下一次你在遇到难以定位的Bug的时候也可以想想怎么样可以逐步缩小问题的范围直到发现问题。
#### 新手解决完线上故障后,下次可能还会发生类似故障
新手在遇到线上故障后,采用一些临时解决方案,比如说重启服务,发现恢复了,然后就把这事忘记了。对于线上的故障,如果不找到产生的原因,那么下一次还会发生类似的故障,甚至比以前还更严重。
高手对于线上故障会仔细分析Bug产生的原因从根本上解决避免类似的故障再次发生。
比如说我以前所在的项目组采用敏捷开发每周一个Sprint每周会部署上线。但上线后经常会出现一些故障导致在部署后就要回滚或者再打补丁。
虽然每一次上线后的故障可能都不一样但是如果仔细分析背后的深层次原因还是因为上线前没有充分测试导致的。每周34天时间开发12天测试来不及对程序进行充分的测试。所以我们后来从流程上改进将一个Sprint内开发好的程序在测试环境测试一周后再上线这样调整后极少出现线上故障。
有关上面案例中流程改进结果,可以参考专栏文章《[07 | 大厂都在用哪些敏捷方法?(下)](http://time.geekbang.org/column/article/85018)》中“一周一个迭代怎么保证质量?”的说明。
对于新手来说,每一次解决线上故障,同时也是一次学习和总结的机会,不仅是学习如何解决一个线上故障,还要学习解决一类的线上故障,避免类似的故障再次发生。
## 大厂都是怎么处理线上故障的?
在处理故障方面,可以看到新手和高手的差距。同样,如果你留心观察,会发现各个大厂,也都有一套自己线上故障处理的流程。(比如:《[SREGoogle运维解密](http://book.douban.com/subject/26875239/)》《[阿里如何应对电商故障?](http://yq.aliyun.com/articles/105551)》《[滴滴是如何高效率处理线上故障的?](http://www.infoq.cn/article/2017/08/didi-ops-practise)》)
<img src="https://static001.geekbang.org/resource/image/de/9a/de24d22dfe710baf651af9848ac1589a.png" alt="">
通过看这些大厂的故障处理流程,你会发现,大厂其实是把高手解决故障的方式,变成故障处理的流程和操作手册,并且通过反复地故障演习。不断练习和强化对故障处理的流程,让系统更健壮,让新手也可以快速上手,做到高效处理线上故障。
至于具体的处理流程,其实大同小异。
- 首先,对故障进行评级。
根据故障影响的范围对故障进行评级从而决定后续的处理方案。比如说P0是最严重最紧急的可能是大面积服务瘫痪影响大量用户需要紧急处理如果是P5可能只是用户体验相关的晚一点处理也没关系。
- 其次,要马上恢复生产,避免进一步损失。
使用临时方案,恢复生产减少损失是第一位的。可以采用部署回滚、服务降级等处理手段。
<li>
另外,要分析故障原因,修复故障。
</li>
<li>
最后,记录故障发生处理全过程,分析故障原因,提出后续改进方案。
</li>
## 大厂处理线上故障处理机制有哪些值得借鉴的地方?
从流程看,大厂处理线上故障的机制似乎并没有什么特别的,那么有没有值得学习借鉴的地方呢?答案是肯定有的。
- 故障报警和轮值机制
你可以先思考一个问题:如果你所在项目组的系统出现线上故障,要多长时间可以恢复正常?怎么样可以做到最快的速度恢复?
**要做到最快速度处理线上故障,关键就是要让正确的人第一时间就可以去响应。正确的人就是对故障服务最熟悉的人,通常就是这个服务的开发人员。**
但让所有开发人员7x24小时随时待命也不现实所以一般大厂会采用轮值的机制比如说对于每个服务每周要安排两个人值班一个是主要的出现故障第一时间响应另一个人准备着以防万一联系不上主要值班人员时可以顶替值班。
大厂都有一个报警系统值班的那一周值班人员手机要24小时开机笔记本要随身携带如果负责的服务出现故障那么会在第一时间被报警系统呼叫。如果15分钟没有人响应就会层层往上传递值班开发人员没响应就呼叫经理再是总监VP直到CEO。
这套机制虽然被很多开发人员诟病良多,毕竟值班期间要随时待命,但确实是一套非常简单有效的机制,让最熟悉服务的开发人员第一时间去处理,可以帮助线上系统以最快的速度恢复服务。
- 实战演习
在我工作经历中,不止一次出现过数据丢失的情况,其实丢失数据前,都有完善的备份恢复方案和日常备份,然而这些备份恢复方案却从来没执行过,等到真正出问题,才发现这个方案完全是不可行的,日常备份也早已被破坏无法恢复,最终导致数据丢失。
如果日常对这些方案有演习,去实际测试一下,就不至于这么狼狈。实战演习就是频繁地对故障进行演练,来测试平时做的这些方案是不是真的可行,这样遇到真正的故障,才不至于手忙脚乱不知道如何应对。
其中最有名的就是Netflix的混乱猴子军团Netflix在亚马逊云上建立了一个叫做 Chaos Monkey混乱猴子的系统这些猴子会在工作日期间随机杀死一些服务制造混乱来测试生产环境下的稳定性。
也有人把这样的实战演习叫“混沌工程”。
>
混沌工程就像“疫苗”:注射少量潜在有害的异物以预防疾病,这种人为的“破坏”其实是有帮助的。混沌工程通过在技术系统中注入危害(如延迟、CPU故障或网络黑洞)来建立这种免疫力,从而发现和修正潜在的弱点。《[以毒攻毒: Google、Amazon、Netflix如何用混沌工程控制系统风险 ](http://mp.weixin.qq.com/s/cNI0V0poYX0XR8Zl6Z36fA)》
- 日志记录和分析工具
对于软件来说线上出现问题分析日志记录是最简单有效的定位问题方式。这就要求平时在开发的时候就要注意对关键日志信息的记录同时还要搭建像ELK或Splunk这样的日志分析系统方便查询日志。
举个例子一个API请求出现了随机无法访问的故障而这个API可能会经过5-10个服务怎么快速定位是哪一个服务出现问题
一个好的实践是这样的:
对于每一个请求都会分配一个唯一的请求编号requestId在经过每一个服务的时候都带上这个请求编号每个服务都把这个请求的输入和输出记录下来输入的url参数是什么http的header是什么输出的状态码是什么输出内容的大小是什么如果出错异常信息包括错误堆栈是什么
当出现故障的时候找到一个有问题的requestId根据这个requestId去日志分析系统查询相关的所有服务的日志这样马上就可以看出来哪一个服务返回的结果是有问题的。
当然还有一些其他好的实践,例如说新功能上线时,灰度发布的策略。通过开关控制,先让一小部分用户使用,如果出现故障,马上关闭开关,避免影响。
大厂的这些线上故障处理预防的实践都是公开的,通过网上的一些文章或者他们技术人员在技术大会上的分享,你也可以从中了解和学习到很多。重要的是看这些实践的好处是什么,哪些是可借鉴到你的项目中的。
## 总结
今天带你一起学习了线上故障的处理。对于线上故障的处理,基本原则就是要先尽快恢复生产减少损失,然后再去查找原因,最后不要忘记总结复盘。
要做到最快速度处理线上故障,关键就是要让正确的人第一时间就可以去响应。正确的人就是对故障服务最熟悉的人,通常就是这个服务的开发人员。
要让你的故障响应流程在真正遇到故障时能起到作用,需要经常做故障演习,测试你的故障响应流程,测试你的系统在故障下的稳健性。
线上故障的分析,少不了对日志的记录和分析,平时在开发阶段就应该要注意对日志的记录,同时也可以搭建一套适合你项目的日志分析系统,在遇到故障时,能及时的通过日志定位到问题所在。
最后,保持学习大厂对这些线上故障处理的好的实践,应用到你的项目中。
## 课后思考
你平时对于线上故障是如何处理的?有哪些可以改进的地方?你的团队对于线上故障是怎么样的处理流程?有哪些可以改进的地方?欢迎在留言区与我分享讨论。
感谢阅读,如果你觉得这篇文章对你有一些启发,也欢迎把它分享给你的朋友。

View File

@@ -0,0 +1,157 @@
<audio id="audio" title="38 | 日志管理:如何借助工具快速发现和定位产品问题 " controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/3e/e1/3ec25a43a9febb54d860b955c4c387e1.mp3"></audio>
你好,我是宝玉。在开始学习之前我想先问你几个问题:
- 如果你的网站或者服务出现故障,是谁第一时间发现问题的?用户还是运维人员?
- 假设你的服务架构是由若干微服务组成的其中一个微服务的异常导致了你的某个API请求异常你是否能快速定位到是哪个微服务出了问题
- 在部署系统后,你是否能观察出来系统的性能是上升了还是下降了?
如果你自己对这些问题的答案不是很满意,那么就可以来看看,如何借助监控和日志分析工具,或者说日志管理工具,第一时间发现线上问题,以及快速定位产品问题。
## 什么是日志管理?
要理解上面提到的这些问题,首先你要清楚,什么是日志管理。
日志就是操作系统和应用软件自动生成的事件说明或者消息记录包含了时间、日志信息。举例来说下面就是一个典型的Web请求日志
>
<p>10.0.1.22 [15/Oct/2018:13:46:46 -0700] “GET /favicon.ico HTTP/1.1” 404<br>
10.0.1.22 [15/Oct/2018:13:46:58 -0700] “GET / HTTP/1.1” 200</p>
从上面的日志中可以看出来日志包含两次http请求它们发生的时间、请求的URL、请求的IP地址、最后返回的状态码等信息。
在日志数量不多的时候,凭借肉眼或者借助文本编辑器,还能大概看出日志的内容,但是当日志数量一多,从日志里面查找需要的信息就变得很困难了。
现在的应用程序越来越复杂了,尤其是像微服务这样的架构,一个系统需要由若干微服务组成,每个微服务可能还会部署在若干容器上,那么意味着如果你要根据日志去排查故障的话,需要从几十、上百个地方去收集日志,再逐个去分析。
要解决这样的问题,就需要对日志进行统一管理。日志管理就是指对系统和应用程序产生的日志进行处理的方法,包括对日志进行统一收集,对日志数据进行筛选和解析,统一存储,还要让它们可以方便被检索。
当然你不需要自己去从头实现这样的日志管理系统,现在已经有很多成熟的日志管理工具可以帮助你对日志进行管理,你只要去了解这些工具可以帮助你做什么,以及如何基于它们来搭建适合你项目的日志管理系统即可。
## 如何快速发现和定位问题?
也许你会问,为什么说搭建了日志管理系统,就可以帮助快速发现和定位问题呢?
**首先,日志集中式管理后,就可以方便地对所有日志进行统一的检索。**当所有日志都可以放在一起检索了,自然就能高效地定位到问题,而不再需要到各个应用程序的日志里面去分别检索。
同时在检索的方式上可以用类似于SQL语句的方式来检索高效地对结果进行查询和归类。
<img src="https://static001.geekbang.org/resource/image/fb/3b/fbde7467c94ecb5cc2eea0091e487b3b.png" alt="" title="图片来源Splunk">
**然后,对日志进行集中式管理后,可以通过图表直观的看到应用运行情况。**当所有的应用实时将日志传输到一起,日志管理系统就可以根据应用日志中记录的信息,动态地生成图表,实时看到应用运行的情况。
举例来说某一个API服务日志信息记录了每一次Http请求的状态、耗费时间等信息。
>
127.0.0.1 [10/Oct/2018:13:55:36 -0700] "GET /api HTTP/1.1” 200 2326 0.038
那么把这些信息统一收集、实时统计的话就可以随时看到单位时间内这个API错误率有多少平均耗时多久从而可以根据这样的信息生成实时的图表方便查看当前API服务的运行情况。
[<img src="https://static001.geekbang.org/resource/image/7a/48/7a84fb0c28aa75b47f87b4a1b8fe0948.png" alt="" title="图片来源WaveFront">](http://docs.wavefront.com/nginx.html#nginx-integration)
**最后,可以根据日志的数值设置规则自动报警。**对于这些从日志中实时分析出来的数据结果如果设置好相应的阈值在超过阈值后比如说API错误率超过10%或者90%的API请求时间超过1秒就会自动触发报警通知相关的开发人员进行维护。
所以你看,当你搭建好一整套日志管理系统后,不仅可以帮助你快速地对日志进行检索,你也可以根据图表看数据走势,还可以通过对日志分析结果的监控,设置自动报警的规则,第一时间了解系统故障。
## 大厂的日志管理系统的架构是什么样子?
现在对于像阿里、新浪这样的大厂来说,对日志管理系统的应用已经是标配了,比如说阿里云:《[基于ELK实时日志分析的最佳实践](http://yq.aliyun.com/articles/590431)》、新浪:《[ELK Stack在新浪微博的最佳实践](http://chuansongme.com/n/1979684)》、《[新浪是如何分析处理32亿条实时日志的](http://www.open-open.com/lib/view/open1437018728240.html)》,七牛:《[如何快速搭建智能化的统一日志管理系统](http://juejin.im/post/5b63e859e51d4517c564d1a9)》。
可以看得出很多大厂是基于ELK搭建的自己的日志管理系统而ELK的架构也是一套经典的日志管理的架构所以这里我就以ELK为例来说明日志管理系统的基本架构。
先解释一下ELK
>
<p>ELK 是Elasticsearch+Logstash+Kibana的缩写。<br>
ElasticSearch是一套搜索框架提供了方便的接口可以方便地做全文检索可以用来对日志进行检索。<br>
Logstash是一个数据收集工具可以用来收集日志数据。<br>
Kibana是一套可以和ElasticSearch交互的界面通过Kibana可以方便的检索ElasticSearch内的所有数据还可以用图形化的方式展示数据结果。</p>
基于ELK搭建的日志管理系统基本架构是这样的
[<img src="https://static001.geekbang.org/resource/image/b9/f8/b9b53220894009769f5bcb031b7c0cf8.png" alt=""> “图片来源Openstack log analysis using ELK”](http://bingoarun.github.io/openstack-log-analysis-elk.html)
这套架构有几个重要的模块:日志采集和解析、存储和搜索、结果可视化、监控和报警。
- 日志采集和解析
要想对日志进行统一管理就必须要从各个应用系统收集日志。Logstash就可以帮助实现对日志的采集。
如果日志文件只是一行行带时间戳的文本,那其实是无法有效检索的,必须将其解析成结构化的数据,才能方便地检索。
另外一套系统可能由不同的应用类型组成有的是Java写的有的是Go写的日志格式可能完全是不一样的所以还有必要在对日志解析后提取公共元素比如时间、IP地址、主机名、应用名称等。
Logstash不仅可以对日志数据进行收集还能对日志数据进行过滤和解析解析完成后再将解析好的数据发送给ElasticSearch。
- 存储和搜索
当所有的日志数据都被集中存储后,可以想象这个日志数据库是相当庞大的,直接查询效率是比较低下的,这就意味着还需要对日志数据进行索引和分析,从而让你可以快速地检索出来结果。
ElasticSearch就是一套专业的全文检索和数据存储系统同时还有一套类似于SQL的查询语句这样你就可以基于它方便对收集好的日志数据进行检索了。
但ElasticSearch本身类似于数据库没有图形化界面。
- 结果可视化
可视化是日志管理的另一项重要功能。通过可视化的图表,可以直观地看到数据的走势,以及方便地和历史数据进行对比。
比如说通过观察交易数据的走势曲线就能看出来这周的交易数据比上周是增长还是下降根据API响应速度的走势可以看得出新版本部署后性能是提升了还是下降了。
像Kibana就是一套专门针对ElasticSearch的图形化操作工具可以方便对ElasticSearch数据进行检索也可以对结果用图表的方式展现。
- 监控和报警
ELK本身只是提供了一套基础的日志管理框架但是基于它之上还可以有很多扩展比如说自动报警就是一个非常典型的场景可以基于已经存储和索引好的日志数据制定相应的自动报警规则当线上服务发生异常时可以自动地触发报警通知相关值班人员及时处理。
ELK可以通过插件的方式安装像 [ElastAlert ](http://github.com/Yelp/elastalert)或[Watcher](http://www.elastic.co/guide/en/watcher/current/introduction.html)这样的自动报警插件,实现自动报警功能。
[<img src="https://static001.geekbang.org/resource/image/8d/6f/8d59a0962b445900d7668b266e0adf6f.png" alt="" title="图片来源Build your own error monitoring tool">](http://espeo.eu/blog/build-error-monitoring-tool/)
## 怎样搭建一套日志管理系统?
在了解了整个日志管理系统的基础架构后再要去搭建这样一套日志管理系统就可以做到心中有数了。你可以基于这套架构去寻找合适的工具或者直接基于ELK去搭建一套日志管理系统。
关于ELK网上已经有很多安装使用教程比如这一本电子教程《[ELK 教程](http://docs.flycloud.me/docs/ELKStack/)》就写的很详细。
ELK本身是一套开源免费的工具除了ELK还有一些类似的工具可以选择可以和ELK配合使用。
- [Splunk](https://www.splunk.com/)
Splunk是一套商业的日志管理系统搜索功能非常强大操作方便就目前来说要比ELK好用但价钱很高。
- [Grafana](http://grafana.com)
Grafana是一套开源的数据监测和可视化工具可以和ELK或Splunk配合使用展示效果比Kibana要更好。同时可以支持自动报警功能。
- [Wavefront](http://www.wavefront.com)
Wavefront 是 VMware 旗下的一款商业的图形化监控和分析工具可以从ELK 或 Splunk等数据源收集数据在此基础上分析应用的性能瓶颈所在排除故障。也支持自动报警。
- [PagerDuty](http://www.pagerduty.com)
PagerDuty是一套报警服务不仅可以和手机、邮件、Slack等方便地集成还可以和企业的轮值安排结合按照排班顺序呼叫当值人员。
以上就是一些常用日志管理系统以及配套系统工具,基本上可以很好地满足你对日志管理的需求,通过搜索引擎你也可以找到更多类似的服务。
## 总结
今天我带你一起学习了日志管理工具相关的内容。通过日志管理工具,可以集中的管理所有系统的日志,方便对日志进行检索,图形化的展示结果,还可以做到根据设置的规则进行自动报警。
如果你想搭建属于自己的日志管理系统可以基于ELK或者Splunk这样的日志管理工具配合一些插件实现你自己的日志监控和分析工具。
在搭建好日志管理系统后,如果我们再回头看文章开头那几个问题,你会发现:
- 如果你的网站或者服务出现故障,可以通过你设置好的自动报警规则第一时间通知值班人员,及时解决;
- 假如你的某一个微服务出现异常,你可以从你的日志管理系统中直接对所有微服务的日志进行查询,快速定位到问题所在;
- 在部署系统后通过对API响应时间等数据指标的图形化显示你可以直观的看到性能是上升了还是下降了。
总的来说,借助日志管理工具,可以帮助你快速发现和定位产品问题。
## 课后思考
你的项目中是否有应用日志管理工具?你觉得这样的工具的应用,对你的日常项目可以带来哪些好处?如果还没有应用,主要阻力是什么?欢迎在留言区与我分享讨论。
感谢阅读,如果你觉得这篇文章对你有一些启发,也欢迎把它分享给你的朋友。

View File

@@ -0,0 +1,146 @@
<audio id="audio" title="39 | 项目总结:做好项目复盘,把经验变成能力" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/26/d1/260b2031bef65e7e5ffef56e87eb03d1.mp3"></audio>
你好我是宝玉。相信大家都有这种体验经历了无数个“996”加班项目终于成功上线了也进入了稳定运行阶段你终于可以松一口气准备迎接下一个项目的挑战了。
然而,这时还有一件事不要忘记了,那就是对项目复盘,全面总结一下项目过程中的得与失。
## 什么是项目复盘?
“复盘”本来是围棋术语,表示对弈之后,棋手把下棋的过程重演一遍,看看哪些地方下的好,哪些地方下的不好,有哪些更好的走法。把下棋的过程还原,并且分析、讨论的过程就是复盘。
软件项目中的复盘,也是通过分析、讨论开发中出现的问题,进而总结成功经验,吸取失败教训,提升团队能力。
一次项目过程,自然会有一些做的好的地方,也会犯一些错误,复盘就是要分辨出哪些是好的实践,继续保持;哪些是做的不够好的,找出原因,针对性改进,避免再犯同样的错误。
如果没有这样的项目复盘,那下一次做项目,你还会是用同样的方式来做事情,那恐怕踩过的坑可能还得再踩一遍。
也许你会认为,你们团队也开过项目复盘总结会议,但是似乎没有什么效果,是不是项目复盘并没那么有价值?
并不是项目复盘没有价值,多数情况下,是因为没有做好项目的复盘,反而相当于浪费了一次学习提升的机会。比如说一些常见的存在问题的项目复盘情形:
- 总结不出来有效的结论
有些团队流水账的回顾了一遍项目过程,感觉似乎有做的不好的地方,但说不上是什么地方做不好,所以也无法进一步的总结。
- 没做好是客观原因导致的
有些团队在复盘后,将结论归结为是客观原因导致的,比如说:“虽然这次做的不好,只是客户不靠谱,但是下一次遇到一个好客户肯定能做的更好!”,这相当于没有想清楚:是哪里做的不好?为什么做的不好?下一次遇到这样的客户怎么才能做的更好?
- 知道什么原因,但不知道该怎么办
有些经过分析总结,能找到原因,但不知道如何应对。比如说发现主要原因是客户老变需求导致项目延迟,但是不知道如何应对需求变更。
类似于这样的项目复盘,确实达不到好的总结效果,也难有提升。那么怎么样才能做好项目复盘呢?
## 如何做好项目复盘?
项目复盘,首先就是知道项目中哪些是做的好的地方,哪些是做的不好的地方,这样才能把做的好的地方继续发扬光大,做的不好的地方进行改进修正。
那怎么样才能知道哪些地方做的好,哪些地方做的不好呢?
只要对比一下你当初制定的项目目标和最终的项目结果,就可以发现差异,通过这些差异,就可以清楚地知道哪些地方是变好了、哪些地方变糟了,比如说项目延期了,功能被砍了,软件质量相比以前的项目质量提升了。
但光知道差异还不够,需要思考背后的原因,比如说为什么会导致项目延期?做了什么事情让软件质量提升了?也就是说,要从这些事情中能总结出来规律,从而知道哪些做法是真正有效的,值得继承或者推广?哪些做法是无效的?
这里就需要结合软件工程的知识来分析,把实践经验概括为普适的理论或者原则。
最后就是要用这些从经验中学到的理论或原则,指导后续的项目开发,决定要停止做什么,开始做出怎样的改变,以及继续做哪些事。
联想公司对于项目的复盘总结了四个步骤,同样适用于软件项目,我们可以借鉴它的做法,采用四个基本的步骤来进行:
1. 回顾项目目标;
1. 评估项目结果;
1. 分析原因;
1. 总结规律,落实行动。
接下来我就这四个步骤来分别讲一下,如何对项目进行复盘。
**第一步:回顾项目目标**
每个项目在最开始的时候都会确定项目的目标,所以复盘的第一步,就是要回顾最初的项目目标,方便对最终结果进行评估。
在这个环节,需要你描述清楚当初定的项目目标是什么?项目计划中制定的里程碑是什么?其中的关键就在于,对目标的描述要尽可能准确和客观。
**因为只有做到准确和客观,在后续你才能对目标的完成情况进行准确地评估。**
比如说:“我们的目标是做一款伟大的产品”,就不算是准确客观,因为“伟大”是一个根据主观评判的形容词,每个人对伟大的理解是不同的。
你需要将这类形容词换成具体可考核的检查项比如可以总结出类似于这样的目标“三个月时间完成一款在线学习网站产品包括登录、在线学习、留言等主要功能模块上线后的Bug比例低于上一款产品。”
最后再加上最初定的里程碑,比如说:“两个月开始内部测试,三个月正式上线。”这样,大家就可以对目标的完成情况有清晰地认识。
**第二步:评估项目结果**
在对项目的目标进行回顾后,就可以来看看项目的实际结果和当初的目标有多少差异了。这里需要列出两方面的差异:好的差异和坏的差异。
比如说项目的结果是我们花了四个月时间完成整体项目三个月才开始内部测试。原有功能作出了调整学生留言老师回复的功能改成了类似于讨论版大家一起讨论的功能上线后质量稳定Bug比例低于上一款产品。
好的差异:
- 上线后质量很稳定严重Bug很少
- 没有出现需求遗漏,开发和测试能及时同步需求的变更。
坏的差异:
- 功能发生了变化,中间有比较多的需求变更;
- 项目发生了延期。
可以鼓励团队成员一起列出项目中好的差异和坏的差异。需要注意的是,在这一步,只需要客观描述结果就好了,不需要去分析原因,不然大家很容易思维发散,过早陷入对细节的讨论。
**第三步:分析原因**
在结果评估完了后,就可以来分析原因了,分析的时候也可以主要从两方面着手:是什么原因导致了好的差异,什么原因导致了坏的差异。
比如说,导致好的差异的原因:
- 增加了自动化测试代码的比例,改进了开发流程,代码合并之前有代码审核,并且要通过自动化测试;
- 增加了工具的使用,比如持续集成系统的搭建,每次提交后可以清楚的看到测试结果;
- 改进了项目流程对于所有的需求细分后都创建成了Ticket基于任务跟踪系统记录了起来这样可以及时了解任务进程有需求变更的情况相关人员也能及时了解。
比如说,导致坏的差异的原因:
- 老板对于产品干预过多,导致需求变更频繁;
- 项目周期过长,难以响应需求的变化;
- 设计时没有考虑到需求的变更,导致需求变更发生后,很多设计需要修改,最终导致延期。
在分析的时候,可以营造一个宽松的氛围,让团队成员能畅所欲言,讨论时要做到对事不对人,尽可能客观地分析清楚成功和失败的原因。**只有分析清楚原因,才能总结出规律。**
**第四步:总结规律,落实行动**
分析出原因后还不够,最重要的是,还需要去总结背后的规律,才能真正把成功或失败的经验变成个人和团队的能力。这里也可以充分运用你在《软件工程之美》专栏中学习到的知识,去帮助你总结规律。
比如说,接着上面的案例你可以继续总结规律:
- 需求变更是导致项目延期的主要源头,需要在后续项目中控制好需求的变更;
- 自动化测试加上代码审查,再配合持续集成工具,可以有效提升产品质量;
- 任务跟踪系统可以方便地跟踪需求的执行情况,也能保证项目成员能及时同步需求的变更。
总结出来规律后,还需要落实成行动,才能真正做出有效的改变,帮助你在以后的项目中做的更好。落实行动的关键就是:对于好的实践,继续保持;对于不好的实践,停止并寻求改变。
就上面的案例来说,针对上面总结出来的规律,你可以继续整理出需要在后续项目中落实成行动的事项:
- 参考专栏文章《[20 | 如何应对让人头疼的需求变更问题?](http://time.geekbang.org/column/article/89848)》中的解决方案,针对需求变更,我们将缩短项目周期,采用快速迭代的开发模式,及时响应需求变更,同时在一个迭代中,没有特殊情况,不做需求上的变更,有变更放到下一个迭代中;
- 继续增加自动化测试代码的比例,代码在合并前要对代码进行审查,用好持续集成工具;
- 继续使用任务跟踪系统,对需求任务进行跟踪,并且可以尝试对于一些临时性的任务也用任务跟踪系统跟踪起来。
通过分析目标、评估结果、分析原因和总结规律这四个步骤对项目复盘,能有效帮助你发现项目中做的好的地方和做的不好的地方,找出背后的原因,最终总结出来规律,落实成行动,做出积极的改变,把经验变成个人和团队的能力。
## 总结
项目复盘,可以帮助你从刚刚经历过的软件项目中,总结成功经验,吸取失败教训。为什么在同样的工作时间内,有的人就是成长的比较快,收获更多的经验能力?其实他们就像优秀的棋手,通过不断地对做过的事情进行总结复盘,来快速提升自己的能力。
项目复盘主要通过四个步骤进行:回顾项目目标、评估项目结果、分析原因、总结规律落实行动。
另外你需要注意的是对于项目的复盘并不是说只有项目快结束了才要去做日常项目中遇到一些特殊的事情比如线上故障也可以及时总结复盘预防类似的事情再次发生在每一个迭代结束之后都可以阶段性的复盘比如说敏捷开发中每个Sprint的项目回顾会议在整个项目结束的时候进行全面的项目复盘。
在项目复盘的形式上,可以通过团队会议的形式来进行,但是要想做到会议有效率,还需要在会议之前就做好准备工作,事先收集内容;会议进行中要有人组织引导大家积极发言讨论,避免陷入细节的争吵中,更要避免互相甩锅、人身攻击等极端情况发生;会议后,要落实到行动。
关于项目复盘会议,我觉得阿里的这篇文章写的非常好:《[开会=浪费时间?阿里技术团队这样开项目复盘会](http://yq.aliyun.com/articles/675302)》,你可以作为参考。
希望你也可以不断地对做过的事、参与的项目进行总结复盘,把经验变成能力。
## 课后思考
你平时都是如何对项目进行复盘总结的?你觉得哪些地方可以做的更好?你有哪些好的经验可以和大家一起分享讨论的?欢迎在留言区与我分享讨论。
感谢阅读,如果你觉得这篇文章对你有一些启发,也欢迎把它分享给你的朋友。

View File

@@ -0,0 +1,327 @@
<audio id="audio" title="“一问一答”第4期 | 14个软件开发常见问题解决策略" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/fa/67/fa9fd345f34e2e74ff27165e9ea60f67.mp3"></audio>
你好,我是宝玉。恭喜你完成了软件测试和线上维护这两个模块的学习。
软件测试是保障软件质量的重要一环,但也不能过于依赖软件测试,毕竟软件质量体现在功能质量、代码质量和过程质量三个方面,而软件测试只能帮助保证功能质量,代码质量和过程质量还需要团队一起努力。
现在大厂已经很少有手工测试的岗位了,大部分测试工作已经转移到开发上,同时自动化测试的比例越来越高,但这相应的对开发的要求更高了,不仅要写功能代码,还要写自动化测试代码。
软件测试也离不开对工具的使用通过Bug跟踪工具报Bug和跟踪Bug使用测试管理工具管理测试用例基于自动化测试框架写自动化测试代码借助性能测试工具对软件性能进行压力测试。测试工具还可以和持续集成一起整合最大化发挥测试工具的效应。
软件测试做好了不代表你的软件就是安全的,不会导致账号密码泄漏,要想构建安全的软件,需要在整个软件生命周期中都重视安全问题,各个阶段考虑到安全方面的问题,防患于未然,构建出安全的软件。
当你的软件已经测试通过,准备上线发布了,不要忘记在软件发布前做好版本规划,尽可能的让软件的功能质量,满足好用户的预期。一方面要尽可能提供应有的功能和保证质量,另一方面也可以通过合理的发布策略来降低用户的预期。
传统软件发布上线后就是运维负责保障线上运行了但这种分工也导致了开发和运维之间在沟通协作上不够紧密甚至有冲突于是DevOps 出现了,它帮助解决开发和运维之间的沟通协作问题,提升运维开发和自动化能力。通过自动化、信息透明可测量、共同协作的原则,达到更快更可靠的构建、测试和发布软件的目的。
软件发布后不代表项目就结束了,还需要处理线上故障,保障运行。遇到线上故障不用慌,要先恢复生产减少损失,然后再去找原因,最后再去总结复盘。日常还要对故障多演习,这样真的有故障发生了才能做到从容应对。日志管理工具是线上故障排查的好帮手,能帮助你快速定位线上故障,还可以对日志的数据进行监控,有问题提前预警。
最后,项目结束后不要忘记对故障进行复盘,总结成功经验,吸取失败教训。把好的实践继续发扬光大,对于不好的实践马上停止做出积极有效的改变。
以上就是两个模块内容的总结,希望你在学习这些知识后,能应用到实际的项目中去,帮助你项目的质量再上一个台阶。
今天加餐继续分享我们专栏的精彩问答和留言,这些问答和同学们的分享都是对专栏内容的最好补充,希望可以帮助你更好地学习和理解软件工程知识。
## 一问一答
No.1<br>
**hua168**质量是怎么打分的算进KPI考核吧直接用代码质量管理软件如sonar实现自动检查可以吧
**宝玉:**很遗憾,都不好量化,软件检查只是辅助,可以作为一个参考。代码质量要看满足需求,是否设计良好,代码简洁逻辑清晰,可维护、可测试、安全高性能;过程质量要看开发过程对软件工程和项目管理知识的应用;功能质量要看客户满意度。
No.2<br>
**砍你一刀:**能分享一个比较好的测试用例模板吗?
**宝玉:**我建议你试试testrail它的测试用例模板非常专业。
对于测试用例:
- 几个关键的字段是:标题、描述、优先级、分类。
- 测试类型:功能测试、性能测试、回归测试、冒烟测试等。
- 自动化状态没有自动化、只能手动测试、只能自动化、集成CI等。
- 先决条件:这个用例需要满足好什么条件。
- 测试步骤:写清楚一步步的执行步骤。
- 期望结果:操作完成后结果应该是什么样的。
No.3<br>
**kirogiyi**最近发现一种现象,开发人员面对测试人员的时候,会展现出一种职业选手遇到业余选手的姿态,傲慢、理所当然,我觉得这是一种不正常的心理状态,应该怎么去管理?
**宝玉:**这确实是常见的现象,核心还是多一起合作多相互了解吧,让开发人员看到测试的核心价值,就是对测试方案的设计。
我对测试人员敬佩的地方不在于他们会写自动化测试毕竟这个我写起来还更好而是他们总能从我没想到的角度测试出来Bug从而帮助我提升程序质量。
可以安排一些开发人员和测试人员一起合作的事情,比如测试人员提供测试方案测试用例,开发人员按照测试用例去实现自动化测试,让开发人员明白,做好测试其实不是他们想的那么容易。
No.4<br>
**和:**从需求分析到设计,开发,测试,部署,运维,都是我一个人的工作。这样的情况,如何工作效果会更好一些?
**宝玉:**对于这个问题,我觉得你可以自己先分析一下,你觉得目前哪些地方做的好,哪些地方可以有改进?可以从几个方面分析,比如:
- 工具:
有没有用源代码管理工具?<br>
有没有用持续集成跑单元测试?<br>
有没有用Bug/任务跟踪系统?
- 开发流程:
多长时间一个项目周期,一个功能从开发到上线要多长时间?质量如何?<br>
有没有做需求分析和确认?会不会做出来东西不是业务部门想要的?<br>
有没有开发前先做简单的技术设计?<br>
有没有写一些基础的测试用例?<br>
有没有开发后自己测试和找业务部门帮忙测试?<br>
线上的故障有没有一个合适的流程去处理?<br>
有没有写一些基本的文档,如果来一个新人了能否接手?
- 技术实践:
有没有写自动化测试?<br>
有没有用好的技术框架或开源组件?<br>
有没有自动化部署?
分析出问题,知道哪些地方做的不够好以后,就可以有一个改进的计划 ,看如何将改进方案落实下来。
还有就是一个人开发,缺少向其他人合作和学习的机会,可以有意识地创造更多这样的机会,比如内部多和其他部门合作。外面可以参与一些开源项目。
No.5<br>
**hua168**现在不是流行测试驱动开发吗?先写测试代码再写实现代码,那写完再让专门的测试去测?
**宝玉:**测试驱动是一种很好的开发实践但普及率也不算很高。可以看到自动化测试那一篇测试驱动写的是单元测试并不能保证不出Bug只是说能有效提升代码质量。还有就是开发人员测试自己写代码很容易遗漏编码时就没考虑到的逻辑。
No.6<br>
**果然如此:**如果每次发布都对所有方法自动化测试那么1. 一定会耗费很多时间2. 数据库产生很多测试历史数据3. 写测试用例能达到覆盖率高的写代码技巧,如边界测试代码、幂等测试代码如何实现。这种情况怎么办?
**宝玉:**<br>
1.自动化测试确实会耗费很多时间。自动化测试代码通常是金字塔结构:
- 单元测试小型测试代码最多执行也最快占总比例的70%左右通常1分钟内
- 集成测试中型测试代码其次执行比较快占比20%左右控制在10分钟以内
- 端对端测试大型测试最少执行慢占比10%左右。
一般CI里面跑单元测试和集成测试耗时10-15分钟左右其实还可以接受。
2.跑自动化测试,数据库有不同策略。单元测试不访问数据库,完全模拟。集成测试只访问本机数据库,或者模拟的内存数据库,每次创建新数据库,或者使用完清空数据库。端对端测试,每次创建唯一数据(例如增加固定数据+时间戳),连接真实的测试环境,可以不清理数据。
3.高覆盖率的关键在于在写代码时就注意让代码方便地被测试。也不必过于追求100%覆盖70%以上我觉得就不错了。
No.7<br>
**宝宝太喜欢极客时间了:**对测试这块一直很疑惑测试脚本、测试用例、测试数据这三者如何配合一起通过CI进行自动化测试
**宝玉:**是这样的CI本质上只是一个像流水线传送带你的代码提交了流水线传送带开始工作你可以在传送带上面添加任务。
简单来说你可以想象成CI的一个任务启动后给你一个干净的虚机实际是运行Docker Container然后帮你把当前代码下载下来帮助你配置好运行环境然后你就可以在里面安装任何软件、服务和运行任何脚本。
举例来说,你可以在传送带上增加以下任务:
1. 安装所有的依赖包;
1. 运行模拟服务(比如一个内存数据库);
1. 运行单元测试;
1. 运行集成测试。
如果上面所有任务都成功了那么这一次的CI任务就成功了其中一个失败这一次的CI任务就失败了然后你就要检查什么原因导致的然后修复再重新执行保障CI任务成功执行。
No.8<br>
**一步:**Code Review是指把代码放到大屏幕上大家一起看还是类似Github上的合并代码的时候发个PR然后另一个人对需要合并的代码进行检查检查通过后才同意合并请求
**宝玉:**我觉得两种都算Code Review只是形式不一样。
通常PR这种Code Review应该是贯穿到日常开发过程中的每个人都可以去Review有1-2个人Review通过就可以。合并的话不只是Code Review通过还需要自动测试通过。
而大屏幕这种参与人多,成本高,属于偶尔针对特殊故障分析、学习研讨等目的才做的。
No.9<br>
**yellowcloud**我们目前有一个项目是做实时数据采集的,对方将实时数据推送给我们,基本上每天每个时刻都可能有数据推送过来。这样就导致一个问题,我们部署新的版本时,他们的数据还在推送,这样就不可避免地丢失了部署过程中的数据,对方也没有重新推送的机制。请问,这种问题有没有比较好的解决方案,以解决更新版本时数据丢失的问题?
**宝玉:**这个问题其实不复杂,你可以将服务分拆,独立出来一个专门接受数据的服务,这个服务极其简单,只做一件事:接收数据,并存储到数据库或消息队列。
你原有的服务,改从数据库或者消息队列读取即可。更新部署的时候,接受数据的服务就不要轻易更新了,这样就不担心会丢数据了。真要更新,只要和对方协商一下,暂停推送就好了。
No.10<br>
**Charles**如果是瀑布流带点敏捷部分实践的开发方式总觉得UI这个岗位工作量不怎么饱和一个版本过来特别是小版本迭代周期可能是两周UI可能1天就搞定了其他岗位都差不多要全程跟下来这个问题出现在哪里
**宝玉:**这个问题有点不好回答,毕竟对你项目情况不够了解。
我觉得如果UI这个岗位对你的团队来说是必须的并且UI设计师很好地完成了他/她的工作,那么就很好,没有任何问题。毕竟有的人效率就是比较高,好过故意磨洋工看起来很忙。
如果UI这个岗位是可有可无那么就可以考虑不设置这岗位将工作外包出去或者尽可能用一些标准的UI或者让前端工程师兼职UI设计工作。
No.11<br>
**yellowcloud**宝玉老师能不能介绍一整套可以简易部署使用的devOps的工具方便小公司快速部署、实现在实践中感受devOps的魅力。
**宝玉:**如果你要部署持续集成环境可以先试试Jenkins或者Gitlab CI。如果你要部署日志和监控系统可以试试ELK也就是Elasticsearch、Logstash、Kibana三者的结合。网上可以找到很多安装使用教程。
No.12<br>
**一步:**搭建自动化测试,自动化部署,自动化监控系统,都自动化了,开发都做了,是不是就不需要运维和测试了?
**宝玉:**自动化只是把重复的体力活做了。自动化测试的话,还是需要测试人员写测试用例才能有更好的测试效果;自动化部署和监控,也离不开专业运维人员的设计和搭建。
但是可以预见的是,以后低端的手工测试和运维岗位会被挤压的很厉害。如果你看大厂的招聘岗位,这些低端手工岗位都极少或者根本就没有。
No.13<br>
**邢爱明:**1. 谁来主导线上故障处理的过程2. 故障排查是不是应该有一个标准的分析过程让运维、开发、安全各方能更好的协作3. 便利性和安全性如何平衡?
**宝玉:**
<li>
谁主导线上故障,我觉得有两个指标要考虑:一个是这个人或者角色要懂技术懂业务,这样出现故障,能对故障进行评级;另一个是要能调动开发和运维去协调处理,这样出现故障能找到合适的人去处理,不然也只能干着急。
</li>
<li>
故障排查上:如果是操作系统、数据库、网络等非应用程序故障,应该是运维负责;如果是应用服务故障,应该是开发去负责,即使开发最近没有去做发布也应该是开发去查。因为只有开发对于应用程序的结构最清楚,才能找出来问题。排查过程中,运维要给予配合。
</li>
<li>
应该搭建起来像ELK这样的日志管理系统可参考《[38 | 日志管理:如何借助工具快速发现和定位产品问题 ](http://time.geekbang.org/column/article/97682)》),将应用程序日志也放上去,这样正常情况下就不需要去登录服务器了,直接就可以通过日志工具查看到异常信息。另外,一些特殊情况应该允许开发人员登录服务器排查定位。
</li>
No.14<br>
**Charles**目前只放了nginx日志到日志服务做一些简单的分析还有其他什么日志是应该放到日志服务里的有什么比较好的实践吗
**宝玉:**我觉得应用程序的日志也应该考虑放进去,对排查问题很有帮助。应用程序的异常信息、错误堆栈非常有用,必须确保记录下来了。
举个例子来说你的一个手机App一些特定场景下某个API请求出错而这个API可能背后会连接多个服务或者数据库这样的场景下光靠nginx日志是不够的必须要有应用程序的日志配合才好定位。
你可以参考我在《[37 | 遇到线上故障,你和高手的差距在哪里?](http://time.geekbang.org/column/article/97219)》提到了一个requestId的实践。
## 精选留言
kirogiyi:<br>
产品设计、软件开发、软件测试都应该对产品质量负责。
产品设计要重视产品需求的完整性提升用户的操作舒适感展现流畅的页面逻辑设计这是产生良好软件质量的开端。在进行产品设计评审的时候除了评审人员外相应的软件开发团队和软件测试团队一定要派人员参加不能坐等任务分配。有的开发团队和测试团队不去了解需求和产品设计情况只是一味等待产品的UI设计久而久之就形成了少交流多看文档的习惯于是大家就开始机械般各顾各的做完了扔出去就好就很难在产品质量上达成共识。
软件开发是核心开发人员对产品的理解程度和自身的技术水平决定了产品的质量和迭代周期。如果开发团队不去与产品团队交流不去与测试团队核对测试用例那么在开发过程中大多只会去关注是否实现和能否实现至于产品质量出现的问题就不是他们关注的重点。然后就会自私地认为产品设计需要增删改是产品团队的原因产品上线出现Bug是测试团队没有覆盖到部门之间的战争就开始酝酿直至爆发。
软件测试更多的是发现问题、监督问题和约束行为。发现问题的重点在于通过完善的测试覆盖,去找到开发过程中的盲点,而不是去为别人的疏忽大意导致的错误埋单,比如:开发提交的产品有错别字什么的,这种错误就是开发负责人应该承担的。
在明确发现问题后,测试团队有权利去监督开发团队解决问题,直至问题得以彻底解决。除此之外,测试团队可以对开发团队行为进行约束,双方协作完成自动化测试体系和流程的构建,共同遵守规则:开发团队负责单元测试、集成测试和系统测试的代码编写,测试团队负责查缺补漏和必要的人工测试。
因此,个人认为,产品、开发、测试的紧密合作是保障产品质量的必备条件。
相关阅读:[31 | 软件测试要为产品质量负责吗? ](http://time.geekbang.org/column/article/94631)
纯洁的憎恶:<br>
解铃还须系铃人,要想提高软件质量,就要着眼于整个生产链条,每一个环节都要为提高质量出力,而绝不能仅仅依靠质量监控岗位或部门。相反,很多企业设置了类似的部门或岗位,并把质量、安全的重担压在他们肩上,但又没有赋予足够的权力去介入、影响整个链条,结果可想而知。不谋全局者不足以谋一域啊。
把整体质量按照生产链条或链条上的不同角色,划分为若干子部分。通过有机的把控各个子部分质量,形成合力,达到提高整体质量的目的。
相关阅读:[31 | 软件测试要为产品质量负责吗? ](http://time.geekbang.org/column/article/94631)
纯洁的憎恶:<br>
看来是否需要专职测试人员在一定程度上需要视具体业务情境而定。不同的情境会有不同的异常情况和极端情况需要有针对性的设计出完备的测试用例。而且在Bug修复后也要保证修复本身没有Bug。
所以测试也是一个系统性的工作,如果取消专职测试人员,不仅对开发业务水平要求更高,还需要项目自身的不确定性低一些。感觉有测试思维的开发人员,更有可能写出健壮的代码。
相关阅读:[32 | 软件测试:什么样的公司需要专职测试? ](http://time.geekbang.org/column/article/94941)
yasuoyuhao<br>
代码就像程序员的名片要对写出来的代码负责最好的负责方式就是写测试代码让每次代码变动都不会影响到其他代码的运行避免所谓的改A坏B节省迂回的时间浪费。也为CI/ CD做好准备无论目前有没有。
在我们公司程序员不想写测试的原因大多是,不知道怎么开始写,不知道重点应该测试什么。先写测试的开发模式让他们觉得不习惯,但这些都是过程,培养良好的撰写测试代码习惯后,开发品质更有保证,提升开发效率,提升个人能力,我想都是有帮助的。
程序难免有Bug透过追踪软件良好地管控Bug数量与修复进度并且补足测试。
相关阅读:[33 | 测试工具为什么不应该通过QQ/微信/邮件报Bug ](http://time.geekbang.org/column/article/95533)
纯洁的憎恶:<br>
新手用野路子解决问题,高手用模型解决问题:<br>
1.给问题评级。紧迫的调动优势资源先解决,一般的往后放放。<br>
2.尽快恢复生产。生产是企业的首要职责,遇到问题优先恢复生产,减少直接损失,然后再正式地解决问题。<br>
3.找到问题出现的位置。“搜集证据”,通过“粗调”在时空上缩小包围圈,再用“精调”明确问题点,运用排除法最终锁定问题。<br>
4.分析原因,修复问题。<br>
5.提出解决方案。钥匙不一定插在锁眼里,要沿着问题的线索不停“倒带”找到根源。再针对根源,站在系统和流程的高度制定解决方案,避免问题复现。
重点:<br>
1.通过故障报警+业务骨干轮值机制,让正确的人第一时间响应问题。<br>
2.通过实战演习,确保应急预案稳定可行。<br>
3.通过使用日志记录和分析工具,积累、整理日常生产信息,出现问题才有得分析,否则重现问题也无济于事。
相关阅读:[35 | 版本发布:软件上线只是新的开始 ](http://time.geekbang.org/column/article/96289)
alva_xu<br>
线上故障这是ITIL要解决的问题。我觉得最主要还是从三个方面来看。一是从流程上对于事件管理、问题管理、变更管理、服务等级管理等要有明确的流程。二是要有合适的工具比如ticket系统CMDB监控工具、日志平台等。三是从人员组织来看要有一线、二线和三线团队的支持根据所创建的ticket的严重性和紧急性给予不同level的支持。当然这也是目前流行的devops要解决的问题。
相关阅读:[37 | 遇到线上故障,你和高手的差距在哪里?](http://time.geekbang.org/column/article/97219)
alva_xu<br>
我觉得scrum方法中提到的两个会可以作为项目复盘会内容的参考。Sprint评审会议Sprint Review Meeting和Sprint回顾会议Sprint Retrospective Meeting。Sprint 评审会议在 Sprint 快结束时举行 用以检视所交付的产品增量并按需调整产品待办列表是对工作成果的评审。Sprint 回顾会议是 Scrum 团队检视自身并创建下一个 Sprint 改进计划的机会。是对方法论的回顾和提高。项目复盘会也应该从这两个角度去做总结提高。
相关阅读:[39 | 项目总结:做好项目复盘,把经验变成能力 ](http://time.geekbang.org/column/article/98141)
邢爱明:<br>
回想一下,项目复盘想要效果好,需要做一些准备工作:
1. 复盘会前,要求项目组核心人员对项目的情况先自己进行总结,包括做得好和做的不好的方面,有书面文件输出。先要有思考,复盘会上大家才有可讨论的内容,否则会议上大家可能就是随便说说,复盘会成了走形式。
1. 复盘会的会议主持人,需要有比较强的会议主导能力,尤其是参加会议的人来自多个部门的时候。因为大家总结项目中做的不好的地方,难免会涉及到多个部门或团队配合的情况,且每个人的描述也不可能做到百分之百的客观和公正。
如果有人认为总结的内容有问责的含义或需要自己承担责任,复盘会就很容易变成了甩锅会。这时候就需要会议主持人正面介入和引导,让大家讨论解决方案和改进措施,确保按照预定的议程开复盘会议。
相关阅读:[39 | 项目总结:做好项目复盘,把经验变成能力 ](http://time.geekbang.org/column/article/98141)
## 思辨时刻
成:<br>
我们公司团队小每次app开发完成后要求测试人员组织开发全体测试2次用于保证质量。团队小测试人员技术有限性能安全等一般难以保证。
宝玉:<br>
其实即使是小团队也应该加大对自动化测试对投入绝对是磨刀不误砍柴工这样App开发完成后很多测试就可以自动化完成节约时间和人力。当然没有自动化测试覆盖的话这也是很好的一种测试方式。
相关阅读:[31 | 软件测试要为产品质量负责吗? ](http://time.geekbang.org/column/article/94631)
毅:<br>
项目负责人为软件质量总责任人。功能,代码,过程都要关注,并不一定要亲力亲为,因为除了质量他还要兼顾范围、时间和成本。提升质量意识最理想状态是组员有质量人人有责的意识与行动,但实际上这很难。如果自下而上做不到,就自上而下用制度强推,有奖有罚。
最后补充一点就是推行质量保障是需要公司层面作为支持的,否则在推行过程中会有不少阻力,也许在强人项目经理的推动下,个别项目能做的很好,但心会很累。
宝玉:<br>
确实还要考虑金三角的因素。软件项目,也并非一定要有强人项目经理,其实只要按照软件工程,踏踏实实做好每一个环节,质量就不会差到哪去。
比如说在需求上多花点时间精力,把需求确认清楚,这就成本一半了,然后再基于确定的需求做好架构设计再开发,最后开发后做好测试,那么质量就有了基本保障了。
相关阅读:[31 | 软件测试要为产品质量负责吗? ](http://time.geekbang.org/column/article/94631)
邢爱明:<br>
谁来做测试工作,这也是我一直比较疑惑的地方。我现在是甲方,主要做的是企业管理软件,业务逻辑和流程控制都比较复杂,部分系统是需要一些领域的专业知识。
软件开发的时候基本采用的是瀑布模式。首先由专门的人员做需求澄清分析和设计一般我们称为业务分析师他们这些人会输出软件的需求规格说明书包括软件原型、详细说明word文件然后交给开发团队进行功能设计、开发和交付。
在这种模式下,是否需要专职的软件测试人员,有两种意见。
第一种,不需要测试人员,原因是业务逻辑复杂性,找一个普通的外部测试人员进来,还需要花较长的时间去了解需求,学习如何操作一些专业的应用软件,还需业务分析师花费宝贵的时间去做辅导学习。如果不让测试人员学习,就只能测试一些很简单的功能,对把控整个软件交付的质量作用非常小。解决方案就是让业务分析师兼职做测试工作,因为对需求本身非常清楚,学一点测试基础知识,在付出点加班时间,也是能完成功能测试工作的。
第二种,需要专职的测试人员,因为上一种方案中,需求分析师大部分做的还是正向测试,即按照自己设计的功能和流程,判断软件交付是否合格。但是对异常场景的测试还是比较少的,会导致软件上线后,在用户实际操作过程和设想的不同的时候,往往会出现一些功能异常,给用户的直接感受就是软件不稳定。所以说希望通过专业的测试人员,多采用一些探索式的测试方法,尽量多地发现软件中存在的缺陷,提升交付质量。
哪种方案更加合理一点?
宝玉:<br>
我的观点是这种情况下需要专职测试的,业务分析师的重点应该是把需求文档写清楚。
业务复杂不能成为一个借口,想想看开发人员是怎么理解需求的,难道也是业务分析师代劳?肯定也是由业务分析师写成需求文档,然后开发人员基于文档开发,当然中间少不了很多确认环节。
测试也是类似,应该专业的人来做比较好,可以有更好的测试覆盖。一开始肯定是难一点,但是一段时间业务熟悉后,会极大提升整个团队的测试效率,而你也不需要再为这个问题纠结了。
相关阅读:[32 | 软件测试:什么样的公司需要专职测试?](http://time.geekbang.org/column/article/94941)
kirogiyi<br>
对于Devops我只是听说过并没有具体的去了解过它的使用和应用场景。根据宝玉老师的讲述Devops 的基础是自动化,那么自动化之外好像更多的是一种概念,可以因环境而产生各种不同的方式和方法,并没有比较明确的定论。感觉就像敏捷开发一样,满足敏捷宣言思想的操作都可以是敏捷开发,最终适合自己或团队的才是最好的。
宝玉:<br>
自动化确实没有明确的定论,重要的是得要有应用自动化的意识,让自动化变成你项目开发流程的一部分,从而提升效率、改进质量。
应用自动化本质就是应用工具和基于工具二次开发常用的自动化工具比如说自动测试框架、持续集成、日志监控报警。这些都是基础工具还需要针对自己项目的环境基于工具提供的API去定制化的写配置脚本让它可以适合你的项目。
最重要的还是要把这些工具整合到你的开发流程中,比如说:
当你提交代码的时候,持续集成能帮你自动运行自动化测试脚本,可以直观看到测试结果,根据结果再决定是否合并或者继续修改;
当你合并代码后,持续集成能帮你自动化部署到测试环境,并且构建生成生产环境的部署包,甚至帮你自动部署生产环境。
当你要部署的时候,通过自动化的脚本直接部署到生产环境,而不需要手工去干预太多,避免人为因素的失误。
当你部署上线后,通过日志监控报警系统能实时看到部署后的数据变化,及时发现问题。
这样的流程其实是比较通用的、大部分项目都是适用的,只是前期需要投入一定的时间精力去研究和搭建,但是搭建好了这样的整套自动化环境和建设好了相应的开发流程,相应的从效率和质量上的回报也是很大的。
相关阅读:[36 | DevOps工程师到底要做什么事情 ](http://time.geekbang.org/column/article/96895)
好,今天的加餐就到这里,非常感谢同学们用心的留言,也希望我们专栏的同学都能每日精进,学有所成。
感谢阅读,如果你觉得这篇文章对你有一些启发,也欢迎把它分享给你的朋友。