2.ActiveMQ-API使用

版权声明:本文为博主原创文章,转载请附上本文链接。 https://blog.csdn.net/Willson_L/article/details/82683482

2.1 修改登录名认证和Connection的使用

2.1.1 修改登录名认证

在 conf/activemq.xml 文件中,可以修改登录认证,即ConnectionFactory中填写的用户名,密码。

<plugins>
    <simpleAuthenticationPlugin>
        <users>
            <authenticationUser username="lys" password="lys" groups="users,admins"></authenticationUser>
        </users>
    </simpleAuthenticationPlugin>	
</plugins>

2.1.2 Connection使用

在成功创建ConnentionFactory后,下一步是创建Connection,它是JMS定义的一个接口,ConnectionFactory负责返回可以与底层消息传递系统进行通信的实现。通常用户只使用单一连接。根据JMS文档,Connection的目的是“利用JMS提供者封装开放的接连”,以及表示“客户端与提供者服务之间的开放tcp/ip stocket”。

当一个Connection被创建时,它的传输默认是关闭的,必须使用start方法开启。一个Connection可以创建多个Session。

当一个程序执行完成后,必须关闭之前创建的Connection,否则ActiveMQ不能释放资源,关闭一个Connection同样也关闭了 Session,MessageProducer 和 MessageConsumer。

Connection createConnection();

Connection createConnection(String userName, String password);

2.2 Session使用

Session是一个发送或接收消息的线程,可以使用Session创建 MessageProducer,MessageConsumer 和 Message。

Session可以被事务化,也可以不被事务化,通常可以通过向Connection上的适当创建方法传递一个boolean参数对此进行设置。

Session createSession(boolean transacted, int acknowlwdgeMode);

transacted为使用事务标识,acknowledgeMode为签收模式。

  • 当一个事务被提交,消息被处理,如果事务中有一步执行失败,事务就会回滚。这个事务中已经执行的动作将被撤销。在发送消息最后也必须要使用session.commit()方法表示提交事务。
  • 签收模式有三种形式:
  1. Session.AUTO_ACKNOWLEDGE:当客户端从receive或onMessage成功返回时,Session自动签收客户端的这条消息的收条。(常用)
  2. Session.CLIENT_ACKNOWLEDGE:客户端通过调用消息的acknowledge方法签收消息。在这种情况下,签收发生在Session层面:签收一个已消费的消息会自动地签收这个Session所有已消费的收条。
  3. Session.DUPS_OK_ACKNOWLEDGE:此选项指示Session不必确保对传送消息的签收,他可能引起消息的重复,但是降低了Session的开销,所有只有客户端能容忍重复消息的时候,才使用。

2.2.1 事务代码示例

// 第一步:建立ConnectionFactory工厂对象,需要填入用户名,密码,以及连接的地址。默认tcp://127.0.0.1:61616
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(Contstants.USERNAME, Contstants.PASSWORD, Contstants.URL);		
		
// 第二部:通过ConnectionFactory工厂对象我们创建一个Connection连接
// 并且调用Connection的start启动连接, Connection默认是关闭的。
Connection connection = connectionFactory.createConnection();
connection.start();
		
// 第三部:使用事务提交
Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
		
// 第四部: 通过Session创建Destination,指的是一个客户端用来指定生产消息目标和消息来源的对象
// 在ptp模式中,Destination被称做为Queue(队列),在Pub/Sub模式下,Destination被称作Topic(主题)
Destination destination =  session.createQueue("helloworld-queue");
		
// 第五步:我们需要通过Session对象创建消息的发送和接受对象,(生产者和消费者)MessageProducer/MessageConsumer
MessageProducer producer = session.createProducer(destination);
		
// 第六步:我们可以使用MessageProducer的setDeliveryMode方法为其设置持久化特性和非持久化特性(DeliveryMode)
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
		
// 第七部:最后我们使用jms规范的TextMessage形式创建数据(通过Session对象),
// 并用MessageProducer的send方法发送数据,同理客户端使用receive方法进行接受数据。
for (int i = 0; i < 5; i++) {
    TextMessage message = session.createTextMessage("producer hello word!" + i);
    producer.send(message);
}
session.commit();
		
		
// 最后不要忘了关闭资源。
if (connection != null) {
    connection.close();
}

如果在for循环中 throw exception 或者没有执行 session.commit(),则在ActiveMQ查不到消息。

2.2.2 手动签收示例

发送端和接收端设置为 Session.CLIENT_ACKNOWLEDGE。

Session session = connection.createSession(Boolean.FALSE, Session.CLIENT_ACKNOWLEDGE);

接受端在接收完数据后要执行,否则在ActiveMQ的管理后台中,仍然显示数据没有消费。

message.acknowledge();

 

2.3 MessageProducer使用

MessageProducer由Session创建,用来向Destination发送消息。

void send(Destination destination, Message message);

void send(Destination destination, Message message, int deliveryMode, int priority, long timeToLive);

void send(Message message);

void send(Message message, int deliveryMode, int priority, long timeToLive);

deliveryMode为传送模式,priority为消息优先级,timeToLive为消息过期时间。

ActiveMQ支持两种消息传递模式,PRESISTENT和NON_PRESISTENT两种。如果不指定传送模式,默认为持久性消息。如果能容忍消息丢失,那么使用非持久性消息可以改善性格和减少存储的开销。

消息优先级从0-9十个级别,0-4是普通消息,5-9是加急消息,如果不指定优先级,则默认为4,JMS不要求严格按照这十个优先级发送消息,但必须保证加急消息要先于普通消息到达。

默认情况下,消息不回过期。如果消息在特定的周期内失去意义,那么可以设置过去时间,时间单位为毫秒。

2.4 MessageComsumer使用

MessageConsumer由Session创建,用来从Destination接受消息。

MessageConsumer createConsumer(Destination destination);

MessageConsumer createConsumer(Destination destination, String messageSelector);

MessageConsumer createConsumer(Destination destination, String messageSelector, boolean noLocal);

TopicSubscriber createDurableSubscriber(Topic topic, String name);

TopicSubscriber createDurableSubscriber(Topic topic, String name, String messageSelector, boolean noLocal);

messageSelector为消息选择器,noLocal默认设置为false,当设置为true时限制消费者只能接受和自己想通的连接(Connection)所发布的消息,此标记只适用于主题,不适用于队列,name标识订阅主题所对应的订阅名称,持久订阅时需要设置此参数。

2.4.1 messageSelector 示例

发送端代码:

必须使用带Property的方法,否则不能过滤

for (int i = 0; i < 10; i++) {
    MapMessage message = session.createMapMessage();
	// 必须使用带Property的方法,否则不能过滤
	message.setIntProperty("id", i); 
	message.setString("content", "message");
	producer.send(message, DeliveryMode.PERSISTENT, i, 1000 * 60 * 5);
}

接收端代码

// 定义过滤条件
public static final String SELECTOR_0 = "id > 5";


// 省略....
// 接受数据代码
MessageConsumer consumer = session.createConsumer(destination, SELECTOR_0);
		
// 第六步:接受message
while (true) {
	MapMessage message = (MapMessage) consumer.receive();
	String msg = message.getString("content") + message.getIntProperty("id");
	System.out.println(msg);
}

运行结果:

猜你喜欢

转载自blog.csdn.net/Willson_L/article/details/82683482