
























解压到自己想放的目录
打开目录到bin文件夹下,根据电脑32位,还是64位打开文件夹

方式一:运行activemq.bat,不要关闭黑框,关闭就关闭服务了
访问localhost:8161,出现activeMQ的页面就成功了,可以进行登录,账号密码都为admin
方式二:以管理员的身份运行InstallService.bat,会在电脑上安装服务
打开任务管理器,选择服务,找到activeMQ服务启动
或者按win+R,输入services.msc,找到activeMQ启动服务
linux安装差不多也一样,下载对应安装包,解压
进入解压目录,进入斌文件夹,直接运行 ./activemq start
ps -ef | grep activemq 进行查看,也可以输入netstat -tunpl |grep 8161查看
./activemq stop进行停止服务


创建一个生产者:
创建一个maven工程
导入依赖
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.15.10</version>
</dependency>
创建AppProducer类
/**
* @Title: AppProducer.java
* @Package com.yrg.queue
* @Description: TODO(用一句话描述该文件做什么)
* @author yangrg
* @date 2019年12月2日 下午12:48:08
* @version V1.0
*/
package com.yrg.queue;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.ServerSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
/**
* @ClassName: AppProducer
* @Description: TODO(这里用一句话描述这个类的作用)
* @author yangrg
* @date 2019年12月2日 下午12:48:08
*
*/
public class AppProducer {
private static final String url="tcp://127.0.0.1:61616";
private static final String queueName="queue-test";
public static void main(String[] args) throws JMSException {
//1.创建连接工厂ConnectionFactory
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
//2.创建Connection
Connection connection = connectionFactory.createConnection();
//3.启动连接
connection.start();
//4.创建会话
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);//第一个参数:是否启动事务;第二个参数:应答模式(设置了自动应答)
//5.创建一个目标
Destination destination = session.createQueue(queueName);
//6.创建一个生厂者
MessageProducer producer = session.createProducer(destination);
for (int i = 0; i < 100; i++) {
//7.创建消息
TextMessage textMessage = session.createTextMessage("test:"+i);
//8.发送消息
producer.send(textMessage);
System.out.println("发送消息:"+textMessage.getText());
}
//9.关闭连接
connection.close();
}
}
打开activeMQ服务,登录上去,访问网址
运行程序,进入网址中是否有消息

可以看到有一天消息队列,可以点入查看详情

创建一个消费者AppCUstom
/**
* @Title: AppCustom.java
* @Package com.yrg.queue
* @Description: TODO(用一句话描述该文件做什么)
* @author yangrg
* @date 2019年12月2日 下午2:41:16
* @version V1.0
*/
package com.yrg.queue;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
/**
* @ClassName: AppCustom
* @Description: TODO(这里用一句话描述这个类的作用)
* @author yangrg
* @date 2019年12月2日 下午2:41:16
*
*/
public class AppCustom {
private static final String url="tcp://127.0.0.1:61616";
private static final String queueName="queue-test";
public static void main(String[] args) throws JMSException {
//1.创建连接工厂ConnectionFactory
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
//2.创建Connection
Connection connection = connectionFactory.createConnection();
//3.启动连接
connection.start();
//4.创建会话
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);//第一个参数:是否启动事务;第二个参数:应答模式(设置了自动应答)
//5.创建一个目标
Destination destination = session.createQueue(queueName);
//6.创建一个消费者
MessageConsumer consumer= session.createConsumer(destination);
//7.创建一个监听器
consumer.setMessageListener(new MessageListener() {
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("接收消息:"+textMessage.getText());
} catch (JMSException e) {
System.out.println("接受失败");
e.printStackTrace();
}
}
});
//8.关闭连接
//connection.close();//关闭连接会导致监听器退出,接受不到消息
}
}
运行程序,可以看到100个消息被消费

再运行一个消费者(在运行一次程序),可以看到没有接受到消息;
运行生产者,发送消息,观察两个消费者

