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

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

#

       两个半小时之后,我和BlueDavy大叔回到了杭州,一个忙碌而充实的周末就这么过去了。回到家已经1点多了,洗了个澡,精神又来了,想把这个充实的周末写下来,做个纪念。

缘起

       几周前,受到了普元的邀请,去三亚参加一个SOA的技术交流会,原本以为是因为在他们的论坛同时更新了一些文章所以被邀请一起去参加产品部活动,开始不是很想去,毕竟厂商出钱多半就是让你去听听他们的产品,一个周末飞来飞去的也累,但淘宝的BlueDavy大叔要去,顺便也叫我一起去热闹热闹,那么就决定去凑这个热闹。周五下班以后背了个包就直奔机场了,结果到了机场才发现办护照的时候身份证放在家里了,幸好机场还有个临时身份证明办理的便民业务,总算顺利的上了飞机。

人物

       第一天到场,第一个环节就是自我介绍,江湖中人就悉数登场了。Robbin,白衣,俞黎敏,小刚,杨戈,InfoQ中文站的主编霍泰稳和其他几个编辑,灰狐的主创:银狐999,程勇,普元的老大Chris以及普元的很多技术架构师牛人。陈勇的一句话就把我们这批人概括了一下,其实大家都是江湖中人,平时混各个堂口的,今天在普元召集的这么一次活动,有机会能够汇聚一起,谈天说地。

活动

       第一天上午有两个Topic关于SOA的市场价值,下午也有两个Topic关于SOA的企业架构,主讲的都是我们这些外部请来的人。上午下午有很多时间是自由讨论,每个人都有机会发表自己的意见,应该是算圆桌会议,所以你要发言随时随地都可以直接说,不需要顾忌什么,只要觉得要说,该说,就能说。这一天碰撞出不少火花。晚上边吃烧烤边聊,后面去沙滩上继续讨论技术圈的构建(不过这个到了最后也没有一个很好的解决方案)。

       第二天主要是普元分享了他们对于SOA技术的理解和具体的实现,从实际角度去展示了一个SOA的实实在在的成果。

收获

       其实这部分才是我要写得重点。一部分一部分来说吧。

首先是识人,这次在会上看到了很多都是自己曾经蛮佩服的国内开源技术论坛或者社区的创办者,其实从他们身上除了看到技术人员本身所特有的对于技术的追求更多的是对于新事物的理性的学习和分析。其实我一直觉得有一点对于一个架构师或者一个优秀的开发人员来说很重要的特质就是开放的去学习和接受新事物,有一个包容的心态去看待每一个陌生的新生事物,那么才能不断地进步。而排斥和固步自封,只能最后束缚了自己的脚步,慢慢的落后与他人。SOA这个概念提出来很多年了,炒作到实质性的转变也就在这一两年,具体的实践还需要后面几年的实施和验证。所以到场的每一位没有一个敢说自己完全了解SOA是什么,绝大部分都是抱着希望了解SOA实际上究竟是什么的想法而来。在讨论的过程中大家就很直白的说出了SOA是否还是一个虚概念,过去的EAI,BPM以及现在的EBI的区别。没有绝对的否定,只有探讨,学习和交流。我是第一认识他们,而他们之间已经相互很熟悉,但是和他们交流并不存在任何障碍,没有说牛人就是一个圈子,基本很难接触的那种感觉。我想也正是一种Open的心态才能让人进步得更快。

再则谈谈接触普元的朋友。和普元的朋友交流的机会不算很多,不过在第一天的休息的时候和几个主要的技术人员作了交流。因为其实我做SCA也还算比较早,所以对于SCA还是比较熟悉的,同时普元又是SCA中国区的推广者,所以和他们的架构师交流SCA很容易,不像在单位里面基本就是写好使用文档给开发者看,如果要谈具体的原理,基本没有人看过SCA规范,我是在SCA0.96版本上作了稳定版本的,现在解析使用Tuscany,再次组装是自己做的,一来早期的Tuscany对于两个级别的ServiceReference没有做级别控制,二来包括WS模块以及其他模块有很多的Bug,所以作了再次的开发和封装以适应业务开发的需求,其实在我们的研讨会上也说了,开源的缺点就是不稳定,不一定适应商业开发,如果商业开发的话,一般是需要稳定在某一个版本上。同时由于SCA本身的模块化特点,所以部分升级和开发十分方便。这些思想和概念以及遇到的问题和普元的开发团队遇到的一些问题都十分相似,特别是在WS上面,我一度也应为搞不定某些特殊的类型想去使用SDO,不过最后还是直接修复SCAWS组件搞定了,也就没有使用SDO。不过第二天的普元的服务管理和监控让我还是眼前一亮,这个对我来说可能也是后续在服务框架中需要考虑和搭建的,因为如果要采取Service API Mashup Platform,那么这部分内容势必是必须的。同时,普元的很多高手都是SCA组织的成员,这也是我蛮羡慕的,有机会还是要和他们多多学习和交流,虽然后续我的工作重点不是在SCA上了,不过ASF的工作以及SCA的持续学习也是自己“私活”之一。总的感觉来说,普元的技术人员虽然话不多,但是内功深厚,有很多可以去学习和切磋的。

最后就是关于SOA的一些感触。第二天中午最后一点时间是给大家讲关于这一天半的讨论和交流以后对于SOA的收获,由于时间关系,到我们的时候大家尽量简短发言,我也就说了自己的两点想法:1.先学在干在学在干。2.开发人员是我们的客户,不要让我们的客户因为使用我们的产品而痛苦不堪,应该让我们的客户在使用了产品以后提高了生产效率。第一点什么意思呢?在我做服务框架以前,先去研究过OSGI,然后又接触了SOA,最后接触到了SCA。花了1个多礼拜把SCA规范啃了几遍以后,找到了使用SCA实现服务框架的优势以后,就开始搞服务框架了,看了Tuscany的源码与设计思想,做了修改和封装,第一阶段的SCA服务框架就这么出来了。曾一度写了关于SCA如何让SOA落地的一些感想文章,但是后来自己都开始有些迷惑,究竟SOA是什么,仅仅就是用SCA去实现WS来互联互通么?这时候去看了很多关于SCASOA的资料和文章,突然发现又陷入到了一个开发者的角度去审视SOA的陷阱。很多人说SOA只是一种概念,没错,其实就是概念,那么这个概念有什么价值?其实这就是一个思考的过程。参加了BEA2007大会,虽然没有实质性的一些Topic让我有所收获,但是在主题演讲的时候让我突然开了窍。其实任何技术都是有延续性的EAISOA有什么区别,可能很快有人站出来给你一大堆的技术变革,告诉你区别大了去了,但其实SOA的真正价值不是在于说和过去的技术有什么区别,而是它的一种开放,协同的思想,这种思想其实更具各个行业来说都是不同的。这次去普元的交流会上,很明显的可以看出普元是定位在企业级应用的开放协同角度去考虑SOA的价值以及解决方案和实现手段。而我从大会回来,从新考虑了在阿里软件SAAS平台模式下我所关注的SOA的价值以及解决方案,就好比现在我一直在考虑的Service Mashup Platform,这是基于互联网应用的一种角度的思考。同样不同行业的人可能都会有不同的一种思考,但都是基于SOA的一种开放,协同的思想来更具具体的使用场景来考虑。所以如果你抛开业务场景去空想SOA,那么结果就会让自己陷入技术陷阱,用技术的不同来生硬的解释SOA,这种就好比过去讲的笑话,盲人摸象。第二点是我自己在推广我的ASF的一点经验,在普元演示产品的时候看到了他们的studio作的很好,但是对于单元测试以及部分组件的集成测试却做得还不是很够,同时studio是否能够让程序员有便利感(我们很多在场的写惯了程序的人都觉得程序员不写几行代码,就会没有创造感),这些可能会影响客户(开发人员)。其实在我推广ASF的时候有很多的架构师都反对,顶着压力死推,最后救了我的是那些开发人员,一份匿名使用反馈加上性能测试,功能测试,最终还是坚持了下来,并被逐步接受。那么对我来说我能够继续做好的就是加强文档的丰富性,测试的简单性,部属的方便性,以及开发配置的简便性(由于很多是配置型的文件,因此采用schema来做提示和交验我就觉得够了,至于studio是否需要,如果能够做得很完美当然最好了)。

最后其实对于这次活动来说其实我觉得就是一次技术人员的SOA,不同的公司,不同的职业,不同的职位,协同,开放的在一起发表自己的意见来互相学习和交流,本来也就是一种SOA。这儿感谢一下普元,活动本身来说虽然没有对SOA做出很明确的定义,但是其实让每一个人能够去思考,其实问题只有一个答案却可以有千千万万,每个人的角度不同看到的就有不同的内涵。就好比InfoQ主编说的每一个海滩上的沙子都有自己一个唯一标识,我们每一个江湖人士都有自己一个堂口,一个观点一个看法。

开放的心态去学习和交流,我要走路还有很长一段。

花絮:

       白衣不小心摔了一跤,眼镜掉到海里了,我们说是观音大士让他把眼镜作为纪念留在了海南。

       毕玄同学在上岸之前换鞋子的时候,由于不买一个小MM的贝壳,被小MM一直称作大叔,因此我们笑说毕玄就是到了大叔的年纪了。

欢迎访问我的blog:http://blog.csdn.net/cenwenchu79/
msn:cenwenchu_1979@hotmail.com

posted @ 2008-03-03 03:36 岑文初 阅读(1598) | 评论 (6)编辑 收藏

       SOA的基础技术实现方式中WebService占据了很重要的地位,通常我们提到WebService第一想法就是SOAP消息在各种传输协议上交互。近几年REST的思想伴随着SOA逐渐被大家接受,同时各大网站不断开放API提供给开发者,也激起了REST风格WebService的热潮。

       在收到新需求Email之前,我对REST的理解仅仅是通过半懂不懂的看了FieldingREST博士论文,说实话当时也就是希望了解这么一个新概念,对于其内部的思想只是很肤浅的了解了一下。

       ASF的最新需求就是可能需要实现REST风格的WebService集成,因此不得不好好的去看看REST的真正思想含义以及当前各大网站的设计方式。后面所要表述的也是我这个初学者的一些看法和观点,抛砖引玉,希望在我将REST融入到ASF之前能够获得更多的反馈和意见。

SOAP

       什么是SOAP,我想不用多说,google一把满眼都是。其实SOAP最早是针对RPC的一种解决方案,简单对象访问协议,很轻量,同时作为应用协议可以基于多种传输协议来传递消息(Http,SMTP等)。但是随着SOAP作为WebService的广泛应用,不断地增加附加的内容,使得现在开发人员觉得SOAP很重,使用门槛很高。在SOAP后续的发展过程中,WS-*一系列协议的制定,增加了SOAP的成熟度,也给SOAP增加了负担。

REST

       REST其实并不是什么协议也不是什么标准,而是将Http协议的设计初衷作了诠释,在Http协议被广泛利用的今天,越来越多的是将其作为传输协议,而非原先设计者所考虑的应用协议。SOAP类型的WebService就是最好的例子,SOAP消息完全就是将Http协议作为消息承载,以至于对于Http协议中的各种参数(例如编码,错误码等)都置之不顾。其实,最轻量级的应用协议就是Http协议。Http协议所抽象的get,post,put,delete就好比数据库中最基本的增删改查,而互联网上的各种资源就好比数据库中的记录(可能这么比喻不是很好),对于各种资源的操作最后总是能抽象成为这四种基本操作,在定义了定位资源的规则以后,对于资源的操作通过标准的Http协议就可以实现,开发者也会受益于这种轻量级的协议。

       自己理解的将REST的思想归结以下有如下几个关键点:

1.面向资源的接口设计

所有的接口设计都是针对资源来设计的,也就很类似于我们的面向对象和面向过程的设计区别,只不过现在将网络上的操作实体都作为资源来看待,同时URI的设计也是体现了对于资源的定位设计。后面会提到有一些网站的API设计说是REST设计,其实是RPC-REST的混合体,并非是REST的思想。

       2.抽象操作为基础的CRUD

       这点很简单,Http中的get,put,post,delete分别对应了read,update,create,delete四种操作,如果仅仅是作为对于资源的操作,抽象成为这四种已经足够了,但是对于现在的一些复杂的业务服务接口设计,可能这样的抽象未必能够满足。其实这也在后面的几个网站的API设计中暴露了这样的问题,如果要完全按照REST的思想来设计,那么适用的环境将会有限制,而非放之四海皆准的。      

       3Http是应用协议而非传输协议

       这点在后面各大网站的API分析中有很明显的体现,其实有些网站已经走到了SOAP的老路上,说是REST的理念设计,其实是作了一套私有的SOAP协议,因此称之为REST风格的自定义SOAP协议。

4.无状态,自包含

这点其实不仅仅是对于REST来说的,作为接口设计都需要能够做到这点,也是作为可扩展和高效性的最基本的保证,就算是使用SOAPWebService也是一样。

REST vs SOAP

成熟度:

SOAP虽然发展到现在已经脱离了初衷,但是对于异构环境服务发布和调用,以及厂商的支持都已经达到了较为成熟的情况。不同平台,开发语言之间通过SOAP来交互的web service都能够较好的互通(在部分复杂和特殊的参数和返回对象解析上,协议没有作很细致的规定,导致还是需要作部分修正)

REST国外很多大网站都发布了自己的开发API,很多都提供了SOAPREST两种Web Service,根据调查部分网站的REST风格的使用情况要高于SOAP。但是由于REST只是一种基于Http协议实现资源操作的思想,因此各个网站的REST实现都自有一套,在后面会讲诉各个大网站的REST API的风格。也正是因为这种各自实现的情况,在性能和可用性上会大大高于SOAP发布的web service,但统一通用方面远远不及SOAP。由于这些大网站的SP往往专注于此网站的API开发,因此通用性要求不高。

