前言
今天记录下项目里如何自己搭RabbitMQ环境、如何从RabbitMQ监听数据、如何向RabbitMQ推送数据。具体关于RabbitMQ的知识点就不细说了,主要贴出自己的功能代码。
希望可以帮到寻求却暂时没有找到解决方案的兄弟萌。
依赖注入
在pom.xml文件里配置下依赖
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.4.3</version>
</dependency>
复制代码
配置文件里配置RabbitMQ
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
复制代码
配置RabbitMQ连接池
public class RabbitMqFactory {
/**
* 缓存连接工厂,将建立的链接放入map缓存
*/
private static Map<String, ConnectionFactory> connectionFactoryMap = new HashMap<String, ConnectionFactory>();
/**
* 根据rabbitMqName获取一个连接,使用完记得要自己关闭连接 conn.close()
*/
public static Connection getConnection(String rabbitMqName) {
if (StringUtils.isEmpty(rabbitMqName)) {
System.out.println("rabbitMqName不能为空!");
throw new NullPointerException("rabbitMqName为空");
}
if (connectionFactoryMap.get(rabbitMqName) == null) {
initConnectionFactory(rabbitMqName);
}
ConnectionFactory connectionFactory = connectionFactoryMap.get(rabbitMqName);
if (connectionFactory == null) {
System.out.println("没有找到对应的rabbitmq,name=" + rabbitMqName);
}
try {
return connectionFactory.newConnection();
} catch (Exception e) {
e.printStackTrace();
System.out.println("创建rabbitmq连接异常!");
return null;
}
}
/**
* 初始化一个连接工厂
*
* @param rabbitMqName
*/
private static void initConnectionFactory(String rabbitMqName) {
try {
ConnectionFactory factory = new ConnectionFactory();
//新增代码,如果连接断开会自动重连
//factory.setAutomaticRecoveryEnabled(true);
factory.setHost(CommonConstant.HOST);
factory.setPort(CommonConstant.PORT);
//factory.setVirtualHost(vhost);
factory.setUsername(CommonConstant.USER_NAME);
factory.setPassword(CommonConstant.PASS_WORD);
connectionFactoryMap.put(rabbitMqName, factory);
} catch (Exception e) {
e.printStackTrace();
}
}
}
复制代码
配置RabbitMQ相关的常量类。
public class CommonConstant {
//RabbitMq Key
public static final String ROUTING_KEY = "\\\\";
//RabbitMq地址
@Value("${spring.rabbitmq.host}")
public static String HOST = "127.0.0.1";
//RabbitMq端口
@Value("${spring.rabbitmq.port}")
public static Integer PORT = 5672;
//RabbitMq用户名
@Value("${spring.rabbitmq.username}")
public static String USER_NAME = "guest";
//RabbitMq密码
@Value("${spring.rabbitmq.password}")
public static String PASS_WORD = "guest";
//定义token header 头key
public static final String Executor_PersonCache = "Authorization";
}
复制代码
从RabbitMQ监听数据
使用注解配置监听
如果想要从RabbitMQ监听数据,可以直接在你写的方法上配置注解。
代码如下:
配置相应的Queue、Exchange,Exchange的类型有四种,我示例的是topic模式。@Exchange里的value配置你具体想监听的队列名。
@RabbitListener(
bindings = @QueueBinding(
value = @Queue(value = "*", durable = "false"),
exchange = @Exchange(value = "*.topic", type = "topic"),
key = CommonConstant.ROUTING_KEY
)
)
复制代码
配完注解后,可以直接写方法了。注意RabbitMQ里数据的格式,用相应的方式接收再做转换即可。
向url推送数据
这里多唠叨一句,如果想把数据处理好后往url推送。配置如下:
发送Http请求的工具类
public class SendHttpClient {
/**
* http get请求
*
* @param httpUrl 链接
* @return 响应数据
*/
public static String doGet(String httpUrl) {
//链接
HttpURLConnection connection = null;
InputStream is = null;
BufferedReader br = null;
StringBuffer result = new StringBuffer();
try {
//创建连接
URL url = new URL(httpUrl);
connection = (HttpURLConnection) url.openConnection();
//设置请求方式
connection.setRequestMethod("GET");
//设置连接超时时间
connection.setConnectTimeout(15000);
//设置读取超时时间
connection.setReadTimeout(15000);
//开始连接
connection.connect();
//获取响应数据
if (connection.getResponseCode() == 200) {
//获取返回的数据
is = connection.getInputStream();
if (is != null) {
br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String temp = null;
while ((temp = br.readLine()) != null) {
result.append(temp);
}
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
connection.disconnect();// 关闭远程连接
}
return result.toString();
}
/**
* post请求
*
* @param httpUrl 链接
* @param param 参数
* @return
*/
public static String doPost(String httpUrl, String param) {
StringBuffer result = new StringBuffer();
//连接
HttpURLConnection connection = null;
OutputStream os = null;
InputStream is = null;
BufferedReader br = null;
try {
//创建连接对象
URL url = new URL(httpUrl);
//创建连接
connection = (HttpURLConnection) url.openConnection();
//设置请求方法
connection.setRequestMethod("POST");
//设置连接超时时间
connection.setConnectTimeout(15000);
//设置读取超时时间
connection.setReadTimeout(15000);
//设置是否可读取
connection.setDoOutput(true);
//设置响应是否可读取
connection.setDoInput(true);
//设置参数类型
connection.setRequestProperty("Content-Type", "application/json");
//拼装参数
if (param != null && !param.equals("")) {
//设置参数
os = connection.getOutputStream();
//拼装参数
os.write(param.getBytes("UTF-8"));
}
//设置权限
//设置请求头等
//开启连接
//connection.connect();
//读取响应
if (connection.getResponseCode() == 200) {
is = connection.getInputStream();
if (is != null) {
br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String temp = null;
if ((temp = br.readLine()) != null) {
result.append(temp);
}
}
}
//关闭连接
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//关闭连接
connection.disconnect();
}
return result.toString();
}
/**
* post请求
*
* @param httpUrl 链接
* @param jsonParam json参数
* @return
*/
public static String doPost(String httpUrl, JSONObject jsonParam) {
StringBuffer result = new StringBuffer();
//连接
HttpURLConnection connection = null;
OutputStream os = null;
InputStream is = null;
BufferedReader br = null;
try {
//创建连接对象
URL url = new URL(httpUrl);
//创建连接
connection = (HttpURLConnection) url.openConnection();
//设置请求方法
connection.setRequestMethod("POST");
//设置连接超时时间
connection.setConnectTimeout(15000);
//设置读取超时时间
connection.setReadTimeout(15000);
//设置是否可读取
connection.setDoOutput(true);
//设置响应是否可读取
connection.setDoInput(true);
//设置参数类型
connection.setRequestProperty("Content-Type", "application/json");
//拼装参数
if (jsonParam != null && !jsonParam.toJSONString().equals("")) {
//设置参数
os = connection.getOutputStream();
//拼装参数
os.write(jsonParam.toJSONString().getBytes("UTF-8"));
}
//设置权限
//设置请求头等
//开启连接
//connection.connect();
//读取响应
if (connection.getResponseCode() == 200) {
is = connection.getInputStream();
if (is != null) {
br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String temp = null;
if ((temp = br.readLine()) != null) {
result.append(temp);
}
}
}
//关闭连接
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//关闭连接
connection.disconnect();
}
return result.toString();
}
}
复制代码
向url推送数据
配置好方法工具类后,在业务代码中,可以直接将需要推送的数据封装好格式调用相应的方法即可。 比如将数据封装成JSONArray格式,向定义的url推送 代码示例如下:
SendHttpClient.doPost(sensorPushUrl, jsonArray.toJSONString());
复制代码
向RabbitMQ推送数据
把数据发送到rabbitmq的exchange
这里可以先配置一个工具类。
public class SendToExchange {
final static String TYPE = "topic";
final static String CHARSET_UTF8 = "UTF-8";
//MQ生产者exchange,把数据发给这个exchange
final static String rabbitExchangeName = "*.topic";
static boolean mqConnected = false;//mq当前处于连接状态
static Channel channel = null;
//初始化factory
static {
init();
}
public static void init() {
System.out.println("rabbit mq init begin...");
try {
//在mq连接中断后,发送程序判断已经断开,启动重连的时候会执行
if (channel != null) {
try {
channel.close();
} catch (Exception e) {
System.out.println("关闭原有channel 异常");
} finally {
channel = null;
}
}
Connection connection = RabbitMqFactory.getConnection("connection");
channel = connection.createChannel();
/*
*这里只定义exchange,因为每个业务模块都会从这里接入数据,所以不在这里定义队列
*队列的定义在各个业务模块自己的消费端定义
*/
channel.exchangeDeclare(rabbitExchangeName, TYPE, true, false, null);
System.out.println("rabbitmq init OK");
mqConnected = true;
} catch (Exception e) {
System.out.println("rabbitmq初始化错误");
mqConnected = false;
}
}
/**
* 往rabbitmq发数据
*
* @param message
*/
public static void sendToRabbitMq(String message, String routingKey) {
try {
if (StringUtils.isEmpty(message)) {
System.out.println("message is empty");
return;
}
if (channel == null) {
System.out.println("获取channel失败!");
}
channel.basicPublish(rabbitExchangeName, routingKey, null, message.getBytes(CHARSET_UTF8));
} catch (AlreadyClosedException ex) {
System.out.println("往rabbitmq发数据报错,可能连接已关闭,尝试重连");
init();
} catch (Exception e) {
e.printStackTrace();
System.out.println("往rabbitmq发数据报错");
}
}
}
复制代码
调用方法向RabbitMQ推送数据
代码示例如下:这里的routingKey路由规则自己可以最好在常量类里定义下就好了
SendToExchange.sendToRabbitMq(json, routingKey));
复制代码