锁定老帖子 主题:Web Services开发体会和项目教训
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2007-04-28
"另外一个问题是,我们的service方法,如果直接给WebWork这样的框架在服务端用的的话,是不会出问题,当提供给.net客户端用时,就会出现lazy loading的错误"
决得你们在架构上就有问题(呵呵个人见解),首先你要明白service是什么,按照DDD的说法,他就是一个服务,我们要完全把它以下的实现隔离开,在使用时不会去考虑里面是怎样实现的,只要想他是怎么样的就可以,他应该屏蔽以下的所有信息,lazy loading 应该是你DAO层的hibernate抛出来的吧,我个人决得他应该DAO层就应该被屏蔽掉了,而且我还有一点不明,为什么webwork调用就不出现lazy loading呢,webservice调用就出现问题呢,很难理解,你这块是怎么作的,我就知道,在用RMI,EJB时如果你用的Hibernate返回对像时,客户端必须有hibernate包,是因为,hibernate返回的有些对象是自已封装过的,例如List,所以如果你不想hibernate的包出现在客户端,你可以对List进行重新copy一下,呵呵,还是那句话,个人见解可能说的不对,请指示 |
|
返回顶楼 | |
发表时间:2007-04-28
我就一起回复几个问题吧:
题目应该改成采用ibm产品和解决方案的ws开发体会和项目教训 我认为我们的WS问题,与IBM的产品关系并不大,它绝不可能造成灾难性的影响,问题更多出在需求理解和WS技术应用。 确实,SOAP只是WS实现的一种方式,但开发效率比REST高,不过性能问题严重。 xml编码解码确实是慢,不过这也和具体类库有关系。 我们的客户端主要是“Static stub”,不是“Dynamic invocation interface (DII)”调用方式,也不是REST方式,所以,实际的开发中并不直接和xml打交道。另外,服务端是Bottom up方式,WS只是一个部署的问题。 你试过SOAPUI这个工具没? 我们试过一个“.NET Webservice Studio”的工具,它可以根据wsdl文件自动生成方法列表,然后可以输入每个方法的参数,直接调用,省去了自己写单元测试的麻烦,非常方便。但每次不得不重新输入测试数据。eclipse和RAD附带的那个插件和它使用类似。不知道SOAPUI是否是类似的东西? 但我们始终没有解决这样一个问题:象我们这种异构系统,服务器端怎么做功能测试?因为你直接测试服务器端时,回避了一个异构WS兼容性问题。而客户端的C#我还不知道怎么制作脚本,就象IBM的Function Test工具或loadrunner那样录入htpp交互脚本,我对.net不太熟,不知道是否有人用过这类录入工具,专门针对.net客户端的。回归测试和持续集成时测试脚本太重要了。 在用RMI,EJB时如果你用的Hibernate返回对像时,客户端必须有hibernate包,而WS... 那是因为RMI这种协议返回的是stub proxy的序列化对象,而WS返回只是xml文本描述,具体到客户端,就看该种语言对这种xml进行mapping转换了,而wsdl这种IDL定义了这种映射关系,它是各语言之间的桥梁。WS不存在客户端import服务器端package这种强制性要求。 我现在做的项目架构也经过了很长时间的选型。你们遇到的技术上的问题很多我也遇到过 .... 我觉得WS开发,还是遵循很多分布式开发模式,譬如EJB,那本《Core J2EE patterns》很实用。 一般针对WS开发,也有一些类似的最佳实践,网上很多介绍了,我也随便总结一下,特别是我们这个项目用到的: 1、和WS-I兼容 确保最大的互操作性。譬如对于SOAP message模式Document/Literal比RPC/Literal更具有平台中立性,不过前者Axis支持不好,用.net客户端会出现问题,纳闷。 2、使用简单类型 譬如对于Java服务器端,最好用String、int这类,或是自定义的User或User数组等复杂类型(User里面也是简单类型),但不要用List,Map等。其实我们想想,我们对外就是提供别人关心的服务,把我们平台特定的信息或冗余信息传给别人也不妥吧。 3、避免使用细粒度的调用 如果你客户端执行updateUser操作,最好该操作就是一个完整的、包括所有操作的一个facade,譬如该方法里面有更新用户基本信息,更新账号信息,更新用户组等一系列细粒度操作。试想,如果我们客户端依次调用这些细粒度操作,怎么去控制事务?而且,有严重的网络传输问题:http是短连接协议。 4、避免使用空值(nillable) 这些有夸语言兼容性问题。不是每种语言都对空值或null默认值处理友好。有人遇到这种类似问题http://weblogs.asp.net/pgreborio/archive/2003/11/14/37591.aspx http://www.mcse.ms/message908331.html 5、尽量避免在应用内部通讯时使用WS WS主要是为了SOA做的,只是把它当成一种分布式协议太浪费了,因为复杂的XML序列化、反序列化,XML为平台中立做出的IDL描述能力都是需要付出代价的。另外,远程调用协议,消息封装格式有很多种选择啊,SOAP不是惟一选择。我们这个项目恰恰犯了这个大忌,但也无奈。 6、尽量避免对象的深层次嵌套 想想那复杂的xml解析时的性能问题就明白了,也就是说我们的对象最好是plain结构,而不是tree结构。 其它最佳实践,欢迎大家补充! |
|
返回顶楼 | |
发表时间:2007-04-28
可能采用xml开发框架能避免很多麻烦, 楼主的问题我都用cocoon绕开了.
ws唯一特别的地方是它按照标准格式输出xml文档. 调用WS其实很简单 用soap也可以 其实直接post就可以了. 比如rss也可以看做ws的一种. 如果系统是ws结构的 频繁的使用xml传递数据 数据库部分依然采用关系数据库 肯定要付出性能的代价. 而且有些东西保存到关系数据库是很别扭的. 最主要的是将xml映射进关系数据库 xml就死掉了 失去了xml原先的灵活和柔性. 数据被关系数据库套死 整个系统也死了. 如果是内部调用可以不用提供ws接口 但是可以保留ws接口 这样做便于测试和日后对系统进行调整. 比如将他们拆开放到其他服务器上 变集中为分布. |
|
返回顶楼 | |
发表时间:2007-04-28
引用 xml编码解码确实是慢,不过这也和具体类库有关系。
我们的客户端主要是“Static stub”,不是“Dynamic invocation interface (DII)”调用方式,也不是REST方式,所以,实际的开发中并不直接和xml打交道。另外,服务端是Bottom up方式,WS只是一个部署的问题。 客户端慢点就慢摆,又不影响服务器性能。 主要看服务器端的xml编码解码能力,服务器端是java写的xml解析生成吗? |
|
返回顶楼 | |
发表时间:2007-04-28
winterwolf 写道 可能采用xml开发框架能避免很多麻烦, 楼主的问题我都用cocoon绕开了.
ws唯一特别的地方是它按照标准格式输出xml文档. 调用WS其实很简单 用soap也可以 其实直接post就可以了. 比如rss也可以看做ws的一种. 如果系统是ws结构的 频繁的使用xml传递数据 数据库部分依然采用关系数据库 肯定要付出性能的代价. 而且有些东西保存到关系数据库是很别扭的. 最主要的是将xml映射进关系数据库 xml就死掉了 失去了xml原先的灵活和柔性. 数据被关系数据库套死 整个系统也死了. 如果是内部调用可以不用提供ws接口 但是可以保留ws接口 这样做便于测试和日后对系统进行调整. 比如将他们拆开放到其他服务器上 变集中为分布. 我们的应用是不太可能采用cocoon这类xml框架,并且用xml做持久化: 1、我们项目组没有cocoon的开发经验。 2、xml数据库根本不太可能,我们的数据都涉及到国家基础数据,很多积累了上10年,海量的。 3、我们客户端提交的数据是由BO(著名商务智能软件)进行数据ETL(ETL:Extraction,Transformation,Load),最终从一批数据得到一些统计报表。 做项目,我觉得特别可怕的是:总是从技术的角度考虑问题。很多企业业务系统,最核心的、最复杂、最困难理解和分析的往往是业务问题,而不是技术。 |
|
返回顶楼 | |
发表时间:2007-04-28
zwchen 写道 做项目,我觉得特别可怕的是:总是从技术的角度考虑问题。很多企业业务系统,最核心的、最复杂、最困难理解和分析的往往是业务问题,而不是技术。 同意. 有过类似的经历. 但是问题还是出在软件开发上. 现在的ERP及其他的大型系统总是直上而下的设计和开发 无法顾及下面的具体业务需求. ws为我们提供了一个机会 我们可以从满足一个小部门的简单业务需求开始 做一个超大规模的系统. 这样软件开发是至下而上的. 就象战争不同的武器就有不同的战术 当我们手中有了新的武器就应该有新的战术来配合 依然采用贴身肉搏火炮也不起作用. |
|
返回顶楼 | |
发表时间:2007-04-28
看到这里,暗地庆幸,去年我们的基于SOA的项目搁置了,不然又是烂摊子一堆,不过我们没有过多的牵扯到安全方面,主要还是在异构平台互相通讯的问题上。
WS的性能真的是不敢恭维啊~ |
|
返回顶楼 | |
发表时间:2007-04-29
系统架构的问题,技术选型的问题,不熟悉的东西把握不好最好不要用,比如hibernate,用的不好对系统性能影响不是一般的
|
|
返回顶楼 | |
发表时间:2007-04-29
sorphi 写道 ahuaxuan 写道 zwchen 写道 Web Services慢是确定的,我们测试过,另外Hibernate用得也不妥,都是eager loading。 不需要用的对象,都应该手动将其引用置空,这个我想大概是你在分布对象是hibernate的使用cglib增强关联对象造成的,这个时候应该就是手动将这个po转化为vo,特别说明,hibernate在分布式环境下会比较难用一些,很多在单jvm上能做的事在分布环境中确实是不能做的。比如说hibernate自己的集合包装类没有序列化id啊,等等,这时候就需要一个比较精通hibernate的人在团队中“不需要用的对象,都应该手动将其引用置空”,这么做的依据或教训是什么?愿闻其详。 使用httpinvoker算是在分布式环境中么?我在这种场景下从来没手动置空过po中不需要的属性,但也还没碰到过什么莫明其妙的问题。 有两个原因,一个是不需的对象都是cglib的增强类,序列化和反序列化需要额外的开销,第二就是如果两端jvm不一样,那么序列化和反序列化是无法进行的,因为增强类是没有指定序列化id的,所以会使用jvm默认的序列化id,两端的jvm不一样会导致序列化后无法进行正常的反序列化 |
|
返回顶楼 | |
发表时间:2007-04-29
在“讨伐 ”Web Services性能的时候,考虑下,用Web Services目的是什么?如果你把一个单表的修改都用Web Services来实现,毫无疑问,你的系统性能将付出重大代价,Web Services设计本来就不是给你这样用的。Web Services的目的是提供“服务”,通常该服务的意义上来说,应该是重量级的服务。具有传输少,计算大(或者说业务复杂),一个小的数据提交上来,后台执行复杂的计算,或者复杂的业务处理,返回处理结果给前端。
我原来公司也做个一个项目,用Java写后台,CS跟J2ee服务器不停的交换表的增删改查的信息,还好这项目后来被取消了。 永远不要低估跨语言的交流的复杂性,这是我6年各种语言开发的经验之谈。 在实际使用Hibernate的例子中,我比较倾向于使用单个的PO,PO的逻辑关系由程序保证。当然这种设计不符合 Hibernate的思想,不过我的目的是解决问题,根据实际经验来看,这样做在项目中更有实际价值。我用Hibernate的目的只是不想写那么多Jdbc操作,我不打算用他来封装我的业务关系。我的业务逻辑体现是在数据库设计上体现。而程序开发的时候,表的关系是遵循模型设计开发,模型设计中会强制要求开发人员必须遵守模型的关系规则。虽然这样,会在代码中有很多不雅的代码(比起在PO表达对象关系来说),但是我觉得更可控。 |
|
返回顶楼 | |