ASF上考虑发布REST风格的Web Service,可以参考几大网站的设计(兄弟公司的方案就是参考了类似于flickr的设计模式),但是由于没有类似于SOAP的权威性协议作为规范,REST实现的各种协议仅仅只能算是私有协议,当然需要遵循REST的思想,但是这样细节方面有太多没有约束的地方。REST日后的发展所走向规范也会直接影响到这部分的设计是否能够有很好的生命力。

总的来说SOAP在成熟度上优于REST

效率和易用性:

       SOAP协议对于消息体和消息头都有定义,同时消息头的可扩展性为各种互联网的标准提供了扩展的基础,WS-*系列就是较为成功的规范。但是也由于SOAP由于各种需求不断扩充其本身协议的内容,导致在SOAP处理方面的性能有所下降。同时在易用性方面以及学习成本上也有所增加。

       REST被人们的重视,其实很大一方面也是因为其高效以及简洁易用的特性。这种高效一方面源于其面向资源接口设计以及操作抽象简化了开发者的不良设计,同时也最大限度的利用了Http最初的应用协议设计理念。同时,在我看来REST还有一个很吸引开发者的就是能够很好的融合当前Web2.0的很多前端技术来提高开发效率。例如很多大型网站开放的REST风格的API都会有多种返回形式,除了传统的xml作为数据承载,还有(JSON,RSS,ATOM)等形式,这对很多网站前端开发人员来说就能够很好的mashup各种资源信息。

       因此在效率和易用性上来说,REST更胜一筹。

安全性:

       这点其实可以放入到成熟度中,不过在当前的互联网应用和平台开发设计过程中,安全已经被提到了很高的高度,特别是作为外部接口给第三方调用,安全性可能会高过业务逻辑本身。

       SOAP在安全方面是通过使用XML-SecurityXML-Signature两个规范组成了WS-Security来实现安全控制的,当前已经得到了各个厂商的支持,.net php java 都已经对其有了很好的支持(虽然在一些细节上还是有不兼容的问题,但是互通基本上是可以的)。

       REST没有任何规范对于安全方面作说明,同时现在开放REST风格API的网站主要分成两种,一种是自定义了安全信息封装在消息中(其实这和SOAP没有什么区别),另外一种就是靠硬件SSL来保障,但是这只能够保证点到点的安全,如果是需要多点传输的话SSL就无能为力了。安全这块其实也是一个很大的问题,今年在BEA峰会上看到有演示采用SAML2实现的网站间SSO,其实是直接采用了XML-SecurityXML-Signature,效率看起来也不是很高。未来REST规范化和通用化过程中的安全是否也会采用这两种规范,是未知的,但是加入的越多,REST失去它高效性的优势越多。

应用设计与改造:

       我们的系统要么就是已经有了那些需要被发布出去的服务,要么就是刚刚设计好的服务,但是开发人员的传统设计思想让REST的形式被接受还需要一点时间。同时在资源型数据服务接口设计上来说按照REST的思想来设计相对来说要容易一些,而对于一些复杂的服务接口来说,可能强要去按照REST的风格来设计会有些牵强。这一点其实可以看看各大网站的接口就可以知道,很多网站还要传入function的名称作为参数,这就明显已经违背了REST本身的设计思路。

       SOAP本身就是面向RPC来设计的,开发人员十分容易接受,所以不存在什么适应的过程。

总的来说,其实还是一个老观念,适合的才是最好的

       技术没有好坏,只有是不是合适,一种好的技术和思想被误用了,那么就会得到反效果。RESTSOAP各自都有自己的优点,同时如果在一些场景下如果去改造REST,其实就会走向SOAP(例如安全)。

       REST对于资源型服务接口来说很合适,同时特别适合对于效率要求很高,但是对于安全要求不高的场景。而SOAP的成熟性可以给需要提供给多开发语言的,对于安全性要求较高的接口设计带来便利。所以我觉得纯粹说什么设计模式将会占据主导地位没有什么意义,关键还是看应用场景。

       同时很重要一点就是不要扭曲了REST现在很多网站都跟风去开发REST风格的接口,其实都是在学其形,不知其心,最后弄得不伦不类,性能上不去,安全又保证不了,徒有一个看似象摸象样的皮囊。

REST设计的几种形式

参看了几个大型网站的REST风格的API设计,这里做一下大致的说明:

FaceBook:

请求消息:

       URI设计上采取了类似于REST的风格。例如对于friends的获取,就定义为friends.get,前面部分作为资源定义,后面是具体的操作,其他的API也是类似,资源+操作,因此就算使用httpget方法都可能作了update的操作,其实已经违背了REST的思想,但是说到,其实那么复杂的业务接口设计下,要通过RUCD来抽象所有的接口基本是不实际的。在URI定义好以后,还有详细的参数定义,包括类型以及是否必选。

响应消息:

       有多种方式,XML,JSONXMLXSD作为参考。有点类似于没有HeadSOAP,只不过这里将原来可以定义在WSDL中的XSD抽取出来了。

Flickr:

       请求消息:

       http://api.flickr.com/services/rest/?method=flickr.test.echo&name=value

       这里就可以很明显看出它所定制的REST请求其实和RPC没有什么太大的区别。

       消息返回:

正确处理返回

<?xml version="1.0" encoding="utf-8" ?>

<rsp stat="ok">

         [xml-payload-here]

</rsp>

错误处理返回

<?xml version="1.0" encoding="utf-8" ?>

<rsp stat="fail">

         <err code="[error-code]" msg="[error-message]" />

</rsp>

       根据返回可以看出已经违背了REST的思想,还是把Http协议作为传输承载协议,并没有真正意义上使用Http协议作为资源访问和操作协议。

       总的来说,只是形式上去模仿REST,自己搞了一套私有协议。

Ebay

       请求消息:

       采用xml作为承载,类似于SOAP,不过去除SOAP消息的封装和包头,同时在请求中附加了认证和警告级别等附加信息。

       消息返回:

       类似于SOAP消息,不过删除了SOAP的封装和包头,同时在返回结构中增加了消息处理结果以及版本等附加信息。

       这个很类似于当前Axis2框架的做法,将SOAP精简,同时根据自身需求丰富了安全,事务等协议内容。

Yahoo Maps

       请求消息:

       http://local.yahooapis.com/MapsService/V1/geocode?appid=YahooDemo&street=701+First+Ave&city=Sunnyvale&state=CA

       采用REST推荐的方式,URI+Parameters

       返回消息:

<?xml version="1.0" encoding="UTF-8"?>

<ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns="urn:yahoo:maps"

xsi:schemaLocation="urn:yahoo:maps http://local.yahooapis.com/MapsService/V1/GeocodeResponse.xsd">

 <Result precision="address">

    <Latitude>37.416384</Latitude>

    <Longitude>-122.024853</Longitude>

    <Address>701 FIRST AVE</Address>

    <City>SUNNYVALE</City>

    <State>CA</State>

    <Zip>94089-1019</Zip>

    <Country>US</Country>

 </Result>

</ResultSet>

SOAP的精简xml返回,其他信息,例如出错码等信息由Http协议头来承载。

YouTube

请求消息:

http://www.youtube.com/api2_rest?method=youtube.users.get_profile&dev_id=YOUR_DEV_ID&user=YOUTUBE_USER_NAME

可以看到对于资源操作的URI定义也是参数的一部分。

返回消息:

<?xml version="1.0" encoding="utf-8"?>

<ut_response status="ok">

    <user_profile>

        <first_name>YouTube</first_name>

        <last_name>User</last_name>

        <about_me>YouTube rocks!!</about_me>

        <age>30</age>

        <video_upload_count>7</video_upload_count>

    </user_profile>

</ut_response>

       自定义的类SOAP消息。

Amazon

       请求消息:

       https://Amazon FPS web service end point/?AWSAccessKeyId=Your AWSAccessKeyId

      &Timestamp=[Current timestamp] &Signature=[Signature calculated from hash of Action and Timestamp]

      &SignatureVersion=[Signature calculated from hash of Action and Timestamp]

      &Version=[Version of the WSDL specified in YYYY-MM-DD format] &Action=[Name of the API]

      &parameter1=[Value of the API parameter1] &parameter2=[Value of the API parameter2]

      &...[API parameters and their values]

       返回消息:

       类似于SOAP的自有协议,消息体中包含了消息状态等附加信息。

总结:

       看了上面那么多网站的设计,总结一下主要有这么几种设计方式。

请求消息设计:

1. 基本符合REST标准方式:资源URI定义(资源操作)+参数。这类设计如果滥用get去处理其他类型的操作,那么和2无异。

2. REST风格非REST思想:资源URI定义+参数(包含操作方法名)。其实就是RPCREST跟风。

3. 类似于SOAP消息,自定义协议,以xml作为承载。(可扩展,例如鉴权,访问控制等),不过那就好比自己定义了一套SOAPSOAP extends。大型的有实力的网站有的采取此种做法。

响应消息设计:

1.       REST标准方式,将Resource State传输返回给客户端,Http消息作为应用协议而非传输协议

2.       XML作为消息承载体,Http作为消息传输协议,处理状态自包含。

3.       自定义消息格式,类似于SOAP,提供可扩展部分。

作为遵循REST的理念来看我的选择是响应1和请求1的设计。

RESTASF的集成

ASF要集成REST就现在来看有两种比较合适的方法。

一.就是采用Axis2REST实现,这种方式的好处就是开发周期短,容易集成,但是请求和响应的格式无法改变,资源URI设计受限,Axis2REST其实就是将SOAP消息精简,请求的时候删除了SOAP的头,响应的时候仅仅返回资源信息,如果提供xsd就可以被各种客户端所解析。并非真正的REST

二.就是采用Restlet开源框架,将Restlet开源框架集成到ASF中,由于Restlet本身就是可内嵌的应用框架,因此集成不成问题,同时Restlet框架只是API结构框架,因此实现和定义完全分开,集成Restlet以后可以自己实现其中的解析引擎也可以采用默认提供的引擎,同时对于内嵌Jetty等多种开源项目的支持,将更多优势融入到了Rest中。看了一下国内也有很多朋友已经关注Restlet开源项目,看了它的架构设计,个人觉得还是比较灵活和紧凑的。

题外话

       在写这篇文章以前写了一篇调研报告群发给各个架构师们参考,期待反馈。下午正好和我们的首席架构师聊了一会儿。其实我和他的感觉是一样的,REST是否真的在我们现有的服务框架中需要集成,理解了REST的思想再去看应用场景,那么可以发现如果要完全遵循REST的设计理念来设计接口的话,那么强要去改变现有已经存在的或者还未开发的接口就会落入为了技术而技术,为了潮流而跟风的近地。当然并不否认REST的好,其实我们兄弟公司的一些业务场景有部分的接口十分合适这类设计,面向资源,高效,简洁,易用都能够体现出它的价值。我们将会和我们的兄弟公司合作,也会参考他们的设计理念,在参考当前各个网站的实现情况下,部分的采用这类形式的发布,提供给第三方的ISV,无疑是我现在把REST融入到ASF中最好的理由。

       有了需求去做才不会陷入为了技术而技术,毕竟技术是由商业价值驱动的,同样社会上充斥着各种技术的鼓吹,如果稍不留神就会陷入跟风的潮流中。

欢迎访问我csdn的blog:http://blog.csdn.net/cenwenchu79/,也欢迎和我做交流,msn:cenwenchu_1979@hotmail.com,关于SOA,REST,SAAS。

posted @ 2008-02-22 08:45 岑文初 阅读(4279) | 评论 (1)编辑 收藏

 

JVM优化配置

       这里首先要说明的是这里提到的JVMSunHotSpot JVM 5和以上的版本。性能优化在应用方面可以有很多手段,包括Cache,多线程,各种算法等等。通常情况下是不建议在没有任何统计和分析的情况下去手动配置JVM的参数来调整性能,因为在JVM 5以上已经作了根据机器和OS的情况自动配置合适参数的算法,基本能够满足大部分的情况,当然这种自动适配只是一种通用的方式,如果说真的要达到最优,那么还是需要根据实际的使用情况来手动的配置各种参数设置,提高性能。

       JVM能够对性能产生影响的最大部分就是对于内存的管理。从jdk 1.5以后内存管理和分配有了很多的改善和提高。

内存分配以及管理的几个基本概念和参数说明:

Java Hotspot Mode

server client两种模式,如果不配置,JVM会根据应用服务器硬件配置自动选择模式,server模式启动比较慢,但是运行期速度得到了优化,client启动比较快,但是运行期响应没有server模式的优化,适合于个人PC的服务开发和测试。

Garbage Collector Policy

       Jdk 1.5的时候已经提供了三种GC,除了原来提供的串行GCSerialGC)以外,还提供了两种新的GCParallelGCConcMarkSweepGCParallelGC采用了多线程并行管理和回收垃圾对象,提高了回收效率,提高了服务器的吞吐量,适合于多处理器的服务器。ConcMarkSweepGC采用的是并发方式来管理和回收垃圾对象,降低垃圾回收产生的响应暂停时间。这里说一下并发和并行的区别,并发指的是多个进程并行执行垃圾回收,那么可以很好的利用多处理器,而并行指的是应用程序不需要暂停可以和垃圾回收线程并发工作。串行GC适合小型应用和单处理器系统(无需多线程交互,效率比较高),后两者适合大型系统。

       使用方式就是在参数配置中增加-XX:+UseParallelGC等方式来设置。

       对于这部分的配置在网上有很多的实例可以参考,不过最终采用哪一种GC还是要根据具体的情况来分析和选择。