可以看到两个消费者平均消费
主题模式:
创建Appproduce
/**
* @Title: AppProducer.java
* @Package com.yrg.queue
* @Description: TODO(用一句话描述该文件做什么)
* @author yangrg
* @date 2019年12月2日 下午12:48:08
* @version V1.0
*/
package com.yrg.topic;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.ServerSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
/**
* @ClassName: AppProducer
* @Description: TODO(这里用一句话描述这个类的作用)
* @author yangrg
* @date 2019年12月2日 下午12:48:08
*
*/
public class AppProducer {
private static final String url="tcp://127.0.0.1:61616";
private static final String topicName="topic-test";
public static void main(String[] args) throws JMSException {
//1.创建连接工厂ConnectionFactory
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
//2.创建Connection
Connection connection = connectionFactory.createConnection();
//3.启动连接
connection.start();
//4.创建会话
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);//第一个参数:是否启动事务;第二个参数:应答模式(设置了自动应答)
//5.创建一个目标
Destination destination = session.createTopic(topicName);
//6.创建一个生厂者
MessageProducer producer = session.createProducer(destination);
for (int i = 0; i < 100; i++) {
//7.创建消息
TextMessage textMessage = session.createTextMessage("test:"+i);
//8.发送消息
producer.send(textMessage);
System.out.println("发送消息:"+textMessage.getText());
}
//9.关闭连接
connection.close();
}
}
运行程序,可以在网址的topic中看到消息

创建订阅者AppCustom
/**
* @Title: AppCustom.java
* @Package com.yrg.queue
* @Description: TODO(用一句话描述该文件做什么)
* @author yangrg
* @date 2019年12月2日 下午2:41:16
* @version V1.0
*/
package com.yrg.topic;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
/**
* @ClassName: AppCustom
* @Description: TODO(这里用一句话描述这个类的作用)
* @author yangrg
* @date 2019年12月2日 下午2:41:16
*
*/
public class AppCustom {
private static final String url="tcp://127.0.0.1:61616";
private static final String topicName="topic-test";
public static void main(String[] args) throws JMSException {
//1.创建连接工厂ConnectionFactory
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
//2.创建Connection
Connection connection = connectionFactory.createConnection();
//3.启动连接
connection.start();
//4.创建会话
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);//第一个参数:是否启动事务;第二个参数:应答模式(设置了自动应答)
//5.创建一个目标
Destination destination = session.createTopic(topicName);
//6.创建一个消费者
MessageConsumer consumer= session.createConsumer(destination);
//7.创建一个监听器
consumer.setMessageListener(new MessageListener() {
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("接收消息:"+textMessage.getText());
} catch (JMSException e) {
System.out.println("接受失败");
e.printStackTrace();
}
}
});
//8.关闭连接
//connection.close();//关闭连接会导致监听器退出,接受不到消息
}
}
运行程序,发现接收不到消息
原因是因为主题模式要先订阅才能获得消息,而我们先是发布消息,才订阅
重新运行发布者,观察订阅者

在运行一个订阅者,重新发布消息,观察两个订阅者

可以看到两个订阅者消息消费一样
Spring jms理论




