2013年6月17日星期一

JMS与Java消息中间件


 JMS是一种企业消息传送的API,并不是MOM消息中间件系统的全部,JMS也是一种规范,类似于JDBC,我们通JMS API访问 JMS的服务器。目前JMS服务器的主要产品有 IBM WebSphere MQ、SonicMQ、Sun Open MQ、BEA  WebLogic  JMS、Oracle AQ  以及 我们最常用的JBoss MQ 和 Apache的 ActiveMQ.。而JMS服务器是MQ(Message Queen)产品家族中的一种,Microsoft Message Queuing(mSMQ)也是MQ产品类似于JMS服务器。
JMS在J2EE系统中的应用场景
   异步消息比同步消息操作更加便利。在J2EE系统中最常见的一个场景,前端浏览器 jsp/servlet向服务器端发出一个请求,jsp/servlet将请求传递给后端的应用程序处理业务逻辑,业务模块将响应的结果直接返回给客户端,而不是真正的计算结果,例如一个网站的用户注册功能,一个用户点击注册以后,将会发送一份邮件给他当时的注册邮箱,如果需要等到邮件发送成功再返回给用户结果的话,用户体验将会很差,所以将结果直接返回给用户,将用户注册的信息通过消息发送给后端程序慢慢处理。
JMS Cluster
谈到 JMS一词 大体上有 3个部分  1 消息发送端  2中间件服务器  3消息接收端  3个组件缺一不可。 JMS消息分为两种消息模式,点对点和发布者/订阅者。许多提供商支持这一因此,程序员可以在他们的分布式软件中实现面向消息的操作,这些操作将具有不同面向消息中间件产品的可移植性。
 

http://l99raa.bay.livefilestore.com/y1pg92LAov90l3hJaPBGkJnXsqRwNHnmdw7vpbm6VozavIPtJJDnQzKqxtpPwrB6DjlEitcPYSr5ON62WkX5KmDzreapKUaMet6/DRF.png?psid=1
Java消息服务器是指,将数据通过消息作为载体在网络中从一个系统异步传送给另一个系统。这样的异步消息传送意味着:发送者不需要等待接收者接收或处理该消息;它可以自由地发送消息并持续进行处理。这样一个异步式的架构主要依赖于一台消息服务器(message server)。消息服务器,也称为消息路由器(message router)或代理(broker),它负责从一个消息传送客户端向其他消息传送客户端传送消息。
JMS对与一个大型系统是必不可少的一个应用组件,可以利用JMS来实现3个目的:
            1.提高可伸缩性(Increase Scalability),
            2.可以利用JMS来缓解系统瓶颈(Reduce  Bottlenecks)
            3.提高系统对用户的响应能力
JMS公共API内部,和发送和接收JMS消息有关的JMS API接口常用的有7个:
        ·ConnectionFactory
        ·Destination
        ·Connection
        ·Session
        ·Message
        ·MessageProducer
        ·MessageConsumer
其中关键的5个部件,如图所示:
JMS API
查看大图请点击这里
Topic与Queue消息的区别
    Queue是一对一的消息传送,你可以看做是QQ应用程序中的一对一发送消息,一个人发出消息,只能有另外一个人阅读的到,中间需要通过一个队列支持Queue消息发送完毕后会保存在 JMS服务器的队列中,如果接收端接收以后将从队列中摘除。如图所示
http://l99raa.bay.livefilestore.com/y1pBMmD5G5XKCl5OM-cJV2PLvaN1GHnZ6mEwoC-DavOzzhHpFTnVeDERKWTIIW0eo3y9jxVmht3LGAYFS0hTvUIfEcIibsDOv82/p2p.png?psid=1
Queue消息发送到服务器,接收端会平均接收到发送端发送过来的消息,如图所示,一次发送150个消息,3个接收端每个收到50个
http://l99raa.bay.livefilestore.com/y1pDIUvLhMqs4VBwqyKXpE-4fImDxWL7hlUZUlqZYXRGbgLB81FDKJ_ejSl3eaFvP3M1FtV6y-p9KtxilPG7DO644DqjsqOzgrg/JMS-Dispatch.png

Topic  是一对多的消息传送,你可以看做是QQ应用程序 QQ群 聊天中的一对多发送消息,一个人发出消息,可以有多个订阅的人阅读的到,需要有一个消息主题作为支柱,Tocip消息发送完毕以后 无论有没有客户端接收,JMS服务器中的Topic消息都不会存在JMS服务器中。如图所示
http://l99raa.bay.livefilestore.com/y1p8wAJsZVtvdi48tGMpXfevLlrUzeeGXQwQJtjvsjJkcu4i4W8pzi9XuISR5pAMGZQU_k0xjSrLfFdJ0IBLP5ZjGVCIZJBv-ox/topic.png?psid=1
发送Topic消息无论连接在JMS服务器上有多少个接收端,将会收到同样的消息,而且Topic发送完毕以后不会保留在JMS服务器,否则将会和Topic消息的设计思想相互冲突。
http://l99raa.bay.livefilestore.com/y1plVf5LCPVGFnz7jN4CqQcianHZtJRkWOpPKaMLu12T56ZHANceuj3Ba5FcIj12H4Zo58X-o5ENe9ytURFpVvq5MJl27HzruBy/JMS-Dispatch-topic.png?psid=1