Heap

       OOM的各种经历已经让每一个架构师开发人员看到了了解Heap的重要性。OOM已经是Heap的临界点,不得不引起注意,然而Heap对于性能的潜在影响并未被引起重视,不过和GC配置一样,在没有对使用情况作仔细分析和研究的情况下,贸然的去修改Heap配置,可能适得其反,这里就来看一下Heap的一些概念和对于性能的影响。

       我们的应用所能够得到的最大的Heap受三部分因素的制约:数据处理模型(32位或者64位操作系统),系统地虚拟内存总数和系统的物理内存总数。首先Heap的大小不能超过不同操作系统的进程寻址范围,当前大部分系统最高限度是4GWindows通常是2GLinux通常是3G。系统的虚拟内存也是分配的依据,首先是不能超过,然后由于操作系统支持硬盘来做部分的虚拟内存,如果设置过大,那么对于应用响应来说势必有影响。再则就是要考虑同一台服务器上运行多个Java虚拟机所消耗的资源总合也不能超过可用资源。就和前面OOM分析中的一样,其实由于OS的数据处理模型的限制,机器本身的硬件内存资源和虚拟内存资源并不一定会匹配,那么在有限的资源下如何调整好资源分配,对于应用来说尤为重要。

关于Heap的几个参数设置:

       说了Heap的有限资源问题以后,就来看看如何通过配置去改变JVM对于Heap的分配。下面所说的主要是对于Java Heap的分配,那么在申请了Java Heap以后,剩下的可用资源就会被使用到Native Heap

       Xms: java heap初始化时的大小。默认情况是机器物理内存的1/64。这个主要是根据应用启动时消耗的资源决定,分配少了申请起来会降低启动速度,分配多了也浪费。

       Xmx:java heap的最大值,默认是机器物理内存的1/4,最大也就到1G。这个值决定了最多可用的Java Heap Memory,分配过少就会在应用需要大量内存作缓存或者零时对象时出现OOM的问题,如果分配过大,那么就会产生上文提到的第二类OOM。所以如何配置还是根据运行过程中的分析和计算来确定,如果不能确定还是采用默认的配置。

       Xmn:java heap新生代的空间大小。在GC模型中,根据对象的生命周期的长短,产生了内存分代的设计:青年代(内部也分成三部分,类似于整体划分的作用,可以通过配置来设置比例),老年代,持久代。每一代的管理和回收策略都不相同,最为活跃的就是青年代,同时这部分的内存分配和管理效率也是最高。通常情况下,对于内存的申请优先在新生代中申请,当内存不够时会整理新生代,当整理以后还是不能满足申请的内存,就会向老年代移动一些生命周期较长的对象。这种整理和移动会消耗资源,同时降低系统运行响应能力,因此如果青年代设置的过小,就会频繁的整理和移动,对性能造成影响。那是否把年青代设置的越大越好,其实不然,年青代采用的是复制搜集算法,这种算法必须停止所有应用程序线程,服务器线程切换时间就会成为应用响应的瓶颈(当然永远不用收集那么就不存在这个问题)。老年代采用的是串行标记收集的方式,并发收集可以减少对于应用的影响。

       Xss:线程堆栈最大值。允许更多的虚拟内存空间地址被Java Heap使用。

以下是sun公司的性能优化白皮书中提到的几个例子:

1.对于吞吐量的调优。机器配置:4G的内存,32个线程并发能力。

java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20

       -Xmx3800m -Xms3800m 配置了最大Java Heap来充分利用系统内存。

       -Xmn2g 创建足够大的青年代(可以并行被回收)充分利用系统内存,防止将短期对象复制到老年代。

    -Xss128 减少默认最大的线程栈大小,提供更多的处理虚拟内存地址空间被进程使用。

    -XX:+UseParallelGC 采用并行垃圾收集器对年青代的内存进行收集,提高效率。

    -XX:ParallelGCThreads=20 减少垃圾收集线程,默认是和服务器可支持的线程最大并发数相同,往往不需要配置到最大值。

 

2.尝试采用对老年代并行收集

java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC

-Xmx3550m -Xms3550m 内存分配被减小,因为ParallelOldGC会增加对于Native Heap的需求,因此需要减小Java Heap来满足需求。

-XX:+UseParallelOldGC 采用对于老年代并发收集的策略,可以提高收集效率。

 

3.提高吞吐量,减少应用停顿时间

java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:SurvivorRatio=8 -XX:TargetSurvivorRatio=90 -XX:MaxTenuringThreshold=31

 

-XX:+UseConcMarkSweepGC -XX:+UseParNewGC 选择了并发标记交换收集器,它可以并发执行收集操作,降低应用停止时间,同时它也是并行处理模式,可以有效地利用多处理器的系统的多进程处理。

-XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=31 表示在青年代中Eden和Survivor比例,设置增加了Survivor的大小,越大的survivor空间可以允许短期对象尽量在年青代消亡。

 

-XX:TargetSurvivorRatio=90 允许90%的空间被占用,超过默认的50%,提高对于survivor的使用率。

 

类似的例子网上很多,这儿就不在列下来了,最终是否采取自己配置来替换默认配置还是要根据虚拟机的使用情况来分析和配置。

posted @ 2008-01-23 16:16 岑文初 阅读(2954) | 评论 (2)编辑 收藏

       OOM这个缩写就是Java程序开发过程中让人最头痛的问题:Out of Memory。在很多开发人员的开发过程中,或多或少的都会遇到这类问题,这类问题定位比较困难,往往需要根据经验来判断可能出现问题的代码。原因主要是两个:对象没有被释放(多种情况引起,往往是比较隐蔽的引用导致被Hold而无法被回收)。另一种就是真的Memory不够用了,需要增加JVMHeap来满足应用程序的需求。最近有同事发的关于解决OOM的问题,让我了解了原来OOM除了在JVM Heap不够时会发生,在Native Heap不够的时候也会发生,同时JVM HeapNative Heap存在着相互影响和平衡的关系,因此就仔细的去看了关于OOMJVM配置优化的内容。

OOM

       在其他语言类似于C,Delphi等等由于内存都是由自己分配和管理,因此内存泄露的问题比较常见,同时也是很头痛的一件事情。而Java的对象生命周期管理都是JVM来做的,简化了开发人员的非业务逻辑的处理,但是这种自动管理回收机制也是基于一些规则的,而违背了这些规则的时候,就会造成所谓的“Memory Leak”。

OOM(Java Heap)

       错误提示:java.lang.OutOfMemoryError

这类OOM是由于JVM分配的给应用的Heap Memory已经被耗尽,可能是因为应用在高负荷的情况下的却需要很大的内存,因此可以通过修改JVM参数来增加Java Heap Memory(不过也不能无限制增加,后面那种OOM有可能就是因为这个原因而产生)。另一种情况是因为应用程序使用对象或者资源没有释放,导致内存消耗持续增加,最后出现OOM,这类问题引起的原因往往是应用已不需要的对象还被其他有效对象所引用,那么就无法释放,可能是业务代码逻辑造成的(异常处理不够例如IO等资源),也可能是对于第三方开源项目中资源释放了解不够导致使用以后资源没有释放(例如JDBCResultSet等)。

       几个容易出现问题的场景:

       1.应用的缓存或者Collection:如果应用要缓存Java对象或者是在一个Collection中保存对象,那么就要确定是否会有大量的对象存入,要做保护,以防止在大数据量下大量内存被消耗,同时要保证Cache的大小不会无限制增加。

       2.生命周期较长的对象:尽量简短对象的生命周期,现在采用对象的创建释放代价已经很低,同时作了很好的优化,要比创建一个对象长期反复使用要好。如果能够设置超时的情景下,尽量设置超时。

       3.类似于JDBCConnection Pool,在使用Pool中的对象以后需要释放并返回,不然就会造成Pool的不断增大,在其他Pool中使用也是一样。同样ResultSetIO这类资源的释放都需要注意。

       解决的方法就是查找错误或者是增加Java Heap Memory。对于此类问题检测工具相当多,这里就不做介绍了。      

OOM(Native Heap)

错误提示:requested XXXX bytes for ChunkPool::allocate. Out of swap space

       Native Heap MemoryJVM内部使用的Memory,这部分的Memory可以通过JDK提供的JNI的方式去访问,这部分Memory效率很高,但是管理需要自己去做,如果没有把握最好不要使用,以防出现内存泄露问题。JVM 使用Native Heap Memory用来优化代码载入(JTI代码生成),临时对象空间申请,以及JVM内部的一些操作。这次同事在压力测试中遇到的问题就是这类OOM,也就是这类Memory耗尽。同样这类OOM产生的问题也是分成正常使用耗尽和无释放资源耗尽两类。无释放资源耗尽很多时候不是程序员自身的原因,可能是引用的第三方包的缺陷,例如很多人遇到的Oracle 9 JDBC驱动在低版本中有内存泄露的问题。要确定这类问题,就需要去观察Native Heap Memory的增长和使用情况,在服务器应用起来以后,运行一段时间后JVM对于Native Heap Memory的使用会达到一个稳定的阶段,此时可以看看什么操作对于Native Heap Memory操作频繁,而且使得Native Heap Memory增长,对于Native Heap Memory的情况我还没有找到办法去检测,现在能够看到的就是为JVM启动时候增加-verbose:jni参数来观察对于Native Heap Memory的操作。另一种情况就是正常消耗Native Heap Memory,对于Native Heap Memory的使用主要取决于JVM代码生成,线程创建,用于优化的临时代码和对象产生。当正常耗尽Native Heap Memory时,那么就需要增加Native Heap Memory,此时就会和我们前面提到增加java Heap Memory的情况出现矛盾。

应用内存组合

       对于应用来说,可分配的内存受到OS的限制,不同的OS对进程所能访问虚拟内存地址区间直接影响对于应用内存的分配,32位的操作系统通常最大支持4G的内存寻址,而Linux一般为3GWindows2G。然而这些大小的内存并不会全部给JVMJava Heap使用,它主要会分成三部分:Java HeapNative Heap,载入资源和类库等所占用的内存。那么由此可见,Native Heap Java Heap大小配置是相互制约的,哪一部分分配多了都可能会影响到另外一部分的正常工作,因此如果通过命令行去配置,那么需要确切的了解应用使用情况,否则采用默认配置自动监测会更好的优化应用使用情况。

       同样要注意的就是进程的虚拟内存和机器的实际内存还是有区别的,对于机器来说实际内存以及硬盘提供的虚拟内存都是提供给机器上所有进程使用的,因此在设置JVM参数时,它的虚拟内存绝对不应该超过实际内存的大小。

待续……


JVM
优化配置


更多内容可访问:http://blog.csdn.net/cenwenchu79/
posted @ 2008-01-22 16:54 岑文初 阅读(2817) | 评论 (2)编辑 收藏

Author: wenchu.cenwc

Email: wenchu.cenwc@alibaba-inc.com

Memcached 介绍与分析

       Memcached是一种集中式Cache,支持分布式横向扩展。总结几个它的特点来理解一下它的优点和限制。

       Memory:内存存储,不言而喻,速度快,对于内存的要求高,不指出的话所缓存的内容非持久化。对于CPU要求很低,所以常常采用将Memcached服务端和一些CPU高消耗Memory低消耗应用部属在一起。(作为我们AEP正好有这样的环境,我们的接口服务器有多台,接口服务器对于CPU要求很高(由于WS-Security),但是对于Memory要求很低,因此可以用作Memcached的服务端部属机器)

       集中式Cache:避开了分布式Cache的传播问题,但是需要非单点保证其可靠性,这个就是后面集成中所作的cluster的工作,可以将多个Memcached作为一个虚拟的cluster,同时对于cluster的读写和普通的memcached的读写性能没有差别。

       分布式扩展:Memcached的很突出一个优点,就是采用了可分布式扩展的模式。可以将部属在一台机器上的多个Memcached服务端或者部署在多个机器上的Memcached服务端组成一个虚拟的服务端,对于调用者来说完全屏蔽和透明。提高的单机器的内存利用率,也提供了scale out的方式。

       Socket通信:传输内容的大小以及序列化的问题需要注意,虽然Memcached通常会被放置到内网作为CacheSocket传输速率应该比较高(当前支持Tcpudp两种模式,同时根据客户端的不同可以选择使用nio的同步或者异步调用方式),但是序列化成本和带宽成本还是需要注意。这里也提一下序列化,对于对象序列化的性能往往让大家头痛,但是如果对于同一类的Class对象序列化传输,第一次序列化时间比较长,后续就会优化,其实也就是说序列化最大的消耗不是对象序列化,而是类的序列化。如果穿过去的只是字符串,那么是最好的,省去了序列化的操作,因此在Memcached中保存的往往是较小的内容。

       特殊的内存分配机制:首先要说明的是Memcached支持最大的存储对象为1M。它的内存分配比较特殊,但是这样的分配方式其实也是对于性能考虑的,简单的分配机制可以更容易回收再分配,节省对于CPU的使用。这里用一个酒窖比喻来说明这种内存分配机制,首先在Memcached起来的时候可以通过参数设置使用的总共的Memory,这个就是建造一个酒窖,然后在有酒进入的时候,首先申请(通常是1M)的空间,用来建酒架,酒架根据这个酒瓶的大小分割酒架为多个小格子安放酒瓶,将同样大小范围内的酒瓶都放置在一类酒架上面。例如20cm半径的酒瓶放置在可以容纳20-25cm的酒架A上,30cm半径的酒瓶就放置在容纳25-30cm的酒架B上。回收机制也很简单,首先新酒入库,看看酒架是否有可以回收的地方,如果有直接使用,如果没有申请新的地方,如果申请不到,采用配置的过期策略。这个特点来看,如果要放的内容大小十分离散,同时大小比例相差梯度很明显,那么可能对于使用空间来说不好,可能在酒架A上就放了一瓶酒,但占用掉了一个酒架的位置。

       Cache机制简单:有时候很多开源的项目做的面面俱到,但是最后也就是因为过于注重一些非必要性的功能而拖累了性能,这里要提到的就是Memcached的简单性。首先它没有什么同步,消息分发,两阶段提交等等,它就是一个很简单的Cache,把东西放进去,然后可以取出来,如果发现所提供的Key没有命中,那么就很直白的告诉你,你这个key没有任何对应的东西在缓存里,去数据库或者其他地方取,当你在外部数据源取到的时候,可以直接将内容置入到Cache中,这样下次就可以命中了。这里会提到怎么去同步这些数据,两种方式,一种就是在你修改了以后立刻更新Cache内容,这样就会即时生效。另一种是说容许有失效时间,到了失效时间,自然就会将内容删除,此时再去去的时候就会命中不了,然后再次将内容置入Cache,用来更新内容。后者用在一些时时性要求不高,写入不频繁的情况。

       客户端的重要性:Memcached是用C写的一个服务端,客户端没有规定,反正是Socket传输,只要语言支持Socket通信,通过Command的简单协议就可以通信,但是客户端设计的合理十分重要,同时也给使用者提供了很大的空间去扩展和设计客户端来满足各种场景的需要,包括容错,权重,效率,特殊的功能性需求,嵌入框架等等。

       几个应用点:小对象的缓存(用户的token,权限信息,资源信息)。小的静态资源缓存。Sql结果的缓存(这部分用的好,性能提高相当大,同时由于Memcached自身提供scale out,那么对于db scale out的老大难问题无疑是一剂好药)。ESB消息缓存。