Spring jms演示
导入依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yrg</groupId>
<artifactId>Jms-Spring</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<spring.version>4.2.5.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jms -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.activemq/activemq-core -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.7.0</version>
<exclusions>
<exclusion>
<artifactId>spring-context</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
创建配置文件 common.xml
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:annotation-config></context:annotation-config>
<!-- ActiveMQ提供的ConnectionFactory -->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://127.0.0.1:61616"></property>
</bean>
<!-- JMS提供的连接池 -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="targetConnectionFactory"></property>
</bean>
<!-- 一个队列的目的地 -->
<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="queue"></constructor-arg>
</bean>
</beans>
创建priducer.xml
<!--引入common信息 -->
<import resource="common.xml"/>
<!-- 配置jmsTemplate用于发送消息-->
<bean class="org.springframework.jms.core.JmsTemplate" id="jmsTemplate">
<property name="connectionFactory" ref="connectionFactory"></property>
</bean>
创建接口IProducerServer
/**
* @Title: IProducerServer.java
* @Package com.yrg.jms.producer
* @Description: TODO(用一句话描述该文件做什么)
* @author yangrg
* @date 2019年12月3日 上午9:40:52
* @version V1.0
*/
package com.yrg.jms.producer;
/**
* @ClassName: IProducerServer
* @Description: TODO(这里用一句话描述这个类的作用)
* @author yangrg
* @date 2019年12月3日 上午9:40:52
*
*/
public interface IProducerServer {
void sendMessage(String message);
}
创建实现类ProducerServerImpl
/**
* @Title: ProducerServerImpl.java
* @Package com.yrg.jms.producer.ipml
* @Description: TODO(用一句话描述该文件做什么)
* @author yangrg
* @date 2019年12月3日 上午11:09:06
* @version V1.0
*/
package com.yrg.jms.producer.ipml;
import javax.annotation.Resource;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import com.yrg.jms.producer.IProducerServer;
/**
* @ClassName: ProducerServerImpl
* @Description: TODO(这里用一句话描述这个类的作用)
* @author yangrg
* @date 2019年12月3日 上午11:09:06
*
*/
public class ProducerServerImpl implements IProducerServer {
@Autowired
JmsTemplate jmsTemplate;
@Resource(name="queueDestination")
Destination destination ;
public void sendMessage(final String message) {
//使用jmsTemplate发送消息
jmsTemplate.send(destination, new MessageCreator() {
//创建一个消息
public Message createMessage(Session session) throws JMSException {
TextMessage textMessage = session.createTextMessage(message);
return textMessage;
}
});
System.out.println("发送消息:"+message);
}
}
在producer.xml中添加
<bean class="com.yrg.jms.producer.ipml.ProducerServerImpl" id="producerServerImpl"></bean>
创建信息生产者AppProducer
/**
* @Title: AppProducer.java
* @Package com.yrg.jms.producer
* @Description: TODO(用一句话描述该文件做什么)
* @author yangrg
* @date 2019年12月3日 上午11:23:13
* @version V1.0
*/
package com.yrg.jms.producer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.yrg.jms.producer.ipml.ProducerServerImpl;
/**
* @ClassName: AppProducer
* @Description: TODO(这里用一句话描述这个类的作用)
* @author yangrg
* @date 2019年12月3日 上午11:23:13
*
*/
public class AppProducer {
@SuppressWarnings("resource")
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:producer.xml");
IProducerServer producerServer = context.getBean(ProducerServerImpl.class);
for (int i = 0; i < 50; i++) {
producerServer.sendMessage("test"+i);
}
context.close();
}
}
运行AppProducer,发送消息,可以到网址中查看消息
现在来创建消费者
首先创建消息监听器ConsumerMessageListener
/**
* @Title: ConsumerMessageListener.java
* @Package com.yrg.jms.consumer
* @Description: TODO(用一句话描述该文件做什么)
* @author yangrg
* @date 2019年12月3日 下午2:59:22
* @version V1.0
*/
package com.yrg.jms.consumer;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
/**
* @ClassName: ConsumerMessageListener
* @Description: TODO(这里用一句话描述这个类的作用)
* @author yangrg
* @date 2019年12月3日 下午2:59:22
*
*/
public class ConsumerMessageListener implements MessageListener{
//监听到消息要做的事情
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("接受消息:"+textMessage.getText());
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
创建配置文件consumer.xml
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<import resource="common.xml"/>
<!-- 配置消息监听器 -->
<bean id="consumerMessageListener" class="com.yrg.jms.consumer.ConsumerMessageListener"></bean>
<!-- 配置消息监听容器-->
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"></property>
<property name="destination" ref="queueDestination"></property>
<property name="messageListener" ref="consumerMessageListener"></property>
</bean>
</beans>
创建Appconsumer消费者
/**
* @Title: AppConsumer.java
* @Package com.yrg.jms.consumer
* @Description: TODO(用一句话描述该文件做什么)
* @author yangrg
* @date 2019年12月3日 下午2:19:20
* @version V1.0
*/
package com.yrg.jms.consumer;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @ClassName: AppConsumer
* @Description: TODO(这里用一句话描述这个类的作用)
* @author yangrg
* @date 2019年12月3日 下午2:19:20
*
*/
public class AppConsumer {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:consumer.xml");
}
}
运行两次程序,再发布消息
主题模式:修改三个地方就可以变成主题模式
1.在common.xml中添加
<!-- 一个主体目的地,发布订阅模式 -->
<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="topic"></constructor-arg>
</bean>
2.在ProducerServerImpl中将@Resource(name="queueDestination")改为@Resource(name="topicDestination")
3.在consummer.xml中消息监听容器改为以下
<!-- 配置消息监听容器-->
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"></property>
<property name="destination" ref="topicDestination"></property>
<property name="messageListener" ref="consumerMessageListener"></property>
</bean>
主题模式改好了,进行测试,主题要先订阅才能接受消息















