1、本文分享RabbitMQ的工具类,经过实际项目长期测试,在此分享给发家,各位大神有什么建议请指正 !!!

2、下面是链接池主要代码:

 import java.util.HashMap;
import java.util.Map; import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory; /**
* 获取RabbitMq连接
* @author skyfeng
*/
public class RabbitMqConnectFactory {
static Logger log = LoggerFactory.getLogger(RabbitMqConnectFactory.class);
/**
* 缓存连接工厂,将建立的链接放入map缓存
*/
private static Map<String, ConnectionFactory> connectionFactoryMap = new HashMap<String, ConnectionFactory>();
/**
* 根据rabbitMqName获取一个连接,使用完记得要自己关闭连接 conn.close()
*/
public static Connection getConnection(String rabbitMqName) {
if(StringUtils.isEmpty(rabbitMqName)){
log.error("rabbitMqName不能为空!");
throw new java.lang.NullPointerException("rabbitMqName为空");
}
if(connectionFactoryMap.get(rabbitMqName)==null){
initConnectionFactory(rabbitMqName);
}
ConnectionFactory connectionFactory = connectionFactoryMap.get(rabbitMqName);
if(connectionFactory==null){
log.info("没有找到对应的rabbitmq,name={}",rabbitMqName);
}
try {
return connectionFactory.newConnection();
}catch (Exception e) {
log.error("创建rabbitmq连接异常!",e);
return null;
}
}
/**
* 初始化一个连接工厂
* @param rabbitMqName
*/
private static void initConnectionFactory(String rabbitMqName){ try {
ConnectionFactory factory = new ConnectionFactory();
//新增代码,如果连接断开会自动重连
//factory.setAutomaticRecoveryEnabled(true);
factory.setHost("127.0.0.1");
factory.setPort(5672);
//factory.setVirtualHost(vhost);
factory.setUsername("test");
factory.setPassword("test");
connectionFactoryMap.put(rabbitMqName, factory);
} catch (Exception e) {
e.printStackTrace();
}finally{
}
} }

3、消费端的代码:

 import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer; /**
* RabbitMQq客户端代码
* @author skyfeng
*
*/
public class CustomerMqClient { final static Logger log = LoggerFactory.getLogger(CustomerMqClient.class);
private final static String RABBITMQ_NAME = "mq_name";
private final static String EXCHANGE_NAME = "Exchange_name";
private final static String QUEUE_NAME = "queue_name";
private static Channel channel = null;
private static Connection connection = null; /**
* 初始化客户端代码
*/
public static void initClient() {
//重新链接时判断之前的channel是否关闭,没有关闭先关闭
if(null != channel && channel.isOpen()){
try {
channel.close();
} catch (Exception e) {
log.error("mq name =[" +RABBITMQ_NAME+"] close old channel exception.e={}",e);
}finally {
channel = null;
}
}
//重新链接时判断之前的connection是否关闭,没有关闭先关闭
if (null != connection && connection.isOpen()) {
try {
connection.close();
} catch (Exception e) {
log.error("mq name =[" +RABBITMQ_NAME+"] close old connection exception.e={}",e);
}finally{
connection = null;
}
}
//从链接池中获取链接
connection = RabbitMqConnectFactory.getConnection(RABBITMQ_NAME);
try {
channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, "topic", true);
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "#");//#号接收所有的数据
Consumer consumer = new CustomerMqConsumer(channel);//具体的业务逻辑在CustomerMqConsumer中
channel.basicConsume(QUEUE_NAME, false, consumer);
} catch (Exception e) {
log.error("CustomerMqClient mq client connection fail .....{}", e);
//发生异常时,重连
reConnect();
}
} // 异常时,重连的方法
public static void reConnect() {
log.error("等待5s后重连");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
initClient();
} }

4、生产端代码:

 import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.rabbitmq.client.AlreadyClosedException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection; /**
* 把数据发送到rabbitmq的exchange,
*/
public class SendToExchange {
static Logger log = LoggerFactory.getLogger(SendToExchange.class); final static String TYPE = "topic";
final static String CHARSET_UTF8 = "UTF-8";
//MQ生产者exchange,把数据发给这个exchange
final static String rabbitExchangeName = "ExchangeName";
static boolean mqConnected = false;//mq当前处于连接状态 static Channel channel=null;
static{
init();
}
public static void init(){
log.info(" rabbit mq init begin...");
try {
//在mq连接中断后,发送程序判断已经断开,启动重连的时候会执行
if(channel!=null){
try {
channel.close();
} catch (Exception e) {
log.error("关闭老channel 异常",e);
}finally{
channel = null;
}
}
Connection connection = RabbitMqConnectFactory.getConnection("connection");
channel = connection.createChannel();
/*
*这里只定义exchange,因为每个业务模块都会从这里接入数据,所以不在这里定义队列
*队列的定义在各个业务模块自己的消费端定义
*/
channel.exchangeDeclare(rabbitExchangeName, TYPE, true, false, null);
log.info(" rabbit mq init OK");
mqConnected = true;
} catch (Exception e) {
log.error("rabbitmq初始化错误",e);
mqConnected = false;
}
}
/**
* 往rabbitmq发数据
* @param message
*/
public static void sendToRabbitMq(String message,String routingKey){
try {
if(StringUtils.isEmpty(message)){
log.debug("message is empty");
return;
}
channel.basicPublish(rabbitExchangeName, routingKey, null, message.getBytes(CHARSET_UTF8));
}catch(AlreadyClosedException ex){
log.error("往rabbitmq发数据报错,可能连接已关闭,尝试重连,data:",message,ex);
init();
}catch (Exception e) {
log.error("往rabbitmq发数据报错,data:",message,e);
}
}
}

