消息中间件(一)JMS与ActiveMQ

JMS基础参见:http://blog.csdn.net/zhangxs_3/article/category/625599

实践中存在的问题(引自《大型网站系统与Java中间件实践》第六章):

一、如何解决消息发送一致性

1.消息发送一致性定义

消息发送一致性是指产生消息的业务动作与发送消息的一致,也就是说,如果业务操作成功了,那么由这个操作产生的消息一定要发送出去,否则就丢失消息了。另一方面,如果业务操作没有发生或者是失败了,就不应该把消息发出去。

2.消息一致性很难保证吗

解决方式一:

JMS中定义的XA系列的接口就是为了实现分布式事务的支持。

缺点:>引入了分布式事务,这会带来一定的开销增加复杂度。

>对于业务操作有限制,要求业务操作的资源必须支持XA协议,才能够与发送消息一起来做分布式事务。但并非所有需要与发送消息一起做成分布式事务的业务操作都支持XA协议。

解决方式二:

(1)业务处理应用首先把消息发送给消息中间件,标记消息状态为待处理。

(2)消息中间件收到消息后,把消息存储到消息存储中,并不投递该消息到Destination(Queue/Topic)。

(3)消息中间件返回接收到的消息处理的结果(仅是入库处理)给业务处理应用,结果是成功或者失败

(4)业务方收到消息中间件返回的结果并进行处理:

a)如果收到的结果是失败,那么就放弃业务处理,结束。

b)如果收到的结果是成功,则进行业务自身的操作。

(5)业务完成后发送业务处理结果给消息中间件。

(6)消息中间件收到业务处理的结果,根据结果进行处理:

a)如果业务失败,则删除消息存储中的消息,结束。

b)如果业务成功,则更新消息存储中的消息状态为可发送,并进行调度,进行消息的投递。

上述方案,如何保证消息发送一致性呢??

我们对于每一个步骤可能发生的异常情况进行分析。

分析只需看:业务操作和消息发送状态是否一样即可,即同时成功或者同时失败。

(1)业务应用发消息给消息中间件。如果这步失败了,无论是网络原因还是消息中间件的原因,或是业务应用自身的原因,我们都会看到业务操作还没有做,消息也还没有存储到消息中间件中,业务操作和消息发送两者状态一致,没有问题。

(2)消息中间件把消息入库。如果这步失败了,无论是消息存储有问题,还是消息中间件收到业务消息后有问题,或者是网络问题,可能造成两个结果。一个是消息中间件失效,那么业务应用收不到消息中间件返回的结果;二是消息中间件插入消息失败,并且有能力返回结果给应用,这时消息存储中都没有消息。

(3)业务应用收到消息中间件返回结果异常。这里出现异常的原因可能是网络、消息中间件的问题,也可能是业务应用自身的问题。如果业务应用自身没有问题,那么业务应用并不知道消息在消息中间件中的处理结果,就会按照消息发送失败来处理,如果这时消息在消息中间件中入库成功的话,就会造成不一致。如果是业务应用有问题,那么如果消息在消息中间件中处理成功的话,也就会造成不一致了;如果未处理成功,则还是一致的。

(4)业务应用进行业务操作。这一步不会差生太大问题。

(5)业务应用发送业务操作的结果给消息中间件。如果这一步出现问题,那么消息中间件啊将不知道如何对消息的状态进行更新,可能造成不一致。

(6)消息中间件更新消息状态。如果这一步出现问题,与上一步造成的结果类似。

从上面的分析可以看出,需要了解的两个主要的控制状态和流程的节点就是业务应用和消息中间件。

从上面的梳理和分析可以看到,对于各种异常情况我们遇到的状态有如下三种:

>业务操作未进行,消息未存储。

>业务操作未进行,消息存入存储,状态为待处理。

>业务操作成功,消息存入存储,状态为待处理。

三种情况中,第一种不需要进行额外处理,因为它本身就是一致的;第二种和第三种都需要了解业务操作的结果,然后来处理已存入消息存储、状态是待处理的消息。

那么如何了解业务操作的结果呢?

下图展示了这个过程。

由消息中间件主动询问业务应用,获取待处理消息所对应的业务操作的结果,然后业务应用需要对业务操作的结果进行检查,并把结果发送给消息中间件(业务处理的结果有失败、成功、等待,等待是多出来的一种状态,代表业务操作还在处理中),然后消息中间件根据返回的业务处理结果更新消息状态。可以说这是发送消息的一个反向流程。

发送消息的正向流程和业务操作结果的反向流程结合起来,就解决了业务操作和发送消息一致性的问题。

该方案的两个限制。

