Chinaunix首页 | 论坛 | 博客
  • 博客访问: 521381
  • 博文数量: 78
  • 博客积分: 995
  • 博客等级: 准尉
  • 技术积分: 1462
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-15 20:22
个人简介

技术中沉思的时候最快乐,问题得到完美解决的时候最有成就感!

文章分类

全部博文(78)

文章存档

2013年(39)

2012年(37)

2011年(2)

分类: LINUX

2012-06-05 13:08:46

现象
项目后端服务器几乎全部以c++完成,svr的基础建立在一个比较简陋的多路复用socket框架上面,
     整个大的项目架构是一年多前建立的,随着:
     1) 产品需求变化反复,代码为应付需求改来改去,夹杂了非常多的临时的业务逻辑,几乎没有任何
        文档(有些需求确实太小太临时了,根本不会去维护一份文档,也没有地方去维护,基本上文档
        只是用来说明svr大体架构的);
     2) 开发人员的来来去去,有些代码多次易手,开发人员素质能力的良莠不齐导致代码风格迥异,有些
        陈年svr已经很难去阅读维护,腐化的不行;
     3) 因为只有一个简陋的socket框架,用起来不怎么方便,开发人员会根据自己的喜好在此基础上
        进行一些自己的包装,于是产生了很多库,这些库代码风格各异,质量层次不齐,有些就完全只是
        开发人员自己用,自然库的接口乱七八糟,随着业务需求变化库的接口随意变化是经常的事情;
        时间一长,人员调整,最后发现:这些库根本没有带来好处,没有产生技术积累积淀应该带来的
        好处,反而成了非常称重的一份累赘,不维护不行,维护代价也非常大;

