背景

基于总线的设计,借鉴了计算机内部硬件组成的设计思想(通过总线传输数据).在分布式系统中,不同子系统之间需要实现相互通信和远程调用,比较直接的方式就是“点对点”的通信方式,但是这样会暴露出一些很明显的问题:系统之间紧密耦合、配置和引用混乱、服务调用关系错综复杂、难以统一管理、异构系统之间存在不兼容等.而基于总线的设计,正是为了解决上述问题.总线则作为中枢系统,提供统一的服务入口,并实现了服务统一管理、服务路由、协议转换、数据格式转换等功能.这样能够将不同系统有效地连接起来,并大大降低了连接数(每个子系统只需要和总线建立连接)和系统间连接拓扑的复杂度.

如图所示:

基于服务总线的设计,往往需要ESB(Enterprise Service Bus,企业服务总线)产品来充当基础设施.ESB采用了“总线”这样一种模式来管理和简化应用之间的集成拓扑结构,以广为接受的开放标准为基础来支持应用之间在消息、事件和服务的级别上动态的互连互通. ESB是一种在松散耦合的服务和应用之间标准的集成方式.

在其内部设计和实现中,通常会应用到一些经典的架构模式,例如:Broker模式、消息总线模式、管道过滤器模式、发布订阅模式等.这里,我们将重点介绍这几种核心的架构模式.

Broker模式

Broker可以看作是服务总线中的一部分,通常应用于同步调用的场景(调用服务后阻塞,等待远程服务响应完成后再返回结果).Broker可以看作是代理、分发,意味着对服务的调用,可以直接通过Broker来完成.在软件架构设计中,向已经存在(引用或者调用)关系的两者中间加入“第三者”是一种常见的解耦方式,显然,Broker也不例外.

如下图所示:

为了进一步加深读者对Broker模式的理解,这里通过举例来说明:

在现实生活中,我们需要租房子(可以看作是一种服务调用),可以通过几种途径来完成.第一,我们可以先在网上了解,然后跑到目标小区去询问和看房,最后再找房东签合同等;第二,也可以直接找附近的地产中介,说出我们的要求和预算,请中介直接帮我们搞定一切.很明显,第一种方式,需要自己对目标有足够的了解而且还要亲自去找房东签合同(依赖具体,可以看作是紧密耦合),而第二种方式,仅仅需要告知中介需要什么即可完成租房,甚至都不需要知道哪个小区有房子、房东到底是谁等这些信息(依赖抽象,并通过第三者来实现解耦).当然,找中介虽然省事,也会产生额外的经济开销.同理,通过Broker来调用服务也可能会产生一定的开销.

消息总线模式

SOA系统有三种基础组件:消息总线、信息转换/处理引擎和存储库.一般来说,这些组件会集成到ESB中,而在这些基础组件中,消息总线是最重要的.消息总线主要应用于异步通信场景(投递消息后立刻返回结果,而不用等待远程系统返回执行成功),可以大大提升响应速度和系统吞吐量.当然,消息总线也同时支持同步通信模式.基于消息总线模式的设计中,消息中间件屏蔽了系统间底层通信的细节,是比较典型的(异步)松耦合的架构.

在企业中,随着业务的逐渐发展,各大系统之间的调用交互变得非常频繁,关系错综复杂.

想象如果有几十或者上百个系统(在保险、金融领域很常见),将变得难以维护.通过引入消息中间件,便能有效的解决这些问题.不同系统之间,只需要连接到消息总线,能保证成功投递/接收消息即可.对于消息投递者(生产者)而言,根本不用关心消息的接收者(消费者)到底有哪些,也不用关心消费者接收到消息之后该如何处理.对于接收者(消费者)而言,只需要关注与自己有关的消息,接收到消息后并做出相应的处理即可.

如下图所示:

