软件开发的家园,编程爱好者的天地.

现在是:北京时间 2016/4/14 上午11:50:51 星期四

设为首页  |  加入收藏  |  网站地图

我对SOA的认识以及心得
发布于:第八基地 来源:互联网 作者:天堂路上 时间:2011-10-12 点击:176
注:本文来源于我给公司内部发的邮件中,所以背景都是基于我们现在的应用,而且思路也很混乱,请大家见谅。

自05年开始接触到分布式架构,06年在原先的基础上从头开始设计了一套分布式架构,当时SOA这个概念也没这么火。整个大平台的开发、性能和可扩展性都得到了考验,觉得有一些东西想和大家一起分享。

我不知道我所说的这些算不算真正的SOA,我也没读过什么SOA的书籍,我觉得SOA这个概念非常抽象,任何概念的产生都是由原因的。因此,我也不会说一些抽象的原则,只是想说一些在过去几年实施“SOA”过程中的一些心得和一些细节,希望对大家有用。

      不说什么是SOA,先来说说我们现有架构遇到的一些问题:

同样一个逻辑,A系统(ASP)使用COM实现一份(我们现在的JAVA库),B系统(.NET)在开发的时候觉得调用JAVA也是很麻烦的,索性自己实现一份逻辑,可能是存储过程,也可能是在代码中硬编码SQL,C系统(由系统部门开发的.NET程序)也用到了相同的逻辑,由于和产品部门缺乏必要的沟通,也实现了一份逻辑。最后,如果这个相同的逻辑需要修改,则需要修改A、B、C三个系统,一份逻辑在三个地方实施有几个缺点,一来是因为如果需要修改要改三个地方,二来是增加了工作量,三来是占用了不必要的资源(因为大家可能都实现了自己的缓存)。所有网站全部部署在一个WEB服务器上,直接实现负载均衡。这样的方案有几个缺点,一是几乎没一个网站程序都有自己的缓存,每台服务器的缓存是冗余的,而且甚至每个网站中的缓存都有重复,二是如果一个网站有问题会影响到其它网站(比如进程回收,应用程序池不能100%解决这个问题,而且我们现在并没有注重应用程序池的划分,又比如某些应用是长请求、过长时间占用线程),三是不能有效利用服务器资源,这是因为不是每一个网站都具有相同的访问量,不是每一个网站都需要相同的资源(有些需要特别多IO、有些需要特别多CPU、有些甚至是内存)。虽然说我们现在是使用了三层架构,但并没有什么重用,而且所有的层还是部署在相同的服务器上的。为了解决前面的2大问题,我们首先想到了:

 是不是有什么方法可以让相同的逻辑被其它系统重用? 是不是考虑把逻辑以服务的形式对外部(其他模块)公开?由此引入面向服务架构的概念,我们通过这些公开的服务进行逻辑的重用,提高系统性能也降低了模块之间的耦合性。架构图见我以前写的文章http://www.cnblogs.com/lovecherry/archive/2008/06/18/1224496.html

如果确实采用这种架构,我们的开发方式会有什么改变呢?

 在一般情况下,我们一般认为A系统对应A数据库,B系统对应B数据库,每一个系统都有自己的数据库。传统的方式是A系统和B系统在数据库端直接使用JOIN进行交叉耦合。如果实施SOA的话,最佳实践应该是对于大多数系统来说,禁止A系统直接访问B系统的数据库,反之亦然。我要你的数据,就必须调用你公开的服务。而且这个服务或者说接口或者说契约,尽量是粗粒度的。比如一个逻辑包括X和Y和Z三个过程,如果独立提供三个方法的话,每一次方法调用都是网络调用的过程,性能比较低,而且更重要的原因,这个模块提供了这么细粒度的三个方法,如果这三个构成了一定逻辑的话,很有可能这个逻辑就在调用方和提供方两个模块都实现了相同的逻辑。虽然说确实是提供了服务,但是没有达到封装逻辑这个重要的目的,而且也产生了性能的下降,这种服务就显得很不值得。一个大系统有许多模块或者说子系统,每一个都有自己的复杂逻辑和存储结构。开发人员可能只熟悉自己的那一部分,如果我的系统确实要用到其它系统的数据,按道理是应该想到调用它提供的程序集。很多时候我们并没有这么做,是因为我们并不知道对方有没有提供我需要的功能,即使知道提供了也不知道怎么去使用,如果要去用的话可能熟悉对方系统的时间会比直接在数据库中进行JOIN需要的时间还要长。这是一种恶性循环,因为这样又导致了一个逻辑在多处出现,一份数据在多处取得、保存和缓存。有了SOA,我们应该能在SHAREPOINT或WIKI上看到一份清单,在哪个HTTP或TCP端点上具有什么服务,服务中有哪些方法,这些方法是干什么的,返回什么,传入什么,使用的注意事项,如果我开发的系统需要用到外部的数据,我第一时间想到的不应该是去看数据库中我需要的数据在哪里,而是应该是去看看是否对方系统提供了这样的服务,如果没有提供的话则和服务的提供者进行一些沟通。你可能会问,我作为系统的开发者,我也不知道要对外提供哪些服务,我也不知道别人需要用到什么,确实是,但是至少我们现在可以做的是把内部使用到的一些逻辑以服务形式对外公开,一般来说自己系统的这些函数如果能满足自己要求的话从功能上来说可以满足别人要求,只不过别人可能需要的并不是这么多罢了。我们现在做TECHSPEC的时候可能关注内部的实现,如果是SOA的话,我们就需要关注现在在做的这个系统会用到别人的哪些接口,别人可能会用到我什么接口,我需要公开出来。可能还会考虑,我用了ABC三个系统的接口,是否需要把这个逻辑以粗粒度服务公开出来。每一个公开接口的参数、返回都需要仔细考虑,把这些都列入到架构设计中,和架构师一起完成服务的定义。开发人员可能只对自己系统的接口和逻辑比较熟悉,架构师的作用是给开发人员建议,哪些接口你可能需要,哪些接口你可能需要对外提供,是否需要做缓存。我们现在的部署是非常简单的,如果实施了SOA,很有可能一个系统需要调用十几个外部子系统的接口,每一个接口都需要制定地址、调用策略以及契约。地址和调用策略需要是可配置的,一般定义在配置文件中或者数据库中,这样一个系统的部署可能非常复杂,打个比方就像芯片的引脚一样,有很多,一个引脚没有接到合适的地方,系统就不能工作。虽然部署负责了,但是系统之间的耦合非常小的,大家只是依赖于某个网络环境中的地址,依赖于某个契约。这样的话,系统的伸缩性就很强,有些服务需要很高的资源,就给独立的服务器,有些服务占用资源很小,可以合并在一起。当然,也可以根据服务的性质,比如特别需要IO、特别需要CPU来分配到合适的服务器上。服务器并不一定是一样的,有的服务器内存特别大,有的服务器CPU特别好。还会遇到一个问题,就是开发人员不太愿意调用其它的接口。一是对别人的东西往往默认会觉得是实现糟糕的,性能很差的,二是觉得不放心,会不会到时候你没给我正确的数据,影响我的开发,产生相互推卸责任的问题。其实,这种想法不对,一个人不可能开发系统的全部,作为使用者来说要使用别人的接口信任别人的接口,作为接口提供者来说需要积极对自己的接口负责,进行完善的单元测试,如果调用者有特别的需求在讨论后进行改进。这也就是说引入SOA的话,我们需要更多的沟通。
下一篇:ORM漫谈
对我有帮助
(0)
0%
对我没帮助
(0)
0%
返回顶部
在线反馈
在线反馈