1.需要确定发送的消息的内容。因为我们在业务操作做之前会把状态标记为待处理,这要求先能确定消息内容;这里有一个变通,即先把主要内容也就是也就是能够标记该次业务操作特点的信息发过来,然后等业务操作结束后需要更新状态时再补全内容。不过这还是要求在业务操作之前能够确定一些索引性质的信息。

2.需要实现对业务的检查。为了支持反向流程的工作,业务应用必须能够根据反向流程发送过来的消息内容进行业务检查,确定这个消息所指向的业务操作的状态是完成、待处理,还是正在进行中,否则,待处理状态的消息就无法被处理了。

二、消息模型对消息接收的影响

在JMS中,有Queue(点对点)和Topic(发布/订阅)两种模型,来看一下两种模型的特点。

1.JMS Queue模型

该模型的特点:

>应用1和应用2发送消息到JMS服务器,这些消息根据到达顺序形成一个队列,应用3、应用4进行消息的消费。需要注意的是应用3和应用4收到的是不同的消息,也就是说JMS Queue方式下,如果Queue中的一个消息被一个应用消费了,那么连接到JMS Queue上的另一个应用是收不到这个消息的。即是JMS Queue中的每一个消息只能被一个应用消费,之后就从JMS中删除了。

>消息从发送端发送出来时不能确定最终会被哪个应用消费,但是可以明确的是只有一个应用会去消费这条消息。上图中应用3和应用4所接受到的消息的条数和顺序都不是固定的。

因此,JMS Queue模型也被成为Peer To Peer(PTP)方式。

2.JMS Topic模型

从上图中可以看出,从发送消息的部分和JMS Topic消息服务器内部的逻辑来看,两种模型是一样的,两者最大的区别在于消息的接收部分。在JMS Topic模型中,接收消息的应用3和应用4都可以独立的接收到所有到达Topic的消息。JMS Topic模型也被成为Pub/Sub方式。

3.JMS中客户端连接的处理和带来的限制

在使用JMS时,每个Connection都有一个唯一的ClientId,用于标记连接的唯一性,也就是说刚才对于Queue和Topic的介绍中,我们是默认一个接收应用只用了一个连接。现在来看一下多连接的情况,如下图所示:

从上图可以看到,应用3和JMS服务器建立了两个连接,应用4和JMS建立了一个连接。可以看到这三个连接接收到的消息是完全不同且不重复的,每个连接接收到的消息条数以及收到消息的顺序则不是固定的。

从上图可以看到,应用3和JMS服务器建立了一个连接,应用4和JMS建立了两个连接。两个应用一共建立了三个连接,每个连接都会接收到所有发送到Topic中的所有消息。

4.我们需要什么样的消息模型?

我们对于模型的需求:

.消息发送方和接收方都是集群。

.同一个消息的接收方可能有多个集群进行消息的处理。

.不同集群对同一条消息的处理互不干扰。

分析:对于第一个需求,JSM是可以直接支持的。对于需求二和需求三来说,即是假设有8条消息和两个集群,每个集群有两台机器,那么需要这两个集群中的机器分别处理掉8条消息,不能遗漏也不能重复。如下图所示,

前面我们介绍的JMS只提供了Queue和Topic两种模型,但是这两种模型直接使用在这个场景都是有问题的。

我们需要结合这两种模型做改进,实现满足我们需求的模型。如下图:

具体来说,我们可以把集群和集群之间对于消息的消费当作Topic模型来处理,而集群内部的应用的各个具体实例对于消息的消费当做Queue模型来处理。我们可以引入ClusterId,用这个Id来标识不同的集群,而集群内的各个应用实例的连接也是用同样的ClusterId。当服务器端进行调度时,根据ClusterId进行连接分组,在不同的ClusterId之间保证消息的独立投递,而拥有同样ClusterId的连接则共同消费这些消息。这个策略是分两级来处理,把Queue和Topic两种模型的特点结合起来使用,从而达到多个不同的集群进行消息订阅的目的。

时间: 2024-10-12 05:33:10

消息中间件(一)JMS与ActiveMQ的相关文章

深入浅出JMS(三)--ActiveMQ简单的HelloWorld实例

第一篇博文深入浅出JMS(一)–JMS基本概念,我们介绍了JMS的两种消息模型:点对点和发布订阅模型,以及消息被消费的两个方式:同步和异步,JMS编程模型的对象,最后说了JMS的优点. 第二篇博文深入浅出JMS(二)–ActiveMQ简单介绍以及安装,我们介绍了消息中间件ActiveMQ,安装,启动,以及优缺点. 这篇博文,我们使用ActiveMQ为大家实现一种点对点的消息模型.如果你对点对点模型的认识较浅,可以看一下第一篇博文的介绍. JMS其实并没有想象的那么高大上,看完这篇博文之后,你就知

消息中间件和JMS介绍(一)