比较典型的应用场景:张三在CRM系统中录入了一条客户签约订单的信息并审核通过后,CRM系统会向消息总线投递一条消息(消息中包含必要信息,例如员工ID,订单编号,产品编号和交易金额等,而CRM系统不用关心有哪些系统会接受到该消息).员工绩效奖金管理系统订阅了该消息主题,收到消息通知后开始处理(给张三执行加奖金操作),同时,进销存系统收到消息通知后也会即时地更新商品库存的数量.这样,便实现异构系统之间的松耦合、异步通信.当然,真实场景可能比这里更复杂,但是实现思路上都大同小异.

在理解了上述实例之后,有必要了解下Java EE中被广泛应用和实现的JMS(Java消息服务).

JMS是一种关于消息的规范,业界流行的ActiveMQ则是实现了JMS规范的开源消息总线.

JMS支持两种模式:发布/订阅模式和队列模式(点对点模式).其中,发布/订阅模式借鉴了现实生活中的出版社(发布图书)和读者(订阅图书),消息的消费者(读者)只需要订阅自己感兴趣的消息(图书)即可,消息生产者(出版社)生产(出版)了消费者(读者)感兴趣的新消息(新书)后,会通知消费者(读者)接受处理.在JMS发布/订阅模式中,通常以Topic(主题)来标识消息,是一对多的模式,意味着同一个主题可以同时被多个消费者来订阅和消费.而在JMS 队列模型中,通常以Queue name来标识消息,是一对一的模型,意味着同一条消息只能被一个消费者接收并消费(且只能被消费一次).在生产者和消费者都是集群的环境中,通常需要将这两种模式结合起来使用,情况会复杂很多,而且需要考虑容错性、负载均衡、消息一致性、消息优先级等复杂的问题.

业界主流的消息总线(消息中间件)产品,普遍支持消息过滤、自动重试、分布式事务、持久化、消息优先级、消息回溯、(生产者/消费者/中间件自身)集群、故障转移等高级特性.

总结

基于总线架构的主要优势在于:

可扩展性

使用消息架构,可以在不影响现有应用的情况下增加或移除应用.

低复杂度

每个应用只需要和总线通信,只有1个连接点,降低了应用程序集成的复杂度.

灵活性

对于构成复杂处理的应用程序通信组来说,只需要改变配置和控制路由参数就能满足业务逻辑或者需求变更,而不需要更改服务本身.

松耦合

应用程序直接和消息总线通信,不依赖其它应用程序,因此可以替换和修改.

可扩展性

可以把多个应用程序附加到总线上,进行并发处理,达到负载均衡的目的.

基于总线的模型,可以面向同构和异构系统(跨平台).当前主要应用于传统企业应用的整合与系统集成中(例如:电信、保险、金融等行业).由于基于总线的模型是一种集中式的架构,总线自身容易形成性能瓶颈,但可以通过横向扩展, 然后在其上层增加LVS进行负载均衡, 实现高并发,高可用.

