1. 点对点通信

点对点是一种一对一通信方式,更像是有一个队列,一个人往队列里放消息,另一个人从队列中取消息,其最大的特点是一个消息只会被消费一次,即使有多个消费者同时消费,他们消费的也是不同的消息。

2. 简单实现

添加依赖

添加Maven依赖:

<!-- https://mvnrepository.com/artifact/org.apache.activemq/activemq-all -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.15.2</version>
</dependency>

activemq.properties

在resource下创建一个activemq.properties,用来保存activemq的用户名、密码、连接地址等信息:

username = xxx
passwd = xxx
url = tcp://xx.xx.xx.xx:61616

ActiveMqUtils

创建一个工具类,用来获取连接,因为工厂类一般都是比较重量级的类,不应该重复创建:

package org.cc11001100.activemq;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import java.io.IOException;
import java.util.Properties; /**
* @author: CC11001100
* @date: 2017/11/8 18:20
* @email: CC11001100@qq.com
*/
public class ActiveMqUtils { private static ConnectionFactory connectionFactory; static{
try {
Properties properties = new Properties();
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("activemq.properties"));
connectionFactory=new ActiveMQConnectionFactory(properties.getProperty("username"),
properties.getProperty("passwd"),
properties.getProperty("url"));
} catch (IOException e) {
e.printStackTrace();
}
} /**
* 获取JMS连接
*
* @return JMS Connection
*/
public static Connection getConnection(){
try {
return connectionFactory.createConnection();
} catch (JMSException e) {
e.printStackTrace();
}
return null;
} }

SenderUtils

创建发送消息的工具类:

package org.cc11001100.activemq;

import javax.jms.*;
import java.util.function.Function; /**
* @author: CC11001100
* @date: 2017/11/8 18:12
* @email: CC11001100@qq.com
*/
public class SenderUtils { /**
* 向指定的队列发送消息
*
* @param queueName 发送到哪个队列
* @param generateMessage 使用这个方法产生要发送的消息
*/
public static void send(String queueName, Function<Session, Message> generateMessage){ Connection conn=null;
Session session=null;
MessageProducer messageProducer=null; try {
conn = ActiveMqUtils.getConnection();
assert conn != null;
conn.start();
session=conn.createSession(true, Session.AUTO_ACKNOWLEDGE); /*队列名是区分大小写的,如果不存在的话会自动创建一个*/
Queue queue=session.createQueue(queueName);
messageProducer=session.createProducer(queue);
/*设置非持久化,持久化的意思是要求发送的时候接收方要在线*/
messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT); // 生成消息并发送
Message message = generateMessage.apply(session);
messageProducer.send(message); /*在提交的时候消息才会真正的发出去*/
session.commit();
} catch (JMSException e) {
e.printStackTrace();
}finally{ if(messageProducer!=null){
try {
messageProducer.close();
} catch (JMSException e) {
e.printStackTrace();
}
} if(session!=null){
try {
session.close();
} catch (JMSException e) {
e.printStackTrace();
}
} if(conn!=null){
try {
conn.close();
} catch (JMSException e) {
e.printStackTrace();
}
} } } }

注意:在session.commit()之前消息是不会被发送出去的。

ReceiverUtils

创建接收消息的工具类:

package org.cc11001100.activemq;

import javax.jms.*;
import java.util.function.Function; /**
* @author: CC11001100
* @date: 2017/11/8 18:37
* @email: CC11001100@qq.com
*/
public class ReceiverUtils { /**
* 从指定队列中接收一个消息
*
* @param queueName 队列名称
* @return 接收到的消息内容
*/
public static Message receive(String queueName){ Connection conn=null;
Session session=null;
MessageConsumer messageConsumer=null; try {
conn=ActiveMqUtils.getConnection();
assert conn != null;
conn.start();
session=conn.createSession(true,Session.AUTO_ACKNOWLEDGE); Queue queue=session.createQueue(queueName);
messageConsumer=session.createConsumer(queue); /*这是一个阻塞式的方法,在接收到消息之前会一直阻塞着*/
Message message=messageConsumer.receive();
session.commit();
return message;
} catch (JMSException e) {
e.printStackTrace();
}finally{ if(messageConsumer!=null){
try {
messageConsumer.close();
} catch (JMSException e) {
e.printStackTrace();
}
} if(session!=null){
try {
session.close();
} catch (JMSException e) {
e.printStackTrace();
}
} if(conn!=null){
try {
conn.close();
} catch (JMSException e) {
e.printStackTrace();
}
} } return null;
} /**
* 从指定队列接收一个消息并将它传递给回调方法处理,返回处理后的结果
*
* @param queueName 队列名称
* @param callback 处理消息的回调方法
* @param <T> 处理消息后的返回值
* @return 处理消息后的返回值
*/
public static <T> T receive(String queueName, Function<Message, T> callback){
Message message = receive(queueName);
assert message!=null;
return callback.apply(message);
} }

Main

创建测试类:

