艾伟也谈项目管理,代码背后的点滴

  有段时间没有更新技术blog了,现在有空每天都写写围脖,记录生活和工作的点滴,但是有时候发现有些技术的想法和工作总结没有像过去那么完整的写很大一篇,但是也有零零散散的不少点滴,因此想着随意的写这么一个连续的片段分享。   为什么叫做代码背后的点滴呢,其实在现在互联网应用来说,其实用什么语言,用什么平台有些场景有影响,但已经不是绝对重要的因素的,其实代码被后的设计思想才是最重要的。而用最熟悉的方式去表现最自然的想法,那才能做到游刃有余,就好比我向华黎同学申请这次内部奖励的奖品希望是手写笔,因为不论什么画图工具用起来都会妨碍我的顺畅的表达,最终我把注意力集中到了画本身上,而丢失了应有的灵感(在没有拿到画笔前,最近先少画点图)。写代码也是一样,不要被流行,高性能,有潜力这些词搞丢了自己的目标,工具就是工具,能广泛的去学,但不必要广泛的用,把干活要用的那门搞熟练了再说。废话不多说,言归正传。         

  先说一下,以下的任何观点都必须“对症下药”,没啥万能灵丹妙药,怎么用,什么时候用是关键。 

  聚与散    

  场景一,在分享时谈到Jetty7整个体系架构就一个线程资源池,为什么?整个jetty体系都是事件驱动模式(包括系统事件:NIO事件,包括业务事件:request suspend),我们系统很多时候有很多资源池(线程,DB,服务)等等,有些是直接的,有些是间接的(依赖于第三方包引入的)。我们要求每个开发者都要给资源池设置上限,给队列限定长度,防止崩溃,但是当这些资源池散落在各个地方的时候,那么每一个资源达到边界以前,总和可能已经超过了系统负载能力,那么一样会奔溃。因此资源的统一规划看来有必要,那可以考虑将物理隔离变成逻辑隔离(防止业务干扰,同时可以根据权重模型来动态分配和预留资源),另一方面整个小团队到大团队,对于连接池的使用抽象出来以后,那么多个依赖都可以在抽象的基础上公用一个物理资源池,如果引入第三方缓存,都可以将资源策略应用到多机上。回过来,这里就要说聚和散的关系,聚能够在一定程度上有全局观,同时可以根据策略模型来调配资源,散最大的好处就是业务隔离,互相不会影响。最近在写一个线程资源分配的小东西,目标就是:资源可根据权重模型分配。(权重模型两条:设定某一类key获取资源可以保留一定资源独享,设定某一类key获取资源最大上限可控)其实这就是一个逻辑隔离资源的最基本的雏形。        

   场景二,有同学谈起他们的系统属于消耗CPU类型的应用,特别是对数据库获取到的数据作处理和渲染的时候,问有啥好的建议。我的建议是数据获取端没啥可优化的话,考虑数据存入端增加数据预处理功能,将数据处理的压力分摊到更多也数据存入方。当然这个代价是数据的可复用性降低,业务逻辑侵入到其他系统,数据存入方性能会有所下降(如果这三点不足以影响业务流程和数据存入方,那么可做)。其实这是聚和散的另一种表现,很多时候需要考虑的是全局优化,而不是局部优化。      

   场景三,我今天看了淘宝Tair的作者若海介绍关于tair的一些设计思路的文章,这和早先我做memcached的客户端思想是有共同点的。首先就是数据的获取从服务端中转路由变成了客户端获得配置本地hash选择目标服务器,这就将服务路由的功能客户端化了,避免了单点的瓶颈,也提高了访问性能。同时metadata的数据保存在configserver中,以弱依赖的方式主动推送,避免客户端受到影响。但他的设计里面数据同步是服务端做的,而我当年是客户端做的(队列中异步备份),当时一方面是没有办法去改服务端的memcached,另一方面服务端能有多少,客户端有多少,这些压力的分摊,天然的缓解服务端的压力,将压力分散在了客户端上。(代价就是客户端工作多一点,即时性依赖于各个客户端的能力)这也是一种散。     

  场景四,TOP大数据请求的处理设计,TOP的目标是什么?大坝。主要职能:限流,授权,路由。那么路由这件事情必须在TOP走么,数据交互和平台校验是否一定要在一个流程中完成,其实不然,安全校验通过以后可以颁发会话标识和目标服务地址,直接由客户端和服务端交互。(这其实就和很多分布式文件系统或者分布式缓存系统一样的考虑,校验通过后就直接建立数据通道进行数据交互,避免性能受到影响),这了的聚和散就涉及到业务的耦合性分析决定流程的聚散,改善性能和稳定性。    

   场景五,上面谈到过最近自己实现资源分配逻辑隔离的这样的资源池,现在就是做线程池,起初不想用jdk自带的线程池,原因是自带线程池启动线程后,线程只要在coresize内就不会被销毁,也没有调度来从池里面获取执行任务,完成任务放回到资源池,这些线程就轮训的去获取队列的数据。好处在于没有一个manager的管理性能和复杂度会提升,缺点就是资源分配就无法实现。其实这就是典型的一种资源分配有一个实例主导还是由多个消费者自己主导的设计。

  强弱依赖         

  场景:Jetty的Continuation设计中,从调用suspend方法来悬挂起请求,避免退出容器service方法req和res被回收,到业务主动调用complete结束请求流程,回写数据到客户端,都采用产生事件,异步的由核心线程池去执行。这样业务线程池的线程生命周期就不会受到系统线程输出快慢或者容器本身压力的影响。这种弱依赖能够极大的解耦两个系统的服务能力和稳定性。 

  关键先生         

  场景一,有同学一个压力测试报告中做了这么一个测试,整个事务处理流程第一步骤消耗CPU,第二步骤消耗IO。整体事务时间=CPU 10 ms + IO 90 ms。他考虑是否能够通过缩短IO消耗时间或者CPU消耗时间来提升RT时间,就能够提升TPS。他的结果是IO提升一倍TPS没有任何变化,CPU消耗时间提升一倍,TPS翻番。这能说明啥,说明瓶颈在CPU上,提升一倍,那么处理能力增加一倍(就好比资源池内的资源生命周期缩短,被利用的次数更多),大部分请求都在CPU上排队等待处理,因此系统的TPS取决于瓶颈资源的处理能力而不是简单的缩短RT就可以改变的。(贴切的比喻就是漏斗,不论你大口朝上或者朝下,小口决定了水流量,小口就是那个关键先生)          

  场景二,异步化压力测试的结果中有如下一组结果:


