【EJB四】——JMS消息服务之P2P和Pub/Sub

JMS:java消息服务,JMS客户端可以通过JMS服务进行异步消息传输。可以支持两种模型:P2P和Pub/Sub

P2P

点对点消息传输模式,这种模式主要包括发送者,消息队列和接收者

特点:
1、每个消息只有一个消费者,一旦被接收(消费),此消息就不存在于消息队列中了。
2、发送者和接收者在时间上没有依赖性(当消息发送后,无论接收者有没有在接收,都不会影响消息进入消息队列)
3、接收者在成功接收消息之后,需要向队列应答成功。

Pub/Sub

发布/订阅的模式。主要包括:发布者,主题,订阅者三部分。

特点:
1、每个消息可以有多个消费者。(这是和P2P最大的不同)只要消费者订阅了某个主题,那这个主题的发布者所发布的消息,就会被订阅者全部接收。
2、发布者和订阅者必须有时间上的依赖(这种依赖是指,订阅者必须在发布之前先进行订阅,才能接收到发布的消息)
3、为了缓和这种严格的时间相关性,JMS允许订阅者创建一个可持久化的订阅,这样,即使订阅者没有运行,也能接收到发布者的消息

实现思路

二者除了模式不同外,程序中的实现是非常类似的。都是通过一个连接工厂connectionFactory来获取connection来,然后再通过创建
Session来创建发送者(发布者),通过context来查找并获取队列或者主题,通过发送者(发布者)来发送或发布消息。
在这里需要知道的是:某个队列或者主题是由应用服务器来提供的,不由任何一个客户端来创建。我们在客户端只需要通过JNDI来进行查找就好了。
简单的了解了这两种消息服务的区别后,通过一个小例子来加深一下对他们的理解:

P2P code

创建两个消费者MyQueueMDBBean和MyQueueMDBBean1:
//配置的queue/MyQueue为我们要发送消息的消息队列
@MessageDriven(
    activationConfig={      @ActivationConfigProperty(propertyName="destinationType",propertyValue="javax.jms.Queue"),      @ActivationConfigProperty(propertyName="destination",propertyValue="queue/MyQueue")
    }
)
//只要实现了MessageListener接口,接收到消息会自动触发onMessage这个方法
//这里相当于一个消费者
public class MyQueueMDBBean implements MessageListener {

    public void onMessage(Message arg) {
        TextMessage textMessage=(TextMessage)arg;
        try {
            System.out.println("MyQueueMDBBean已接收到queue消息了,消息为:"+textMessage.getText());
        } catch (JMSException e) {

            e.printStackTrace();
        }

    }

}
由于JBoss不能自己创建Queue对象,必须在server/default/deploy目录下找到一个xxx-service.xml文件中加入:
注意JNDIName的大小写和程序中要保持一致。
<mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.org.destination:server=Queue,name=myqueue" >
    <attribute name="JNDIName" >queue/MyQueue</attribute>
    <depends optional-attribute-name = "DestinationManager" >
    jboss.mq:service=DestinationManager
    </depends>
</mbean>

发送者代码:

public static void main(String[] args) throws NamingException, JMSException {
        InitialContext context=new InitialContext();
        //获取队列工厂
        QueueConnectionFactory factory=(QueueConnectionFactory) context.lookup("ConnectionFactory");
        //获取connection
        QueueConnection connection=factory.createQueueConnection();
        //创建QueueSession
        QueueSession session=connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
        //获取的destination对象
        Queue queue=(Queue)context.lookup("queue/MyQueue");
        //创建消息
        TextMessage textMessage=session.createTextMessage("hello,world!");
        //创建发送者
        QueueSender sender=session.createSender(queue);
        //发送消息
        sender.send(textMessage);
        //关闭会话
        session.close();
        System.out.println("消息已成功发送!");

    }

Pub/Sub Code

创建消费者TopicMDBBean,TopicMDBBean1和TopicMDBBean2
//这里相当于一个消费者
@MessageDriven(
    activationConfig={
        @ActivationConfigProperty(propertyName="destinationType",propertyValue="javax.jms.Topic"),
        @ActivationConfigProperty(propertyName="destination",propertyValue="topic/myTopic")
    }
)
public class TopicMDBBean implements MessageListener {

    public void onMessage(Message arg) {
        TextMessage textMessage=(TextMessage)arg;
        try {
            System.out.println("TopicMDBBean已接收到topic消息了,消息为:"+textMessage.getText());
        } catch (JMSException e) {

            e.printStackTrace();
        }

    }

}
客户端代码和P2P类似,把Queue改成Topic就可以了,这里也必须配置"topic/myTopic"主题。
public static void main(String[] args) throws NamingException, JMSException {
        InitialContext context=new InitialContext();
        //获取队列工厂
        TopicConnectionFactory factory=(TopicConnectionFactory) context.lookup("ConnectionFactory");
        //获取connection
        TopicConnection connection=factory.createTopicConnection();
        //创建QueueSession
        TopicSession session=connection.createTopicSession(false, QueueSession.AUTO_ACKNOWLEDGE);
        //获取的destination对象
        Topic topic=(Topic)context.lookup("topic/myTopic");
        //创建消息
        TextMessage textMessage=session.createTextMessage("hello,world!");
        //创建发送者
        TopicPublisher sender=session.createPublisher(topic);
        //发送消息
        sender.send(textMessage);
        //关闭会话
        session.close();
        System.out.println("消息已成功发送!");

    }

}

