JMS两种模型,布上apache-activemq服务器JMS(四)

来源:互联网 发布:tor网络 原理 编辑:程序博客网 时间:2024/06/07 23:56

选用的服务器是apache-activemq-5.13.0,是在本机上打开的。

将服务器在电脑上找到对应的机型数下在bin文件夹下打开activemq.bat文件即开启了服务器。端口号61616

目录:

1,模型解析

2,参数解析

3,源代码


一模型解析:

JMS支持两种消息模型:Point-to-Point(P2P)和Publish/Subscribe(Pub/Sub),即点对点和发布订阅模型

1,P2P模型

有以下概念:消息队列(Queue)、发送者(Sender)、接收者(Receiver)。每个消息都被发送到一个特定的队列,接收者从队列获取消息。队列保留着消息,直到它们被消费或超时。

(1) 每个消息只有一个消费者(Consumer)(即一旦被消费,消息就不再在消息队列中)

(2) 发送者和接收者之间在时间上没有依赖性,也就是说当发送者发送了消息之后,不管接收者有没有正在运行,它不会影响到消息被发送到队列。

(3) 接收者在成功接受消息之后需要向队列应答成功

注:如果希望发送的每个消息都被成功处理,或被特定的消费者消费,那么需要采用P2P模型。

使用场合:想让接收者进行且只进行一次处理,组件之间进行同步通信。

个人理解:这种模型的应用很常见,例如:qq/微信/飞信聊天(私聊),(1)小A和小B互加qq好友,小A给小B发一条消息”你干嘛呢?”,这条消息只有小B能接收到,别人接收不到——每个消息只有一个消费者;(2)如果小B没有登录qq,也没关系,当小B登录qq后,就会看到这条消息——发送者和接收者之间在时间上没有依赖性,也就是说,当发送者发送了消息之后,不管接收者有没有正在运行,它不会影响到消息被发送到队列;

2,Pub/Sub模型 

 有以下概念:主题(Topic)、发布者(Publisher)、订阅者(Subscriber)。客户端将消息发送到主题。多个发布者将消息发送到Topic,系统将这些消息传递给多个订阅者。

(1)每个消息可以有多个消费者

(2) 发布者和订阅者之间有时间上的依赖性。针对某个主题(Topic)的订阅者,它必须创建一个订阅之后,才能消费发布者的消息,而且,为了消费消息,订阅者必须保持运行的状态。

    为了缓和这种严格的时间上的依赖性,JMS允许订阅者创建一个可持久化的订阅(即,发送者和接收者之间在时间上没有依赖性。这样的话,即使订阅者没有运行,它也能接收到发布者的消息。)

    如果希望发送的消息可以被一个/多个消费者消费,那么可以采用Pub/Sub模型。

个人理解:这种模型的应用也很常见,例如,如果qq群聊天是这样的:小A、小B、小C都是”聊天群”中的成员,小A、小B在线,小C不在线,小A发布一条消息”明天放假”,那么只有小B能接收到,当小C上线后也接收不到。这样是不是很不合理——发布者和订阅者之间有时间上的依赖性;因此,为了缓和这种严格的时间上的依赖性,JMS允许订阅者创建一个可持久化的订阅(即,发送者和接收者之间在时间上没有依赖性。这样的话,即使订阅者没有运行,它也能接收到发布者的消息。)——还是上面的例子,小A、小B、小C都是”聊天群”中的成员,小A、小B在线,小C不在线,小A发布一条消息”明天放假”,小B可以接收到,当小C上线后也可以接收到。

以上只是目前的个人理解,可能与实际有所偏差。


3,总结:

P2P模型与Pub/Sub模型的根本区别:对于p2p模型的每个消息只能有一个消费者 ; pub/sub模型可以有多个消费者 。


二参数详解:

1创建共产参数解析:

new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");

分别表示默认用户名密码  和服务地址  注意:这里服务器是部署在本机上的。

除了以上的设置方法还有:通过下面的方法设置用户名和密码,这个用户名和密码在conf目录下的credentials.properties文件中,也可以在activemq.xml中配置
  connectionFactory.setUserName("system");

  connectionFactory.setPassword("manager");

2, 创建Session,参数解释:
            第一个参数是否使用事务:当消息发送者向消息提供者(即消息代理)发送消息时,
消息发送者等待消息代理的确认,没有回应则抛出异常,消息发送程序负责处理这个错误。
            第二个参数消息的确认模式:
            AUTO_ACKNOWLEDGE : 指定消息提供者在每次收到消息时自动发送确认。消息只向目标发送一次,但传输过程中可能因为错误而丢失消息。
             CLIENT_ACKNOWLEDGE : 由消息接收者确认收到消息,通过调用消息的acknowledge()方法(会通知消息提供者收到了消息)
             DUPS_OK_ACKNOWLEDGE : 指定消息提供者在消息接收者没有确认发送时重新发送消息(这种确认模式不在乎接收者收到重复的消息)。


三代码:

1发送者:

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.Session;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;


public class Sender {

public static void main(String[] args) throws JMSException {
//  设置的默认用户名和密码   还有设置连接服务器的端口  这里服务器是部署在本机的
// 还可以通过下面的方法设置用户名和密码,这个用户名和密码在conf目录下的credentials.properties文件中,也可以在activemq.xml中配置
    //   connectionFactory.setUserName("system");
  //     connectionFactory.setPassword("manager");
ConnectionFactory connectionFactory=new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");
Connection connection=connectionFactory.createConnection();
connection.start();

Session session=connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
//创建一个目的地,它用来接收消息: 这里创建的是一个Queue,表明我们用的是  p2p方式,
//另一种Destination是  Topic,用于订阅模式
Destination destination=session.createQueue("testQueue");
//Topic destination = (Topic)context.lookup("topic/LeadfarTopic");
//创建生产者
MessageProducer producer=session.createProducer(destination);
       // TopicPublisher publisher = session.createPublisher(destination);
//指定消息的保存发送模式  设置不持久化
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

//设置文本信息
Message messge=session.createTextMessage("hello jms");
//发送信息
producer.send(messge);
// publisher.send(msg);
//提交会话
        session.commit();
        System.out.println("消息发送成功");
}


}


2接受者:

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;


import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;


public class Receive {


/**
* @param args
* @throws JMSException 
*/
public static void main(String[] args) throws JMSException {
ConnectionFactory connectionFactory=new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");
Connection connection=connectionFactory.createConnection();
connection.start();

 //创建会话
        Session session=connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
        //创建一个目的地,它用来接收消息: 这里创建的是一个Queue,表明我们用的是  p2p方式,    另一种Destination是  Topic,用于订阅模式
        Destination destination=session.createQueue(  "testQueue"  );
        //Topic destination = (Topic)context.lookup("topic/LeadfarTopic");
        //创建消费者
MessageConsumer consumer=session.createConsumer(destination);
consumer.setMessageListener(new MessageListener() {

@Override
public void onMessage(Message arg0) {
TextMessage text=(TextMessage)arg0;
System.out.println("接收到了"+text);

}
});

}


}





0 0
原创粉丝点击