容器


请求服务


请求处理模式


TPS


Nginx+ Jetty


Time.get


同步


1534


Nginx+ Jetty


Time.get


异步


1068


Nginx+ Jetty


User.get


同步


1060


Nginx+ Jetty


User.get


异步


1027

 

 

 

 

 

 

 

 

  Time.get是不向后中转服务的模拟请求,也就是服务端很快就响应给客户端了,而user.get是真实模拟服务向后请求,有一定消耗。但看这个结果,同样是同步和异步对比,前者性能相差很大,后者相差不大。原因?异步一定有消耗,但这个消耗占整体事务处理时间的比例是多少,这就会放大影响。而TOP大部分服务都要比user.get更加耗时,因此后面才是线上的真实状况。(因此场景模拟是压力测试最重要的条件),这里的关键先生还是要看整个事务处理的消耗点。衍生一下上次电话面试的一个北京的朋友,谈到了NIO,问了他是否做过BIO和NIO的测试比较,什么时候用NIO最好,他还真做过四类测试,有结果,但还是没搞明白为什么:1.传输数据量大,后端服务处理慢。2.传输数据量大,后端服务处理快。3.传输数据量小,后端服务处理慢。4.传输数据量小,后端处理速度快。结果是NIO在4处于劣势。其实BIO释放的够快,那么NIO的异步在整体事务处理消耗就形成了劣势。        

  生命周期         

  场景:在异步分享过程中,谈到了事件驱动的架构设计。原来的流程可以分成很多个步骤,每一个步骤由于处理的需要都会申请必要的资源,不同步骤有些是共享资源,有些是不共享的,那么从资源的生命周期角度来说,一个流程中所有资源的生命周期都是一样,就是整个业务事务的执行周期,对于在一个业务流程中各个步骤很少共享资源的状况,或者有等待外部返回内容的情况时,切割开流程步骤,降低资源生命周期,提升资源利用率,是事件驱动的最大优势。NIO如此,Servlet3规范如此。简单来说就是:按需分配。另一方面我们也能看到,处理都是无状态的,只有输入和输出,无状态的处理更容易复用。看起来这种设计很好,但其实背后还是有不少问题:1.流程复杂化,原来通过程序保证流程的顺序和依赖,现在切割以后,如何驱动,顺序如何保证,如何容错,都给系统增加很大的维护成本。2.异步化后消耗时间必然增大,不论是通过pull主动获取状态变更还是通过push被通知到,都在性能和时间消耗上会有一些付出。因此还是需要依环境而定。 

  瓶颈移动         

  场景一,还是一个同学的优化的案例,当时谈到有个叫做最佳线程数,但是觉得在优化过程中最佳线程数是在变化的,其实很多时候当你觉得任何的结论是不稳定的,那么你需要进一步深入挖掘下去。其实之所以最佳线程数这个值不稳定,关键在于我们如何去优化,找到问题所在。和前面举例一样,系统可以看成各种类型资源池的一个整体,然后由很多个步骤不断申请资源来完成各个步骤,最后返回结果。那么说白了,哪个资源池是流程中处理能力最弱的,他就是问题所在,就是瓶颈,但是通过优化后这个瓶颈可能有所改善,与此同时另一个资源成为漏斗的小口,这时候,瓶颈移动了,优化的预期结果和提升的瓶颈点性能就不吻合了。所以,把带宽,CPU,IO,外部服务,DB,Web线程池等等都看成资源池,找到瓶颈所在去优化,同时在优化过程中不断修正优化目标,达到最后全局优化的效果。         

  场景二,异步化分享中谈到一点,异步化要有全局观。例如A依赖与B系统,组成了一个完整的服务体系,通过异步化方式将A的资源生命周期缩短到只有A处理的时间,B的资源生命周期就是B的处理时间,此时如果A是原有整个系统的瓶颈,那么就会产生雪中送炭的效果,系统整体性能会有所提高(大部分情况下,原因看后面介绍)。如果B是瓶颈,那么就是雪上加霜,更多的水流被放进来,如果B自身没有流量控制,那么系统就会处于不健康的状况,甚至奔溃,系统的整体RT时间可能会增加(A节省的时间小于B增加的时间)。因此这就是系统间瓶颈移动产生的影响,同样也和一个系统一样,考虑优化一定是整体性的考虑,否则问题不会朝着预期的方向解决。        