执行结果

P2P:

第一次执行:

第二次执行:

每次发消息,只有一个消费者能够接收到消息。

Pub/Sub:

第一次执行:

每发一次消息,只要进行监听了此主题的订阅者都可以收到这个消息!

总结

我认为通常在使用JDM的P2P发送消息时,至少应该是有一个消费者的,否则采用这个方式就没有任何意义。
所以如果我们想让我们发出去的指令只被执行一次,且每条消息都可以被成功处理可以选择P2P模式,如果想让自己发出去的消息可以被多个人接收,
或者一个或多个人处理,可以选择Pub/Sub模式
时间: 2024-10-13 11:57:06

【EJB四】——JMS消息服务之P2P和Pub/Sub的相关文章

消息中间件--ActiveMQ&amp;JMS消息服务

### 消息中间件 ### ---------- **消息中间件** 1. 消息中间件的概述 2. 消息中间件的应用场景(查看大纲文档,了解消息队列的应用场景) * 异步处理 * 应用解耦 * 流量削峰 * 消息通信 ---------- ### JMS消息服务 ### ---------- **JMS的概述** 1. JMS消息服务的概述 2. JMS消息模型 * P2P模式 * Pub/Sub模式 3. 消息消费的方式 * 同步的方式---手动 * 异步的方式---listener监听 4.

JBoss EAP应用服务器部署方法和JBoss 开发JMS消息服务小例子

一.download JBoss-EAP-6.2.0GA: http://jbossas.jboss.org/downloads JBoss Enterprise Application Platform(JBoss EAP)作为Redhat公司的商业产品是一个更加关注企业级特性和稳定性的实用部署版为了与JBoss Application Server(JBoss AS) 为了使这两个产品有差异化避免用户混淆因此 RedHat公司在2013年4月将JBoss AS正式更名为WildFly改名后的

三:JMS消息服务规范

一:JMS是什么?--->JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API--->用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信.--->Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持.---> JMS 使您能够通过消息收发服务(有时称为消息中介程序或路由器)从一个 JMS 客户机向另一个 JMS客户机发送消息.--->JMS(Java

Intellij IDEA 创建消息驱动Bean - 接收JMS消息

除了同步方式的调用之外,有时还需要异步调用,用来处理不需要即时处理的信息,例如短信.邮件等,这需要使用EJB中的独特组件——消息驱动Bean(Message-Driven Bean,MDB),它提供了Java消息服务JMS(Java Messaging Service)的处理能力,由消息驱动Bean来处理JMS消息.JMS的消息由客户端程序产生,并被发布到服务器的消息队列,消息驱动Bean随之检索消息并执行其内容.这种事件或者数据的通信就称为异步形式,客户端或者服务端Bean都无须依赖对方的直接

JMS消息传输机制

JMS消息传送模型: 消息传送机制, 是基于拉取(pull)或者轮询(polling)的方式.  JMS具备两种"消息传送模型": P2P和Pub/sub. (1) P2P:点对点消息传送模型, 允许JMS客户端通过队列(queue)这个虚拟通道来同步或异步发送消息; 消息的生产者为Sender, 消费者为receiver.   receiver主动到队列中请求消息,而不是JMS提供者将消息推送到客户端;   主要原因是一个队列通道可能有多个receiver,每个receiver可能对

JAVA消息服务JMS规范及原理详解

一.简介 JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信.Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持. JMS允许应用程序组件基于JavaEE平台创建.发送.接收和读取消息.它使分布式通信耦合度更低,消息服务更加可靠以及异步性. 二.常用术语介绍 在提到JMS时,我们通常会说到一些术语,解释如下: 消息

JMS(java消息服务)学习一

一.JMS是个什么鬼 1.百度百科解释:JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信.Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持. 2.JMS是一组消息服务的api即接口规范即数据库的JDBC消息服务的JMS. 二.为什么要学习,使用JMS 1.在JAVA中,如果两个应用程序之间对各自都不了解,甚至这

JMS(java消息服务)整合Spring项目案例

转载自云栖社区 摘要: Sprng-jms消息服务小项目 所需的包: spring的基础包 spring-jms-xx包 spring-message–xx包 commons-collection-xx包 commons-pool2-xx包 aop切面的包: spring-aop,spring-aspect... Sprng-jms消息服务小项目 所需的包: spring的基础包 spring-jms-xx包 spring-message–xx包 commons-collection-xx包 c

干货--JMS(java消息服务)整合Spring项目案例

Sprng-jms消息服务小项目 所需的包: spring的基础包 spring-jms-xx包 spring-message–xx包 commons-collection-xx包 commons-pool2-xx包 aop切面的包: spring-aop,spring-aspect,aopalliance,aspectjrt.jar,aspectjweaver.jar 配置: 1.配置ConnectionFactory 2.配置jmsTemplate; 3.配置Destination 4.配置