以ActiveMQ为例JAVA消息中间件学习【1】
前言
在慢慢的接触大型的javaweb的项目就会接触到很多的中间件系统。
其中消息中间件在很多场景下会被运用。
这里主要就对最近所学习到的消息中间件知识做一个笔记,为以后的实际运用打下一个良好的基础。
什么是中间件,什么是消息中间件
最近被很多人问到,所以这里解释一下,我只是讲我的理解,也没有什么官方的定义。所谓中间件,顾名思义,是在一个过程中中间使用的元件。具体一点说:在整个业务系统中,用户看不到,但是也不是最底层的操作,在中间实现桥梁作用的技术或者是软件都可以称为中间件。
那么消息中间件,重点就在消息上面了。
消息就存在两个步骤,第一个步骤是发送,第二个步骤是接收,而这个两个步骤是异步的。完成这两个步骤的中间件就是消息中间件了。
听到这里你肯定还不是很明白。我就比较的并且白话的来说。
没有消息中间件,那就是我告诉你做什么,你就马上做什么,就像我们写的普通的接口服务一样。
有消息中间件,那就是,我告诉中间件你要做什么,我的中间件发送消息给你的中间件,你的中间件收到消息告诉你,你再开始做。
要是再不理解也没关系,继续看下去。
什么是JMS,什么是AMQP
java message service(java消息服务)
面向消息中间件的API,用于发送消息,进行异步通信
AMQP是一个提供统一消息的应用层标准协议,是一个统一的消息模型,为了跨平台而生。
简单的说,因为发送消息必须先要有规定,就和HTTP一样,要通信就必须要有协议去规定(规定消息怎么发,消息长成什么样等),而JMS是针对与java的协议,而AMQP是面向应用的协议。
几种消息中间件
JMS中的相关称呼
提供者:提供服务的中间件服务器
客户端:发送和接收消息的应用程序
生产者、发布者:创建并发送消息的客户端
消费者、订阅者:接受并处理消息的客户端
消息:传送的数据内容
消息模式:不同的消息模式对应不同的消息传递方式
队列模式:
队列中的消息只能被一个消费者消费
消费者可以随时消费队列中的消息
主题模式:
消息被所有订阅者消费,每个订阅者都能收到消息,就和我们现在的微博一样,只要你关注了,那就能都能收到消息。
消费者不能消费之前发送主题的消息,也就是说在你订阅之后才会收到消息,但是之前的历史消息你是看不到的。
ConnectionFactory:用于创建连接到消息中间件的连接工厂
Connection:代表应用程序和消息服务器之间的通信链路
Destination:消息发布和接收的地点
Session:会话,表示一个单线程的上下文,用于发送和接收消息
MessageConsumer:由会话创建,用于接收发送到目标的消息
MessageProducer:由会话创建,用于发送消息到目标
Message:是在消费者和生产者之间传送的对象,消息头,一组消息属性,一个消息体
上面所有类的关系
简单的实现(队列模式)
我们使用ActiveMQ进行实现
下载地址:http://activemq.apache.org/download.html
解压后找到\bin\win64目录下的activemq.bat直接运行即可
使用maven导入依赖
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.9.0</version>
</dependency>
编写消息的提供者
import org.apache.activemq.ActiveMQConnectionFactory; import javax.jms.*; /**
* 消息的提供者
*/
public class Producer {
//ActiveMQ的地址
private static final String URL = "tcp://127.0.0.1:61616";
//队列的名字
private static final String QUEUE_NAME = "active-test_queue"; public static void main(String[] args) throws JMSException {
//1、创建工厂
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(URL); //2、创建连接
Connection connection = connectionFactory.createConnection(); //3、启动连接
connection.start(); //4、创建会话
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); //5、创建目的地
Destination destination = session.createQueue(QUEUE_NAME); //6、创建一个生产者
MessageProducer producer = session.createProducer(destination); for (int i = 0; i < 10; i++) {
//7、创建消息
TextMessage textMessage = session.createTextMessage("testMessage " + i);
//8、发送消息
producer.send(destination, textMessage);
System.out.println("发送消息:" + textMessage.getText());
} //9、关闭连接
connection.close();
}
}
然后运行
本地ActiveMQ访问地址是
http://127.0.0.1:8161/
点击Manage ActiveMQ broker
帐号密码都是admin
然后点击上面的
其中10就是我们发送的10条消息
然后我们编写消费者
import org.apache.activemq.ActiveMQConnectionFactory; import javax.jms.*; /**
* 消息的消费者
*/
public class Consumer {
//ActiveMQ的地址
private static final String URL = "tcp://127.0.0.1:61616";
//队列的名字
private static final String QUEUE_NAME = "active-test_queue"; public static void main(String[] args) throws JMSException {
//1、创建工厂
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(URL); //2、创建连接
Connection connection = connectionFactory.createConnection(); //3、启动连接
connection.start(); //4、创建会话
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); //5、创建目的地
Destination destination = session.createQueue(QUEUE_NAME); //6、创建一个消费者
MessageConsumer messageConsumer = session.createConsumer(destination); //7、创建一个监听器
messageConsumer.setMessageListener(new MessageListener() {
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("接收到消息" + textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
});
}
}
然后运行之后查看队列中的消息
可以看到已经被消费了
当我们启动多个消费者,然后再启动生产者,我们可以看到在队列模式下一个消息只能被一个消费者消费
第一个
接收到消息testMessage 0
接收到消息testMessage 3
接收到消息testMessage 6
接收到消息testMessage 9
第二个
接收到消息testMessage 1
接收到消息testMessage 4
接收到消息testMessage 7
第三个
接收到消息testMessage 2
接收到消息testMessage 5
接收到消息testMessage 8
简单的实现(主题模式)
代码上面就改动一点点
/**
* 消息的提供者
*/
public class Producer {
//ActiveMQ的地址
private static final String URL = "tcp://127.0.0.1:61616";
//主题的名字
private static final String TOPIC_NAME = "active-test_topic"; public static void main(String[] args) throws JMSException {
//1、创建工厂
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(URL); //2、创建连接
Connection connection = connectionFactory.createConnection(); //3、启动连接
connection.start(); //4、创建会话
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); //5、创建目的地
Destination destination = session.createTopic(TOPIC_NAME); //6、创建一个生产者
MessageProducer producer = session.createProducer(destination); for (int i = 0; i < 10; i++) {
//7、创建消息
TextMessage textMessage = session.createTextMessage("testMessage " + i);
//8、发送消息
producer.send(destination, textMessage);
System.out.println("发送消息:" + textMessage.getText());
} //9、关闭连接
connection.close();
}
}
/**
* 消息的订阅者
*/
public class Consumer {
//ActiveMQ的地址
private static final String URL = "tcp://127.0.0.1:61616";
//主题的名字
private static final String TOPIC_NAME = "active-test_topic"; public static void main(String[] args) throws JMSException {
//1、创建工厂
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(URL); //2、创建连接
Connection connection = connectionFactory.createConnection(); //3、启动连接
connection.start(); //4、创建会话
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); //5、创建目的地
Destination destination = session.createTopic(TOPIC_NAME); //6、创建一个消费者
MessageConsumer messageConsumer = session.createConsumer(destination); //7、创建一个监听器
messageConsumer.setMessageListener(new MessageListener() {
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("接收到消息" + textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
});
}
}
然后我们先启动消息的发送者,然后再启动订阅者试试
我们发现订阅者没有接收到任何消息,因为在主题模式下只有先订阅再接收,你是不能收到一个主题下的历史消息的。
然后我们关闭所有,然后启动两个订阅者,然后再启动发送者。
我们看到
第一个
接收到消息testMessage 0
接收到消息testMessage 1
接收到消息testMessage 2
接收到消息testMessage 3
接收到消息testMessage 4
接收到消息testMessage 5
接收到消息testMessage 6
接收到消息testMessage 7
接收到消息testMessage 8
接收到消息testMessage 9
第二个
接收到消息testMessage 0
接收到消息testMessage 1
接收到消息testMessage 2
接收到消息testMessage 3
接收到消息testMessage 4
接收到消息testMessage 5
接收到消息testMessage 6
接收到消息testMessage 7
接收到消息testMessage 8
接收到消息testMessage 9
说明在主题模式下,每一个订阅者都会收到一条一模一样的消息。
总结
至此我们已经可以简单的使用ActiveMQ了。我们第一阶段也就完成了。
思考几个问题,我们需要熟悉整个过程,在整个过程中那些东西是会被多次使用的,那些使用后马上需要关闭,而那些是不能马上关闭的?
主题模式和队列模式分别应该应用在实际中的哪种场景?
后面我们会慢慢继续学习。
以ActiveMQ为例JAVA消息中间件学习【1】的更多相关文章
- 以ActiveMQ为例JAVA消息中间件学习【2】
前言 之前我们学习了什么是消息中间件,以ActiveMQ为例做了一个最简单的消息中间件的实现.但是我们做的就只能算是个例子而已,因为在实际的项目中肯定会有spring插一脚,所以spring肯定有来管 ...
- 以ActiveMQ为例JAVA消息中间件学习【4】——消息中间件实际应用场景
前言 当前真正学习消息中间件,当前已经走到了,可以简单的使用,网上有很多那种复杂的高可用的架构,但是那些都是对于一些比较大型的项目来说的. 对于一些小型的项目可能用不到那么大的架构,于是我们需要从最简 ...
- 以ActiveMQ为例JAVA消息中间件学习【3】——SpringBoot中使用ActiveMQ
前言 首先我们在java环境中使用了ActiveMQ,然后我们又在Spring中使用了ActiveMQ 本来这样已经可以了,但是最近SpringBoot也来了.所以在其中也需要使用试试. 可以提前透露 ...
- Java消息中间件入门笔记 - ActiveMQ篇
入门 消息中间件带来的好处: 1)解耦:系统解耦 2)异步:异步执行 3)横向扩展 4)安全可靠 5)顺序保证 栗子: 通过服务调用让其它系统感知事件发生 系统之间高耦合 程序执行效率低 通过消息中间 ...
- java消息中间件之ActiveMQ初识
目录 消息中间件简介 解耦合和异步 可靠性和高效性 JMS P2P Pub/Sub AMQP JMS和AMQP对比 常见消息中间件 ActiveMQ RabbitMQ Kafka 综合比较 标签(空格 ...
- Java工程师学习指南 完结篇
Java工程师学习指南 完结篇 先声明一点,文章里面不会详细到每一步怎么操作,只会提供大致的思路和方向,给大家以启发,如果真的要一步一步指导操作的话,那至少需要一本书的厚度啦. 因为笔者还只是一名在校 ...
- Java工程师学习指南(完结篇)
Java工程师学习指南 完结篇 先声明一点,文章里面不会详细到每一步怎么操作,只会提供大致的思路和方向,给大家以启发,如果真的要一步一步指导操作的话,那至少需要一本书的厚度啦. 因为笔者还只是一名在校 ...
- Java多线程学习笔记
进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...
- Java Web学习系列——Maven Web项目中集成使用Spring
参考Java Web学习系列——创建基于Maven的Web项目一文,创建一个名为LockMIS的Maven Web项目. 添加依赖Jar包 推荐在http://mvnrepository.com/.h ...
随机推荐
- Python开发——【循环】语句
while循环 while 条件: # 要执行的循环体 # 如果条件为真,那么循环体则执行 # 如果条件为假,那么循环体不执行 死循环 count = 0 while True:# 条件永远为真 pr ...
- UNION 和 UNION ALL 操作符
SQL UNION 操作符 1.UNION 操作符用于合并两个或多个 SELECT 语句的结果集. 请注意:UNION 内部的 SELECT 语句必须拥有相同数量的列.列也必须拥有相似的数据类型.同时 ...
- linux学习第七天 (Linux就该这么学)
今天讲了chmod (权限 设置)和 chown(属性 设置),特殊权限:SUID u+s 数字法是4 x=s - = S,SGID g+s 数字法是2 x=s -=S,SBIT o+t x=t ...
- python小结 1
1.变量 记录状态 类型:数字,字符串,元组,列表,字典 可变不可变(内存地址不变的情况下,值能不能改变): 不可变:字符串,数字,元组 可变:列表,字典 访问顺序: 直接访问:数字 有序:字符串,列 ...
- python之模块的导入
今天在做一个项目的时候卡在模块导入这个点上了.赶紧回头总结一下 一.被导入的文件和工作的脚本在一个目录下 1.导入一个.py文件里的功能或参数(导入模块) 先看一下目录结构: module里有两个功能 ...
- 《C#从现象到本质》读书笔记(四)第4章C#和面向对象
<C#从现象到本质>读书笔记第4章C#和面向对象 面向对象程序设计OOP 面向对象的三大特性是: 1)封装:类可以将它的成员私有化,只暴露它认为应当暴露给外界的成员.通过私有化成员,外界不 ...
- 在JSP页面获取集合的长度
在jsp页面上经常遇到得到集合长度.字符长度.字符切取等应用需,在2.0以前这种需是许多程序员对JSTL及为不满意的地方之一.为此在2.0 中添加了functions标签,其提供对以上需求的支持. 使 ...
- tensorflow o. 到 tensorflow 1. 部分改变
一下内容为笔者实际应用中遇到的问题,可能(必须)不全,后面会持续更新. (1) tf.nn.run_cell 改为 tf.contrib.rnn (2) tf.reduce_mean 改为 ...
- 顺序栈的基本操作(C语言)
由于现在只学了C语言所以就写这个C语言版的栈的基本操作 这里说一下 :网上和书上都有这种写法 int InitStack(SqStack &p) &p是取地址 但是这种用法好像C并不 ...
- APP微信支付报错《商户号该产品权限未开通,请前往商户平台>产品中心检查后重试》
问题 最近项目使用MUI,HBuilder.开发打包H5的app 在开发H5 plus支付的时候,遇到以下问题: App微信支付调官方的统一下单接口返回错误信息 {return_msg=商户号该产品权 ...