反思
 记得06年刚刚从学校毕业,进入迅雷,做的第一个产品是迅雷博客,这个产品虽然最后失败了,但
      失败的是产品定位,从架构上从技术上来说应该都可以说是成功的;这个产品经历了两年多,需求自然
      也经常改了改,但整个架构和代码没有像现在的项目这样腐化的不行;现在想来,这个项目技术上能
      成功缘由两个字“简单”,简单的 mysql+apache+fcgi+动静互配cache,甚至没有写一个像样的svr;
  kiss 原则,keep it simple stupid,最简单的就是最好的;
  那过去我们为什么要采用这些“复杂高级”技术呢?工作了多年,有很多感受:

      1) 为了性能
              cgi,fcg -> 简单的多进程阻塞svr -> 非常粗陋的异步多路复用svr -> 精致的异步多路
          复用svr -> 多线程异步多路复用svr(seda)
              上面就是工作中用到的主要开发框架,随着时间的推移,一步一步前进,一步一步高级,
          一切都为了追求高性能,高并发...从最初的鄙视cgi,fcg,鄙视php,时间一长甚至都忘了
          cgi,fcg,php的存在;每碰到什么需求,条件反射的会思考,怎么搭svr满足这个需求;

  反思:过早的优化是万恶之源

          一问:性能真的这么重要么?
                 产品都还没出来,甚至产品方向都还确定的时候,开发高并发高吞吐量的svr有什么屁用?
              产品最最重要的是能用,能提供稳定的服务;而不是开发了n久才出来,看起来高并发高服务
              能力,却到处暗藏bug,动不动就core的服务;快速的搭建出一个能用的原型,然后迅速推向
              市场,推到用户面前,然后不断的改进用户体验,满足用户需求才是最重要的;
                 在一个用户都没有的时候想着用户千万,pv过亿,不切实际;系统架构是要预估,但预估
              最多10倍,而不是幻想中的100,1000倍;
          二问:cgi,fcg,php 很菜吗?
                 现在的项目组开发人员碰到需求,想都不用就是怎么自己搭svr去实现,因为在很长一段
              时间内,cgi,fcg 成了性能低下的代表,php成了菜鸟采用的工具;其实想想facebook,
              每天pv几十亿,php用的非常广泛...
                 对,cgi,fcg,php是阻塞的,如果一个工作进程阻塞住,是没法做其他工作的;但其实
              仔细算算,假设起100个php工作,每个请求话费50ms,全力工作,一天按16个有效工作时间
              每天服务请求=100*20*3600*16=115200000,是1.1亿请求,这么大的一个请求,这个产品已经
              非常成功了...
           三问:如果cgi,fcg,php真顶不住了,是不是要自己写svr解决?
                 恭喜啊,产品非常成功,在这个100产品,99个失败的环境下,很不容易;
              站着什么都不做是最好的解决方案,机器是廉价的,宁肯浪费机器一个小时,绝不浪费人一
              分钟;加机器能解决的问题不是问题...

           其实:不带状态,不需要在内存中一直维护的业务,php+mysql+nginx+memcache之类的架构足矣
 阻塞就阻塞吧,够用就好,异步非阻塞,何必呢????
           项目:比如下载验证,常用的svr agent等模块,完全可以拿上面或其他类似的架构实现

       2) 成熟的架构,开源的技术用的过少

              或者是视野不开阔,对业界已有的成熟架构和技术不熟悉;或者是满足现状,习惯了问题习惯
           了bug,即使知道有成熟的架构和技术,也视而不见;或者是有畏惧心理,一是担心开源的东西
           不牢靠,另外担心掌握这些开源的东西学习成本高,所以干脆埋头苦干...
              成熟的架构和开源的架构确实是有学习成本的,另外很多东西不是直接拿过来就可以用的,需
           要用一些手段和技术整合到现有的业务大框架中的;

              于是现在项目中开发人员还经常要去写一些早已经被写过n次的东西,比如lru数据结构;于是
           还经常写dbp就为了在db前面挡层cache...
              就感觉一群人还处在刀耕火种的原始社会,什么都自己发明,什么都自己创造,结果千奇百怪
           良莠不齐的轮子满项目都是,看似什么都有,却什么都不能放心的用;svr中到处是看起来差不多
           的代码,似重复又还真有一两处不一样...一个简单的svr动不动就是几十个文件,看进去发现
           其实就为了实现一个非常的代理分发功能...查个问题,要一头扎进那些是是非非的代码中去,
           改处简单的不能再简单的地方,都要反反复复上上下下检查一遍,然后自测,提测...

           其实:开源项目的质量远比我们想像的高多了,开源的东西有时好用的用了会上瘾,开源项目
              对于我们的帮助是非常大的...业界早已经有好多开源的东西,视野开阔点!!!

           项目:去年年初写了大量代码,非常复杂的业务逻辑,异常复杂的异步调用,状态机貌似都
              不够用了...自定义二进制协议,编解码手工完成,svr的client要写出来都不是一件简单
              的事情用c++去写client生不如死,感觉恶心到快不行了;

              后来用上了 thrift 做编解码,然后狠狠的包装了下,包装到后面,用起来根本感觉不到
              他的存在,但他又实实在在的帮了大忙;这个玩意貌似倒成了我们开发的一个好帮手了。
              前段时间改一个非常旧的svr,里面还是用的二进制自定义协议,完全没了改的动力。
              于是干脆重写,重写都比直接在旧的上面还省力...

       3) 基础技术沉淀过少
              为什么那么多种代码风格?为什么那么多不通用的东西?为什么那些代码那么容易就腐化了?
           基础技术积淀太浅导致了这些问题,因为没有一些固有的东西,要实现一些东西,只能自己随意
           造,而开发人员的素质良莠不齐,造出来的东西可能bug问题重重,就不用说沉淀了;不能沉淀
           的后果是:后面的人抛弃前面的人的代码,自起炉灶,然后引出了新的问题;再后面的人又抛弃
           前人的代码...就这样循环,不停的写,不停的抛弃...

              代码越写的精炼,越写的简洁,越写的有技术含量,自然系统就越稳固;于是系统的质量就
           完全依赖于开发人员的素质高低;然而一个项目组里面肯定有些人代码写的比较烂,于是项目很
           容易在那里开始烂...
              一个过于依赖开发人员的素质的项目是很难的,一来不可能保证所有的开发人员能力都那么
           牛逼,二来项目很容易被开发人员所左右,离职对于开发人员来说是很正常的;

              拿对面的腾讯来说,他们有大量的基础固件,经常搭一个svr对于任何一个开发人员来说
           都是非常容易的,而且生成的svr就包括了大量的功能(比如监控,统计,流量控制,防雪崩,
           防过载等等),这样就不再需要开发人员做这些对他们有难度的工作,他们只需要关心比较简单
           的业务逻辑了;如果一个开发人员连这个工作都不能胜任的话,那直接可以开掉了...
              纯业务的代码本身还是比较容易理解,改来改去,也就是那个地方,腐化也仅仅是那一处的
           腐化,而不是像现在有的项目,从上到下都腐化了...

              架构在大量基础固件上的代码,代码行数文件数就要少好多好多,而代码行数其实和代码质量
           是有极大关系的,越复杂的代码越容易产生bug,也越容易腐化;
              代码越少越好,直至最后无代码境地...当然无代码不可能,但如果能在完成需求的基础
           上保证代码越少越好,绝对是有利而无弊的;

              可能大量的基础固件会束缚某些人的创造性,但其实很多开发人员创造出来的东西的价值
           远比他造成的问题要低的多...
              
              那为什么腾讯有,而迅雷没有呢,一:不重视,二:没有好的产品驱动;好的基础固件是从
           业务研发中诞生的,绝对不是凭空想象出来的,脱离业务的基础固件是虚幻的毫无用处的(
           以前公司貌似有人是专门来做这个技术支撑的,但后面没戏了,完全脱离业务的玩意没人用);好
           的产品推动基础固件升级,好的固件支持产品更加优秀,两者是相辅相成,互相推动的;陷入到
           先有蛋还是先有鸡的问题上去了;好在迅雷还是有些蛋的....

              说说自动化的问题,有个观点:能让机器完成的绝不让开发人员去完成,一是因为能让机器
           完成,没必要让开发人员去完成,人都是会犯错的,再优秀的开发人员也无法避免;二是确实很
           多开发人员其实没能力去完成或者说完成不了...

           其实:代码越少越好,能自动化的绝对自动化,尽量减少对开发人员的依赖...
           项目:在原来的socket框架上保证了一层,终于写一个svr文件数目只需要几个了,降到了原来
               的20%左右,看起来就要清晰不少;基础固件的作用是非常明显的;

阅读(5098) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~