1.消息
消息队列技术中(后文也简称MQ )有一个基本概念需要在开篇前进行讨论:消息和消息
协议。消息即是信息的载体,这个描述相信各位读者都能够明白。消息发送者需要知道如何构
造消息:消息接收者需要知道如何解析消息。所以为了让消息发送者和消息接收者都能够明白
消息所承载的信息,消息本身就需要按照一种统一的格式描述消息,这种统一的格式称之为
消息协议。有效的消息一定具有某一种格式,而没有格式的消息是没有意义的。
消息从发送者到接收者的方式也有两种。一种我们可以称为直接消息通信,也就是说消息
从一端发出后(消息发送者)直接发送消息给最终接收者,并得到处理后的回执一一无论是阻
塞方式还是非阻塞方式。这种通信方式的一种具体实现就是我们已经介绍过的RPC ; 另一种
方式可以称为中转消息通信,即消息从某一端发出后,首先会进入一个容器进行处理和临时
存储,当消息接收者准备好或者达到某种传输条件后,再由这个容器发送给另一端,这种容
器的一种具体实现就是消息队列。
2.消息协议
了解下就是了
JMS 不是消息队列,更不是某种消息队列协议。而1S 是Java 消息服务接口,是一套规范
的Java API 接口
3.ActiveMQ 基本概念和使用
windows 的安装
https://blog.csdn.net/clj198606061111/article/details/38145597
4.demo
package test108MQ;
import java.net.Socket;
import org.apache.activemq.transport.stomp.StompConnection;
/**使用API 向ActiveMQ 发送Stomp 协议消息(生产者端)
* @Description
* @Author zengzhiqiang
* @Date 2018年10月8日
*/public class TestProducer {
public static void main(String[] args) {
try {
//建立Stomp 协议的连接(不同的协议默认端口是不同的,stomp61613)
StompConnection con = new StompConnection();
Socket so = new Socket("10.10.1.227",61613);
con.open(so);
con.setVersion("1.2");
con.connect("admin", "admin");
//以下发送一条信息
con.send("/test","now send a message "+Math.random());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
package test108MQ;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Map;import org.apache.activemq.transport.stomp.StompConnection;
import org.apache.activemq.transport.stomp.StompFrame;/**
* @Description
* @Author zengzhiqiang
* @Date 2018年10月8日
*/public class TestConsumer {
public static void main(String[] args) throws Exception {
//建立连接
StompConnection con = new StompConnection();
Socket so = new Socket("10.10.1.227",61613);
con.open(so);
con.setVersion("1.2");
con.connect("admin", "admin");
String ack = "client";
con.subscribe("/test","client");
//接收消息
for(;;){
StompFrame frame = null;
try {
///注意,如果没有接收到消息,那么这个消费者线程会停在这里,直到本次等待超时
frame = con.receive();
} catch (Exception e) {
// TODO: handle exception
continue;
}
///打印本次接收到的消息
System.out.println("frame.getAction()= "+frame.getAction());
Map<String, String> headers = frame.getHeaders();
String message_id = headers.get("message-id");
System.out.println("frame.getBody()= "+frame.getBody());
System.out.println("frame.getCommandId()= "+ frame.getCommandId());
//在ack 是client 标记的情况下, 确认消息
if("client".equals(ack)){
con.ack(message_id);
}
}
}
}
结果:
5.ActiveMQ 中的Queue 和Topics
JMS-Topic 队列基于“订阅一发布”模式,当操作者发布一条消息后,所
有对这条消息感兴趣的订阅者都可以收到它一一也就是说这条消息会被复制成多份然后进行分
发。只有当前“活动的”订阅者能够收到消息,换句话说如果当前JMS-To pic 队列中没有订阅
者,这条消息将被丢弃
JMS-Queue 是一种“负载均衡”模式的实现。一个消息能且只能被一个消
费者接收。如果当前几1S-Queue 中没有任何消费者,那么这条消息将会被Queue 存储起来
(实际应用中可以存储在磁盘上,也可以存储在数据库中,完全是看ActiveMQ 如何配置〉,
直到有一个消费者连接上。另外,当消费者在接收到消息后,如果在它断开与JMS-Queue 连
接之前没有发送ACK 信息(可以是客户端手动发送,也可以是自动发送),那么这条消息将
被发送给其他消费者
由于Queue 模式的
队列是要进行消息状态保存的,所以无论你是先运行“消费者”端,还是先运行“生产者”端,
最后“消费者”都会收到一条消息。
以上是我摘取的比较重要的笔记。
--------------------------yhy record。