放翁(文初)的一亩三分地

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  210 随笔 :: 1 文章 :: 320 评论 :: 0 Trackbacks

#

        blog已经快两年了,起初仅仅是为了自己“备个案”,结果慢慢演变成为了“分享成瘾”。前几天一个朋友给我的blog留言,谈到希望在新年里能够看到的不仅仅是我对技术的分享,更希望能够看到对于技术学习、职业发展的规划。因此想到了写一点什么分享一下自己这些年的一点点“收获”,周星驰的喜剧之王里面说到他是一个演员(虽然被叫做跑龙套的),我想我,就一个写代码的。

爱这行

       从事任何行业都一样,只有真正的爱上了这份工作,才会投入热情,才会在顺境中自我警醒,在逆境中寻找突破。这个行业的竞争很激烈,你停下来走,别人就立刻会跑步超过你,没有对这一行业的一种热情,就很难在困境中保持一种执着的态度坚持到底。

踏踏实实“扎马步”

       今天无意中看了“校长”的“程序员&司机”,其中谈到了关于程序员速成的问题。其实速成班毕业的 “系统杀手”早已在遍布大江南北,只是在互联网时代,互联网的应用型软件生命周期越来越短,业务驱动主导的情况下,这种速成方式看起来反而提高了企业生产效率。但这样的人才也就只能写几个Facebook上的插件应用或者iGoogle上的Gadget,真的要出GoogleAmazonYahoo改变互联网世界的企业,还是需要踏踏实实先学“扎马步”的人。

       很多在学校的同学或者刚刚毕业的朋友都看什么热门学什么,SpringAJAXHibernate等等,又有多少人在看Spring之前把J2SENIOXMLCollection等先好好学习一下,在看AJAX之前把Http协议、DTDXML Schema好好看一下,在学习Hibernate以前先把J2EE事务规范搞清楚。Java最大的好处就是开源,能够让人们站在更高的起点来作出更多的创新,但是对于学习者来说,不了解自己站在什么上面的时候,可能摔下来会很痛。在用的时候多问一些为什么,在遇到问题的时候多找找原因,在了解以后多提出一些优化的方案,这样才会进步的更快,走的更远。

       记得我前一阵子回家的时候和妈妈聊起最近的工作,虽然妈妈不太明白,但是也知道我现在做的东西技术含量比较高,嘱咐我“千万不要什么都教给自己的同事,徒弟带出就不要师傅了”(这当然是老一辈的观念了)。我和她说:“不要担心,这种学的会的不教迟早也会,学不会的教了也学不会”。其实这里说的学的会的就是技术,而学不会的就是经验和能力。这个行业的人在日积月累过程中并不会去比较掌握的知识面有多广多深,毕竟这行业更新很快,其实能力强的人在多年的学习中就积累了很多的找问题,分析问题,总结问题,提出建议,发掘创新的能力,这些才是这行业人在发展中最宝贵的财富,也是一个人成长的标志。开始的过程中,踏踏实实地“扎马步”,了解一些最基本的知识,那么上层技术的发展对于他来说仅仅只是一个短暂的学习过程,甚至可以触类旁通。因此还是要奉劝每一个新入行的同学,踏踏实实,静下心来做技术,就算工作安排得都是一些浮躁和重复的工作,用高效的方式来结束那些重复劳动,多留一些时间给自己打基础。

逆境养兵、顺境攻城掠地

       普通人的工作经历通常都是起伏不定的,一个人的能力是否能够得到体现,不仅仅靠自己的努力,有时候也需要“天时”、“地利”。马云比较有名的一句话:“今天很残酷,明天更残酷,后天很美好,但是大多数人死在明天晚上,看不到后天的太阳!!!”,其实也在说明一件事,就是很多时候需要一种坚持的精神才能得到宝贵的机会。

今天是我进入阿里巴巴满3年,这3年让我感触很深的是:1.逆境不要气馁,厚积薄发。2.顺境不要懈怠,一股作气,把握机会展现自己最大的能力。3.在逆境和顺境的转换过程中,创造机会,不要坐等机会,要学会不在其位,也谋其职。最后一点就拿我自己的亲身经历来说,我原来就职于一家通信公司,因此对于互联网应用的开发和架构设计要比很多人弱,进入阿里巴巴以后工作了半年(主要作业务开发),正好阿里软件创立,当时被分配到了阿里软件第一个产品负责客户模块,当时的应用是通过MDA框架配置搭建的,开发人员很大程度上不需要自己做太多的编码,但是这个平台并没有搭建过如此复杂的大型应用,因此存在着不少问题,当然这些问题都是通过业务产品线的人反馈给平台部的人,当时平台部门人员很少,但是却要修复和完善诺大一个平台,因此常常搁置开发人员的反馈。当时在自己工作之余就琢磨和研究平台,同时跟踪调试平台,最后直接给出解决方案,逐渐的就融入到了平台开发中,最后被吸收到了平台部门,进入平台部门以后遇到了两位很好的老大,根据我的特质给我安排了研究和学习的工作。接下去就是不断地参与阿里软件各个基础平台的构建,核心技术的研究和探索,找到了兴趣和工作的最佳结合点。因此,当你困惑的时候首先不是去抱怨,而是审视一下自己是否还有作的不够的,是否还有可以提升的空间,多给自己制造一些机会,也许我们不用等到后天,也不会死在明天夜里,明天早晨我们就看到了太阳。

海纳百川、冰冻三尺

       很多朋友可能听老师或者前辈也说过类似的话,就是作为一个技术人员要广也要钻。就好比现在很多人都要DB Scale out,同时也要Scale up。我从自己的角度来说一下广和钻的看法。广:1.要有容人之量。(很多时候程序员最大的毛病就是喜欢在技术上比较,未尝不是好事,但是一个人的能力总归有限,多看看别人的,多听听别人的,也许能够让自己少用时间获得更多的收获,特别是自己战友的声音)2.触类旁通,多问个为什么,多跨过界去学习。在阿里巴巴,PDSADBAUI等等职位各司其职,作为开发的我们其实也应该去了解如何去画Use Case,如何假设服务器和应用环境,如何写一些略微复杂的SQL,了解一些DB的特性,如何能够简单的作出一些基础的页面,使用简单的css来美化一下门面。这些就是需要多跨过界,多虚心的去学习。钻:1.本职工作技术一定要扎实,每作一个技术点就要把技术吃透,同时延伸开来,发掘更多的技术亮点。2.多接触新鲜事物,但是有选择的去了解,有目的的去学习和实践(目的的源泉就是工作的需求)。3.学会分享,一个人自己搞懂一个技术很容易,一个人要把他熟悉的技术写下来就会发觉原来自己还有那么多没有搞清楚,一个人如果要把写下来的东西宣讲给别人听,他就会发现,原来写下来的仅仅是那么一小块,因此学会分享,从自己了解,到记录分享,到演讲传播就是一个不断深化和广化的过程。个人觉得小公司锻炼人(啥都自己干),大公司培养人(该干的要干好),因此自己常回头看看自己在广和钻上的不足,可以让自己进步的更快,学的更全面。    

       学中医积累经验,学西医寻找突破

       中医以对人体经络血脉了解为基础,通过望闻问切来寻找病理根源,行医年限越久,找问题解决问题的经验越强。西医以科学技术为手段,通过试验化的方式不断寻找突破,并且将成果积累并且传递给更多的人,但是否年限越久越有能力,或者是使用得器材越广越资深,这点全要看个人对于医术的理解,如果仅仅停留在对器械的使用和对成果的依赖,那么只会成为一个庸医。当然这里绝对没有对中西医的差别化或者评价,仅仅要说明的是,在手段丰富的情况下,容易忽视了本质,只看到了皮毛,积累的时候多一些追根溯源,站在别人的成果上才更踏实,因此在对经验积累上向中医多学一些,在寻找突破,传播技术上多学一点西医的风格。不过说到低,还是要看学习的人,静的下心,沉得住气,才会有积累,才会有突破.

