docker安装ActiveMQ
- 编写docker-compose文件
version: "3"
services:
activeqm:
image: webcenter/activemq:latest
container_name: activemq
ports:
- "8161:8161"
- "61616:61616"
volumes:
- "./data:/data/activemq"
- "./log:/var/log/activemq"
environment:
- ACTIVEMQ_ADMIN_LOGIN=admin #账号
- ACTIVEMQ_ADMIN_PASSWORD=123456 #密码
- 启动服务:docker-compose up -d
- 登录网页:http://192.168.xxx.xx:8161/
Maven实现点对点通讯模式
- pom引入核心包
<!-- activemq核心包 -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.7.0</version>
</dependency>
- 编写消息生产者连接MQ,且推送消息到ActiveMQ中
public static void test() throws JMSException {
String username = "admin";
String password = "123456";
String url = "tcp://127.0.0.1:61616";
// 获取连接工厂
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(username, password, url);
// 创建JMS客户端到JMS Provider 的连接
Connection connection = connectionFactory.createConnection();
connection.start();
// 通过连接创建会话
Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
// 创建队列
String queueName = "my-queue";
Queue queue = session.createQueue(queueName);
// 创建生产者,设置不持久化
MessageProducer producer = session.createProducer(queue);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
// 发送消息
for (int i = 0; i <= 5; i++) {
// 创建文本消息
TextMessage textMessage = session.createTextMessage("ActiveMQ Message" + i);
// 生产者将消息推送到activemq中
producer.send(textMessage);
}
// 提交会话(用于事务提交)
// session.commit();
// 关闭连接
connection.close();
}
-
调用方法后,进入web界面查看,可查看刚刚推送的6条消息信息
-
编写接收者连接MQ,且消费ActiveMQ中的消息
public static void receive() throws JMSException {
String username = "admin";
String password = "123456";
String url = "tcp://127.0.0.1:61616";
// 获取连接工厂
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(username, password, url);
// 创建JMS客户端到JMS Provider 的连接
Connection connection = connectionFactory.createConnection();
connection.start();
// 通过连接创建会话
Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
// 创建队列
String queueName = "my-queue";
Queue queue = session.createQueue(queueName);
// 创建队列消息消费者
MessageConsumer consumer = session.createConsumer(queue);
while (true) {
// 接收消息
TextMessage receiveMessage = (TextMessage)consumer.receive();
if(Objects.nonNull(receiveMessage)) {
System.out.println("从ActiveMQ中接收到消息:" + receiveMessage.getText());
session.commit();
} else {
break;
}
}
session.commit();
connection.close();
}
- 调用消息接收,通过web界面查看队列消息信息
JMS消息可靠机制
- ActiveMQ的消息签收机制是:客户端成功接收一条消息的标志是该消息已经被签收,且做成功应答
- 消息签收包括:
- 带事务:如果session带有事务,且事务被成功提交,则消息会被自动签收。而当事务回滚时,则消息会被再次传送
- 不带事务:此时session的消息签收方式,取决于session的配置
- ActiveMQ的三种模式消息签收
- 消息自动签收:Session.AUTO_ACKNOWLEDGE(包括开启事务和不开启事务)
// 生产者不开启事务,客户端自动签收模式
Session session = createConnection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
// 消费者不开启事务,自动签收消息
Session session = createConnection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
开启事务,需要调用commit()方法提交事务
// 事物消息 生产者以事物形式,必须要将消息提交事物,才可以提交到队列中。
Session session = createConnection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
session.commit();
// 消费者
Session session = createConnection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
session.commit();
* 客户端调用acknowledge方法手动签收:Session.CLIENT_ACKNOWLEDGE;手动签收:textMessage.acknowledge();
// 生产者不开启事务n,客户端必须有手动签收模式
Session session = createConnection.createSession(Boolean.FALSE, Session.CLIENT_ACKNOWLEDGE);
// 消费者不开启session,客户端必须有手动签收模式
Session session = createConnection.createSession(Boolean.FALSE, Session.CLIENT_ACKNOWLEDGE);
TextMessage textMessage = (TextMessage) createConsumer.receive();
//手动签收
textMessage.acknowledge();
* Session.DUPS_OK_ACKNOWLEDGE:这种模式下,消息不是必须签收的,可能会重复发送
springboot整合ActiveMQ
- maven引入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- spring boot web支持:mvc,aop... -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
生产者
- 引入yml配置
spring:
activemq:
broker-url: tcp://127.0.0.1:61616
user: admin
password: admin
queue: myqueue
- 创建队列配置queueConfig
@Configuration
public class QueueConfig {
@Value("${queue}")
private String queue;
@Bean
public Queue logQueue() {
return new ActiveMQQueue(queue);
}
}
- 创建生产者(使用JmsMessagingTemplate进行消息发送)
@Component
@EnableScheduling
public class Producer {
@Autowired
private JmsMessagingTemplate jmsMessagingTemplate;
@Autowired
private Queue queue;
@Scheduled(fixedDelay = 5000)
public void send() {
jmsMessagingTemplate.convertAndSend(queue, "测试消息队列" + System.currentTimeMillis());
}
}
消费者
- 引入yml配置
spring:
activemq:
broker-url: tcp://127.0.0.1:61616
user: admin
password: admin
queue: myqueue
- 创建消费者(使用JMSListener)
@Component
public class Consumer {
@JmsListener(destination = "${queue}")
public void receive(String msg) {
System.out.println("监听器收到msg:" + msg);
}
}