当我们在为一个软件设计架构的时候,我们不仅仅要确保所做出来的架构要满足系统的业务需求,更加要确保做出来的架构要满足可维护性,安全,稳定性的非业务行的需求。

另外一个非常重要的非功能性需求就是性能。性能涉及到很多方面的关注点,例如吞吐量,延迟等。SOA的很多的设计原则和一些指导从来没有告诉我们如何去解决SOA中遇到的性能问题,因为SOA的关注点不在这里,其实SOA天生就是会导致很差的性能的:因为SOA涉及到了分布式,这就决定了它有很多不得不要的延时和不同的层之间的通信问题。

任何问题,都有其对应的解决方法或者缓解的措施,我们在接下来的文章中会给给出一些解决方案来实现如何在SOA应用中提升性能,扩展性,还有可用性的问题。

在SOA应用中,提升性能的一个常用的策略就是使用负载均衡,这一点我们在后面详细讲述。如果负载均衡使用的合适,它确实会在很大的程度上面提升服务的可用性。 
很大的技术朋友感到性能,可用性,扩展性很容易通过使用很大的硬件设备来达到。其实很多的情况下,事情都不是这么容易的,尤其是当新的技术和开发的方法引入的时候。

在SOA应用中解决上面提到的那些问题的时候,我们不是一头雾水,而是有很多的现存方法和经验可以借鉴。所以,我们现在面临的挑战不是说“找不到方法”,而是“如何更好的,恰当的使用这些经验和方法”。

因为我们在后面会讲述一些常用的模式,其实我们知道:模式就是对一类问题的解决方法,但是很多的人会把模式滥用,误用。 
言归正传,下面我们就进入详细的讲述。

提出问题

为了使得大家更加清楚的知道这个模式的使用场景,我这里还是通过一个示例来进行说明。现在假设我们有一个在线的音乐网站。我们这个音乐网站购买一些唱片或者下载一些歌曲。这个音乐网站运行了一个后台的服务,专门用来批量的购买唱片的订单。另外,这个站点还运行了一个实时单向的处理订单的服务:就是用户下了订单之后,然后立刻就处理。

大家肯定会想:为什么要搞两个这样的服务呢?

1.      这是一个假定的场景,为了说明一些问题。

2.      在现实中,有时候确实存在这样的情况:如果实时的订单处理是在忙不过来,那么就把订单保存起来,在后台运行服务进行处理。

在图中,左边的请求量就反应了在一般的正常的情况下,音乐站点每天的业务情况。此时,一般是由服务1还处理用户提交的订单。如果站点业务是在太忙,一部分的订单处理就会分摊到服务2。

在图中,右边的请求量就反应了一个比较极端的情况:某一天某段时间内,大量的用户在站点购买唱片,此时导致服务1要处理的清单极多,而此时,这些订单的相关还没有及时的保存到数据库中,导致服务2无法为服务1分担任务。

所以,我们的问题就是: 如何设计服务,使得其花费的成本最小(经济方面),同时又使得服务可以同时处理一般情况和一些比较极端的高负载情况的请求,而且还不会挂掉 。

当然,我们为了可能想砸钱购买一些很强大,很多的设备来应付,但是如果这些高负载情况出现的不频繁,那么大部分时候,这些设备可能就是闲置了,那钱就花得有点冤枉。现在,另外一个比较不错的选择就是使用一些“云”,在高负载的情况下,我们付钱购买更好的设备和相关的支持,一旦过了高峰期,我们就不使用这些额外的设备和支持,也就是 按需花钱 。

如果我们不用“云”,我们如何设计呢?

解决方案

采用Decoupled Invocation模式,将请求与回复进行分离:服务的边界收到请求的数据包,然后将其放在一个可靠的队列中,然后从队列中读取数据包,采用负载均衡将这些请求按照优先级分发到不同的处理组件上面。

我们看到下面的这个图,在图中我们可以知道:Decoupled Invocation模式的实现需要三个基本的组件:一个处理者,一个队列,还有一个分发器。

看到下图:

下面我们就介绍一下这个模式的实现是如何工作的:

1.      首先 处理者 负责监听发送到服务的请求。

2.      新的请求到达之后, 处理者 发送一个应答的响应给发送者(如客户端),告诉发送者,我们已经收到了。

3.       处理者 的主要的职责就是初始化请求处理,或者进行消息的转换等。不管怎么样,这个初始化的处理的动作要尽可能的小,目的就是为了使得处理过程更快,更快的处理下一个请求和发送应答响应。

4.       处理者 把请求消息发送到队列中。队列是这个模式需要实现的第二个组件,用来保存接受到的消息。

队列的实现方式有很多,我们在实现队列的过程中,把保存的请求消息持久化,以免出现丢失数据的问题。如果队列支持事务相关的功能,那么我们可以在借用之后要讲述的Transaction Service模式来配合,从而增强可用性与健壮性。