RabbitMQ连接池、生产者、消费者实例的更多相关文章

  1. Linux 进程间通信(包含一个经典的生产者消费者实例代码)

    前言:编写多进程程序时,有时不可避免的需要在多个进程之间传递数据,我们知道,进程的用户的地址空间是独立,父进程中对数据的修改并不会反映到子进程中,但内核是共享的,大多数进程间通信方式都是在内核中建立一 ...

  2. 线程锁,threadinglocal,线程池,生产者消费者模型

    1.线程锁 1.锁Lock(只能锁一次) import threading import time v = [] lock = threading.Lock() def func(arg): lock ...

  3. Java 线程池 +生产者消费者+MySQL读取300 万条数据

    1.1需求 数据库300 万条用户数据 ,遍历获取所有用户, 各种组合关联, 获取到一个新的json ,存到redis 上. 1.2 难点 数据库比较多, 不可能单线程查询所有的数据到内存. 1.3解 ...

  4. Go语言协程并发---生产者消费者实例

    package main import ( "fmt" "strconv" "time" ) /* 改进生产者消费者模型 ·生产者每秒生产一 ...

  5. Java多线程15:Queue、BlockingQueue以及利用BlockingQueue实现生产者/消费者模型

    Queue是什么 队列,是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的.无论使用哪种排序方式,队列的头都是调用remove()或poll()移 ...

  6. JDBC连接池。。。转载

    1. 引言  近年来,随着Internet/Intranet建网技术的飞速发展和在世界范围内的迅速普及,计算机  应用程序已从传统的桌面应用转到Web应用.基于B/S(Browser/Server)架 ...

  7. 用连接池提高Servlet访问数据库的效率

    Java Servlet作为首选的服务器端数据处理技术,正在迅速取代CGI脚本.Servlet超越CGI的优势之一在于,不仅多个请求可以共享公用资源,而且还可以在不同用户请求之间保留持续数据.本文介绍 ...

  8. (转)websphere线程池 连接池设置

    原文:http://www.talkwithtrend.com/Article/207511 池(Pool)是WebSphere中最常涉及的概念之一.从网络.Web 服务器.Web 容器.EJB 容器 ...

  9. 为什么要用Jedis连接池+浅谈jedis连接池使用

    为什么要使用Jedis连接池 Redis作为缓存数据库理论上和MySQL一样需要客户端和服务端建立起来连接进行相关操作,使用MySQL的时候相信大家都会使用一款开源的连接池,例如C3P0.因为直连会消 ...

随机推荐

  1. valign

    值 描述 top 对内容进行上对齐. middle 对内容进行居中对齐(默认值). bottom 对内容进行下对齐. baseline 与基线对齐.

  2. 1.game.h

    game.h //以后会一直更新的呢. /*2020.2.4 更新了文件输入输出模板 @Bill_liu2020 加入了visual.h @bingogyz(orz) 代码:https://blog. ...

  3. mybatis-plus 错误

    错误:java.lang.NoClassDefFoundError: org/apache/velocity/context/Context 原因: 缺少velocity的依赖 解决方案: <d ...

  4. Led Night Light Factory: Traveler Led Night Light

    Wake up in a strange hotel room in the evening and find the way to the bathroom, without stepping on ...

  5. unittest学习5-断言

    unittest提供了以下断言方式: 方法 检查 新进 assertEqual(a, b) a == b   assertNotEqual(a, b) a != b   assertTrue(x) b ...

  6. kali 安装google输入法

    脑子一热装了一礼拜的kali,在20多遍的重装后终于成功了 先码一篇如何安装google输入法 首先得更新源,用leafpad /etc/apt/sources.list打开,或vi也可以,更新源百度 ...

  7. jquery--获取input checkbox是否被选中以及渲染checkbox选中状态

    jquery获取checkbox是否被选中 html <div><input type="checkbox" id="is_delete" n ...

  8. C# 泛型说明

    详细说明转 https://www.cnblogs.com/dotnet261010/p/9034594.html 最近项目用到了多个参数的泛型方法,这里说明下泛型的组成: /// <summa ...

  9. spring_boot 中通过PageHelper分页

    1. 第一步 导入pom.xml依赖 <!--PageHelper模版--> <!--PageHelper模版--> <dependency> <groupI ...

  10. 矩阵-bzoj1898

    This article is made by Jason-Cow.Welcome to reprint.But please post the article's address. BZOJ1898 ...