在一个公司创立初期,他可能只有几个应用,系统之间的关联也不是那么大,A系统调用B系统就直接调用B提供的API接口:后来这个公司做大了,他一步步发展有了几十个系统,这时候A系统要调用B系统的接口,但是B系统前几天刚改了一下接口A并不知情.所以A发现调不通于是给B系统管理员打电话,小王啊,改了接口咋不告诉我呢.我还以为我们系统出错了呢.弄得小王一顿尴尬,我这自己改个东西还的通知这个通知那个的. 1 中间件介绍 我们看到上面的故事中的小王他真的是很累啊.自己修改一个接口还的给所有调用接口的系统管理员打

Spring jms 与 ActiveMq初识

Spring JMS 与 ActiveMQ初识 1.1 Spring jms 与 ActiveMQ简介 jms 的全称是 Java Message Service,其主要作用是在生产者与消费者之间进行消息的传递:实际业务场景下,当A系统完成某项业务操作后,需要通知B系统或者其他任意系统 A系统操作完成的状态,以及操作中涉及到的相关信息,比如 当会员卡发放系统完成给用户绑定一张会员卡的操作之后,可以发出一条消息,消息内容是 uid或phone为XXX的用户,绑定了一张XX类型(普通卡.贵宾卡等)的

JMS and ActiveMQ first lesson(转)

JMS and ActiveMQ first lesson -- jms基础概念和应用场景 2011-6-18 PM 9:30 主讲:kimmking <[email protected]> 整理:林木森 ppt下载地址: http://code.google.com/p/activemq-store-mongodb/downloads/list 下面开始: kimmking:介绍下jms和ActiveMQ.在讲JMS之前,我们聊聊相关的背景.谁知道JMS是什么意思? kimmking:对,是

开源jms服务ActiveMQ的负载均衡+高可用部署方案探索

一个文件(或目录)拥有若干个属性,包括(r/w/x)等基本属性,以及是否为目录(d)与文件(-)或连接文件(l)等属性.此外,Linux还可以设置其他系统安全属性,使用chattr来设置,以lsattr来查看,最重要的是可以设置其不可修改的特性,即便是文件的拥有者都不能进行修改.这个属性相当重要,尤其是在安全机制方面(security). 文件默认权限:umask 当建立一个新的文件或目录时,它的默认属性是与umask有关的.通常,umask就是指定当前用户在建立文件或目录时的属性默认值.那么,

JMS服务器ActiveMQ的初体验并持久化消息到MySQL数据库中

JMS服务器ActiveMQ的初体验并持久化消息到MySQL数据库中 一.JMS的理解JMS(Java Message Service)是jcp组织02-03年定义了jsr914规范(http://jcp.org/en/jsr/detail?id=914),它定义了消息的格式和消息传递模式:消息包括:消息头,消息扩展属性和消息体,其结构看起来与SOAP非常的相似,但一般情况下,SOAP主要关注远程服务调用,而消息则专注于信息的交换:消息分为:消息生产者,消息服务器和消息消费者.生产者与消费者之间

Spring 实现远程访问详解——jms和activemq

前几章我们分别利用spring rmi.httpinvoker.httpclient.webservice技术实现不同服务器间的远程访问.本章我将通过spring jms和activemq实现单Web项目服务器间异步访问和多Web项目服务器间异步访问. 一.  简介 1.      什么是Apache ActiveMq Apache ActiveMq是最流行和最强大的开源消息和集成服务器.同时Apache ActiveMq是速度快,支持多种跨语言客户端和协议,同时配有易于使用的企业集成模式和优秀

JMS Apache ActiveMQ(消息中间件)使用攻略

首先在做任何技术预研的时候:我会搞清除它是什么?为什么要使用它? JMS 他是什么? Java Message Service是一组接口和相关语义,他定义了JMS客户如何访问企业消息产生的功能. JMS支持消息中间件的两种传递模式:点到点模式(point to point)和发布-订阅模式(pub/sub). JMS消息模型: 消息头(header):JMS消息头包含了许多字段,它们是消息发送后由JMS提供者或消息发送者产生,用来表示消息.设置优先权和失效时间等等,并且为消息确定路由. 属性(p

深入浅出JMS(二)--ActiveMQ简单介绍以及安装

现实的企业中,对于消息通信的应用一直都非常的火热,而且在J2EE的企业应用中扮演着特殊的角色,所以对于它研究是非常有必要的. 上篇博文深入浅出JMS(一)–JMS基本概念,我们介绍了消息通信的规范JMS,我们这篇博文介绍一款开源的JMS具体实现--ActiveMQ.ActiveMQ是一个易于使用的消息中间件. 消息中间件 我们简单的介绍一下消息中间件,对它有一个基本认识就好,消息中间件(MOM:Message Orient middleware). 消息中间件有很多的用途和优点: 1. 将数据从