SOA服务总线设计的更多相关文章

  1. SOA实践之基于服务总线的设计

    在上文中,主要介绍了SOA的概念,什么叫做“服务”,“服务”应该具备哪些特性.本篇中,我将介绍SOA的一种很常见的设计实践--基于服务总线的设计. 基于服务总线的设计 基于总线的设计,借鉴了计算机内部 ...

  2. WisDom.Net 框架设计(二) 服务总线

    WisDom.Net 框架设计--服务总线 1.Soa 简介     soa 就是面向服务的体系结构 是一个组件模型,不同的组件之间通过定义良好的接口联系起来.就像盖房子一块砖头一块砖头的砌墙,一片一 ...

  3. 面向服务的SOA架构与服务总线ESB

    之前的软件的开发主要是面向对象的编程架构 方法---对象---模块---组件---服务,感觉现在的开发的主流的软件架构的设计思想都是对其进行重用,只不过范围越来越大,有一个系统之间进行通信到多个系统之 ...

  4. SOA服务设计与实现的几个语言无关的原则速记

    一.SOA定义 SOA即面向服务架构(Service-Oriented Architecture).在SOA中,一切皆服务.一个服务是通过消息交换来调用的程序,一个信息系统是共同完成一个特定任务的一组 ...

  5. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

  6. ESB 企业服务总线

    整理的OSChina 第 38 期高手问答 —— ESB 企业服务总线,嘉宾为@肖俊_David . @肖俊_David 恒拓开源架构师,热衷于JAVA开发,有多年的企业级开发经验.曾参和设计和开发基 ...

  7. 企业服务总线ESB

    # 企业服务总线ESB 由中间件技术实现并支持SOA的一组基础架构,支持异构环境中的服务.消息以及基于事件的交互,并且具有适当的服务级别和可管理性. 通过使用ESB,可以在几乎不更改代码的情况下,以一 ...

  8. 企业服务总线Enterprise service bus介绍

    企业服务总线(Enterprise service bus). 以往企业已经实现了很多服务, 构成了面向服务的架构,也就是我们常说的SOA. 服务的参与双方都必须建立1对1 的联系,让我们回顾一下SO ...

  9. SpringCloud系列十:SpringCloudConfig 高级配置(密钥加密处理(JCE)、KeyStore 加密处理、SpringCloudConfig 高可用机制、SpringCloudBus 服务总线)

    1.概念:SpringCloudConfig 高级配置 2.具体内容 在 SpringCloudConfig 之中考虑到所有配置文件都暴露在远程仓库之中的安全性问题,所以提供有安全访问的处理机制,这样 ...

随机推荐

  1. Java-并发入门

    本文由@呆代待殆原创,转载请注明出处:http://www.cnblogs.com/coffeeSS/ Java中实现多线程的方法 实现Runnable接口 实现Runnable接口里的run()方法 ...

  2. [NOI 2011][BZOJ 2434] 阿狸的打字机

    传送门 AC自动机 + 树状数组 建成AC自动机后,设end[i]为第i个串的末尾在Trie树上的节点. 可以发现,对于一个询问(x,y),ans等于Trie树上root到end[y]这条链上fail ...

  3. BZOJ 1202 [HNOI2005]狡猾的商人(并查集)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1202 [题目大意] 给出一些区间和的数值,问是否存在矛盾 [题解] 用并查集维护前缀和 ...

  4. python基础--接口与归一化设计、封装、异常、网络编程

    1 接口与归一化设计 1.1 归一化概念: 归一化的好处: 1.归一化让使用者无需关心对象的类是什么,只需要知道这些对象都具备某些功能就可以了,这极大降低了使用者的使用难度. 2.归一化使得高层的外部 ...

  5. lightoj 1244 - Tiles 状态DP

    思路:状态DP dp[i]=2*dp[i-1]+dp[i-3] 代码如下: 求出循环节部分 1 #include<stdio.h> 2 #define m 10007 3 int p[m] ...

  6. Erlang学习记录(三)——表达式大集合

    Erlang中的表达式必须以.结束才会去执行.如果不加.你在编译环境下按多少次Enter,表达式都不会执行,表达式之间可以用,分隔,以.结尾后所有的表达式都会执行,但是只有最后一个以.结尾的表达式会在 ...

  7. InetAddress之域名解析

    1. getByName public static InetAddress getByName(String host) throws UnknownHostException { return I ...

  8. [转]Android的ADT与SDK的区别

      adt只是一个eclipse的插件,里面可以设置sdk路径     SDK(Software Development Kit): 一般是一些被软件工程师用于为特定的软件包.软件框架.硬件平台.操作 ...

  9. Ubuntu 16.04/CentOS 6.9安装Node.js 6.9.5

    Ubuntu: CentOS: wget https://nodejs.org/dist/v6.9.5/node-v6.9.5-linux-x64.tar.xz tar -xvf node-v6.9. ...

  10. hdu3401 Trade 单调队列优化dp

    Trade Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...