分发器是第三个需要实现的组件。它主要是用来创建多个消息读取器的,然后不同的读取器将消息发到了对应的业务组件。分发器可以把接收到的消息按照一定的优先级来划分(优先级的定制可以按照业务或者相关的资源来考虑)。分发器在整个Decoupled Invocation模式实现中其中至关重要的位置,因为它可以延时对请求的处理。

这里有一点需要注意的就是有关服务发送应答消息给请求发送方 。

我们刚刚说过,服务端这边接收到了请求之后,其实还没有处理,而是保持请求消息,以便后面去处理。所以此时服务这边只是发送了一个很简单的响应应答消息给发送方,告诉它们消息已经收到了。但是很多的时候,事情不是这么简单。例如,电子商务站点中把订单请求消息发送之后,我们希望得到一个订单的编号和一些处理的信息,而不是简单的Yes或No。

所以,在使用这个Decoupled Invocation模式的时候,一定要把不同的消息区分开来,不能把所有的消息都按照这个方式来实现。特别是那些涉及到业务处理才能回应的请求要特别的处理:需要不同的边界来发送响应。这可能不太好理解,我这里还是解释一下。看到下面的图:

在上图中:

1.  如果请求的消息只是一般的消息,可以延迟的处理,并且发送方只要知道消息是否被接受了,不需要额外的信息,此时我们可以让处于第一个边界的处理者直接处理(把请求保存,然后发送响应)。

2.  如果请求的消息的发送需要更加详细的应答响应信息,那么处理者就不能草率的发送一个简单的响应了,而是要把消息进一步的传递到更深的层次,发送业务组件,然后业务组件处理之后,发送响应给客户端。

到这里,朋友们就会发现: 如果是第二类的消息,这个模式似乎就没有作用了:因为消息还是要实时的处理了。不否认,存在这个问题,或者说,我们这里讲述的这个模式可以很好的处理第一类消息,对于第二类消息的处理,也不是没有作用的 。

我们可以把消息再次的分析, 分为浅层处理的消息,深层处理的消息 。所谓的浅层处理的消息,这主要是根据请求方的期望来分的。如果我们把一个消息完完全全的处理看出是100%的话,或者说,请求发期望的响应只有把服务方把整个消息彻底的处理完之后才能得到,例如,订单的处理,如果请求发要知道处理的完全的详细信息,例如编号,配送日期,配送厂家,发货员等等。

其实这样的情况在现实中有,但是不多见,就拿我们现在的几家大型的电子商务站点而言,我们提交了订单之后,只要知道订单的编号,是否开始配送就行了,我们不是希望立刻马上得到100%的全部信息。所以,现实中的订单处理的请求消息都是浅层处理消息,我们可以定期的去查看状态。

所以,一般而言,我们还是可以使用这个模式来处理消息的。如果消息需要进一步的处理才能返回响应,我们可以在分发器这里把这些消息放在一个高优先级的对象中,尽可能快速的处理。

也不是说,我们非要在消息处理的时候要用这个模式才能实现高性能。这个模式最好的使用场景就是在 请求-回调 (这一点要和我们常常看到的请求-应答区分)。

所谓的请求-回调就是:发送请求消息之后,不需要立刻得到完全的响应,可以在之后由服务器回调客户端,发送消息。很多的时候,我们可以采用异步的方式来实现。客户端发送方不用等处理完之后才返回。而我们常见的“请求-应答”方式,就是客户端发送方把消息发送之后,就等着服务端处理完成之后,才进行后续的操作。

技术实现

下面,我们就看看如何使用现有的技术实现这个模式。首先,要实现这个模式,我们最好是采用成熟的解决方案和组件。很多的企业级的消息组件都可以用来帮助我们。例如,微软的MSMQ,Java中的WebSphere MQ, Progress SonicMQ,还有Apache ActiveMQ,另外还有基于AMQP的队列RabbitMQ。

另外,在实现的时候,需要考虑是否把请求消息持久化(很多的队列都可以配置是否持久化消息),如果不持久化,也就是把消息放在内存中,那么业务逻辑组件和前面的边界组件都要在一个进程中。如果持久化了,那么使用消息的各个组件就可以运行在不同的进程中,从而达到高性能。在.NET中,我们借助WCF采用上述的思想,可以实现高性能的消息处理的。代码示例这里就不举例了,掌握了上面的思想和介绍的消息组件,应该是没有问题的。

备注:本文已经投稿IT168并且出版,转载请标注出处!