不做一个纯粹的“技术人员”

       不做一个纯粹的“技术人员”,其实也就是说要培养自己多方面的能力,我仅仅把自己想到的一些点列出来说说:

1. 项目产品化的思想。现在就算在学校里面给导师作项目都讲究一个商业价值,更不要说在企业里工作。作为一个开发或者架构师最重要的就是要有产品化的概念,这也是项目是否成功的关键。软件的目的是为人服务,如何服务的好,那就要以一个产品的思路去做项目,而不是作为实验室的实验品,为客户提供好服务就会给公司带来商业价值,对自己的工作也会有很好的肯定。这是一个良性循环,反之则是恶性循环(多赢变成多输)。如何做到产品化,首先就是需要去了解需求,而不是布置需求,其次就是设计时多听取一些不同角色的意见,最后就是在客户的反馈过程中反省。

2. 多一些设计,少砌两块砖。代码写的再好,其实也只是用砖块砌墙砌的比较好罢了,这年代已经不会为了节省两块砖而给一个优秀工作者了,同时技术的日新月异,总是摆弄技巧,学习花拳绣腿已经跟不上时代了。多了解一些行业背景,多参与一些架构设计,将业务设计用良好的架构体系来实现,那才是一个称得上有能力的技术人员。

3. 学会前瞻,学会自己找事。记得我刚进平台组,最不适应的就是我的老大基本不太给我布置太详细的任务,这就好比进入大学,老师不给作业,自己反而心里没底了,其实自己找事的过程就是一个自己学习的过程,当我一天下来感觉没干什么,没学到什么,心里就开始发虚。如何能够前瞻性的去选择一些目标,如何对现有情况提出一些创新和建议,都是一种更高能力的要求。现在SIP组也是一样,在我们这个组里虽然现在每周还是布置一定工作,但是我对其他两个同学的要求也是希望能够有前瞻性,学会发现问题,预防问题,更甚者就是提出创新。当你具备了这种环境的时候,你就需要锻炼自己的能力了。

4. 做个让老大放心的人。这点也许很多人和我一样在业务上很早就让老大觉得可以安心睡觉了,但是其实另一方面,如何在商业角度看问题,如何培养新人,如何协调部门合作等等,都会让你的老大更加安心。另一方面来看,其实在这些能力的培养过程中,你不再局限于业务水平的提升,让自己在更多方面更加成熟。

六脉神剑

       今天是我进入阿里巴巴3年整。在阿里巴巴有个说法,只有在阿里巴巴工作了3年,才能算是一个真正的阿里人,因为理解阿里巴巴的文化,需要三年时间的沉淀。这里就从一个写代码的角度分享一下阿里巴巴的六脉神剑文化。

客户第一:如果你是做架构的,作平台的,作开发工具的,那么客户就是和自己一样的开发者,多学习一下开源项目的精神,多从使用者角度去考虑问题,那么你的东西才会被更多的人认可和使用,永远不要去做一个“玩具”的开发者。如果你是做产品的,那么就多听,多想,多问,永远不要急着去写代码。

拥抱变化:敏捷开发的基本原则。互联网应用尤其如此,不要害怕变化,在需求和架构之间找到平衡点(说起来比较容易^_^)。

团队合作:一个人的力量始终有限,分享,交流,合作能够让自己事半功倍,学的更多,看得更远。

诚信:说到就要做到,做了就要做好,做软件开发一样也需要有责任感,贴满狗皮膏药的代码上如果注释是你的名字未来也会给你蒙羞。踏踏实实地用心去写代码,去设计架构,不经意间得到的要远远比那么一点工资来的多。

激情:还是那句话,你如果不爱这行,乘着年轻赶快转行。

敬业:专业执着,精益求精

很感谢各位能看完这篇感受分享,以上都仅仅是个人的一点感受,能够引起共鸣那么证明我们的经历很相似,如果能够给到你一点帮助,那写这些就真的有意义了。不论你在别人眼里是一个资深架构师还是开发人员,其实如果你爱这个行业的话,你应该就是一个写代码的,但是每个人的经历都是一本“写代码的自我修养”,珍惜自己的选择,让自己在兴趣和工作中找到最佳结合点。

posted @ 2009-03-11 02:38 岑文初 阅读(4989) | 评论 (20)编辑 收藏

 

       今天看了“Database Sharding at Netlog, with MySQL and PHP”一文,和去年我们讨论扩展的思路很类似(不过这种分布式扩展,计算,存储的思路都很类似),但是这片文章的作者是在日益爆炸式增长的用户数据下实践的分享,因此这里将文中的一些思想记录下来分享一下。

       Netlog拥有4000万活跃用户,每个月有超过5000万的独立用户访问网站,每个月有5亿多的PV。数据量应该算是比较大的。作者是Jurriaan Persyn,他从一个开发者角度而非DBA或者SA角度来谈Netlog是如何通过数据切分来提高网站性能,横向扩展数据层的。原文在:http://www.jurriaanpersyn.com/archives/2009/02/12/database-sharding-at-netlog-with-mysql-and-php/

       首先,还是先谈到关于数据库在数据日益庞大的情况下一个演变过程。
   
   第一阶段:读写同在一台数据库服务器

   

第二阶段:读写分离(可以解决读写比例均衡或者读居多的情况,但是带入了数据复制同步的问题)



   第三阶段:部分数据独立部署结合读写分离。(部分数据根据其业务独立性情况,可以将所有的数据独立存储到数据库服务器,分担数据读写压力,前提是要求数据具有较高的业务独立性)

    
       第四阶段:数据分拆结合读写分离(三阶段的增强)


       第五阶段:问题出现,分拆也无法解决数据爆炸性增长,同时读写处于同等比例。


       解决问题两种方式:DB Scale up DB Scale out。前者投入以及后期扩展有限,因此需要进行数据切分。



       上图就是将photo的数据切分到了10台数据库服务器上。

       切分数据的两个关键点:

1. 如何根据存储的数据内容判断数据的存储归属,也就是什么是内容的分区主键。

2. 采用什么算法可以根据不同的主键将内容存储到不同的分区中。

分区主键的选择还是要根据自身的业务场景来决定,Netblog选择的是用户ID

采用什么方式将分区主键映射到对应的分区可以通过以下四种方式:

1. 根据数据表来切分。(前提就是数据独立性较强,和前面提到的三阶段类似)