JMS消息的属性
JMS的每条消息分为 Header、Properties   、Body   3个属性 :
Header、Properties 中包含可设置的参数,分别是:
JMSDestination   消息发送的目的地
JMSDeliveryMode  传递模式, 有两种模式: PERSISTENT 和NON_PERSISTENT,PERSISTENT 表示该消息一定要被送到目的地,否则会导致应用错误。NON_PERSISTENT 表示偶然丢失该消息是被允许的,这两种模式使开发者可以在消息传递的可靠性和吞吐量之间找到平衡点。
JMSMessageID  唯一识别每个消息的标识,由JMS Provider 产生。
JMSTimestamp  一个消息被提交给JMS Provider 到消息被发出的时间。
JMSCorrelationID  用来连接到另外一个消息,典型的应用是在回复消息中连接到原消息。
JMSReplyTo        提供本消息回复消息的目的地址
JMSRedelivered  如果一个客户端收到一个设置了JMSRedelivered 属性的消息,则表示可能该客户端曾经在早些时候收到过该消息,但并没有签收(acknowledged)。
JMSType  消息类型的识别符。
JMSExpiration   消息过期时间,等于QueueSender 的send 方法中的timeToLive 值或TopicPublisher 的publish 方法中的timeToLive 值加上发送时刻的GMT 时间值。如果timeToLive值等于零,则JMSExpiration 被设为零,表示该消息永不过期。如果发送后,在消息过期时间之后消息还没有被发送到目的地,则该消息被清除。
JMSPriority  消息优先级,从0-9 十个级别,0-4 是普通消息,5-9 是加急消息。JMS 不要求JMS Provider 严格按照这十个优先级发送消息,但必须保证加急消息要先于普通消息到达。

Body 分为以下5种:
TextMessage
    这种类型携带了一个java.lang.String作为有效负载。它可以用于简单的文本消息交换,还可以用于更复杂的字符数据交换,比如XML文档等。
ObjectMessage
    这种类型携带了一个可序列化Java对象作为有效负载。它可以用于Java对象交换。
BytesMessage
    这种类型携带了一组原始类型字节流(primitive byte)作为有效负载。它可以使用应用程序的本机格式(native format)来交换数据,这种格式可能不兼容其他现有的Message类型。当JMS纯粹用于两个系统之间的消息传送时,也可以使用这种类型,而且该消 息的有效负载对JMS客户端来说是不透明的。
StreamMessage
    这种类型携带了一个Java原始数据类型流(int、double、char等)作为有效负载。它提供了一套将格式化字节流映射为Java原始数据类型的简便方法。在以固定顺序进行原始应用数据交换时,这种模型非常易于编程实现。
MapMessage
    这种类型携带了一组名/值对(name-value pair)作为有效负载。有效负载类似于一个java.util.Properties对象,除了有效负载值必须是Java原始数据类型或它们的包装器之外。MapMessage可以用于传送键入的数据。
如图所示:
jms的组成

JMS的消息存储
   
基于内存       最快
   基于文件       最慢
   基于数据库   比较慢
 
JMS的消息过滤功能
   这里selector是一个字符串,用来过滤消息。也就是说,这种方式可 以创建一个可以只接收特定消息的一个消费者。Selector的格式是类似于SQL-92的一种语法。可以用来比较消息头信息和属性。例如:发送消息属性中指定ip地址位数是奇数的接收,而ip地址位数是偶数的绝对不会接收到消息,具体实现方法请Google 关键字“jms selector
JMS消息的顺序
   乱序接收,顺序处理。也就是说,消息在发送,传输和接收过程中可能是乱序的,但消费者在接收到消息之后,并不立即处理,而是先将消息排序,然后在处理。 JMS消息头部的 JMSCorrelationID可以帮助我们完成这个工作。JMSCorrelationID存放了另一个消息的id。消息的发送者,如果要保证消息的顺序性,要将后发送的消息的JMSCorrelationID设置成前一个消息的id。消费者接收消息后,如果发现其头部有 JMSCorrelationID,则查看该消息是否已被处理过,如果没有,则等待该消息,至到该消息被处理后,才处理这个消息。这一工作需要发送者和接收者都记住已经发送和接收过的消息,以便于给后来的消息参考。由此可见,在JMS中设置JMS的head还是能起到不少作用的。

口水:
本文图绘采用国产软件 《亿图图示专家》所绘制,感谢《亿图图示专家》的所有开发人员制造出这么好的工具。

没有评论:

发表评论