(转)如何构建高性能,稳定SOA应用之-负载均衡-Decoupled Invocation(一)的更多相关文章

  1. 快速理解高性能HTTP服务端的负载均衡技术原理(转)

    1.前言 在一个典型的高并发.大用户量的Web互联网系统的架构设计中,对HTTP集群的负载均衡设计是作为高性能系统优化环节中必不可少的方案.HTTP负载均衡的本质上是将Web用户流量进行均衡减压,因此 ...

  2. 基于开源软件构建高性能集群NAS系统,包括负载均衡(刘爱贵)

    大数据时代的到来已经不可阻挡,面对数据的爆炸式增长,尤其是半结构化数据和非结构化数据,NoSQL存储系统和分布式文件系统成为了技术浪潮,得到了长足的发展.非结构化数据目前呈现更加快速的增长趋势,IDC ...

  3. 利用 Rational ClearCase ClearMake 构建高性能的企业级构建环境

    转载地址:http://www.ibm.com/developerworks/cn/rational/r-cn-clearmakebuild/ 构建管理是 IBM® Rational® ClearCa ...

  4. 高性能Linux服务器 第11章 构建高可用的LVS负载均衡集群

    高性能Linux服务器 第11章 构建高可用的LVS负载均衡集群 libnet软件包<-依赖-heartbeat(包含ldirectord插件(需要perl-MailTools的rpm包)) l ...

  5. 构建基于分布式SOA架构的统一身份认证体系

    摘要:本文充分利用SOA架构松耦合的特点,通过规范统一网络接口实现业务系统整合,既提升系统安全性,又简化资源访问操作,具有重要的理论和现实意义. 统一身份认证旨在将分散在各个信息系统中的用户和权限资源 ...

  6. FPGA+x86构建高性能国产网络测试仪竞技之道

    众所周知,以太网已经深入我们的生活无处不在,企业.校园.大数据中心和家庭等都离不开网络,否则我们的生活将受到严重的影响. 以太网的接口速率也是迅速发展:10M.100M.GE.10GE.40GE.10 ...

  7. 【读书笔记】2016.12.10 《构建高性能Web站点》

    本文地址 分享提纲: 1. 概述 2. 知识点 3. 待整理点 4. 参考文档 1. 概述 1.1)[该书信息] <构建高性能Web站点>: -- 百度百科 -- 本书目录: 第1章 绪论 ...

  8. 【推荐】【给中高级开发者】构建高性能ASP.NET应用的几点建议

    本篇目录 早期阶段就要对应用进行负载测试 使用高性能类库 你的应用是CPU密集还是IO密集的 使用基于Task的异步模型,但要慎重 分发缓存和会话(session)状态 创建Web Gardens 巧 ...

  9. 《构建高性能web站点》随笔 无处不在的性能问题

    前言– 追寻大牛的足迹,无处不在的“性能”问题. 最近在读郭欣大牛的<构建高性能Web站点>,读完收益颇多.作者从HTTP.多级缓存.服务器并发策略.数据库.负载均衡.分布式文件系统多个方 ...

随机推荐

  1. 【JavsScript】Spine的作者曾经是Backbone的作者

    基于MVC的JavaScript Web富应用开发 Alex MacCaw,是一名Ruby/JavaScript程序员,在开源社区中很有名望,是Spine框架的作者,开发过Taskforce,Soci ...

  2. windows下如何github ssh 公钥

    windows下如何github ssh 公钥   1. 安装git,从程序目录打开 "Git Bash"  2. 键入命令:ssh-keygen -t rsa -C " ...

  3. Linux内核高端内存 转

        Linux内核地址映射模型x86 CPU采用了段页式地址映射模型.进程代码中的地址为逻辑地址,经过段页式地址映射后,才真正访问物理内存. 段页式机制如下图.   Linux内核地址空间划分 通 ...

  4. xy

    用C#實現Blob數據類型 PowerBuilder提供了Blob數據類型, 用來處理二進制數據(如:圖像,文件,二進制流,文本等等). 本質上, Blob是可變長的字節數組, 它提供了一系列全局函數 ...

  5. GNU C/C++ __attributes__ GCC中的弱符号与强符号

    最近在看一些源代码,遇到了一些使用__attribute__修饰函数和变量的属性方面的代码,不是太了解,很是汗颜,再此做个总结:   GCC使用__attribute__关键字来描述函数,变量和数据类 ...

  6. 完美的.net泛型也有特定的性能黑点?追根问底并且改善这个性能问题

    完美的.net真泛型真的完美吗 码C#多年,不求甚解觉得泛型就是传说中那么完美,性能也是超级好,不错,在绝大部分场景下泛型表现简直可以用完美来形容,不过随着前一阵重做IOC时,才发现与自己预想中不一样 ...

  7. IOS 按比例裁剪图片

    拍照或者从图片库中获取图片 操作过程中容易闪退,也总会有内存压力警告,第一步,首先可以考虑裁剪图片,实际上可能不需要那么大的.其次可以考虑把耗时的比如存储过程放进线程. 这里封装裁剪图片的类方法. / ...

  8. How to setup ELM327 Bluetooth WiFi for Android software Torque

    1.    Install OBDII 2.    Install Android Software Torque a)    Copy software to phone from CD b)   ...

  9. 单表多次join的sql

    select o1.emp_name as 员工姓名1 , o2.emp_name as 员工姓名2 from tableTest join employee o1 on tabletest.[Emp ...

  10. [Java] SSH框架笔记_SSH三大框架的工作原理及流程

    Hibernate工作原理及为什么要用? 原理:1.通过Configuration().configure();读取并解析hibernate.cfg.xml配置文件2.由hibernate.cfg.x ...