时间: 2024-08-16 21:55:52

艾伟也谈项目管理,代码背后的点滴的相关文章

艾伟也谈项目管理,只有好代码的项目能成功吗?

Simon Brown,集开发者.架构师及作家于一身,他认为成功的项目需要的不仅仅是好代码.在他的演讲<好代码是不够的>中,Brown讨论了项目成功所需的所有元素,从前期设计到操作文档. Brown认为好代码是一个好的开始,但要取得成功,人们需要知道要构建什么.要发布什么以及它可以运作起来. 要知道构建什么,需要一套需求.收集完需求之后,要有一个"大局观",软件架构代表了当前对该产品的认识.然后,大问题需要被分解成更小的解决方案,其中包含了组件.组件之间的交互以及用到的服务

艾伟也谈项目管理,编程习惯

文/Alexey Radul 译/程显峰 原文地址:http://web.mit.edu/~axch/www/programming_habits.html 近年来,我对编程艺术有很多体会.过后,我发现有些体会是错的:有些体会我遗忘了但又重新感受到:而另外有些则是必然会发现的.我还完善了一套项目管理的好习惯,这些习惯包括我自己的,或者小组的,抑或是更大的,公司内部的.一方面,这些习惯对软件的成功开发是至关重要的(太小或者纯粹巧合的不算),另一方面,这些习惯也不是什么高深莫测的东西,较小的篇幅就可

艾伟也谈项目管理,个人管理:写书之前应该回答的几个问题