集成设计

       为什么需要集成?直接使用现有的两个Java实现Memcached是否就可以了?

       当前集成主要为了两方面考虑,首先是方便的配置使用,如何将Memcached内嵌到类似于ASF以及其他框架中去,并且通过配置文件方便使用,这就需要作部分的集成工作,这部分工作主要是定义了配置文件以及通过Stax去解析配置的功能。然后是如何管理Memcached,这部分内容包括了初始化,运行期检测,资源回收的工作。最后是扩展,这里的扩展分成两部分(功能的扩展以及框架实现的扩展),功能扩展例如当前扩展了虚拟的cluster,可以让多个memcached Client组成一个虚拟的cluster,如果通过放入cluster的方式放入到其中一个Cache Client中的话,那么就可以在整个cluster都作好备份,这样其实可以根据memcached的单机多实例以及多机多实例作交互备份,提高可靠性。当然后续还有很多可以扩展的内容,这里只是一个开头。框架实现的扩展指的是这里采用了类似于JdkJAXP的框架设计,只是规定了框架API结构,至于实现者动态载入,这个和ASF等现在可扩展的框架一样,提供了很方便的扩展点,后续的设计中会提到。

接口设计类图:

1 Cache接口包类图

       ICacheIMemcachedCache实现的是最基本的Cache的功能,只是IMemcachedCache有所增强,提供了对于虚拟的Cluster的操作,批量操作,统计的功能。ICacheManagerIMemcachedCacheManager分别是对于上面两个Cache的管理类,根据配置文件解析,初始化客户端池,建立虚拟集群,销毁客户端池等工作。

2 Memcached 实现包

       省略了一些辅助类定义。这部分是具体的实现,同时可以在图上看到spi包内的CacheManagerFactory就是用来提供扩展使用的接口。只需要定义在jarMETA-INF下面建立services目录,建立两个名为:com.alisoft.xplatform.asf.cache.IMemcachedCacheManagercom.alisoft.xplatform.asf.cache.spi.CacheManagerFactory的文件就可以替换MemcachedCacheManagerCacheManagerFactory的实现类,从而改变Memcached Client实现机制。如果没有这两个文件在Classpath目录下面,那么默认将会使用当前框架中的两个实现。

3 Memcached的结构图

       Memcached Server就是部署在不同服务器或者在同一台服务器上的Memcached实例,一般采用后台守护进程方式运行。SocketPool是客户端连接到服务端的Socket通信层,Memcached Client可以归属为虚拟的ClusterMemcachedCacheManager作用是管理ClusterCache。从这个结构图可以看出客户端的每一层都是很独立,这样有利于层次的交互,以及组合扩展。

测试与使用

1. 配置:

需要有一个名为memcached.xml的文件在classpath中,可以在jar里面也可以在任意classpath可以找的到的地方,需要注意的是,CacheManager实现了对于多个memcached.xml merge的功能。

具体的配置内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<memcached>//总标签

  //memcached Client的配置,也就是一个IMemcachedCache的配置。Name必须填,表示Cache的名称,socketpool必须填,表示使用的远程通信连接池是哪一个,参看后面对于socketpool的定义。后面都是可选的,第三个参数表示传输的时候是否压缩,第四个参数表示默认的编码方式

<client name="mclient1" socketpool="pool1" compressEnable="true" defaultEncoding="UTF-8" >

        <!--errorHandler></errorHandler-->//可定义错误处理类,一般不需要定义

    </client>

    <client name="mclient2" socketpool="pool2" compressEnable="true" defaultEncoding="UTF-8" >

    </client>  

     //socketpool是通信连接池定义,每一个memcached Client要和服务端交互都必须有通信连接池作为底层数据通信的支持,name必填,表示名字,同时也是memcached client指定socketpool的依据,failover表示对于服务器出现问题时的自动修复。initConn初始的时候连接数,minConn表示最小闲置连接数,maxConn最大连接数,maintSleep表示是否需要延时结束(最好设置为0,如果设置延时的话那么就不能够立刻回收所有的资源,如果此时从新启动同样的资源分配,就会出现问题),nagleTCP对于socket创建的算法,socketTOsocket连接超时时间,aliveCheck表示心跳检查,确定服务器的状态。Serversmemcached服务端开的地址和ip列表字符串,weights是上面服务器的权重,必须数量一致,否则权重无效

    <socketpool name="pool1" failover="true" initConn="10" minConn="5" maxConn="250" maintSleep="0"

        nagle="false" socketTO="3000" aliveCheck="true">

        <servers>10.0.68.210:12000,10.0.68.210:12222</servers>

        <weights>5,5</weights>

    </socketpool>  

    <socketpool name="pool2" failover="true" initConn="10" minConn="5" maxConn="250" maintSleep="0"

        nagle="false" socketTO="3000" aliveCheck="true">

        <servers>10.0.68.210:22000,10.0.68.210:22222</servers>

        <weights>5,5</weights>

    </socketpool>

    //虚拟集群设置,这里将几个clientcache设置为一个虚拟集群,当对这些IMemcachedCache作集群操作的时候,就会自动地对集群中所有的Cache作插入,寻找以及删除的操作,做一个虚拟交互备份

    <cluster name="cluster1">

        <memCachedClients>mclient1,mclient2</memCachedClients>

    </cluster>            

</memcached>

2. 测试代码,这里就附带一个单元测试类的代码就可以很清楚的知道使用方法。


后话

没有不好的,只有不适合的,适合的场景使用,根据场景适合的使用,才是提高性能的最有效手段。后需要根据所需的应用场景继续对这部分集成内容作完善,实践完善设计。

 
posted @ 2008-01-02 22:58 岑文初 阅读(2060) | 评论 (1)编辑 收藏

     周四下午听了一节课就提早回来了,周五身体不好也就没有去公司,也没有写关于第二天的一些所见所闻,其实第一天的启发也并非完全是参加了大会的感触,只是正好和自己目标有些碰撞,感觉还有一些可写的。第二日,早晨的内容其实昨天已经也略有所闻,但是可能更为详细一些,下午的内容就基本没怎么听了,因为唯一一个感觉还算是比较务实的课堂连载给我的感觉就是“空”,也可能是因为时间都只有一个小时,所以基本那些演讲人翻翻ppt就来不及了,也没什么可以细致的解答的,而提问的同学听来听去就是问一个问题:“实施SOA怎么做?”老师能给的一个答案就是“不同的情况又不同的处理办法吧”。既然写了,那么还是流水的记录一下这一天的所见所闻。

       早晨还是主题演讲,和昨天一样,也是技术+实践。一共分成了五部分:1.提高企业生产效率:企业社会计算与业务流程管理。2.中国生活网项目介绍。3.极速虚拟化。4.东软的演讲。5.BEA咨询副总裁的实施创新。这五部分内容,第一部分还是有一些其启发的内容,因此最后介绍一下。

中国生活网,东软的演讲就像给我blog留言的一个同样去了BEA2007的朋友说的一样,商业推广大于技术创新推广。

极速虚拟化主要介绍的是BEAVMWare公司合作的一种应用服务部署模式,将原来的服务器+OS+VM+WEBContainer+App改变成为服务器+LiquidVM+WLS-VE+App,省略了原来的OS,同时通过虚拟层的优化,将硬件服务器由单机独立部署,转变成为硬件资源池,软件负载均衡动态部署应用,提高服务器的利用率,将软件抽象出来与底层硬件分离。由于这部分内容和底层硬件优化比较紧密,和上层软件架构不是很相关,因此对我来说能够实践的机会比较少。

BEA咨询副总裁讲的实施创新,一开始就以当前最为火热的几个web2.0的网站作为切入点,讲述了一下这些网站成功就是在与创新,后面就是推广性的介绍了一下当前互联网应用的情况,并没有提到如何去创新。赫赫,不过如果说出来了,就不叫作创新了,创新还是要根据每个人的商业嗅觉,当有了技术的支持以后,如何变技术为社会价值,并将其社会价值最大化,那就依赖于个人创新能力体现了。

最后谈谈上午第一个主题演讲:提高企业生产效率:企业社会计算与业务流程管理。这个主题其实针对的客户群应该不是类似于我这样的应用平台开发架构师,而是国有大中型企业的IT技术经理。这部分内容其实应该是涉及到了SOA的应用,将SOA+Web2.0结合应用到了企业级信息管理中。不过同一本佛经,不同的和尚悟出的道理也是不同的,给出下面几个重点词,做一下解释和自己的一些分享(这里只是从自己的角度去看待主题中的一些关键内容)。

Key point:资产管理的演变

Detail企业的资产管理由Capital的管理àInformation管理àInteraction管理。其实第一步就是我们过去说的最原始的ERP风潮的进化,而第二步其实是在当前Web2.0的启发下,企业内部管理的再次变革,当然这次变革是跟随当前互联网Web2.0的技术变革而产生的。一个领域的变革,能够启发另一个领域的变革。当企业内部由有形资产比例占据绝对优势逐渐转变成为人力资源等无形资产占据绝对优势以后,企业管理的手段以及方式都将作很大的改变,而一个企业和一个互联网应用一样,如果想要不断发展,那么就不能仅仅依靠两三个管理者的智慧,而是要依靠企业员工所构筑的企业内社会网络来不断提供新鲜血液。这点也就是Web2.0的重要特性之一,社区概念和群众参与。将每一个个体的生产率转变成为企业生产率。而完成这一点当前能够采取的有效手段,就是通过SOA+BPM在企业中的实施来达成。构建信息共享网络(现在可比以前丰富多了,blog,rss,wiki等等,在回来的时候我们几个还谈论了可以构建企业内部的交友社区,解决大龄男女的终身大事问题)。管理的交互策略:将流程,人员,信息提供给每一个企业员工,员工可以参与流程的制定,以及及时反馈企业流程问题。

My option企业是否需要SOA来完善自身信息化,还是根据各自的情况和财力而定。对我的架构设计来说,其实可以同样推出这么一个观念,架构设计需要能够融入创新,可以灵活扩展,提倡每个开发工程师和架构设计师贡献ideasolution,这也是SCA的一个亮点和根基所在。

Key point:企业社会计算+BPM+SOA = 提升生产效率

Detail首先说一下三部分的各自功能。企业社会计算的功能:1.参与者驱动的协作工具。2.社会搜索与专业知识的发现。3.组装与Mashup(后面会谈以下关于Mashup的一些了解)。BPM的功能:1.连接到交互与协作的工具。2.建立专门的协作模型(终端)。3.使企业流程民主化。SOA的功能:1.服务创建与启用。2.服务的动态发现。3.普遍的安全访问。这三部分如何提升企业生产率呢?企业社会计算是以用户为中心,那么个人的智慧就能够最大限度的贡献并且提升成为企业智慧。BPM提供了实时业务可视和控制,能够及时地纠正问题,并且快速做出响应。SOA将活动和数据转换为可重用和松耦合的服务,提高了业务开发速度,降低了开发成本,最大限度地利用已有资源。

My option其实这三点就是昨天BEA对于创世纪平台的构想,将Web2.0思想+BPM可视化工具+SOA模块化服务三者结合起来,最大限度地挖掘互联网应用的价值,提高灵活快速的开发和响应模式,满足客户需求,最终达到业务级别的敏捷。说到这儿,其实我发现那么多的概念,思想和规范,最终的目标归结起来就是阿里巴巴的考核第一条:客户第一。互联网应用的客户就是无数的网民,每个人的需求不同,每个人的喜好不同,如何开发出在这么一个广阔的客户群体中能够长期生存的应用,只能够不断地根据用户反馈来分析,创新,改变,那么应用的设计,开发都需要敏捷。Java世界中,初学者会使用Jdk提供了很多API包,成熟的开发人员可以根据很多开源项目来构建自己所需要的应用。而到了今天,其实需要更高层次的封装和构建,也就是业务级别的封装和构建,使得互联网应用开发能够基于这些服务组件自由组装,拼装出客户所需要的应用,极端一点说,可能客户通过一个工具就可以订制出自己所需要的一个组合应用。用个形象的比喻,就好比量体裁衣式的一对一的模式已经不能够适合这个飞速发展的互联网时代,需要的是可定制化的模版式设计,客户只需要将自己喜欢的上衣,裤子,帽子搭配好,根据自身尺寸就可以定制到自己喜欢的套装,快速便捷。有人可能会问,那么大家都穿成一样岂不是很没有个性。两个方面看这个问题:首先看看快餐的启发,为什么人们那么容易接受快餐?在效率和可用性上如果能够满足的情况下,每个月快餐店推出的一款新产品就足以让现代人觉得有新鲜感。(周日中午和老婆去爸爸妈妈家吃饭,听到了楼下有喊磨剪刀戗菜刀,爸爸说这也就这边小镇上才有的风景了。老婆问,那么城里面刀钝了怎么办?赫赫,大家都一个反应,真的不行就换一把呗。)另一个方面就是个性化,其实在SAAS模式下多租户的个性化也是和重要的一点,我们需要批量定制,同时需要个性化服务,不存在矛盾,如果觉得矛盾了,那么架构设计需要考虑是否能够有更好的优化。在BEA的不同角色多视图的演示中,就是展现的这么一点,其实个性化的并不是底层的应用服务,而是在同一层的应用服务池中,用Mashup的方式来结合客户端的精彩技术构建出丰富多彩的个性化界面,满足用户地个性化需求,说到底也就是以业务组件抽象为基础,多角度展现应用。