实践:


将activeMQ复制到三个文件夹
cp -rf apache-activemq-5.15.10/ /usr/local/activeMQSum/activeMQ-a
cp -rf apache-activemq-5.15.10/ /usr/local/activeMQSum/activeMQ-b
cp -rf apache-activemq-5.15.10/ /usr/local/activeMQSum/activeMQ-c


创建一个共享文件夹
mkdir kahadb

进入第一个目录
cd activeMQ-a

里面有个conf目录,进入
cd conf/
其中有个activemq.xml的配置文件,进行编辑
vim activemq.xml

找到网络连接配置

将其他协议注释掉

给A节点添加网络的配置项

保存退出
还需要配置后端管理地址的jetty.xml服务器的端口
vim jetty.xml

A节点的端口是8161,不需要修改直接退出
同样的配置B节点

配置activemq

还要在这里配置共享文件夹
找到如下地方

改成共享文件夹的地方

配置B节点的jetty

B节点配好,保存退出
C节点和B节点配置差不多,将activemq拷贝过去

修改C节点的activemq

修改jetty

C节点修改完成
依次启动activemq
./activeMQ-a/bin/activemq start
./activeMQ-b/bin/activemq start
./activeMQ-c/bin/activemq start

输入 ps -ef | grep activemq 进行查看

可以看到三个进程已经启动
依次输入
netstat -tunpl | grep 61616
netstat -tunpl | grep 61617
netstat -tunpl | grep 61618
查看端口服务

可以看见C节点无服务
C节点处于Slave状态,所以无服务
进行测试将B节点杀掉
./activeMQ-b/bin/activemq stop

查看服务

可以看见C节点处于Master状态了
启动B节点
用之前写的项目Jms-test、来进行测试
将提供者Appproducer的url改为
private static final String url="failover:(tcp://127.0.0.1:61617,tcp://127.0.0.1:61618)?randomize=true";
将AppConsumer的url改为
private static final String url="failover:(tcp://127.0.0.1:61616,tcp://127.0.0.1:61617,tcp://127.0.0.1:61618)?randomize=true";
启动生产者AppProducer,去网址查看消息发送到哪里
通过控制台可以看到消息发送到了61618的服务
将C节点关闭,看看消费者会从那个服务器消费消息
输入./activeMQ-c/bin/activemq stop 关闭
通过网址可以看见C节点的网址已经关闭
而B节点能够访问,且消息也在其中,当然能被消费者消费
运行消费者
可以在A节点网址看见消息被消费了

并且连接的是B节点,点击Network

在B节点网址也能看见消息被消费,且消费者是A节点





























//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////