jms和activemq
一、什么是JMS
JMS是java message service的缩写即java消息服务,是java定义的消息中间件(MOM)的技术规范(类似玉JDBC)。用于程序之间的异步通信,如果两个应用程序需要通信,则可以通过JMS来进行转发,达到解耦的目的。
二、JMS的消息模型
JMS有两种消息模型:
1、点对点或队列模型(Point-to-Point Messaging Domain):消息的生产者将生产出的消息加入到一个队列中,消息的接受者从队列中获取消息。队列保留着消息,直到他们被消费或者超时。
特点:①每个消息都只有一个消费者,如果队列中的消息被某个消费者消费,该消息会移出队列。
②消息的生产者和消费者之间没有时间的约束,生产者可以生产消息,无论消费者是否在运行。同样只要消息队列中有消息,消费者就可以消费和生产者的状态无关。
③消费者接受完消息之后要向队列反馈成功的信息。
2、发布订阅模型(Publish/Subscribe Messaging Domain ):发布者发布消息,所有的订阅者都会接受到消息。
特点:①发布一个消息会有多个订阅者接受到消息
②消息发布者和订阅者之间有时间上的相关性。订阅一个主题的订阅者只能接收到自它订阅之后发布的消息。JMS规范允许客户创建持久订阅,这在一定程度上放松了时间上的相关性要求。持久订阅允许订阅者接受它在未处于激活状态时发送的消息。
三、JMS的对象模型
1、连接工厂(ConnectionFactory):用于创建JMS连接
2、JMS连接(Connection):表示JMS客户端和服务器端之间的一个活动的连接,是由客户端通过调用连接工厂的方法建立的。
3、JMS会话(Session):表示JMS客户与JMS服务器之间的会话状态。JMS会话建立在JMS连接上,表示客户与服务器之间的一个会话线程。
4、JMS目的地(Destination):生产者发送消息的地方。点对点模式中的目的地是queue,发布订阅模式中的目的地就是topic。
5、生产者(Message Producer)和消费者(Message Consumer)对象由Session对象创建,用于发送和接收消息。
四、ActiveMQ
上面说到JMS是java消息服务的技术规范,它制定了在整个消息服务提供过程中的所有数据结构和交互流程。而MQ则是消息队列服务,是面向消息中间件(MOM)的最终实现,是真正的服务提供者;MQ的实现可以基于JMS,也可以基于其他规范或标准。
ActiveMQ就是Apache组织的一个开源的消息中间件,它实现了JMS技术规范。
1、ActiveMQ点对点模式
下面的代码都是测试代码,消费者如果关闭连接,则只能消费一次消息,所以没有关闭。
public class MsgSender { //ActiveMq 的默认用户名
private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;
//ActiveMq 的默认登录密码
private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;
//ActiveMQ 的链接地址
private static final String BROKEN_URL = "tcp://127.0.0.1:61616";//ActiveMQConnection.DEFAULT_BROKER_URL; public static void main(String[] args) { //创建一个链接工厂
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(USERNAME,PASSWORD,BROKEN_URL);
Connection connection = null;
Session session = null;
MessageProducer messageProducer = null;
try {
//从工厂中创建一个链接
connection= connectionFactory.createConnection();
//开启链接
connection.start();
//创建一个事务(这里通过参数可以设置事务的级别)
session = connection.createSession(true,Session.SESSION_TRANSACTED);
//创建一个消息队列
Queue queue = session.createQueue("myqueue");
//消息生产者
messageProducer = session.createProducer(queue);
int count = 0;
while(true){
Thread.sleep(1000); //创建一条消息
TextMessage msg = session.createTextMessage("生产消息"+count);
System.out.println("生产消息"+count++);
//发送消息
messageProducer.send(msg);
//提交事务
session.commit();
}
} catch (JMSException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
try {
if(connection != null){
connection.close();
}
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
public class MsgReciver { private static final String USERNAME = ActiveMQConnection.DEFAULT_USER; private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD; private static final String BROKEN_URL = "tcp://127.0.0.1:61616";//ActiveMQConnection.DEFAULT_BROKER_URL; public static void main(String[] args) {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
connectionFactory = new ActiveMQConnectionFactory(USERNAME,PASSWORD,BROKEN_URL);
try {
connection = connectionFactory.createConnection();
connection.start();
session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue("myqueue");
MessageConsumer consumer = null;
consumer = session.createConsumer(queue); MsgListener listener=new MsgListener();
consumer.setMessageListener(listener);
} catch (JMSException e) {
e.printStackTrace();
}
}
}
public class MsgListener implements MessageListener { @Override
public void onMessage(Message msg) {
TextMessage tmsg = (TextMessage)msg;
try {
System.out.println("接收到的数据:"+tmsg.getText());
} catch (JMSException e) {
e.printStackTrace();
}
} }
2、发布订阅模式
public class MsgSender { //ActiveMq 的默认用户名
private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;
//ActiveMq 的默认登录密码
private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;
//ActiveMQ 的链接地址
private static final String BROKEN_URL = "tcp://127.0.0.1:61616";//ActiveMQConnection.DEFAULT_BROKER_URL; public static void main(String[] args) { //创建一个链接工厂
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(USERNAME,PASSWORD,BROKEN_URL);
Connection connection = null;
Session session = null;
MessageProducer messageProducer = null;
try {
//从工厂中创建一个链接
connection= connectionFactory.createConnection();
//开启链接
connection.start();
//创建一个事务(这里通过参数可以设置事务的级别)
session = connection.createSession(true,Session.SESSION_TRANSACTED);
//创建一个Topic
Topic myTopic = session.createTopic("mytopic");
//消息生产者
messageProducer = session.createProducer(myTopic);
int count = 0;
while(true){
Thread.sleep(10000);
//创建一条消息
TextMessage msg = session.createTextMessage("发布消息"+count);
System.out.println("发布消息"+count++);
//发送消息
messageProducer.send(msg);
//提交事务
session.commit();
}
} catch (JMSException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
try {
if(connection != null){
connection.close();
}
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
public class MsgReciver { private static final String USERNAME = ActiveMQConnection.DEFAULT_USER; private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD; private static final String BROKEN_URL = "tcp://111.230.239.152:61616";//ActiveMQConnection.DEFAULT_BROKER_URL; public static void main(String[] args) {
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
connectionFactory = new ActiveMQConnectionFactory(USERNAME,PASSWORD,BROKEN_URL);
try {
connection = connectionFactory.createConnection();
connection.start();
session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
Topic myTopic = session.createTopic("mytopic");
MessageConsumer consumer = null;
consumer = session.createConsumer(myTopic);
MsgListener listener=new MsgListener();
consumer.setMessageListener(listener);
} catch (JMSException e) {
e.printStackTrace();
}
}
}
public class MsgListener implements MessageListener { @Override
public void onMessage(Message msg) {
TextMessage tmsg = (TextMessage)msg;
try {
System.out.println("接收到的数据:"+tmsg.getText());
} catch (JMSException e) {
e.printStackTrace();
}
} }
3、spring集成ActiveMQ
引入jar包
<!-- 整合activemq -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.15.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
activemq.brokerURL=tcp://127.0.0.1:61616 activemq.queue=myqueue activemq.topic=mytopic
<!-- 集成ActiveMQ -->
<!-- 配置能够产生connection的connectionfactory,由JMS对应的服务厂商提供 -->
<bean id="tagertConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<constructor-arg name="brokerURL" value="${activemq.brokerURL}"/>
</bean>
<!-- 配置spring管理真正connectionfactory的connectionfactory,相当于spring对connectionfactory的一层封装 -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="tagertConnectionFactory"/>
</bean>
<!-- 配置生产者 -->
<!-- Spring使用JMS工具类,可以用来发送和接收消息 -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 这里是配置的spring用来管理connectionfactory的connectionfactory -->
<property name="connectionFactory" ref="connectionFactory"/>
</bean>
<!-- 配置destination -->
<!-- 队列目的地 -->
<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="${activemq.queue}"/>
</bean>
<!-- 话题目的地 -->
<bean id="itemAddTopic" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="${activemq.topic}"/>
</bean> <!-- 配置监听器 -->
<bean id="myQueueListener" class="com.myproject.listener.MqQueueListener"/>
<bean id="mqTopicListener" class="com.myproject.listener.MqTopicListener"/>
<!-- 系统监听器 -->
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="destination" ref="queueDestination"/>
<property name="messageListener" ref="myQueueListener"/>
</bean>
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="destination" ref="itemAddTopic"/>
<property name="messageListener" ref="mqTopicListener"/>
</bean>
public class MqQueueListener implements MessageListener { @Override
public void onMessage(Message message) {
TextMessage testMessage = (TextMessage)message;
try {
System.out.println("收到信息:"+testMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
public class MqTopicListener implements MessageListener { @Override
public void onMessage(Message message) {
TextMessage testMessage = (TextMessage)message;
try {
System.out.println("收到信息:"+testMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
} }
@Service
public class UserServiceImpl implements UserService { @Autowired
private UserMapper userMapper;
@Autowired
private RedisCacheUtil redisCacheUtil; @Autowired
private JmsTemplate jmsTemplate;
@Resource(name="itemAddTopic")
private Destination destination; @Override
public User getById(Map<String, Object> params) {
Integer userId = Integer.parseInt(params.get("id").toString());
User user = (User)redisCacheUtil.get(RedisKey.USER_BASIC_INFO+userId);
if(user == null ){
user = userMapper.selectByPrimaryKey(userId);
if(user != null ){
redisCacheUtil.set(RedisKey.USER_BASIC_INFO+userId, user);
}
}
ObjectMapper mapper = new ObjectMapper();
try {
final String userInfo = mapper.writeValueAsString(user);
//获取到用户后发送一个消息给其他模块
jmsTemplate.send(destination, new MessageCreator() { @Override
public Message createMessage(Session session) throws JMSException {
TextMessage msg = session.createTextMessage(userInfo);
return msg;
}
});
} catch (JsonProcessingException e) {
e.printStackTrace();
} return user;
}
}
jms和activemq的更多相关文章
- 深入浅出JMS(三)--ActiveMQ简单的HelloWorld实例
第一篇博文深入浅出JMS(一)–JMS基本概念,我们介绍了JMS的两种消息模型:点对点和发布订阅模型,以及消息被消费的两个方式:同步和异步,JMS编程模型的对象,最后说了JMS的优点. 第二篇博文深入 ...
- 【JMS】JMS之ActiveMQ的使用
这篇文章主要是简单介绍一下JMS和ActiveMQ,以及使用ActiveMQ来写两个demo. 1. JMS是啥 百度百科的解释: JMS即Java消息服务(Java Message Service) ...
- ActiveMQ第二弹:使用Spring JMS与ActiveMQ通讯
本文章的完整代码可从我的github中下载:https://github.com/huangbowen521/SpringJMSSample.git 上一篇文章中介绍了如何安装和运行ActiveMQ. ...
- Simple guide to Java Message Service (JMS) using ActiveMQ
JMS let’s you send messages containing for example a String, array of bytes or a serializable Java o ...
- JMS and ActiveMQ first lesson(转)
JMS and ActiveMQ first lesson -- jms基础概念和应用场景 2011-6-18 PM 9:30 主讲:kimmking <kimmking@163.com> ...
- spring集成JMS访问ActiveMQ
首先我们搭建一个spring-mvc项目,项目可以参考:spring-mvc 学习笔记 步骤: 在pom.xml中加上需要的包 修改web.xml,增加IOC容器 spring配置文件applicat ...
- JMS之——ActiveMQ时抛出的错误Could not connect to broker URL-使用线程池解决高并发连接
转载请注明出处:http://blog.csdn.net/l1028386804/article/details/69046395 解决使用activemq时抛出的异常:javax.j ms.JMSE ...
- 【ActiveMQ】Spring Jms集成ActiveMQ学习记录
Spring Jms集成ActiveMQ学习记录. 引入依赖包 无论生产者还是消费者均引入这些包: <properties> <spring.version>3.0.5.REL ...
- 深入浅出 JMS(三) - ActiveMQ 安全机制
深入浅出 JMS(三) - ActiveMQ 安全机制 一.认证 认证(Authentication):验证某个实体或者用户是否有权限访问受保护资源. MQ 提供两种插件用于权限认证: (一).Sim ...
- 深入浅出 JMS(四) - ActiveMQ 消息存储
深入浅出 JMS(四) - ActiveMQ 消息存储 一.消息的存储方式 ActiveMQ 支持 JMS 规范中的持久化消息与非持久化消息 持久化消息通常用于不管是否消费者在线,它们都会保证消息会被 ...
随机推荐
- Luogu4389 付公主的背包(生成函数+多项式exp)
显然构造出生成函数,对体积v的物品,生成函数为1+xv+x2v+……=1/(1-xv).将所有生成函数乘起来得到的多项式即为答案,设为F(x),即F(x)=1/∏(1-xvi).但这个多项式的项数是Σ ...
- DRF 版本和认证
Django Rest Framework 版本控制组件 DRF的版本 版本控制是做什么用的, 我们为什么要用 首先我们要知道我们的版本是干嘛用的呢~~大家都知道我们开发项目是有多个版本的~~ 当我们 ...
- Django ORM模型
Object Relational Mapping(ORM) 一,ORM介绍 1, ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象 ...
- 数据分析---用pandas进行数据清洗(Data Analysis Pandas Data Munging/Wrangling)
这里利用ben的项目(https://github.com/ben519/DataWrangling/blob/master/Python/README.md),在此基础上增添了一些内容,来演示数据清 ...
- 【BZOJ2333】【SCOI2011】棘手的操作 treap合并
题目大意 有\(n\)个节点,标号从1到\(n\),这\(n\)个节点一开始相互不连通.第\(i\)个节点的初始权值为\(a_i\),接下来有如下一些操作: \(U~x~y\):加一条边,连接第\(x ...
- mac centos linux 安装PHP扩展 INTL(国际化) ———— error: 'ext/standard/php_smart_str.h'
PHP简单源码安装扩展 五个步骤: 详细说明下: cd /fujieace/php7.0/ext/intl:#进入INTL扩展目录? 在编译扩展时候需要phpize准备环境,准备程序需要获取这个目录的 ...
- 【BZOJ2034】最大收益(贪心)
[BZOJ2034]最大收益(贪心) 题面 BZOJ 题解 首先显然让价值越大的占用一个时刻一定更优. 所以把所有东西按照价值排序之后来处理,那么显然就是把前面的全部放好之后,考虑来放当前这个东西,如 ...
- [NOI2015]寿司晚宴(状压dp)
为了庆祝NOI的成功开幕,主办方为大家准备了一场寿司晚宴.小G和小W作为参加NOI的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了n−1种不同的寿司,编号1,2,3,⋯,n-1,其中第种 ...
- JDK8中的并行流
1.IntStream.parallel():获取并行流处理 2. Collection中调用parallelStream()获取并行流 3.并行排序Arrays.parallelSort()
- Libre OJ 130、131、132 (树状数组 单点修改、区间查询 -> 区间修改,单点查询 -> 区间修改,区间查询)
这三题均可以用树状数组.分块或线段树来做 #130. 树状数组 1 :单点修改,区间查询 题目链接:https://loj.ac/problem/130 题目描述 这是一道模板题. 给定数列 a[1] ...