上面第二点好像谈的越来越与主题无关了,其实本来就是非针对我的课题,我自然就会遐想到其他地方去了。早晨就这么过去了,中午吃过饭,和同事去黄埔江边逛了一下看看时间尚早,就去了一楼的厂商参展区,昨天晚上也去了一下,不过因为太晚,很多厂商都收拾走了,也没有太多收获,今天正好去看看。由于当前比较关心Web Service安全性能方面的问题,因此特意去了BEA的展台看看是否有收获,开始看到了BEA的安全介绍展台,和展台的朋友聊了一阵,发现大家的角度不同,他主要是侧重于用户鉴权和资源访问控制这部分的安全策略,BEA对于用户鉴权和资源访问控制提供了数据库设计和对应的API,也没有仔细了解就转去了另外地方看看。走了几步看见了一个BEA的展台正在给几个朋友看SOAP消息,这下我就来劲了,马上走过去看看,果然这个展台是我想去的展台,正好那两个看的人都没有兴趣走开了,我一对一的和工作人员交流,问起了BEA现在对Web Service所采用的安全策略是什么?SAML2.0。性能怎么样?(因为我这边作的压力测试web service在附带了WS-Security Signature以后对于CPU的消耗高了几倍)没做过测试,因为刚刚开发出来一个月。兼容性如何(对于Php,.net)?没有做过测试。那位工作人员不是负责这个模块开发的,所以也不是很了解,我请他帮忙到时候给我一些SAML 2的资料,并留了我的card给他,他也很友好的答应给我回复。有一点点的失望,不过毕竟开发人员工作可能都很忙,这种展会都是推广的多。

转眼看了看表就到了140分了,赶紧去了三楼参加下午的培训,结果那个教室一早满员,我只好站在边上听,巧的是正好有个人走了,我就安心的座了下来听,看过BEA World2007的分会场安排的朋友就会知道,其实每一个会场两天下午安排的都是系列性的讲座,也就是每一个会场每天多节课都是相互关联的,我选择的这个是比较适合架构师和PM听的结合概念,设计和实践的系列讲座,所以次次人满为患,但是今天下午听了一节课以后,加之昨天下午的两节,我提早和我同事说还是早点走吧。

就这样结束了我2天的BEA SOA之旅,庆幸的是还是有不少的收获,不论是否是大会给我的启发。前一阵子给自己的blog以及所有的IM都改了一个名字,叫做:做块石头沉下去。因为觉得做一个技术人员(个性使然,目标是做一个大P),应该像一块石头一样沉在下面,踏踏实实的做事,经得起成功,也经得起失败。不过今天早晨跑步的时候又觉得,其实做技术的人,应该做一块可以浮起来也能够沉的下去的石头,去参加这样的技术大会,就是抱着浮起来的心态,去看看新的世界,接受新的思想,石头沉的太深太久会被淤泥掩埋,同样会因为闭塞而止步不前。当然浮起来就是为了去更好的地方沉下去,河流那么大,要学的还有很多很多。
    更多分享在我的csdn的blog:http://blog.csdn.net/cenwenchu79

附加:今天早晨还看了关于mashup的两篇文章,很不错,也受益匪浅。

http://www.ibm.com/developerworks/cn/webservices/ws-soa-mashups/?S_TACT=105AGX52&S_CMP=content

posted @ 2007-12-17 11:56 岑文初 阅读(1123) | 评论 (2)编辑 收藏

 

BEA World 2007 SOA第一日手记

       前一阵子工作忙,去北京参加CSDNweb2.0的机会错过了,这次我正好处与服务框架第一阶段总结期,同时测试部的资深总监受到BEA的邀请,可以带上架构师一起去,所以有机会去上海参加BEA World 2007 SOA大会。说起来我们老大说这次会议的主题和我也算是“专业对口”,不是一直在说SCASOA落地么,那么就去看看BEA怎么让SOA走的踏踏实实的。

       会议一共分成了两天,这两天上午都是主题演讲,下午和其他的年度大会一样,分成很多分会场,自己可以根据自己的兴趣去选择所要听的主题。因为也没有太多时间去看电子邮件中的会刊,所以对主题都还不清楚,早晨起床就粗粗浏览了一下上午的主题,一共分成了四块:1.超越SOA:技术融合与动态应用。2.江苏电力SOA实践。3.基础架构新探索。4.铸就面向客户的英国航空公司。正好是技术与实践相结合,两个技术案例,两个商业案例。9点左右,大厅门一开,大家鱼贯而入,选了贵宾席后面的第二排,就开始了我这上午半天的BEA SOA之旅。我想看我blog的多半是技术人员,我们就不讲关于BEA公司的宣传内容,直接进入主题,首先是总的谈谈这几部分具体介绍的内容,然后谈谈我这个半吊子的SOA学习者的一些感触。

       超越SOA:技术融合与动态应用:

既然是BEA公司的SOA年度会议,那么自然会将BEA公司对于SOA的解决方案和产品推向我们每一个人。这次BEA推出的是他们的SAAS的平台Genesis(创世纪),SAAS今年很热,当然我们自己公司也是基于SAAS理念来构筑我们的电子商务平台,BEA是将三个热门的思想(WEB2.0 SAAS SOA)结合在了一起,放在这个创世纪平台上,这三部分任何一项都可以作为互联网应用开发的新理念来指导新一轮的互联网运动浪潮,不过结合起来是否能够达到想象的效果,这还需要实践来检验。BEA为我们演示了一个关于模拟汽车销售,服务,研发以及客户多角色共同参与的项目实践,在同一个业务系统中,角色的不同所看到的视图不同,同时不同角色可以相互沟通,更甚者客户可以对于设计者提出设计需求,同时销售可以观察客户行为,主动地推荐产品。同时BPM的流程管理灵活性也在这个展示中成为了灵活适应需求的一个亮点。

江苏电力SOA的实践:

一个感觉,画图的水平不错,满眼的线路图。

基础架构新探索:

这部分内容其实是对于第一部分的介绍做了部分的系统架构介绍,也就是对于刚在的Genesis平台作了一个总体的概述,以及一个远景规划。阐述了Genesis平台的层次结构设计,主要分成四个层次:

User Interaction

Business Process

Service Network

Hosting

最低下一层叫作Hosting,并不是我们常规考虑的硬件Hosting,而是指的我们各个业务系统原来的各种实现,也就是我们常说的各种信息孤岛或者就是不同的遗留应用或者针对SAAS来说就是ISV的应用,这些Hosting常常技术实现不同,但是希望能够被融合起来,发挥更大的价值。Service NetworkSOA概念中的Service Domain,这一层往往来说是我们现在比较关注去实现的一层,因为这层是SOA是否能够真正达到服务融合,服务复用的基础,如何让服务注册,路由,交互,为上层提供灵活组合的基础,是一个关键性的问题。Business Process层的作用主要是通过BPM来将下层的Service串起来,发挥服务灵活响应需求变化的要求。User Interaction这层次属于比较高要求的层次,其实也就是结合了Web2.0的一个特性,那就是客户参与和贡献,使得产品更加具有活力。

英国航空公司的案例:

另一个感觉,好多数字展示了英航在互联网信息化的成就。

以上是我上午听了四个主题讲座的如实感受和介绍,后面把我自己的一些新的体会感悟说一下。

       前面说了,ASFSCA-based Application Service Framework)第一期正好告一段落,其实在周二来上海之前,我正在画第一期的结构图以及后续需要规划和完善的功能图,当时其实有一些迷惘,作为我来说,不能和Tuscany一样做纯粹架构设计和实现,我需要关心业务部门的需求,根据需求来考虑框架功能实现优先级。根据首架的需求,我的第二期内容在年内暂时大部分内容是对于前期框架Web Service安全性能优化,多种分布式场景技术实现及测试,跨平台客户端兼容性的测试,最后一点就是ISV服务互通的架构支撑预研。总结了前期的工作,同时把一些新的功能点做了罗列(对于基础框架生命周期的维护和监测,扩展点的增加),同时也对性能优化方案作了初步的制定,但是总感觉好像有些迷失方向的感觉,难道按照现有需求就只需要完成这些就达到了我们ASF的阶段性交付了么,对于ISV服务互通采用什么策略呢?正好周二也要来上海,也没有再多想,不过虽然刚才说了早晨的演讲就这么些,但是对我脑子里那些问题倒是正好给了一些spark,下面就将这些spark一一道来。

       SPARK OneDBA。不要误会,不是我们公司的DBA,呵呵,是Dynamic Business Application的缩写。这个词汇是我第一次听到,也是BEA公司给我的一个新的概念,叫做动态业务应用。它的概念其实就是指服务于服务之间组成了业务应用可以根据用户需求灵活变化,成为动态而非过去,由需求,建模,概要设计,详细设计,编码实现而产生出来的传统商业应用。应为传统应用最大的弱点就是固化和僵硬,面对现在互联网应用的多变性和客户化,传统的设计理念和模式已经很难适应这种应用场景,因此需要一种敏捷的开发模式,面向服务+BPM+ESB,可能这些技术早就都已经存在并且也都曾经被广为推崇,但是结合起来所能达到的效果确不是1+1+1=3的效果。同时结合Web2.0的特质,倡导参与贡献多于遵循使用,这种灵活的框架模式无疑成为应用平台很好的一个理念。此时我回顾了我这段时间SCA的一些工作,当前的服务框架已经能够做到让开发者不用过多关心业务逻辑以外的内容,业务模块化和面向服务交互的理念已经深入开发过程中,但是考虑一下提到的以后ISV应用的互通解决策略,就可以发现,其实由于当前我们所开发的系统首先都是新系统,采用同样的技术架构,虽然ISV和我们的交互已经是异构环境,但是我们系统之间处于业务流程相对来说比较固定,服务组装交互实现可以定义好的情况,也就是说是一种服务静态组装的过程。但是对于未来我们的ISV应用来说,首先都是异构的实现,然后就是在ISV之间串联未必可以通过静态配置和设计事先确定,同时针对用户行为分析是否可以及时动态调整服务流程,都是一个动态的过程,这也给我一个启示,那就是第二期的互通,需要量体裁衣(最后会提到为什么要用这个词),来构造适合的Service Network Business Work Flow。当然这个过程还是和我先前说的一样,按照需求的优先级逐步实现,按需而进。

       Spark TwoUser Interaction。其实这个概念应该是我在我同事北京带回来程序员web2.0增刊中所看到的一个理念。我想现实生活中其实这类工作老早开展起来了,就好比你去商场买东西给你一个反馈表,让你填写一下,那么那个产品会根据客户的反馈作一定的改进。只是今天BEA给我展示的时候,通过不同角色所看到的用户操作界面的个性化和专业化,让User Interaction这个概念在技术上有了实实在在的表现,同时在基于刚才提到的DBA基础上,客户的反馈在最最极端的情况下都可以直接主导流程(即客户可以修改流程),不过BEA也说了这还是需要安全策略的配置允许的。那么作为我们未来互联网应用的场景下,这种面向客户的交互其实对于互联网应用来说无疑是很有吸引力的。

       Spark Three:社会计算。这个词很新鲜,也是今天第一次听到,下午也在一个分会场站了50分钟(会场太小,走错以后再回来就只能站着了)。社会计算和Web 2.0中的Social networking有一定的概念上的类似,其实就是沟通,也就是团体的沟通,个体的沟通,通过什么样的有效手段来沟通,rss,mash up,blog,都是一种手段,在上面的例子里面,买车子的客户可以通过blog反馈给DesignerSales可以push给客户一个小短片来展示给客户看新的产品,这些都是一些很有效的沟通手段,其实沟通就是为了双赢,互联网贸易除了安全这个大问题以外,剩下的最大问题就是如何让买卖双方因为沟通问题导致交易受挫。同时社区化是应用的互通价值最大化的有效生态环境保证。

       Spark Four:客户行为分析。其实也是一种手段,不过指的是自学习的一种行为分析,类似于Google对于客户行为分析。如果留意一下,我们在日常搜索中如果搜索的内容经常会出现,那么Google就会智能化的提高客户体验。

       其实,对我最有启发的还是第一点,同时对于我来说有很多的问题需要去深入了解和分析,同时结合当前框架以及业务场景做量体裁衣,这么说的目的其实在于听过了BEA的创世纪平台规划后,整个框架设计和理念都是让人觉得很有创新和价值的,但是BEA规划到了2009年,他的功能点和横向纵向切面都作了规划,但是这么一个庞然大物对于ASF来说并不合适,ASF也并不需要朝着这个方向发展。阿里的人都喜欢用武侠小说来打比方,我就打个比方,BEA为韦小宝提供了一套盔甲的解决方案,不论从外观和安全性上来说都是完美无缺的,不过韦小宝其实需要的是一件金丝甲,轻轻薄薄的,跑路快,又可以刀枪不入。同时有什么问题随时可以修补增改。框架设计的敏捷性和框架问题相应的敏捷性是同样重要的,庞大的项目版本周期长,为了不同客户订制困难,那么就是另一个固化和僵硬的体现。当然设计框架几个关键点需要把握:扩展性,规范通用性(不要用私有的协议),学习基础上的创新。

       上面是上午的内容,其实为什么花了那么多字写了上午的内容,其实是下午的内容没什么好说了^_^

       下午一共参加了四个分会场,一个就是刚才提到的站了50分钟的社会计算和Web2.0的讲座,概念性的介绍,不过扩展了思路。Liquid Infrastructure for Enterprise Java Application,这个课程名字不错吧,流动性的框架针对企业及的java应用,结果去了一听,是谈到使用vmware的产品,如何在服务器池中部署企业应用,提高效率和节约成本,晚上吃饭的时候和我们的测试部老大谈起了这个,他刚进公司就做了这样的实施,得却对于效能有一定的帮助,不过对我原先的理解就偏差大了,早知道仔细看看简介了。最后两节课是SOA一个培训的联系课程,今天下午四节,明天下午4节,我今天下午就参加了两节,最后两节,一节是谈到了关于SOA的治理,一位香港的朋友介绍的,听了一节课,就知道他最后一句说出了他SOA治理的名言:SOA治理最难的就是搞定内部关系,技术从来就不是问题。赫赫,这句至理名言好象在很多行业中盛行。第二节课是对SOA技术的一个汇总,讲师开始整一个介绍了Web Service的框架,最后才提了一句孤立的Web Service不是SOA,真是画龙点睛啊,要是没有这句话,我真的要为他捏把汗了,不过他发的BEA对于SOA的最后几个领域模型介绍还是应该蛮有帮助的,不过因为时间紧迫,他没有讲这些重点,而是把时间让给了最后BEA认证介绍的讲师。我么,提起包包,吃晚饭去了。

       这就是我第一天BEA的手记,明天是否会下午全部听完,这就要看我们同行老大的安排了,不过还是期待明天上午的主题演讲能够有一些Spark,让我也能有所收获。这次也看见一些同行的朋友提问,有些是技术型的,但是听那两个SOA讲座的有不少还是理论先行的,这感觉SOA又开始在这儿“漂浮”起来。

       总的来说,其实参加这样的大会我也早就有心理准备,未必能够真的了解很多核心的解决方案,只是可以接触一些新的思想,新的碰撞可能会给自己的工作带来一些灵感和启发,后续周末或者下周就可以把第一阶段总结和第二阶段的思考再从新规划一下。转眼就11点半了,洗澡睡觉,期待明天的碰撞,不论是否有火花。

