1.添加maven依賴
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.14.5</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-stomp</artifactId>
<version>5.14.5</version>
</dependency>
</dependencies>
2.application.properties
#activemq
activemq.host=192.168.1.23
activemq.port=61613
activemq.user=admin
activemq.password=admin
spring.activemq.pool.enabled=true
spring.activemq.pool.max-connections=10
#默認情況下activemq提供的是queue模式,若要使用topic模式需要配置下面配置
spring.jms.pub-sub-domain=true
3.生產者 JmsProducer
package com.yangfeng.msservice.service;
import org.apache.activemq.transport.stomp.Stomp;
import org.apache.activemq.transport.stomp.StompConnection;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.UUID;
/**
* 消息生產者
*
* @author yangfeng
* @date 2020-03-09
*/
@Component
public class JmsProducer {
@Value("${activemq.user}")
private String userName;
@Value("${activemq.password}")
private String password;
@Value("${activemq.host}")
private String host;
@Value("${activemq.port}")
private Integer port;
public StompConnection connectionFactory() throws Exception {
StompConnection conn = new StompConnection();
conn.open(host, port);
conn.connect(userName, password);
return conn;
}
/**
* 發送JMS消息
*
* @throws Exception exception
*/
public void sendMessage(String queueName, String message)
throws Exception {
StompConnection stompConnection = connectionFactory();
String tx = UUID.randomUUID().toString().replaceAll("-", "");
HashMap<String, String> headers = new HashMap<>();
headers.put(Stomp.Headers.Send.PERSISTENT, "true");
stompConnection.begin(tx);
stompConnection.send(queueName, message, tx, headers);
stompConnection.commit(tx);
stompConnection.disconnect();
}
}
4.消費者JmsConsumer
import com.alibaba.fastjson.JSONException;
import com.yangfeng.msservice.service.JmsProducer;
import com.yangfeng.service.IAllocationResultService;
import org.apache.activemq.transport.stomp.StompConnection;
import org.apache.activemq.transport.stomp.StompFrame;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.net.SocketTimeoutException;
import java.util.Map;
/**
* 從消息隊列中消費
*
* @author yangfeng
* @date 2020-04-09
*/
@Component
public class JmsConsumer implements ApplicationListener<ContextRefreshedEvent> {
private static Logger LOG = LoggerFactory.getLogger(FlightAssignparkConsumer.class);
@Resource
private IResultService resultService;
@Resource
public JmsProducer jmsProducer;
private static final String QUEUE_FLIGHT_ASSIGNPARK = "flight_assignpark";
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
try {
consumeMsg(QUEUE_FLIGHT_ASSIGNPARK);
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
}
/**
* 從mq中消費消息
*
* @param queueName
* @throws Exception
*/
public void consumeMsg(String queueName) throws Exception {
LOG.info("*********從消息隊列中獲取機位分配結果、靠橋率結果統計數據**************");
new Thread(() -> {
while (true) {
StompFrame frame;
String messageId = "";
StompConnection stompConnection = null;
try {
String ack = "client";
stompConnection = jmsProducer.connectionFactory();
stompConnection.subscribe(queueName, ack);
stompConnection.keepAlive();
// 注意,如果沒有接收到消息,
// 這個消費者線程會停在這裏,直到本次等待超時
long waitTimeOut = 30000;
frame = stompConnection.receive(waitTimeOut);
Map<String, String> headers = frame.getHeaders();
messageId = headers.get("message-id");
LOG.info("消息id:{}", messageId);
//具體的業務處理......
resultService.saveResult(frame.getBody());
// 在ack是client標記的情況下,確認消息
if ("client".equals(ack)) {
stompConnection.ack(messageId);
}
} catch (SocketTimeoutException e) {
LOG.error(e.getMessage());
continue;
} catch (JSONException ex) {
LOG.error("message_id:{},數據異常:{}", messageId, ex.getMessage());
continue;
} catch (Exception e) {
LOG.error(e.getMessage());
continue;
} finally {
try {
stompConnection.disconnect();
} catch (Exception e) {
LOG.error(e.getMessage());
}
}
}
}).start();
}
}