package org.cc11001100.activemq;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.TextMessage;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer; /**
* @author: CC11001100
* @date: 2017/11/8 18:49
* @email: CC11001100@qq.com
*/
public class Main { public static void main(String[] args) { final String QUEUE_NAME = "FOO_QUEUE"; // 生产者
new Thread(()->{ while(true){ try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
} SenderUtils.send(QUEUE_NAME, session -> {
try {
return session.createTextMessage(Long.toString(System.currentTimeMillis()));
} catch (JMSException e) {
e.printStackTrace();
}
return null;
});
} }).start(); // 消费者
new Thread(()->{ while(true){
ReceiverUtils.receive(QUEUE_NAME, message->{
if(message instanceof TextMessage){
try {
TextMessage textMessage = (TextMessage) message;
System.out.println(textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
return message;
});
} }).start(); } }

ActiveMQ笔记之点对点队列(Point-to-Point)的更多相关文章

  1. ActiveMQ笔记(7):如何清理无效的延时消息?

    ActiveMQ的延时消息是一个让人又爱又恨的功能,具体使用可参考上篇ActiveMQ笔记(6):消息延时投递,在很多需要消息延时投递的业务场景十分有用,但是也有一个缺陷,在一些大访问量的场景,如果瞬 ...

  2. php 利用activeMq+stomp实现消息队列

    php 利用activeMq+stomp实现消息队列 一.activeMq概述 ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线.ActiveMQ 是一个完全支持JMS1.1和J ...

  3. 实战Spring4+ActiveMQ整合实现消息队列(生产者+消费者)

    引言: 最近公司做了一个以信息安全为主的项目,其中有一个业务需求就是,项目定时监控操作用户的行为,对于一些违规操作严重的行为,以发送邮件(ForMail)的形式进行邮件告警,可能是多人,也可能是一个人 ...

  4. Linux进程间通信IPC学习笔记之消息队列(SVR4)

    Linux进程间通信IPC学习笔记之消息队列(SVR4)

  5. Spring boot 集成ActiveMQ(包含双向队列实现)

    集百家之长,成一家之言.  1. 下载ActiveMQ https://mirrors.tuna.tsinghua.edu.cn/apache/activemq/5.15.9/apache-activ ...

  6. 学习ActiveMQ(二):点对点(队列)模式消息演示

    一:介绍 点对点的消息发送方式主要建立在 消息(Message ),队列(Queue),发送者(Sender),消费者(receiver)上,Queue 存贮消息,Sender 发送消息,receiv ...

  7. ActiveMQ 笔记(二)部署和DEMO(队列、主题)

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.部署操作 1. 部署在linux 上的acvtiveMQ 要可以通过前台windows 的页面访问, ...

  8. ActiveMQ笔记(1):编译、安装、示例代码

    一.编译 虽然ActiveMQ提供了发布版本,但是建议同学们自己下载源代码编译,以后万一有坑,还可以尝试自己改改源码. 1.1 https://github.com/apache/activemq/r ...

  9. ActiveMQ_点对点队列(二)

      一.本文章包含的内容 1.列举了ActiveMQ中通过Queue方式发送.消费队列的代码(普通文本.json/xml字符串.对象数据) 2.spring+activemq方式   二.配置信息 1 ...

随机推荐

  1. CodeForces Round #527 (Div3) C. Prefixes and Suffixes

    http://codeforces.com/contest/1092/problem/C Ivan wants to play a game with you. He picked some stri ...

  2. 选项卡控件(TabControl)的操作

    移除选项卡和删除不同:前者可以从控件中移除不需要的选项,后者可以删掉整个控件.

  3. PHP面向对象之重写

    覆盖(override): 基本概念 覆盖,又叫“重写”: 含义: 将一个类从父类中继承过来的属性和方法“重新定义”——此时相当于子类不想用父类的该属性或方法,而是想要定义. 覆盖的现实需要: 对于一 ...

  4. .net下使用NPOI读取Excel表数据

    这里只写MVC下的情况 public ActionResult Index() { var path = Server.MapPath(@"/content/user.xlsx") ...

  5. LBP纹理特征[转自]

    LBP方法(Local binary patterns)是一个计算机视觉中用于图像特征分类的一个方法.LBP方法在1994年首先由T. Ojala, M.Pietikäinen, 和 D. Harwo ...

  6. python的N个小功能之正则匹配

    1.. 匹配任意除换行符“\n”外的字符:2.*表示匹配前一个字符0次或无限次:3.+或*后跟?表示非贪婪匹配,即尽可能少的匹配,如*?重复任意次,但尽可能少重复,惰性匹配:4. .*? 表示匹配任意 ...

  7. Codeforces Round#514 Div.2 翻车记

    A:签到 #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> # ...

  8. BZOJ3717 PA2014Pakowanie(状压dp)

    显然贪心地有尽量先往容量大的背包里放.设f[i]为i子集物品最小占用背包数,g[i]为该情况下最后一个背包的剩余容量,转移显然. #include<iostream> #include&l ...

  9. Seek the Name, Seek the Fame POJ - 2752(拓展kmp || kmp)

    题意: 就是求前缀和后缀相同的那个子串的长度  然后从小到大输出 解析: emm...网上都用kmp...我..用拓展kmp做的  这就是拓展kmp板题嘛... 求出extend数组后  把exten ...

  10. Day22-1-知识回顾

    1. 知识点概要 --Session --CSRF --Model操作 --Form验证(ModelForm) --中间件 --缓存 2.知识回顾 2.1客户端请求及服务器端返回,都包含请求头和bod ...