posted @ 2007-12-13 20:38 岑文初 阅读(1039) | 评论 (0)编辑 收藏

SSL &WS-Security--Web Service安全保障

       今天早晨看了一下blog的留言,发现有位朋友给我留了言,提到了他正在研究SCA,同时也有些困惑,当在异构分布式环境的情况下,不论是否使用SCA规范来实现,都采用Web Service来完成面向服务的服务调用,觉得SCA没有什么优势可言。其实这是一个误解,SCA框架规范并不是一个具体的业务场景解决实施规范,它是一种框架结构性规范,它的精华部分主要在于:一.将抽象和封装由对象提升到了业务组件模块 .框架的可扩展性(也就是因为没有实现的约束,才会能够易于扩展)。当然这两点所带来的好处那就是在这么一个精炼的框架核心规范下,不断融入了外界的各种好的技术和理念,就好比现在的Web2.0最重要的一点特质,规范的只是接口(用于统一交互的管理),开放的是接口下的任何贡献,主动参与和主动的集成将会使得框架越来越有活力,Spring就是很好的例子。而SCASpring的差异我也早在前面的文章中说过,SCA和其他的规范一样,并不是一个横空出世的规范,是积累在过去的失败中沉积的产物。最后打了个比方,SCA规范好比一本菜谱,至于采用什么锅子,用哪里产的材料都是由厨师自己掌握,这也是架构师和程序员需要共同努力将这个规范实践的原动力,正确的做事和做正确的事是成败的两个关键。言归正传,继续这次的主题。

在前面的服务框架工作中,对于Web Service的支持成为了这段时间的重点工作,从开始的压力测试,Java客户端的兼容性测试到.net,php客户端的兼容性测试,WS-Security的集成,服务框架对于Web Service的支持在需求中逐渐增强。AEP第一期基本完成准备上线,第二期的需求也已经在酝酿中,ASF的第二期功能需求也逐渐的被提出来了,有一点看上去优先级比较高,因此我就开始动手先做,那就是SSL。一开始的时候对于SSL需求有些误解,以为是要做Web 服务器端的SSL,其实我们需要做的是硬件的SSL,只不过“首架”的意思是需要对SSL模式下的客户端调用作准备(的确,客户端在SSL不论是硬件还是软件模式下都需要作一定的工作)。后续将讲述一下我在做Web 服务器端SSL平台集成的工作和SA专家交流了解的硬件SSL的架构策略。

What is SSL

       虽然以前也对SSL有所闻,也常看到IE突然蹦出一个安全提示框,但是对于SSL的具体原理以及结构没有仔细看过。既然要用了,还是那个原则,先把原理搞清楚,然后再去实践。

       SSL(Secure Socket Layer)是一种通信交互协议,由Netscape公司在1994年制定,主要目的就是确保在web 服务器和浏览器之间数据传输安全。SSL协议层是在TCP/IP层和应用层之间。当前TLS(Transport Layer Security)正在逐渐替代SSL(最新版本v3)

       SSL协议分成以下几部分:

       Record ProtocalSSL的基础层,SSL所有的上层操作都是基于这个层次,这层主要负责消息内容的分段,压缩,加密和数字摘要等操作。

       Handshake Protocal故名思义就是握手协议,也是在正式应用数据传输前双方交换加密设置以及认证的流程规范协议。

       Change Cipher Spec Protocol是基于record协议层通知远端服务器修改record协议层中安全设置的协议。

       Alert Protocol是基于record协议发送警告到远端服务器的协议。

SSL的具体流程图:

 

       SSL的流程也体现了对于对称性密钥和非对称性密钥的使用,由于对称性密钥加密比非对称性密钥加密要快1000倍,那么对称性密钥被用来做对内容的加密,而非对称性密钥用来做传递对称性密钥的加密手段。

       服务端所需要具备的是一个拥有服务端的标示,公钥私钥对的证书。在握手的流程中,服务端将带有公钥的证书抽取出来发送给客户端,客户端就首先可以判断证书颁发者是否属于本机受信的CA,如果不是,就会类似于IE跳出提示,如果通过了这部分CA认证,双方就可以通过非对称性加密算法来交换客户端生成的临时对称密码,进行安全加密信息交互。

软件SSL的实践

       因为当前所有的单元测试都是通过我提供的ASF模板类,所以启动的Web Service都是服务框架中Jetty发布的Web Service,很轻量级,没有以往测试Web应用的复杂,不需要单独去启动一个Web Container。前期对于WS-Security的集成已经使得单元测试可以支持带WS-SecurityWeb Service的测试。

       抱着试一试的心理,直接用服务框架发布了SSLWeb Service,客户端调用了一下,没有成功,但是错误还不能定位是客户端还是服务端的问题,因此首先去外部配置了Tomcat来建立了一个SSL服务端。

