背景

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

如图所示:

基于服务总线的设计,往往需要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进行负载均衡, 实现高并发,高可用.

最新文章

  1. Android开发的小技巧,在Android Studio中使用Designtime Layout Attributes
  2. python "yield"(转载)
  3. 【Linux_Fedora_应用系列】_1_如何安装音乐播放器和mp3解码
  4. JavaScript - 2个等号与3个等号的区别
  5. Javascript 图片左右滑动与切换
  6. How to using to code import to GL journal[AX2012]
  7. 64位Windows7升级IE11后无法启动的解决办法
  8. ANDROID_MARS学习笔记_S05_006_距离传感器
  9. BZOJ 1015 [JSOI2008]星球大战starwar
  10. Cohort Analysis and LifeCycle Grids mixed segmentation with R(转)
  11. peoplesoft function PSTREENODE 通过 deptid 获得部门树 一级部门 code
  12. 洛谷银牛派对SPFA
  13. JasperReport的安装
  14. Fedora 25 安装 Bugzilla
  15. ajax跨域问题小结
  16. QDoubleSpinBox浮点型数字调节框
  17. Auto.js 初试-Android开发JS利器
  18. Jmeter --- 分布式测试
  19. DataGridview的自动排序设置
  20. C++加速程序的全局执行函数

热门文章

  1. BZOJ 2588: Spoj 10628. Count on a tree-可持久化线段树+LCA(点权)(树上的操作) 无语(为什么我的LCA的板子不对)
  2. STL容器 -- Stack
  3. ZSTU OJ 4272 最佳淘汰算法
  4. POJ1845 Sumdiv [数论,逆元]
  5. 【前端必备】三、JS篇
  6. linux——(2)文件权限与目录配置
  7. 【BZOJ 1050】1050: [HAOI2006]旅行comf (动态SPFA)
  8. 2017 Multi-University Training 1 解题报告
  9. BZOJ 2395 [Balkan 2011]Timeismoney(最小乘积生成树)
  10. 【构造】Ural Championship April 30, 2017 Problem K. King’s island