2. 基于内容区间范围的分区。(就好比前1000个用户的信息存储在A服务器,1000-2000存储在B服务器)

3. 采用Hash算法结合虚拟节点的方式。(这类在memcached等等分布式场景中最常见,其实也是一个难点),缺点就是在于动态增加存储节点会导致数据部分或者全部失效。

4. 目录式的分区。最简单也是最直接的方式,key和分区的对应关系被保存,通过查找目录可以得到分区信息。适合扩展,就是增加查询损耗。

如何将数据分布的尽量均匀,如何平衡各个服务器之间的负载,如何在新增存储机器和删除存储机器的时候不影响原有数据,同时能够将数据均摊,都是算法的关键。在分布式系统中DHTDistribute Hash Table)被很多人研究,并且有很多的论文是关于它的。

数据的横向切分给应用带来的问题:

1. 跨区的数据查询变得很困难。(对于复杂的关联性数据查询无法在一个请求中完成)

2. 数据一致性和引用完整性较难保证。(多物理存储的情况下很难保证兼顾效率、可用性、一致性)

3. 数据分区之间的负载均衡问题。(数据本身的不均衡性,访问和读写的不均衡性都会给数据分区的负载均衡带来困难)

4. 网络配置的复杂性。(需要保证服务器之间的大数据量频繁的交互和同步)

5. 数据备份策略将会变得十分复杂。

解决这些问题当前已经有的一些开源项目:

1. MySql Cluster,解决读写分离问题已经十分成熟。

2. MySql Partitioning,可以将一个大表拆分为很多小表,提高访问速度,但是限制与这些小表必须在同一台服务器上。

3. HSCALESpock Proxy都是建立与MySql Proxy基础上的开源项目,MySql Proxy采用LUA脚本来进行数据分区。

4. HiveDBMySql分区框架的java实现。

5. 另外还有HyperTable,HBase,BigTable等等。

Netblog几个需求:

1.              需要灵活的可扩展性。对于存储增加减少需要能够动态的及时实施,因为数据量增长很快,如果策略会导致数据失效或者部署需要重新启动,则就不能满足需求。

2.              不想引入全新的数据层和与原有系统不匹配的抽象层,因为并不是所有数据都需要切分,仅仅在需要的情况下通过API的方式来透明切分数据。

3.              分区的主键需要可配置。

4.              需要封装API,对开发人员透明数据切分的工作。

      Netblog Sharding的实现




    上图就是
NetblogSharding的结构图,主要分成了三部分:ShardSharddbSharddbhostShard就是一个表,里面存放了部分用户数据。Sharddb是一个表的组合就像一个虚拟的DBSharddbhost是具体的存储分区。ShardSharddb可以根据负载的情况被移动到不同的host中去。

       对于Shard的管理,Netblog采用的是目录查询的管理方式。目录信息也存储在MySql中,同时会通过互备,Memcache,集群来确保安全性和高效性。

       Shard Table API采用了多一层的映射模式来适合各种不同属性的查询情况。数据和记录在数据库中存储除了UserID以外还有对应的ItemIDItemID的作用就是定义了具体获取数据的字段信息,例如关联照片表时,ItemID就是PhotoId,关联视频表时,ItemID就是videoID

       一个获取用户id26博客信息的范例:

1Where is user 26?

   User 26 is on shard 5.

2On shard 5; Give me all the $blogIDs ($itemIDs) of user 26.

That user's $blogIDs are: array(10,12,30);

3On shard 5; Give me all details about the items array(10,12,30) of user 26.

Those items are: array(array('title' => "foo", 'message' => "bar"), array('title' => "milk", 'message' => "cow"));

对于Shard的管理Netblog采取的措施主要有这些:

1. 服务器之间的负载均衡根据用户数,数据库文件大小,读写次数,cpu load等等作为参数来监控和维护。根据最后的结果来迁移数据和分流数据。

2. 移动数据时会监控用户是否在操作数据,防止不一致性。

3. 对于数据库的可用性,采用集群,master-mastermaster-slave复制等手段。

最后通过三种技术来解决三个问题:

1. Memcached解决shard多次查询的效率问题。

根据上面的范例可以看到,一次查询现在被分割成为了三部分:shard查询,item查询,最终结果查询。通过memcached可以缓存三部分内容,由前到后数据的稳定性以及命中率逐渐降低,同时通过结合有效期(内容存储时效)和修改更新机制(add,update,delete触发缓存更新),可以极大地解决效率问题。甚至通过缓存足够信息减少大量的数据库交互。

2. 并行计算处理。