Tomcat SSL服务端的配置:(只需要修改一个文件conf/server.xml

    <Connector port="8443" maxHttpHeaderSize="8192"

               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"

               enableLookups="false" disableUploadTimeout="true"

               acceptCount="100" scheme="https" secure="true"

               clientAuth="false" sslProtocol="TLS" keystoreFile="D:/work/asf/webservice/src/conf.test/keys/alisoft.jks"

               keystorePass="alisoft" keystoreType="jks" truststoreFile="D:/work/asf/webservice/src/conf.test/keys/alisoft.jks"

               truststorePass="alisoft" truststoreType="jks"/>

clientAuth没有必要配置成为true,不需要重复反向再认证。如果这个值设为false。其他几个值就是生成的服务端证书库位置及密码。这里所要注意的就是要求keystore密码和私钥密码一样,因为只有一个配置密码的地方,这在生成公钥密钥对时两者密码写成一致。这样就OK了,直接访问8443端口就能作为https来访问服务了。

采用XFire客户端来做单元测试,代码如下:

public static void SSLSecurityTest()

         {

                   Service serviceModel = new ObjectServiceFactory().create(IAccountService.class);

                   //https的客户端代码需要增加的

                   System.setProperty ( "java.protocol.handler.pkgs" , "com.sun.net.ssl.internal.www.protocol" );

                   System.setProperty ( "javax.net.ssl.keyStore" , "D:/work/asf/webservice/src/conf.test/keys/myisvdemo.jks" );

                   System.setProperty ( "javax.net.ssl.keyStorePassword" , "myisvdemo" );

                   System.setProperty ( "javax.net.ssl.trustStore" , "D:/work/asf/webservice/src/conf.test/keys/myisvdemo.jks" );

                   System.setProperty ( "javax.net.ssl.trustStorePassword" , "myisvdemo" );

                   System.setProperty ("java.protocol.handler.pkgs","com.sun.net.ssl.internal.www.protocol");

                   Security.addProvider ( new com.sun.net.ssl.internal.ssl.Provider());

                  

                  

                   String serviceUrl = "http://localhost:8080/axis2/services/AccountService";

                   String serviceHttpsUrl = "https://localhost:8443/xfire/services/AccountService";

                   String serviceHttpsUrl2 = "https://localhost:8443/axis2/services/AccountService";

                  

                   try

                   {

                            IAccountService service = (IAccountService)serviceFactory.create(serviceModel,serviceHttpsUrl2);

                           

//WS-Security所需要的配置

                            Client client = ((XFireProxy)Proxy.getInvocationHandler(service)).getClient();

                            client.addOutHandler(new DOMOutHandler());

                            Properties properties = new Properties();

                            properties.setProperty(WSHandlerConstants.ENABLE_SIGNATURE_CONFIRMATION, "false");

                            properties.setProperty(WSHandlerConstants.ACTION, WSHandlerConstants.SIGNATURE);

                            //properties.setProperty(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP);

                            properties.setProperty(WSHandlerConstants.SIG_PROP_FILE, "keys/client.properties");

                            //properties.setProperty(WSHandlerConstants.USER, "myisvdemo");

                            properties.setProperty(WSHandlerConstants.USER, "wenchu");

                            properties.setProperty(WSHandlerConstants.PW_CALLBACK_CLASS, ClientUtPasswordHander.class.getName());

                            //properties.setProperty(WSHandlerConstants.SIG_KEY_ID, "IssuerSerial");//"DirectReference","IssuerSerial","SKIKeyIdentifier"

                            properties.setProperty(WSHandlerConstants.SIG_KEY_ID, "SKIKeyIdentifier");

                            client.addOutHandler(new WSS4JOutHandler(properties));

                            AccountBean[] result = service.getUserAccountList("te", "ta");

                            System.out.println(result.length);          

                   }

                   catch(Exception ex){ex.printStackTrace();}

         }

       这样保证了客户端的配置已经没有问题了,因此就主要将ASF框架中的SSL集成进去。由于ASF中集成的是Jetty,因此只需要在Jetty动态建立Mapping Server的时候,Serverconnector为以SslSocketConnector类型来构造,这样就可以响应https的部分了,同时也可以在其它端口发布成为不需要SSL的服务。这里细节就略去了,改造不是很复杂,只需要对Jetty较为了解即可。不过这里还是要赞一下Jetty,真是轻量级的好东西啊。集成以后再次作单元测试,OK,测试通过。

.Net的客户端测试

       最后就需要对.netSSL的测试,由于.net客户端已经在上次配置了policy作为WS-Security的配置,按照常理来说应该不需要再配置证书之类的东西了,就尝试着做了一下,在建立Web Reference的时候会有提示说证书授权的认证不符合要访问的地址的身份,这个可以忽略。然后接下去测试了一下,就总是提示无法建立TLS/SSL的交互通道,查了一下,只需要加入下面一句话即可:

System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

它的作用就是接受所有的证书,也就是在我们SSL中的流程中,检查证书CA是否受信这部分省略,就好比我们访问一些非受信证书的网站跳出的提示框我们点击确认一样。

到此为止,应用服务器的SSL配置和测试就基本结束了。后面要谈到的就是硬件SSL的结构和设计。

硬件SSL结构设计

       首先为什么要使用SSL来加密呢,干脆用WS-Security就好了,而且WS-Security有着很多SSL所无法做到的特性(不基于传输层,保障非点对点的安全传输,部分加密等等)。但是在前面的压力测试中明显可以看到还没有用到加密,仅仅是签名服务器的CPU消耗就成倍的增长,可见对于性能的影响。同时上面提到的应用服务器SSL,其实也是类似于WS-Security,消耗比较大。因此就提出了硬件SSL的设计。

       这里主要提了两种,第二种也是现在SA比较推荐的。

一.              为应用服务器增加独立的SSL加速卡,例如roadcom CryptoNetXM卡,SSL加速卡的作用在于能够将应用服务器处理SSL的工作独立完成,让应用服务器专心处理应用请求,使得应用服务器性能不受影响。

 

SSL加速卡部署图

       由于许多服务器使用的是不同的加密数据,因此管理这样一个Web服务器组会花费比较大并且复杂。同时传统的负载均衡阵列中每一个处理加密服务器要求有一个SSL加速卡和数字证书,而证书是被CA签署过的一个电子认证标识,在加密通信方面提供了一致性的验证,这样对于CA的电子认证标识管理也是很复杂的一件事,因此产生了第二种设计模式。

二.              SSL基础结构与BIG-IP结合

BIG-IP是一个运行有BIG-IP负载均衡软件的服务器,它通过SSL加速卡实现了SSLoff-loading,同时还可以实现应用层和IP层的负载均衡。通过SSL终结,前端的BIG-IP负责SSL的集中处理以及同时将处理后的请求负载均衡到各个应用服务器上,这样既降低了SSL证书管理成本,也减少了Web服务器组的管理复杂性。

 



 

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1926332

posted @ 2007-12-10 08:56 岑文初 阅读(2591) | 评论 (1)编辑 收藏

 

       上周周四快速了结了对于搜索引擎的集成以后,又从新回到对ISV WebService接口集成和测试的支持中。测试部发现了一个很棘手的问题,将WS-Security集成到了ASF(应用服务框架)中以后,接口中如果出现中文,就会导致异常抛出。这个问题相关的同事已经跟踪了12天了,但是还是没有头绪,离周末还有一天,我赶紧接手,希望能够赶在测试部下周整体测试前修复这个问题。其实前面做了那么多工作,如果一旦这个问题被卡住,那么就会前功尽弃了。

       首先工作就是要确定,究竟是加了WS-Security导致中文问题,还是本来WS的中文返回就有问题。简单的做了单元测试验证了一下,确认了的却是增加了WS-Security导致的中文作为参数或者作为返回值都回抛出异常。根据异常的翻译来看,就是因为在消息体中出现了非法字符。前几天一位同事让我帮忙看WS的一个中文问题时发现,在Http头上对方返回的编码方式是utf-8而在SOAP消息体中,XML的编码方式却写着gbk,所以客户端解析器在解析SOAP消息中的xml时候采用的是Utf-8的编码方式,解析出来的中文自然是不对的。同时翻阅了一下资料,在xml  1.0的内部二进制嵌入必须用base64编码一下,否则是不允许出现非法字符,在xml 1.1已经对这部分作了扩展。所以这次集成了WS-Security产生的问题,可能就会因为这两种原因造成的。

       但是事实上并不是这两方面的原因造成,Axis2和当前很多Web Service框架都采用了Stax方式的Jaxp(Java API for xml processing),在带WS-Security和不带的两种流程中,所用的Jaxp的读写解析器采用的是不同的解析器,所以才会出现了上面的问题,因此还是要从根本上去了解Stax模式的Jaxp框架结构及工作模式。

Stax(Streaming API for XML)

背景

Stax不是很新的概念了,在2002年就被提出,在2004年被JCP作为编号为173JSR正式发布。因此在我们日常开发中如果说到Jsr 173就是关于Streaming API for XML的内容,同时,在lib中如果列了jsr-173.jar或者stax-api.jar也就是对于Streaming API for XML的接口定义包,同时这个包内只是定义框架接口,并没有具体的实现,JSR 173是接口定义规范,各个开源组织或者厂商都可以根据规范实现自身的Stax,这个后面的结构介绍中就会提到。Stax的创始者是BEA的两位系统工程师,所以在我们日后的出错中,如果类似于com.bea.xml.stream.XXX  Class not found 等错误,多半是在所有的lib库中没有对应的Stax的具体实现,只有接口定义。当前支持JSR的实现有Sun,Bea,Oracle,Breeze Factor和其他的一些开源项目(最出名的就是codehauswoodstox)。

Jdk 1.6种已经把Stax集成到了内部(javax.xml.transform.stax),顺便说一句的就是,在jdk1.5中,范型和对于Collection的增强是很成功的,而在jdk1.6中虽然没有1.5的很多新特性的融入,但是仔细观察一下就可以发现,其实对于xmlweb service的处理和支持作了不少的增强,其实也是针对当前SOA的大趋势作的技术方面的增强,很多概念和实现其实很早就在我们的应用开发中得到体现,个人觉得这也是Sun在开源后的最大受益之处(利用开源来汇集更多的亮点和精华),包括对于1.7OSGI的畅想,其实都是大势所趋。这让我想起了昨天看程序员增刊第一部分对于Web2.0中的特质的一项描述,利用集体智慧,有所放弃有所收获,放弃了独享的知识专利(当然核心部分可以保留),获得的是广泛的集体参与所带来的智慧亮点。

Stax结构体系和功能描述

Stax的提出开始,其本身就只是一个框架性的规范,并没有具体的实现约束,这也为各个开发商和开源组织认可这个规范提供了一个最基本的优势条件。这点也是当前所有的有生命力的框架或者系统所具备的最基本的特点之一,开放性,制定接口,规范流程,但是不约束具体的实现。

功能描述:

       这是我第一次去看JSR的描述,JSRJava Specification Request的缩写,也就是规范申请,其中所需要填的描述中就详细的写出了申请为JSR的目的(这比类似于国内申请专利之类的,不过感觉更为简洁和开放)。

       Streaming API for XML 描述的是一种基于javapull方式来处理XMLAPIStreaming API通过暴露简单的Iterator模式API提供给开发者处理XML的控制权。同时当前两种关于XML的规范,JAXBJAX-RPC也十分需要通过Stax模式来处理xml

       其实早在Stax出现之前,jdk中的已经有了jaxp家族,saxdom,这两种API分别针对不同的应用场景作了很好的封装。SAX是用于处理XML的事件驱动方法,由很多的回调函数组成。而DOM则是将XML解析成为内存中的树状结构,然后通过API来对XML中的元素和标签进行分析。SAX速度快,需要的内存小,但是无法修改XML,而DOM可以提供对于XML任意节点的访问,同时也可以写入内容到XML,但是缺陷就是速度慢,消耗内存大,需要把XML全部解析完以后才能够继续操作。

       网上对于Stax的好处有很多很详细的文档,就我自己的学习理解来看,比较重要的几点就是:1.pull方式替代了pushStax从名字上就可以看出和SAX十分相像,其实很大的一点不同就是在于Pull替代了PushSax可以实现很多固定的回调函数,然后在执行XML解析的过程中不断的被调用和处理,但是缺点很明显,首先被动回调导致开发者无法根据场景来动态选择如何裁减事件处理需求,同时无法同时处理多个XML2.StaxSAX可以更灵活定制事件处理条件。3.Stax可以写入XML4.Stax除了和SAX提供了一样的API模式的处理方式,还封装了Event模式的对象处理方式。5.StaxDOM性能高,应用场景广泛,特别是当前很多应用处理xml数据流时都需要边读边分析,当流结束以后就自动关闭了,此时可能已经将流释放,然而此时在作DOM分析已经无法实现,而Stax正好满足了这种需求。因此对于Stax适用范围的描述如下:需要清晰,有效的pull-parsing模式分析XML,另一方面也需要灵活的对XML Stream进行读写操作,需要创建新的事件类型和扩展XML的文档类型以及属性的情况。

Stax体系结构:

       下图中是Stax接口部分的类图,基本上已经包括了Stax规范中的大部分接口定义。


Stax接口类图

 

 

两类API设计接口:Cursor APIIterator API

       Cursor API的两个接口定义为:XMLStreamReaderXMLStreamWriter。这部分接口提供了类似于游标方式的方法定义,能够在XML解析过程中,从XML文档流获取或者写入信息,同样也类似于游标读取信息一样,只能前进不能后退,在任意一个时刻能够返回XML中的部分信息片断。

       Iterator API的两个接口定义为:XMLEventReaderXMLEventWriterIterator APIXML输入流看作了一组离散的事件对象,这些XML流读入并被Parser分析,然后被解析成为这类事件对象,在开发者的应用程序中,可以主动的Pull(拉)出需要处理的事件对象。

对于这两种API的选择基于下面几点:

1.内存有限类似于J2ME可以选择使用cursor API

2.性能是第一优先级,创建底层的库或者框架结构时使用cursor API更有效。

3.如果需要类似于管道处理XML,使用Iterator API

4.如果想要修改事件流,使用Iterator API

5.如果需要应用能够处理可插入的处理流程,使用Iterator API

6.总的来说,如果你对性能要求不是很高,建议使用Iterator API,因为它更灵活和易扩展。

工厂类

Stax采用的是抽象工厂模式来动态的根据环境配置加载不同的Stax的实现。在我原先查找问题的时候看来也是产生WS-Security中文问题的根源,当带WS-Security的时候对于XML流分析和读写采用了codehauswoodstox包中针对StaxCursor API实现,而不带WS-Security时对于XML流分析和读写采用的是axis2中实现的Cursor API 

工厂类都是抽象类,因此都需要实例来继承实现,如何选取工厂类的实现,并且通过工厂类来生成两套API的实现,按照以下的规则来载入:(以XMLInputFactory为例)

1.       读取系统属性,看配置中是否有javax.xml.Stream.XMLInputFactory等配置的描述。

2.       读取Jrelib/xml.stream.properties文件来读取配置。

3.       从可读取的Jar中读取在META-INF/services/javax.xml.stream.XMLInputFactory文件来判断载入哪一个的工厂类实现。

4.       使用默认的XMLInputFactory实例。

其他接口的说明

       XMLResolver接口可以在分析XML的过程中对于某些资源解析定位到定义和实现的方法上。

       XMLReporter接口用于报告所有的非致命的错误,致命错误通过XMLStreamException来报告。

对于接口使用细节可以参看sun公司的webservice tutorial


WS-Security中文问题解决

       在对新一代的Jaxp做了基本学习以后,那么对于axis2如何处理SOAP消息有了基本的了解,在跟踪了代码调试以后,发现问题主要是出在axis2rampart模块的Axis2Util类,其中的两个方法getDocumentFromSOAPEnvelope(SOAPEnvelope env, boolean useDoom)getSOAPEnvelopeFromDOMDocument(SOAPEnvelope env, boolean useDoom)。在有WS-Security和没有的不同情况下,传入的参数useDoomtruefalse,导致走了两个不同的解析流程。当useDoomtrue的时候,axis2通过SOAPEnvelope对象和axis2Streaming parser来解析和构建Dom Document。当useDoomfalse的时候,首先将SOAPEnvelope对象读入字节数组流,然后在根据Stax工厂生成实例,并且构造出StAXSOAPModelBuilder,然后返回通过StAXSOAPModelBuilder获得的Dom Document对象。

       察看了一下调用者传入参数的地方,其实是通过MsgContext的参数配置来确定采取什么策略,因此只需要将axis2.xml中配置增加一个parameter,设置useDoomtrue即可。或者就是做一个handle或者phaseInflowoutflow中配置这个参数即可。

       搞了那么久也就是修改一个配置,如果光从结果看,花了两天时间真是比较浪费,但是如果从过程来看,那么这两天时间所学到的那还是比较值的。

       由于第二天是周日,问题解决了也就没有再继续细究。但是周日早晨晨跑的时候,给自己列了三个疑问,首先为什么走系统获取的Stax会有问题,再则如果我用sunjaxp实现来替换是否能够解决此问题而不需要配置useDoomuseDoom两种处理模式究竟有什么区别。

问题的再次细究

       周一上班的时候还是记得周日早晨提出的三个问题,因此就仔细的再分析了一下这三个问题。

首先是采取sunjaxp替换,这个实现在sunjwsdp中已经包含了,替换以后然后强制在jre的配置文件中指定使用,出现了异常,看来直接使用还不行,需要针对一些参数作配置,特别是对namingspace的解析,同时也没有花更多时间去细研究。

再则,仔细回想了一下我在定位这个问题的时候做的实验,我曾经试图将中文先用Base64编码,然后服务端接收到以后回传,客户端再用Base64解码,没有任何问题。有时候换一个中文或者中文前后有字母数字,也可以正常处理,同时在跟踪代码过程中看过SOAP消息中的内容,内容是乱码。这让我有点启发,例如我输入参数为“岑文初”每次始终都会出错,如果输入为“岑文”,就没有问题,看了看内存内的变量,发现,原来如果是“岑文初”的时候SOAP消息中的标签封闭被破坏,如果是“岑文”,虽然是乱码,但是没有破坏标签的封闭。

仔细看了看上次提到的两个流程,其实两个流程除了parser不同以外,对于SOAPEnvelope的处理也是不一样的,走UseDoom的是直接将分析好的Dom对象返回,不做附加的处理,只是根据Envelope生成了SOAP的解析器以及配置了StaxCursor的两个接口实现类。不走UseDoom的情况则是完全将SOAPEnvelope再次序列化并且通过外部的Stax实现来解析和处理,但是问题就出在对象到字节流的序列化过程,默认的是使用了SOAP规定的utf-8编码方式,因此在这个过程中有些中文的内容就破坏了SOAP的消息包XML的标签合法性,导致外部解析器分析出现问题。如果将传入和传出的中文都编码成utf-8没有任何问题。

问题总结就是其实根源在于对于内容中的中文字符编码时采用Utf-8破坏了xml的封闭性,而我开始采用的useDoom正好规避了这个过程,也就自然通过了。但是就其设计本身来说,rampart应该是赞同使用useDoomfalse的方式,这才是真正的Stax的模式,同时有很好扩展性。另一方面个人觉得类似于这种抽象工厂机制来说,最好不要在系统变量或者jre中强制指定,这样会导致一些意想不到的问题,虽然是规范,但是细节实现毕竟有差异,因此一些特殊的开源框架的一些莫名其妙的xml解析问题也常常由于这些引起。

几点感悟

       灵活的SPIService Provider Interface)模式是当前框架设计以及底层设计的必要特质,开放才会发展得更好。

       灵活是把双刃剑,在遇到一些灵活的框架设计时,首先必须了解其原理和结构,然后根据实践来验证问题的缘由。

       抽象工厂还是有适用场景的,类似于JaxpSCA等框架的实现,抽象工厂以及利用JarMETA-INF/services来载入SPI的实现是IOC的一种很好的补充。


     更多内容请访问我的blog:http://blog.csdn.net/cenwenchu79

posted @ 2007-12-04 16:10 岑文初 阅读(1356) | 评论 (3)编辑 收藏