我在06年和一个同事写过一本Delphi入门的示例书籍Delphi数据库通用模块及典型系统开发,当时体会到了写书不像想象中的简单,基本上业余时间都没了,所以我之后就不想出书了,其中更重要的一个原因是,我还没有找到一本真正想与大家分享并且自己能写出来的书籍. 博客是个好东东,只要你愿意与人分享交流,你的行为就可以赢得大家的认可,如果你的观点或者文章写的又好,那么就会有更多形式与大家分享,例如最近我们可以看到的很多人都由于blog而出书了.同样,我这两年对博客的投入也赢得了一些人的信任,也收到过好几

艾伟也谈项目管理,对项目管理的几点认识

自2007年参加工作以来,参与的项目也有好几个了,但都是以项目成员的角色参与,从来没有以项目经理的角色参与项目.中国有句古话叫"旁观者清",同一个问题站的角度不同,可能会形成不同的结论.下面我就以一个普通项目成员的角度谈一下对项目管理的几个看法,希望大家给予指正. 1. 团队成员选择 人员选择要谨慎,要尽量选择合适的人员,在选择团队成员时要重点考虑其团队合作能力.编码可读性.能力和项目的匹配度等因素. 2. 项目远景的确定 项目初期项目经理需要和高层以及客户协商,定下项目的远景目标(即

艾伟也谈项目管理,需求管理成熟度的五个级别

需求管理是软件开发全生命周期重要的一个环节,我们每个人都知道它的重要性,但是要真做做好并不简单,我也写了一本在线电子书业务分析与需求.pdf来讲解需求相关内容.对于每种技术和方法,就像以前我写过的企业架构成熟度模型(EAMM)的一样,我们都不可能一下子就精通,而是按照一种学习的曲线进展,本篇本篇主要介绍一下需求管理成熟度的六个级别. 级别0:没有需求(no requirements) 没有任何明确的需求被记录下来,他们假定知道要构建什么,希望节省需求的时间来做开发,但这势必会给开发工作带来混乱,

艾伟也谈项目管理,Richard Durnall谈系统管理和从外向内的组织结构

InfoQ中文站:能给我们介绍一下"系统管理理论"(System Management Theory)么?能不能跟我们分享一下您在实际应用中的经验? Richard Durnall:系统管理理论是过去五十年里出现并逐步发展而来的.它与传统的那种基于管理和控制方式的科学管理理论有很大的不同.首先让我们回顾一下管理科学的历史来了解系统管理理论. 在19世纪工业革命之前,商业规模通常不大,从业人数十分有限.19世纪30年代的技术革命中出现了大规模的工业企业.与传统的村镇工业不同,这些企业开始

艾伟也谈项目管理,打造高效的技术团队,我会关注的7个点

1:使用分布式的版本管理系统 如果你觉得不需要使用版本管理系统,那我们沟通会有代沟,如果你是cvs.svn的粉丝,或者由于某种原因没有使用过分布式版本管理系统,比如git,那强烈建议你去看一下"why git is better than x". 2:一键式发布 这里发布的目标位置,既可以是开发机,做本地测试:也可以是测试机,为QA准备好捉虫游戏的森林:还可以是生产环境(或者beta环境),供用户直接访问. 如深度xp一键恢复系统一样,一键式发布需要自动完成很多工作:代码自动化测试(开

艾伟也谈项目管理,开始一个项目时最重要的是什么?

我的第一个工作是在一家软件资讯公司,刚上班的时候,公司给我们这些初出茅庐的愣头青安排了细致的培训.其中一个重要的科目是项目管理,一名资深软件咨询师前辈来培训我们我们,开场就问我们:"开始一个项目的时候最重要的是什么?" 我们有的说是"代码管理工具",有的说是"Process",有的说是"成员素质",但是这位前辈都摇头表示不满意,当我们都黔驴技穷的时候,他在白板上画了一个大大的方框--"Boundary! Settin

艾伟也谈项目管理,敏捷实施中的常见错误

一些评论员写下了敏捷实施中一些常见错误和反模式.他们贴出了"Top X"列表,列出了需要避免的事项和他们曾在各种组织实现敏捷时见过的错误. Target Process的Michael Dubakov写了两篇博文:"10个敏捷实施中最常见的错误"(Part 1; Part 2 ).他认为"许多公司在敏捷实施中再三犯同样的错误." 他的常见错误列表如下: 1. 从一个工具开始敏捷开发是不同的.一个工具不会立刻产生影响,不会由于这一工具的存在而解决多