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. 跨表更新,Mysql Update Join

    背景 项目新导入了一批人员数据,这些人的有的部门名称发生了变化,有的联系方式发生了变化,暂且称该表为t_dept_members, 系统中有另外一张表 t_user_info 记录了人员信息. 要求将 ...

  2. IntelliJ IDEA 2017.3尚硅谷-----模板

    https://www.jetbrains.com/help/idea/using-live-templates.html  

  3. 九、c++容器

    9.1 简介 容器库是类模板与算法的汇集,允许程序员简单地访问常见数据结构,例如队列.链表和栈. 有三类容器--顺序容器.关联容器和无序关联容器--每种都被设计为支持不同组的操作. 顺序容器:顺序容器 ...

  4. 关于#progma comment 中库文件相对路径问题 (转)

    最近做一个验证程序的对话框编程,因为里面要要用到静态链接库,所以就稍微的学习了下静态链接库知识,学习的过程中感觉到了自己所了解的东西实在是少的可怜,更加坚定了自己要更加上进的决心,要把以前所丢掉的都给 ...

  5. 屏蔽tips

    在屏蔽的地方打上记号,这样解屏蔽时就容易找到屏蔽的地方了

  6. SQL中 select count(1) count中的1 到底是什么意思呢?和count(*)的区别

    count(1),其实就是计算一共有多少符合条件的行. 1并不是表示第一个字段,而是表示一个固定值.其实就可以想成表中有这么一个字段,这个字段就是固定值1,count(1),就是计算一共有多少个1.同 ...

  7. Uncaught TypeError: o.a is not a constructor

    最近在学webpack打包工具,看着挺好玩的,虽然也是工作需要 首先安装啥的我就不说了,后面慢慢写,打包完了以后,运行代码发现提示这个 找半天代码没问题啊,我这个js基础薄弱的人用这个webpack还 ...

  8. php设计模式之工厂方法实例代码

    实现不修改原代码,扩展新功能 <?php header("Content-type:text/html;charset=utf-8"); /** * db接口 * 实现连接数 ...

  9. 调用 url_launcher 模块打开外部浏 览器 打开外部应用 拨打电话 发送短信

    1.Flutter url_launcher 模块    Flutter url_launcher 模块可以让我们实现打开外部浏览器.打开外部应用.发送短信.拨打电话等功能.    https://p ...

  10. DB技能数据库里把技能伤害调整

    1. MagID 技能代号 2. MagName 技能名称 3. Effect Type 效果类型(使用技能时角色的动作效果) 4. Effect 效果(技能产生的动画效果) 5. Spell 每次耗 ...