和第三部分同样,这部分内容其实应该在后面才对,不过当前工作既然做了,也需要写下来分享,那么就提前插队到成长记录当中吧。看了这篇文章以后,可能给人的感觉是有点偏离服务框架的内容。的却,如果纯粹从技术方面来说,这部分应该不属于服务框架范畴。拿杭州作个例子,杭州是全国唯一一个景点不但不涨价,反而免门票的地方,原因何在,无非是管理者看得远,景点的门票收益看得到,但是是小头,免去门票带来的商机那才是金矿。框架其实也是这样,如果客户用起来不方便,甚至都不能用,那么框架再好,也会有人笑话你是个高高在上的理论主意者,这种框架适合于教学,而非实用。现在也是在迈出平台服务框架兼容性的第一步,那天和同事们开玩笑说,以前联通移动的wap业务,好在大家的开发语言都相似,isp只需要兼容各种手机客户端,我们现在要做的就是兼容各种不同开发语言,平台,以后甚至浏览器,我们这种全部都搞通的人出去,那就真的是抢手货了。

周一测试部和ISV support小组的日报反映,.net的客户端对于复杂对象数组返回有问题,紧接着就是.net客户端对于web servicewsse无法调试通过。我以前没有接触过.net,没办法,硬着个头皮装了个vs2005WSE 3。前面一个问题就是我前面半周间断性的解决的问题,在第三篇记录中也写了。后面的问题比较紧急,也比较严重,因为如果wsse不能顺利调试通过,那么将会直接影响我们后续将wsse全面部署的计划,同时ISV已经跟在后面作测试了。看了看时间进度表,下周要进入平台搜索引擎增强的开发和WSSE性能优化(WSSE对于CPU的消耗真是厉害),因此也就只有两天,周四和周五。昨天晚上调试到了很晚(我说的很晚可能有些朋友觉得很早,不过对于我这种早睡早起的人来说,真的算晚了),虽然尽力了,但是还是卡在了最后的部分(服务端返回内容的验证解析),周五一大早到公司就开始继续调试,一直到了下午5点钟,我的神哪,让我看到那个断点不再跳出一个令我已经看到都反胃的出错提示框(顺便说一下,微软的vs出错提示框作的蛮精致,不过再好看都是出错,2天内看到了不下数百次,再好看也让人反胃了),最后在群里面大大的发泄了一把,公司一堆人觉得莫名其妙,不知道我受了什么打击,就搞通一个东西能够压抑成这样,其实这其中的苦也就自己知道,还是那句话:“在没有调试过.net的程序以前不知道开源的好啊,能看到源码是多么开心的一件事情啊,整一个在替微软作白盒测试,连google都被我翻烂了,也就只看到几个老外在Q,而没有人在那儿A”。废话说了那么多,言归正传,实践是建立在理论基础上的,那么先系统性的来介绍一下关于WSSE的内容(如果概念已经十分熟悉了,跳过即可),以及如何解决.net客户端无法调试Java发布的web service的问题。

在互连网应用中Web Service已经得到了广泛的认同,同时也是因为这种广泛的应用,使得Web Service在规范化方面越来越成熟。企业和企业之间的信息交互,很重要一点就是信息的安全性,电子商务等互连网应用这方面的需求更为突出,如果没有安全的保证,没有客户或者企业愿意将信息在网上交互,同时也不会信任任何接受到的信息。然而,作为SOA的有效技术手段,Web Service的动态性很强,服务的开发者无法预料到服务将在什么环境下被使用,因此服务的安全性变得更加复杂。

在考虑安全性方面主要有三个关键性的概念:

机密性(Confidentiality),完整性(Integrity,身份鉴别(Authentication)。

机密性:除了指定的接受者,其他人无法查看消息的内容。通常会使用密钥(对称或非对称)对消息加密,从而保证消息的机密性。
    完整性:确保消息在传输的过程中没有被修改。即保证消息的接收者接收到的消息与消息发送者最初发送的消息完全一致。通常会对消息做摘要(Digest),再使用密钥(对称,非对称)加密摘要,从而保证消息的完整性。   

身份鉴别:确保消息发送者的身份与消息中所声称的用户身份一致。最简单的做法就是让用户同时发送用户名和密码,服务方确认密码的有效性从而判断该用户身份是否与用户名所代表的一致。然而在实际的应用中的做法通常不会如此简单,此时往往会使用密钥对一段信息加密,服务方通过解密此信息确认用户的身份。

那么如何选择使用对称密钥还是非对称密钥?什么时候使用公钥,什么时候使用私钥?首先由于对称密钥的加密解密速度比非对称的密钥快很多(大约1000倍),所以在加密消息的时候一般都使用对称密钥。但是有一个问题就是对称密钥又如何发布呢?网络上两个没有联系的用户如何建立起一个共享的密钥?这时就需要PKI来帮助我们将这个共享的密钥建立起来,即利用非对称密钥中的公钥来加密那个共享密钥,传递到私钥的拥有方。由此可以知道:对称密钥加密普通信息,非对称密钥加密对称密钥。

Integrity,使用非对称密钥的私钥加密摘要,得到的东西是一个广为人知的东西—Digital Signature(数字签名). 而使用对称密钥加密摘要得到的是HMAC(Hash message authentication codes)。他们在保证消息完整性的同时,都具有身份鉴别的功能,不过前者还有一个功能---抗否认性。值得注意的是在Confidentiality中,使用非对称密钥方法是用公钥加密,私钥解密,而在Integrity中使用非对称密钥的方法恰恰相反。

在当前的安全策略上很多时候会使用到SSLVPN,他们的好处和缺点网上都有评论,但作为和传输层无关的安全策略,WS-Security规范无疑是最具广泛的应用。IBMBEA,Microsoft共同制定了WS-Security规范,解决了安全的三个基本问题:机密性、完整性、身份鉴别,在Web Services使用SOAPXML 格式)作为消息封装协议的背景下,标准化组织分别制定了XML EncryptionXML Digital Signature、与SAML(XML格式的Security Token)三套规范,WS-Security则是规定了如何将以上规范组合起来以满足Web Services安全需求的一套规范。

XML Signature规范是将数字签名和XML组合而成的产物,不要以为XML Signature仅仅是将数字签名技术应用于XML文件。

XML Signature包括以下的功能:

    1XML Signature可以对任何能够以URI形式(uniform resource identifier)定位的资源做签名。既包括与签名同在一个XML文件中的元素,也包括其他XML文件中的元素,甚至可以是非XML形式的资源(比如一个图形文件),只要能被URI定位到的资源都可以应用XML Signature. 这也代表了XML签名的对象可以是动态的变化。

    2XML Signature可以对XML文件中的任一元素做签名,也可以对整个文件做签名。

    3XML Signature 既可以用非对称密钥做签名(Digital Signature),也可以用对称密钥做签名(HMAC)

具体的标签以及含义就不做解释了,不过如果要做签名策略配置,需要熟悉这些标签,这也会影响到后续开发中遇到的各种问题。另外两个规范这边就不做说明了,因为现在服务框架暂时只是提供了Signature的要求,如果内容需要加密,那么对于应用来说性能可能是不可接受的,因此需要的是利用SSL和签名结合的策略来实现完整的安全机制。

对于WSSE的支持

       ASF这部分是改造了TusncayWeb Service子项目,Tuscany子项目内部集成的web service的开源框架是axis2,虽然很多朋友评价xfire好于axis2,不过个人在使用过程中感觉其实两者各有所长,只是说如何在适当的场合使用,如果需要和Spring很好的集成,那么xfire当然是最好的选择,如果需要能够有很好的wsse以及其他开源支持,那么axis2应该是个很不错的选择,毕竟apache组织下的开源项目众多,自家人集成起来更是得心应手,特别是wss4jaxis2的集成,axis2addressrampart两个子插件模块使用起来十分方便,同时在框架的可插入性和模块化上,觉得axis2要好过xfire。不过axis2的客户端比xfire要麻烦得多,xfire封装的好多了,这也是很多人喜欢xfire的缘故了(不过再傻瓜也抵不过.net客户端的傻瓜,不过这个傻瓜模式无法让人测试,那么就真的被当成傻瓜了),毕竟易用性往往是吸引到第一批客户的重要特质,这也是后续做ASF所需要考虑的问题。

       使用Axis2的框架结合Jetty这个轻量级内嵌容器作为Web Service发布框架(不得不提的是,在作web service的性能测试的过程中,公司的测试资深人员对于ASFweb service性能作了肯定,其实这和使用Jetty也有一定的关系,现在越来越多的开源框架都使用了Jetty作为内置web轻量级容器,很灵活,同时也可以达到很好的性能要求,在后面工作中对于hessian集成到服务框架中来,也是采用了Hessian+Jetty),并且通过Axis2rampart集成了wss4j,提供了WSSE的增强功能。

对于认证模式场景需求问题的解决

       ASF对于Web Service Security这部分只是要求了Signature,而对于Signature需要提供两种方式,UserNameTokenX.509证书。前者提供给内部的一些应用使用,后者提供给外部ISV使用,两者主要差别也就是在性能上,后者经过测试,在CPU的使用上,是6-8倍于不带SignatureWeb Service

       UserNameToken这种模式很简单,就很类似于我们平常的用户认证,用户名和密码作为明文或者加密,嵌入在Soap Header中即可,客户端根据本地保存的受信用户记录来交验是否是合法用户。

       X.509就比较特殊一些,所谓的证书,其中包括了公钥私钥对(作为签名和认证使用),证书颁发者的信息(可能是一些CA机构或者是用本地的证书生成工具自己生成),证书拥有者的身份信息,以及一些导入的受信第三方的公钥证书。当前的证书方式的签名认证主要有两种模式,一种是双方证书都是由第三方CA认证,同时双方都将对方的CA作为可信的CA,那么请求发起方将会把自己的证书放入到Soap Header中,接受方接受到请求以后,获取证书,发现是受信的CA,那么就认为请求发起方身份可信,同时在作完整性摘要校对。另一种模式就是双方的证书可以没有任何权威的CA作保证,但是双方首先就需要将附带自己公钥的证书发送给对方,对方将这附带有公钥的证书分别导入到证书管理库中(java是某个JKS.netwindows的当前用户或者本机的证书管理文件)。双方交互的时候不需要将证书置入Soap Header中,但是需要将证书的引用标示(序列号或者是X.509 SubjectKeyIdentifier)传递给服务端,服务端根据标示在本地的证书库中查找并且校验,这种模式的好处就是不需要CA的认证(省钱)同时传递的时候不需要将证书带入到Header中,节省了传递报文的大小,缺点就是双方需要互相保存对方的公钥证书到本地的证书库中,同时这种模式也为跨平台带来了很多问题,后续的互通中就会提到。

       ASF的证书认证模式中采用了后者,因为要求每个ISV去有一个第三方CA作为授权不是很可行,但是问题就是如果ISV需要导入我们的公钥证书比较方便,但是我们需要管理那么多ISV的证书,同时又需要动态上传修改保存证书那么就不能用原有的手动导入的模式,同时由于到时候部署的服务器集群不可能都维护一份本地的证书库,因此需要用数据库手段来维护,但是在应用启动以后再要新增或者修改证书,将会比较麻烦,因此采取了扩展wss4j的策略读取方式来适应新的应用场景。

扩展的CrytoProvider类图

扩展后的keystore初始化以及signature部分流程图

         这部分设计主要是扩展了WSS4JCrytoProvider,扩展后的CrytoProvider重载了获取X509证书的几个方法,这里类似于AOP,通过提供ICertsLoaderHandler接口来回调获取其它存储内的certs构建 visual keystore,同时在作signature的时候,如果发现ISVcert不存在于当前的visual keystore 中根据CrytoProvider的接口实现,来决定是全部刷新还是部分获取刷新当前的visual keystore中的certs。这样就可以达到了动态装载和刷新certs的要求,同时根据性能要求选择配置和实现不同的CrytoProvider

.NetJava的互通

       Java 的客户端和服务端Security互通很快就搞定了,只是对于一些应用场景做证书管理的扩展。然而,在经历了.net客户端调用Java发布的ws返回数组对象类型的问题以后,又一个大难题摆在了我的面前,ISV support小组和测试部的日报上把.net客户端无法在wsse的模式下调用Java 发布的 Web Service作为了重点问题,需要我支持,那么当然当仁不让的接下来尽快搞定了,虽然对.net来说,我算是新手中的新手,不过经过两天的测试,让我总结出了.net调试的技巧,那就是截包分析(感觉又回到我前几年在通信行业干活时的状况,对于对方协议不了解,又没有源码可看,那么就截报文来分析么)。开始挺乐观的,想着WS-Security微软也是参与者么,应该会严格遵守的,估计一天搞定,结果活活的折腾了两天,下面所描述的如何互通可能总的看起来应该不是很复杂,不过摸索的过程可真是很费事,google的每一条老外的信息都被我看过了,但是QuestionAnswer少。废话不多说,进入正题。

       首先不管是什么客户端调用什么服务端,都需要先做一件事情,准备key pairs。在Java中证书管理库可以通过Jdk提供的key tools这个工具生成jks格式的Java Key Store,可以将公钥导出,或者将公钥导入,同时可以生成秘钥对保存在证书中。在.net中可以通过makecert的工具来生成符合Public Key Cryptography Standards #12PKCS#12标准定义,包含了公钥和私钥的二进制格式的证书形式,以pfx作为证书文件后缀,同时可以通过mmcwindows的证书存储区进行管理,导入或者导出证书。其实.netjava的互通关键问题就是出在证书格式不同以及获取证书的算法上。下面就具体的描述一下如何从Java的开发者来做好Java WebService.net互通的工作。

        更多内容请参见:http://blog.csdn.net/cenwenchu79
posted @ 2007-11-26 00:43 岑文初 阅读(2956) | 评论 (0)编辑 收藏

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