由于数据的分拆,有时候需要得到对于多Shard数据处理的结果汇总,因此就会将一个请求分拆为多个请求,分别交由多个服务器处理,最后将结果汇总。(类似于Map-reduce

3. 采用Sphinx全文搜索引擎解决多数据分区数据汇总查询,例如察看网站用户的最新更新情况或者最热门日至。这个采用单独系统部署,通过建立全局信息索引,来查询数据情况。

以上是技术上的全部内容,作者在最后的几个观点十分值得学习,同时也不仅仅限于数据切分,任何框架设计都可以参考。

“Don't do it, if you don't need to!" (37signals.com)

"Shard early and often!" (startuplessonslearned.blogspot.com)

看起来矛盾的两句话,却是说出了对于数据切分的一些考虑。

首先在没有必要的情况下就不要考虑数据切分,切分带来的复杂性直接影响可用性,可维护性和一致性。在能够采用Scale up的情况下,可以选择Scale up降低框架复杂度。

另一方面,如果发现了业务增长情况出现必须要扩展的趋势,那么就要尽早着手去实施和规划扩展的工作,并且在切分和扩展过程中要不断地去优化和重构。

后话:

       其实任何架构设计首要就是简单直接,不过度设计,不滥竽充数。其实就是要平衡好:可用性、高效性、一致性、可扩展性这四者之间的关系。良性循环、应时应事作出取舍和折中。用的好要比学会用更重要,更关键。

posted @ 2009-03-04 00:58 岑文初 阅读(1989) | 评论 (2)编辑 收藏

 

目标:

         根据四方面的配置调整,观察SIP5.5在高并发下的性能情况。

         由于SIP接收的请求都是服务型处理请求,因此认为Apache+Jboss只会带来多余的转发损耗,所以正好这次也作一个验证,看看Apache+JBoss是否不适合于这种纯动态服务请求的情况。 
        四方面环境比较:

1. JBoss APR模式与Http1.1模式性能差异。(确切来说应该是JBoss内置Tomcat采用APR的情况)。

2. 是否采用Apache+JBossApache不同的转发模块带来的性能差异。

3. Memcached Client版本优化后对性能影响。

4. ISP有不同延时对于SIP的性能影响。

前置条件:

SIP版本5.5,并发用户600ISP默认耗时20msApache配置和JBoss WebContainer配置,一些优化配置参见附加信息。

最终结果:

       SIP采用Apache(Mod_jk)+JBoss(APR)+Cache2.4.2,具体配置参见附加信息。

测试结果表格:

       详细的测试报告可以参看:http://spreadsheets.google.com/pub?key=pcsQ9Wm01cIEjjQcistPNDg

JBoss配置差异测试比较:

 

Apache(2.0.52)配置

JBoss(4.2.1)配置

Cache Client Version

TPS

TPS区间

APR

2.4.2

1705

1600-1900

HTTP1.1

2.4.2

1615

1550-1700

Mod_jk(1.2.27)

HTTP1.1

2.4.2

2090

1800-2800

Mod_jk(1.2.27)

APR

2.4.2

3223

3200-3400

补充:

         配置成为Http1.1模式的两种情况下,测试结果TPS波动频率很高,在Mod_jk模式下波动幅度也很大。

1.         可以证实在非APR模式和高并发的情况下Web容器处理请求能力不稳定,同时也直接影响到了SIP的性能。

2.         在测试中发现不采用APR模式的情况下,Web容器会消耗大量的socket连接通道。

Apache模块差异测试比较:

 

Apache(2.0.52)配置

JBoss(4.2.1)配置

Cache Client Version

TPS

TPS区间

APR

2.4.2

1705

1600-1900

Mod_jk(1.2.27)

APR

2.4.2

3223

3200-3400

Weblogic.so

APR

2.4.2

1033

350-1400

补充:

         Weblogic.so模块是以前系统遗留的http请求转发模块。在测试过程中Weblogic模块的测试中波动频率和幅度都很大。根据测试结果可以看出:

1.       APR模式下,Apache+JBoss对于SIP这种无静态资源访问,纯API性质的服务来说依旧会有比较好的优化效果,特别是在接受请求环节。(不论是TPS还是TPS波动区间和频率都有很好的表现)

2.       Weblogic.so这个模块性能绝对不行,稳定性极差。

Cache客户端版本差异测试比较:

 

Apache(2.0.52)配置

JBoss(4.2.1)配置

Cache Client Version

TPS

TPS区间

APR

2.4.2

1705

1600-1900

APR

2.4

1615

1550-1700

Mod_jk(1.2.27)

APR

2.4.2

3223

3200-3400

Mod_jk(1.2.27)

APR

2.4

2485

2650-2800

补充:

         2.4.22.4版本在单独测试的环境下:500并发用户,每个并发用户1000getset,性能相差40%左右。

         上面测试结果可以看出:

1.    在无apache时,性能有所提升,但不明显,而在有apache时,性能大幅提升,证明在无apache的情况下,memcache客户端已经不是性能瓶颈,因此替换版本效果不大,在http请求处理性能大幅提升的情况下,memcache客户端性能优化的优势就得到了体现。

2.    在测试中也发现Apache + JBoss波动频率和区间都小于其他几个测试情况,图形十分平稳,证明处理请求不是系统瓶颈。

ISP响应时间差异测试比较:

 

Apache(2.0.52)配置

JBoss(4.2.1)配置

Cache Client Version

ISP响应时间(ms)

TPS

TPS区间

Mod_jk(1.2.27)

APR

2.4.2

20

3223

3200-3400

Mod_jk(1.2.27)

APR

2.4.2

110

Mod_jk(1.2.27)

APR

2.4.2

900

测试优化总结:

1. 不要认为内存使用无关性能。现在很对开发者认为内存申请分配是由gvm来管理,但是内存是否合理使用很可能会影响互联网应用的高并发下性能。GC带来的系统短暂停滞会在高并发下影响性能。

2. 使用java的方法需要有足够的“理由”和“度”。Java1.5以后对concurrent方面做了很不错的支持,但是这些并发处理毕竟会消耗资源,因此在能够避免频繁使用的情况下尽量优化流程。在一些简单的场景下,是否有必要使用一些比较耗时的方法,例如split,用起来很方便,但是在设计底层通信操作的时候还是分秒必争(JProfiler看看消耗的时间占用的比例以及调用的次数),用一些自己简单的方式替换。

3. 眼见未必为实,测试才得真知。在SIP5.5中考虑连接后端ISP方式由HttpURLConnection替换成为HttpClient,感觉HttpClient的开发模式更加容易认为是共享传输通道(Get,Post都单独作为包来交由HttpClient单个实例),虽然看到HttpURLConnection说明中提到会共享通道。结果一压,HttpClient根本上不去,原因是构建这些Get,Post本身也很耗时,同时HttpURLConnection底层共享优化的也很不错。HttpClient的优势还是在于去构建简单的客户端,能够处理附加cookies等额外需求。

4. 链式处理的情况下,上下文中共享信息减少数据频繁访问缓存。

5. 操作系统配置以及Web容器的配置会直接影响应用的性能,特别是一些Socket交互比较频繁,会有很大并发的应用。具体的配置可以参见最后的说明。

6. APR模式对于服务器处理能力有很大的影响,EpollUnix socket都会来带很大的性能提高(降低资源消耗)。

7. 在过去谈过异步Servlet的方式(Servlet3.0的特性之一),但是JBoss5测试下来看,稳定性并不好,并且可能会有一些并发问题。

8. 先列出性能瓶颈可能点,然后分别对已经优化的模块进行单独测试,最后整合并且通过多场景测试来验证优化结果。


附加信息:

JBoss Web Container配置:

<Connector port="8128" address="${jboss.bind.address}"   

         maxThreads="1024" maxHttpHeaderSize="8192"

         emptySessionPath="true" protocol="HTTP/1.1"

         enableLookups="false" redirectPort="8443" acceptCount="1024"

         connectionTimeout="20000" disableUploadTimeout="true" useBodyEncodingForURI="true"/>

Apache work的配置:

Keep alive off

<IfModule worker.c>

ServerLimit          80

ThreadLimit          128

StartServers         10

MaxClients           8000

MinSpareThreads      64

MaxSpareThreads      800

ThreadsPerChild      100

MaxRequestsPerChild 10000

</IfModule>

Linux配置信息:

执行:vi /etc/sysctl.conf   

添加一行:net.ipv4.ip_local_port_range = 1024 65535

       再执行:sysctl -p

         更改ulimit –n属性,可用端口数,还有ip_conntrack_max 

APR

       Tomcat优化了IO(sendfile,epoll,OpenSSL)。操作系统的一些函数(随机数的产生,系统状态的获取等),本地进程优化(共享内存,NT的管道,UnixSocket)Tomcat有配置监听器直接会检测APR模块是否存在,在bin目录下建立native目录,并且放置对应的so或则dll即可。

posted @ 2009-03-03 20:14 岑文初 阅读(1812) | 评论 (2)编辑 收藏

    在大型网站中常常会遇到大流量的数据输出问题,过于频繁的输出到DB、文件、第三方系统都会带来不稳定性和低效率。因此需要采用一定的方式来解决这个问题,其实这部分内容的简单处理框架早就用在实际项目中,不过今天正好有外部的朋友问起我,我就整理了一下作为google的开源代码放上去了,这里也简单介绍一下,有兴趣的朋友可以去看看,最好是能够给一些建议。

  

场景:

         应用频繁访问接口服务器,需要控制每个应用在可配置时间段内(例如一分钟)对于某一服务的访问次数,同时需要记录每一次访问内容到数据库中。

几个点:

1. 高并发情况下,集群服务器需要全局计数。(需要将更新和判断作为原子操作,而非两阶段操作,保证高并发事务)

2. 异步日志批量输出。防止高频率访问第三方系统(DB,本地IO),提高性能。

3. 采用黑名单简化计数器判断。

1,3通过memcache就可以实现,如果需要使用客户端可以看看google code上的:http://code.google.com/p/memcache-client-forjava/

这里主要在说一下2,在很多场景中都会有这样的需求,一些需要输出到DB或者文件的内容需要缓存起来异步批量操作,提高性能也降低对于第三方系统的压力。大致设计结构图如下:

 

 自上而下来看,ThreadA,B,C都是程序中其他模块的线程,他们需要输出记录到数据库或者DB中。当有数据到达需要输出时,仅仅只是将数据放入阻塞队列中,而有一个消费者线程池中的线程发现队列中有数据就将数据写入其中某一个线程的数据分页中(每一个线程维护一个自己的内存分页,当页满或者到达了配置的输出间隔时间以后就将页内数据交给输出线程池中的输出线程完成批量数据输出)。


        

下面是三个类图,囊括了这个小工具框架的所有类:

 

         上图是对外提供的异步输出模板,其他模块可以直接使用模板来输出数据。

上图是异步输出器包,是异步输出模板的内置逻辑实现,其他线程直接使用异步输出模板来输出记录。

         上图是消费者和输出线程的接口和默认实现类,可以替换及扩展。

整个框架基本都可以通过配置文件扩展每一个角色(异步输出类,消费者,写出者),扩展方式就是通过在classpath下增加目录META-INF/services/然后将需要扩展的接口作为文件名称,内容就是接口的实现类,这样既可扩展和替换任何一个角色的具体实现。

具体的代码和测试用例可以去http://code.google.com/p/asynwriter/ 下载。

posted @ 2009-02-12 21:09 岑文初 阅读(2459) | 评论 (5)编辑 收藏

     摘要: Author:文初 Email:wenchu.cenwc@alibaba-inc.com Blog:http://blog.csdn.net/cenwenchu79            什么是Dynamo? Dynamo是Amazon的高效Key-Value存储基础组件(类似于现在被广泛应用的Mem...  阅读全文
posted @ 2009-01-13 08:06 岑文初 阅读(2579) | 评论 (0)编辑 收藏

该文前半部分在程序员1月刊上,由于杂志篇幅有限,因此后半部分没有被刊登,这里就在blog上增加一下:

 

服务集成平台

经过前面的介绍和实践两部分,在Open API在概念和实际操作上都有了一定的理解和认识,这里就再谈谈服务集成平台的作用、角色和定位。这里大致描述一下集成平台当前的实现点,这些实现点也就是服务集成平台的价值所在。

服务集成平台(SIP)的角色和作用



3 SIP Role

ISV(独立软件开发商)最关心什么?

1.       服务资源是否丰富。这关系着是否能够创新。

2.       服务质量是否有保证。这关系着是否能够满足用户最基本的需求。

3.       开发集成是否便利。这关系着开发成本。

ISP(独立服务提供商)最关心什么?

1.       服务安全性是否可靠。如果损害到自身或者用户利益,则就失去了原来开放的初衷。

2.       是否有足够多的应用开发者使用服务。

3.       服务的非业务性需求是否可以满足。(服务监控告警,计费,统计分析等)

SIP是连接ISVISP的“桥梁”。它能解决什么双方最关心的什么问题?

1.       丰富的ISV资源以及丰富的ISP资源。这其实是一个良性循环的过程,就好比一个建材市场,买家和卖家数量远远要比在单独一家实体店中多,从淘宝的B2C模式就可以看出,市场大了以后传统的“大鳄”都要聚集人气。

2.       统一安全标准和多种控制策略,即保证了ISP的安全,又能够让ISV开发起来方便。在前面实践过程中可以很明显的看到,众多的应用id,各自的安全流程,让开发者Mash up无形中增加了很大的开发成本和维护成本。

3.       SIP目的就是让ISP专注于业务服务的开发,而将非业务性的需求,如安全,服务监控预警,日志分析统计,计费,社区等都一揽子解决。这样既解决了ISP的第三个问题,同时也为ISV关心的服务质量无形中作了促进。

在年初的时候,分析和研究国外的Open API时,感觉类似于SIP形态的产品在国外还没有,大家都是各做各的,但这阵子回过头来看,YouTubeGoogle开放平台,FlickrYahoo开放平台,这些平台都属于SIP形态的产品,而且Google要比当前我们做的SIP还要更进一步,那就是数据格式规范化(GData),而SIP当前仅仅只是做到流程规范化。

那是否任何公司都适合去做SIP这类形态的平台呢,这不仅仅是技术问题,还是一个资源的问题。阿里巴巴每一家子公司都有实力去做一个这样的开放平台,但各自独做一套的结果就是资源浪费,同时技术没有得到积累(SIP技术积累是在ISV和不同形态的ISP接入中逐渐产生的),最重要的是这些子公司其实真正需要关注的是如何将业务和数据开放给开发者,吸引更多的开发者来构建出围绕Open API的创新应用,最大化数据和服务的商业价值。

服务集成平台功能特性

服务路由

         服务集成平台就好比硬件里面的“路由器”,服务调用者只需要提供服务注册的名称,就可以调用到某一个服务提供商提供的服务,对于调用者来说无需关心此服务的地址以及提供者。

         根据现阶段的服务集成来看,主要分成四类的服务路由,同步服务路由,异步服务路由,订阅服务路由,大数据量上传服务。同步服务路由就是普通的Http无状态单次请求和响应。异步服务路由应用于服务提供商提供的服务无法在当时处理完毕,先返回一个请求响应,当服务处理结束以后再将服务处理结果返回给服务调用者(短信业务就是一种异步服务)。订阅服务和互联网上RSS之类的订阅十分相似,服务调用者只需要订阅服务即可获得服务提供商推送的服务内容。大数据量上传服务其实也是属于同步服务,但是由于消耗资源和性能压力不同,因此被单独作优化处理。

         对于服务形态不同,服务路由需要支持REST风格的服务路由和类REST风格服务的路由,但对于开发者来说,调用的方式都是用服务名称来路由。

正式环境和测试环境的隔离和切换

         对于服务开发者来说,在应用开发期间需要有外部测试环境的支持,在商用以后需要有正式环境支持,同时两个环境的切换需要尽量的简单。

         服务集成平台支持服务提供商提供测试环境和正式环境的不同服务路由,同时两套环境切换成本低。当服务提供商只有一套环境的时候可以根据策略配置的不同,对调用者访问的范围,频度,次数作限制,保证测试服务不影响正式服务。

安全

         提供对应用身份认证以及服务提供商身份认证的支持,采用多种数字签名算法实现基本的身份认证,支持IP白名单和动态算法更新后端插件提供更高级别的服务安全保证。

         细化了用户授权流程。对于用户Token细分为请求级别和会话级别,同时对于会话级别的权限操作,失效时间可根据服务提供商的配置自定义。同时平台托管维护每个应用每个用户的多身份绑定Token,降低服务提供商开发维护成本。

         服务提供商可配置服务访问量控制和频率控制(所有应用或者单个应用)。也支持配置需要订购才可以使用的服务(有限次数订购,无限次数订购)。

         支持多级服务安全策略配置,为服务配置(无授权,应用授权,用户授权,可选用户授权)等多种级别的安全策略。注:可选用户授权是指如果没有被用户授权的情况下使用接口将返回部分公开数据,而在用户授权情况下使用则返回全部的私有和公开数据。

         对服务提供商多级分类,提供不同的安全策略组合。

监控与告警

         服务使用者服务使用出错监控和告警。

服务提供商提供的服务可用性,超时状况的监控和告警。

服务集成平台服务处理状况,内部模块运行状况监控和告警。

日志采集与统计分析

         高并发下日志采集异步处理,采集服务正常访问和异常访问日志,采集用户绑定类,异步服务类,平台内部服务类等特殊日志。

         每日,每周,每月访问日志统计分析,基础报表和趋势分析图的创建。

         支持分析结果预警配置。

         历史统计数据管理和归档。

 

平台内置服务

         平台为服务提供商以及服务调用者提供了平台级别的服务,为开发商和服务提供者获取平台业务数据以及运行期配置安全策略提供方便。

         平台提供一系列平台模块监控、配置、重置服务,支持在线问题查找、定位、解决的一套机制。

非功能性需求(当前情况)

         性能:压力测试单机500并发用户1600+tps,多机处理能力线性增长。

         模块化:内部处理模块化结构,支持运行期配置、装载、卸载。

容错:服务集成平台核心数据都缓存在Memcache中,因此Memcache集群以及容错策略的扩展都为平台稳定和容错作了基础保证。

配套支持

         通过ISV,ISP,Admin三个Portal,使开发者,服务提供商以及后台维护人员能够自主维护基本信息和查看相关数据。

         为开发者提供社区,测试区的支持,并且提供开发工具包和文档,方便开发。

扩展集成

         支持不同平台的服务集成。支持Google,Flickr,Yahoo等等不同的服务平台的服务集成,当前还没有完全将安全体系集成,只能够支持安全流程透传,消息数据完整过滤。

服务集成平台的一些发展趋势

1.       数据集成和流程集成

当前很多服务都是基础的数据型服务,使用者通过数据筛选获取相应的数据,然后展现给用户,这些服务的集成相对来说功能比较单一,流程也不复杂。但随着服务提供商的发展,数据类型服务将会作为基础服务的一部分,而越来越多业务处理型服务会成为使用者的首选,此时,如何让服务和服务之间数据互通,服务可以通过一定的描述编排,就会变得越来越有价值,就如前面提到的,Google采用GData作为数据规范格式,同时对于安全流程的统一制定,为第二阶段的集成打下了基础。

2.       服务基础平台间的互通

最近Open ID也再次由于各大网站的支持而被人们广泛关注,在未来Open API体系中,伴随着Open ID的发展,服务基础平台之间的服务互通也将会变得越来越容易,但是数据的安全性也会对每个服务平台要求更高。

3.       服务集成平台的层次化

在这篇文章的介绍中仅仅介绍的是最基础的Open APIMash up,其实当前已经有更高层次的Mash up被广为使用,JavaScriptActionScriptFlash/Flex这些技术使得展现更为灵活和丰富。因此未来的服务集成平台将会层次化,从数据集成到流程集成到UI集成,会成为一套自下而上的解决方案,适合各种场景的裁剪选择。

Open API的一些思索和感触

不同角色,不同收获

平台开发者:

         这是我的本职工作和角色。当淘宝等服务提供商的服务接上来以后我就要为它的安全和稳定负责。当SIP一旦出现问题,那么服务提供商和软件开发商将都无法再正常工作,套用蜘蛛侠的一句话:“能力越大,责任越大”。作平台的尤为如此。

服务提供商:

服务提供商接触的最多的就是淘宝的同学,首先看到的就是做一个服务提供商很不容易,要把原有系统中复杂的逻辑抽象出来并不是抽象一个公用函数那么简单,同时对于模块化,边界性,容错性方面的要求要远远高于封闭系统开发本身,因为你现在要面对的是倍于原有访问量上百甚至上千的调用者,对任何一个小疏漏都可能带来灾难性的影响。

软件开发商:

         在写这个文档以前,最多也就是写几个测试的Demo来测试SIP环境中的服务,在淘宝API讨论群中会看到很多新的或者老的ISV在抱怨或者询问一些自己觉得很简单的问题(例如签名等等),同时在监控中也看到很多及其简单错误统计数都会有很高的比例。但是经历过这次对于各种各样国内国外的API的开发,让我深刻体会到了开发者的一些痛苦(当然我没有去使用各个开发社区的第三方语言开发包,这也增加部分的开发难度),我也曾因为签名问题在豆瓣API测试的时候折腾了半天,在调试Google Calendar的时候不得不跟踪开发包代码才找到了一些隐晦的设置通过测试。其实Open API在国内国外都没有完全可以称得上成熟,因此开发者其实是最容易受到影响的。同时他们面对着最难应付的客户,平台或者服务提供商出现问题,客户最先抱怨的也是服务开发商,因此作为平台开发者和ISP其实都要给与一定的支持和帮助,这样才会走向更好的良性循环。

其实上面说的那些无非都是大家最长说的换位思考,一个新兴的开发模式需要各方合作才会走向良好的发展方向。

创意就是财富

         记得前一阵子支付宝能够在上海交水电费引起了很多人关注,杭州本地论坛中都有很多人在问:“什么时候杭州能够也用支付宝交水电费就好了”。其实如果开放了支付服务和水电缴费服务,这种Mash up的应用又有什么难的呢?你都可以直接每个自然月通过Google Calendar设置好日程安排,自动缴完所有的费用,然后短信提示一下即可。未来当各行各业发现了自身资源的潜在价值以后,以服务的方式通过平台互通,那么创意就是财富。

posted @ 2009-01-11 21:22 岑文初 阅读(2239) | 评论 (1)编辑 收藏

     摘要: Author:文初 Email:wenchu.cenwc@alibaba-inc.com Blog:http://blog.csdn.net/cenwenchu79 问题凸现:        年关到了,商家忙着促销,网站忙着推广,阿里软件的服务集成平台也面临第一次多方大规模的压力考验,根据5.3版本的压力测试结果,估算了一下现有的...  阅读全文
posted @ 2009-01-11 21:13 岑文初 阅读(2715) | 评论 (3)编辑 收藏

    应该是去年的年初,我受到普元公司的邀请去参加了一次SCA、SOA的技术交流会,当时也是自己第一次去和那么多陌生的朋友交流技术心得,同时也被普元公司的这种纯技术性的交流方式所打动,也在想哪一天阿里巴巴也能够举办一次这样的小规模有针对性地技术交流会那会让我们这些技术人员收益菲浅。一年后的今天,当老大问我有个这样的会议是否要参加的时候,自己毫不犹豫地报了名,虽然看起来和自己专注的工作不是很相关,但是还是那个想法:首先不了解是无法知道是否和自己相关与否,其次就算不相关,多学多听,触类旁通的技术延展只会给自己带来更多的想象空间和创新思维。

    按照会议安排,早晨有两个讲座,下午有四个讲座,每个讲座1个小时左右。第一个出场的是腾讯的安全中心总监杨勇,整个演讲很轻松,首先是对腾讯的整体产品结构和背景作了一下阐述,然后就从安全中心这个整体来讲述安全对于腾讯的意义,如何实施以及一些流程的制定。没有过多的牵涉安全问题的细节,着重是讲述了安全中心面临的四个方面的问题,以及通过什么手段去解决。这其实和他本身所处的工作职责来说相符合,如果仅仅只是来讲某一个安全技术应用,那么就有些太过狭隘了。不过在提问的时候一个问题的回答让我还是留有一些印象的,主持人收集到一个问题:“腾迅安全中心的建设初期遇到的最迫切需要解决的问题是什么?”,他回答道:“其实腾讯安全中心从建设初期到现在一直面临各种迫切的问题,只是随着时间的不同而不同的演变,最早的协议安全到客户端安全到奥运期间的信息安全都是一个发展的阶段”(因为没有ppt以及记录,因此描述的可能不太准确)。但是这个思想任何技术行业都是一样的,时代不同关注不同,需要解决的问题也是在发展的。

   第二个议题是Discuz的剑心带来的“web应用程序中的字符集攻击”,这个演讲就相对来说比较注重专业细节方面的阐述。作为互联网应用开发者,使用Java的人第一堂课就是中文乱码,很多人只看到如何去配置或者写一点转换语句就可以解决,但是对于编码方式就不求甚解,ISO-8859-1,GB2312,UTF-8,UTF-16区别是什么,为什么会引起乱码。其实了解了编码的原理就很能够解释如何会产生乱码,同时产生乱码的时候也可以根据乱码的情况了解可能是因为什么编码转化造成的(阿里巴巴的宝宝写了一篇很详细的文章说了这个问题,进入公司以后我也是看了那片文章才系统地对编码方式做了完整的了解,以前都是碎片)。不过今天听了这个演讲,到让我知道了原来编码方式也被人用来攻击。其实基本的思想主要就是一点:由于信息转发中对于不同编码解析的方式不同或者是过滤不同,导致出现一些漏洞。通俗的比喻就是刺杀秦始皇的图穷匕见,侍卫就好比第一层把关的信息转发者认为着幅图没有威胁,但是真的按照刺客的处理方式那么就是一个最好的攻击性工具。记得我在和同事探讨REST对于Http协议的使用时说最重要的就是REST不再使用Http协议作为传输承载协议而是作为业务协议,那么解析业务的时候究竟是分析协议中指定的编码方式还是内容中的编码方式,结果会大不一样,同时作为安全人员的角度来看,这也会存在一种安全隐患。所以其实任何一种错误都可以被利用作为攻击的手段。

    下午的议题一共有四个,虽然时间比较长一直连续讲到6点多,但是就像主持人讲的,每一个人都“坚持”下来了,呵呵,当然坚持并不是因为不好听,而是做在那儿听比写代码要累很多,当然讲课的同学们也是十分辛苦的。下午第一个演讲的是team509的创始人吴石,讲的主题是“部分软件安全的思考”,内容专业化很强,对很多比较底层的安全问题(操作系统等)作了一些介绍,当然对于我这个门外汉只能听懂个大概意思,不过还是有所了解那些名词的意思到底是什么。第二个是微软的大牛蛙同学,也是安全领域专家讲述了一下微软的SDL(Security Development Lifecycle),望名生意,安全实施的流程化。第三个演讲是两位同学做的,也是我下午听得比较有感触地,先是网名余弦(钟晨鸣)北京知道创宇信息技术公司的安全研究员,讲的是CSRF蠕虫技术,从一个黑客的角度来阐述CSRF的原理以及危害性。这部分比较技术化一些,但是由于和我关注的Web安全也比较相关一些,所以听起来也不是比较迷糊。虽然听着他讲CSRF,但是其实我脑子里面已经在考虑关于Open API的一些安全问题。其实在阿里软件承载淘宝的API过程中,对于客户端的安全问题就一直都在谈,但是对于SIP来说总是鞭长莫及,因为服务集成平台只会保障ISV和ISP之间的信息交互的真实性,但是用户是否由于ISV的技术问题导致信息伪造提交,那么就不得而知,但是最后表现出来的结果就是ISP的Open API计划为ISP带来了更多的安全隐患,也就是说原来淘宝一家漏洞,以后可能会是千千万万家ISV的漏洞,其实这也是上面几个演讲提到的合作风险问题,第三方的技术能力不得而知,同时产生的风险也会很难控制。其实从这里也多多少少看出来为什么FaceBook,myspace,最早对于用户安全隐私数据的开放不仅仅是开放了数据API,同时也会有整一套上层框架支持,其实也是出于开发者能力不足引起隐私数据被恶意修改而作的防护措施。那么现在Open 用户的数据特别是以后涉及到金额的api如何保证isv不欺诈,isv不被欺骗,这可能是后续需要更加重视的问题。同时,在听了CSRF的攻击中谈到的对于资源定位猜测以及操作的时候,让我对REST的风格又打了一个冷颤,REST对于资源的规划和定位十分容易,但是这也为这类攻击提供了便利,同时对于资源操作依赖于Http协议,也会让资源的安全性打了折扣,这需要对Open API开发人员做更多的安全工作指导,或者提供安全框架来防范Open API可能会产生的安全漏洞。紧接着后面的演讲是北京知道创宇信息技术公司的创始人赵伟,应该是业界比较资深的专家了,本来的议题是“恶意网站检测”,不过他还是讲了他这些年来的一些经历以及安全领域的黑色产业链的问题。平时这方面关注的不多,不过今天这一番交流,让我对安全领域的发展以及现况有所了解,甚至有时候就觉得现在上网就算装了一大堆东西还是感觉在“裸奔”。最后一个议题是51.com的郑歆炜讲的“运维安全经验谈”,总结了运维所面对的问题以及解决方案,协调,沟通,总结,知识库,其实这些对于开发人员来说何尝不是呢。最后小黑作了一个简短的总结,同时预报了明天他会做一次附加的构建安全Web架构的讲座,期待明天半天的研讨会和附加讲座。

    好久没有踏踏实实地坐着好好听课了,这次一天半的学习对于自己来说也算是一次新知识的扫盲,同时也为自己后续的工作可能存在的问题或者可以借鉴的知识作一个铺垫。

posted @ 2008-12-17 22:32 岑文初 阅读(1835) | 评论 (1)编辑 收藏

Author:文初

Blog: http://blog.csdn.net/cenwenchu79/

问题

         小丹同学在旺旺上问我是否可以用Memcached实现简易消息中间件类似的功能。觉得这个需求很奇怪,就问了一下具体的应用场景,然后小丹就上来和我具体的谈了究竟需求是什么。其实小丹的应用场景是这样的:客户需要分析一些业务数据,但是业务数据又是很庞大的,在原有系统每天晚上都有一次日分析,将业务数据分析并且归档,但是如果要产生即时分析的效果,用原有系统无法实现,因为当天的数据内容没有被分析,同时如果即时的去分析并且累加到历史分析数据上,性能也不能满足需求,因此考虑通过消息机制来实现异步分析,至于异步处理的时间容忍度,可以通过配置来实现,同时希望异步分析是可线性扩展的,支持集群,提高效率。为什么不直接使用中间件呢?高并发的稳定性,维护的成本,性能要求,使用成本,这些直接就排出了直接去使用中间件的想法。

起始方案的讨论

         在回到小丹最初提到是否可以通过Memcached来实现类似于简易消息中间件的问题上来。首先是否将消息队列作为一个对象保存在Memcached中,这种做法明显不支持高并发的情况,因为Cache本身的get,put无法保证事务。在Memcached中只有计数器是支持高并发的操作,因此考虑是否使用计数器并且按照一定规则来生成key,通过对计数器的增减来让不同消费者获取到不同的消息,这种机制最大的问题在于:1.轮询的压力不小(小丹希望是订阅者模式,Push过去而不是Pull)。2.计数器增减不论怎么做都实现的是栈而不是队列。那么是否使用我扩展的MemcachedKeySet,这点我自己就反对了,这个功能效率很低,而且对于Memcached本身在高并发下操作是否有影响还不得而知。问题越绕越走向死胡同了。

方案的转变

         转换思路,重新分析小丹的需求,究竟哪几点是他真实需要的:1.通过消息方式解耦Web应用和业务分析处理。2.消息必须较为及时的传递到业务分析模块。3.业务分析模块需要支持集群方式线性扩展性能。实现这些需求真的需要简单的消息中间件或者集中式存储么?看看下图的结构:





         从图上可以看出这么几个问题:1.消息中间件本身处于单点,如果需要扩展或者消息本地化增加了复杂度。2.对于消息的获取是采用push还是pull,如果是push那么需要中间件支持订阅者的维护,如果是pull,则需要考虑并发以及性能问题。3.消息的即时性,这个还是依赖于消息中间件的实现机制。总的来说,如果要通过集中式缓存方式实现消息中间件的简单功能,还是有很多问题。那是否直接使用消息中间件的第三方支持呢,其实又回到了最初提出的不使用的缘由。这么设计是否太复杂呢?

回过头来看看Memcached的使用情况,突然发现其实事情可以简单来说,我记得写过一些说明来解释为什么我说Memcached是集中式缓存而不是分布式缓存,其实是客户端的分发算法让很多人觉得好像分布了数据和可无限扩展。其实这种技术结合Hadoop HDFS的部分设计思路,可以给出一个比较好的解决方案。看看下图的结构设计:



上图去掉了消息中间件的角色,增加了Asyn Processor Manager的角色,但是此角色也可以去掉,更为简化的实现需求,增加Asyn Processor Manager的功能仅仅是为了提供动态增减Asyn Processor的功能。具体说一下流程:

1.              Web应用启动时,读取本地配置获取Asyn Processor列表载入内存,同时根据Asyn Processor Manager的配置去发起请求获取Asyn Processor最新的可用列表(如果无法获取,则以本地的为准)。

2.              Web应用根据本地实现的分发算法(最简单就是采用key hash),来选择Asyn Processor,发送请求处理的消息。

3.              如果Asyn Processor Manager不存在,Web应用也可以实现定时发起query status请求来确认Asyn Processor的存活状态,并且更新,保证消息的正常发送。如果Asyn Processor Manager存在,那么确认Asyn Processor状态是否存活可以由Asyn Processor Manager来做(Push或者Pull),而Web应用则可以使用对Asyn Processor Manager的定时查询来获得最新的Asyn Processor列表。

4.              Asyn Processor Manager可以提供增加和删除Asyn Processor的接口,这样就可以支持Asyn Processor的增加和删除,但也正因为Asyn Processor Manager的单点易于注册和管理Asyn Processor,也增加了单点的风险,因此每一台Web应用需要对Asyn Processor Manager不可用作好本地化配置的后备策略。

5.              使用Http协议作为消息传输协议,这样避免SA去维护端口的麻烦,同时也能够充分利用REST的方式来完成业务逻辑(Options方法可以用于心跳,PutDelete可以用于Processor的增减(设置Http Head认证方式即可解决安全问题),Get方式获取信息(xml,json等等格式可以很容易处理))。

上面的方案可以看出,如果去掉Asyn Processor Manager,其实方案很简化,就是每一个客户端有一层类似于Memcached客户端的分发机制,同时比Memcached免去了对于连接池维护的复杂性,仅仅只需要维护状态标示即可。

最后还嘱咐小丹对于Asyn Processor的设计需要合理化,这部分需要支持消息接受和处理的并行处理,提高Asyn Processor的处理能力,同时通过分页批量处理消息的方式减少对于DB的压力(当然需要根据具体的时效性设置消息页的大小以及消息页Flush的时间)。

后话

         上面的方案可能不是最好或者最优的,这里仅仅只是分享一下自己解决这个问题的一些心得。这此的方案讨论也走了一些弯路,有时候在做任何选择以前首先需要考虑的是到底自己需求是什么,然后再去考虑选择什么技术去实现。同时尽量还是那句老话”Make it Simple”,做技术的人总是喜欢做的很复杂,功能很强大,但是最后迷失了最初的目标,忙于去完善那些80%没有用的功能,却没有去做好那20%客户最Care的功能。化繁为简,见招拆招,才能四量拨千斤。
posted @ 2008-12-12 11:49 岑文初 阅读(1767) | 评论 (0)编辑 收藏

     今天收到InfoQ的推荐邮件,看了标题就很感兴趣,花了一些时间一看,果然是很不错的一个案例分析,同时也让自己学到了不少。大致罗列一下看后的一些文章重点内容。案例地址:http://www.infoq.com/cn/articles/webber-rest-workflow

    1.通过REST服务请求完成状态迁移,同时合理利用OPTIONS来查看资源操作权限。

    2.合理利用Http Heads来返回资源URI,以及通过ErrorCode来确定操作结果,并且作后处理。

    3.通过返回内容指定后续流程资源定位以及操作来实现流程化。

    4.通过Put报头的两种版本比较标示来防止并发修改。(其实也可以优化来做查询缓存的工作)

    5.使用Atom协议来发布和管理资源(Atom是最适合REST风格服务的数据源格式定义)

    6.URI模版的使用建议,慎用,如果确实能够有把握抽象资源定位。

    7.Auth可以通过轻量级Http Head中的Authentication或者WS-*的方式来实现。(也可以通过https实现)

    总的来说,其实整个案例分析下来以后,可以发现如果要使得服务流程化,那么前提就是数据交互格式统一(XML,Atom),然后利用Http协议作为服务协议而非承载协议,利用已有的操作约定,报文头部标示和返回的错误码来完成资源状态迁移的工作,同时通过在返回内容中嵌入流程化内容,使得整个流程可以贯穿。(这里还是简单的流程串联,其实如果在流程规则协议中增加复杂的逻辑定义,则可以实现更为强大的Web workflow)。

    但对于Open API或者类似的REST流程化业务来说,安全其实还是最大的挑战,特别是在对资源的访问控制权限上。当然可以类似于WS-Security提出一套较为安全成熟的方案,但是性能和使用简易性则会大打折扣,也失去了REST本身的优势。

posted @ 2008-12-10 11:32 岑文初 阅读(2155) | 评论 (2)编辑 收藏

仅列出标题
共12页: First 上一页 4 5 6 7 8 9 10 11 12 下一页