1、application.proerties中rabbitMq的配置
# RabbitMQ基础配置
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.publisher-confirms=true
spring.rabbitmq.connection-timeout=
spring.rabbitmq.virtual-host=/
# RabbitMQ监听配置
## 初始并发量
spring.rabbitmq.listener.simple.concurrency=5
## 最大并发量
spring.rabbitmq.listener.simple.max-concurrency=15
## 签收方式
spring.rabbitmq.listener.simple.acknowledge-mode=manual
## 最多一次消费多少条数据 -限流
spring.rabbitmq.listener.simple.prefetch=1
2、rabbitMq工厂类,封装了创建连接,释放连接等操作
package com.jss.wx.config;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* rabbit工厂类
*
* @since 2018/12/13
*/
@Component
public class RabbitMqConnectionFactory {
private static ConnectionFactory connectionFactory = new ConnectionFactory();
private static String addresses;
private static int port;
private static String username;
private static String password;
private static String virtualHost;
/**
* 设置addresses
*
* @param addresses addresses
*/
@Value("${spring.rabbitmq.host}")
public void setAddresses(String addresses) {
setAddressesValue(addresses);
}
/**
* 设置port
*
* @param port port
*/
@Value("${spring.rabbitmq.port}")
public void setPort(int port) {
setPortValue(port);
}
/**
* 设置username
*
* @param username username
*/
@Value("${spring.rabbitmq.username}")
public void setUsername(String username) {
setUsernameValue(username);
}
/**
* 设置password
*
* @param password password
*/
@Value("${spring.rabbitmq.password}")
public void setPassword(String password) {
setPasswordValue(password);
}
/**
* 设置virtualHost
*
* @param virtualHost virtualHost
*/
@Value("${spring.rabbitmq.virtual-host}")
public void setVirtualHost(String virtualHost) {
setVirtualHostValue(virtualHost);
}
/**
* 只创建一个ConnectionFactory
* 双重检查加锁
*
* @return
*/
private static ConnectionFactory getSingleInstance() {
// 设置服务地址
connectionFactory.setHost(addresses);
// AMQP 5672
connectionFactory.setPort(port);
// 用户名
connectionFactory.setUsername(username);
// 密码
connectionFactory.setPassword(password);
// vhost
connectionFactory.setVirtualHost(virtualHost);
// 设置自动恢复
connectionFactory.setAutomaticRecoveryEnabled(true);
return connectionFactory;
}
/**
* 创建连接
*
* @return Connection Connection
*/
public static synchronized Connection getConnection() {
getSingleInstance();
Connection connection = null;
int connectionNumber = 1;
do {
try {
++connectionNumber;
connection = connectionFactory.newConnection();
if (null != connection) {
break;
}
} catch (IOException e) {
System.out.println("RabbitMqConnectionFactory getConnection error , connection bumber");
} catch (TimeoutException e) {
System.out.println("RabbitMqConnectionFactory getConnection error , connection bumber ");
}
} while (connectionNumber < 3);
return connection;
}
/**
* 关闭资源
*
* @param connection connection
* @param channel channel
*/
public static void closeResource(Connection connection, Channel channel) {
if (null != channel) {
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
if (null != connection) {
try {
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 设置addressesValue
*
* @param addressesValue addressesValue
*/
public static void setAddressesValue(String addressesValue) {
RabbitMqConnectionFactory.addresses = addressesValue;
}
/**
* 设置portValue
*
* @param portValue portValue
*/
public static void setPortValue(int portValue) {
RabbitMqConnectionFactory.port = portValue;
}
/**
* 设置 passwordValue
*
* @param passwordValue passwordValue
*/
public static void setPasswordValue(String passwordValue) {
RabbitMqConnectionFactory.password = passwordValue;
}
/**
* 设置 virtualHostValue
*
* @param virtualHostValue virtualHostValue
*/
public static void setVirtualHostValue(String virtualHostValue) {
RabbitMqConnectionFactory.virtualHost = virtualHostValue;
}
/**
* 设置usernameValue
*
* @param usernameValue usernameValue
*/
public static void setUsernameValue(String usernameValue) {
RabbitMqConnectionFactory.username = usernameValue;
}
/**
* 获取ip
*
* @return str ip地址
*/
public static String getAddresses() {
return addresses;
}
/**
* 获取端口
*
* @return port 获取端口
*/
public static int getPort() {
return port;
}
/**
* 获取登录用户名
*
* @return username 登录用户名
*/
public static String getUsername() {
return username;
}
/**
* 获取登录用户密码
*
* @return username 登录用户密码
*/
public static String getPassword() {
return password;
}
}
3、工具类:封装了从mq上拉取消息,以及发送消息到mq上
package com.jss.wx.common.utils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.concurrent.TimeoutException;
import com.jss.wx.config.RabbitMqConnectionFactory;
import com.rabbitmq.client.*;
import org.springframework.stereotype.Component;
import com.rabbitmq.client.impl.recovery.RecordedQueue;
/**
* McdRabbitMqUtil
*
* @since 2019/12/3
*/
@Component
public final class RabbitMqUtil {
private RabbitMqUtil() {
}
/**
* 根据序列名称、taskinfo字符串发送rabbit信息
*
* @param queueName queueName
* @param taskInfo taskInfo
* @throws IOException IOException
* @throws TimeoutException TimeoutException
*/
public static void sendMessageByQueueNameAndTaskInfo(String queueName, String taskInfo) {
Connection connection = null;
Channel channel = null;
try {
// 获取一个连接
connection = RabbitMqConnectionFactory.getConnection();
// 从连接中获取一个通道
channel = connection.createChannel();
// 创建队列声明。第二个参数为true,表示序列持久化; 第二个参数为false,表示不进行序列持久化
channel.queueDeclare(queueName, true, false, false, null);
// 发送消息。第三个参数设置为MessageProperties.PERSISTENT_TEXT_PLAIN,表示消息持久化
channel.basicPublish(RecordedQueue.EMPTY_STRING, queueName, null, taskInfo.getBytes("utf-8"));
} catch (IOException e) {
e.printStackTrace();
} finally {
RabbitMqConnectionFactory.closeResource(connection, channel);
}
}
/**
* 根据队列名称消费消息
*
* @param queueName queueName
* @return String message
*/
public static String receiveMessageByQueueName(String queueName) {
GetResponse responseMessage = null;
Connection connection = null;
Channel channel = null;
try {
// 获取连接
connection = RabbitMqConnectionFactory.getConnection();
// 创建频道
channel = connection.createChannel();
// 自动确认消息
boolean autoAck = true;
// 队列声明
channel.queueDeclare(queueName, true, false, false, null);
responseMessage = channel.basicGet(queueName, autoAck);
} catch (IOException e) {
e.printStackTrace();
} finally {
RabbitMqConnectionFactory.closeResource(connection, channel);
}
// 定义返回结果数据
String result = "";
if (null != responseMessage) {
try {
result = new String(responseMessage.getBody(), "UTF-8");
String ip = null;
String host = null;
try {
InetAddress ia = InetAddress.getLocalHost();
// 获取计算机主机名
host = ia.getHostName();
// 获取计算机IP
ip = ia.getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
}
sendMessageByQueueNameAndTaskInfo("MESSAGE-MONITOR", result + "|" + ip + "|" + host);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return result;
}
/**
* 根据队列名称消费消息-手动应答
*
* @param queueName queueName
* @return String message
*/
public static String receiveMessageByQueueNameManualOperationACK(String queueName) throws IOException, TimeoutException, InterruptedException {
Connection connection = null;
Channel channel = null;
final String[] results = {""};
connection = RabbitMqConnectionFactory.getConnection();
channel = connection.createChannel();
System.out.println("等待接收消息....");
//推送的消息如何进行消费的接口回调
Channel finalChannel = channel;
try {
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody());
System.out.println("接收到的消息" + message);
results[0] = message;
finalChannel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
};
//取消消费的一个回调接口 如在消费的时候队列被删除掉了
CancelCallback cancelCallback = (consumerTag) -> {
System.out.println("消息消费被中断");
};
String s = channel.basicConsume(queueName, false, deliverCallback, cancelCallback);
}catch (Exception e){
e.printStackTrace();
}finally {
/*直接关资源会消息可能没法出现*/
Thread.sleep(100);
RabbitMqConnectionFactory.closeResource(connection, channel);
}
return results[0];
}
}
注:
1、手动应答:确保消费者得到信息,rabbitmq再删除数据。
2、工具类-手动应答我增加了
Thread.sleep(100);
如果没有,就会先关闭资源,导致消费的信息得不到。如果有大佬可以解释这个问题请在评论区帮忙解惑,谢谢。