activeMQ消息队列连接池
来源:互联网 发布:js 固定长度数组 编辑:程序博客网 时间:2024/06/05 08:19
- #activeMQ消息队列连接池创建实战
- 适合了解MQ基本知识的同学
- ## 为什么使用连接池 ##
- 客户端发送请求的时候如果每次都创建Connection会消耗大量的资源,尤其是在高并发的情况下,服务器会被直接打死。试想北京到上海的铁路,如果每去一次就创建一条铁路是多么坑的事。不仅仅创建Connection会消耗资源,session、producer的创建也会消耗大量系统资源,所以针对这些资源都要相应的创建对应的连接池。 -
创建连接池
package com.swkj.pool;import com.swkj.commom.MessageType;import org.apache.activemq.ActiveMQConnection;import org.apache.activemq.ActiveMQConnectionFactory;import javax.jms.*;import java.util.LinkedList;/** * @author wangdongdong * @version V1.0 * @Description: AMQ连接池管理类 * @date 2017/10/25 0025 15:50 */public class AMQPoolFactory { private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;//默认连接用户名 private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;//默认连接密码 private static final String BROKEURL = ActiveMQConnection.DEFAULT_BROKER_URL; //默认连接地址 private int maxConnection = 10; //connection最大连接数 private int minConnection = 1; //connection最小连接数 private int maxSesstionConnection = 100; //每个connection可建的最大session数 private int minSesstionConnection = 10; //每个connection可建的最小session数 private int maxProducerSession = 10; //每个session可建的最大producer数 private int maxConsumerSession = 10; //每个session可建的最大consumer数 private ConnectionFactory factory; //jms工厂 private LinkedList<ConnectionPool> poolConnection = new LinkedList<ConnectionPool>(); private LinkedList<SessionPool> poolSession = new LinkedList<SessionPool>(); /** * 初始化AMQ连接池,生成连接和会话信息 * * @throws Exception */ private void initFactory() throws Exception { try { factory = new ActiveMQConnectionFactory(BROKEURL); if (minConnection > 0 && minConnection <= maxConnection) { for (int i = 0; i < minConnection; i++) { Connection connection = factory.createConnection(USERNAME, PASSWORD); connection.start(); ConnectionPool connPool = new ConnectionPool(); connPool.setConnection(connection);//存放Conn连接 if (minSesstionConnection > 0 && minSesstionConnection <= maxSesstionConnection) { connPool.setActiveSessions(minSesstionConnection);//设置当前存在session数目 for (int j = 0; j < minSesstionConnection; j++) { Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);//为自动确认,pro con不用关心,由activemq确认信息是否到达。 SessionPool sessionPool = new SessionPool(); sessionPool.setConnection(connection); sessionPool.setSession(session); poolSession.addLast(sessionPool); } poolConnection.addLast(connPool); } else { throw new Exception("AMQ配置minSessionConnection和maxSessionConnection错误"); } } } else { throw new Exception("AMQ配置minConnections和maxConnections错误"); } } catch (JMSException e) { throw new Exception("AMQ初始化异常", e); } } /** * @author 王冬冬 * @Description: 从连接池中获取connection连接 * @date 2017/10/25 0025 16:21 * @version V1.0 */ private ConnectionPool getConnection() throws Exception { ConnectionPool connPool = null; if (poolConnection != null && poolConnection.size() > 0) { for (ConnectionPool connectionPool : poolConnection) { int poolSessionSize = connectionPool.getActiveSessions(); if (poolSessionSize < maxSesstionConnection) { connPool = connectionPool;//取会话比较少的连接 } } if (connPool == null && poolConnection.size() < maxConnection) {//当前连接池耗尽的时候需要新创建连接与会话 try { Connection conn = factory.createConnection(USERNAME, PASSWORD); conn.start(); connPool = new ConnectionPool(); connPool.setConnection(conn);//存放Conn连接 if (minSesstionConnection > 0 && minSesstionConnection <= maxSesstionConnection) { connPool.setActiveSessions(minSesstionConnection);//设置当前存在session数目 for (int j = 0; j < minSesstionConnection; j++) { Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); SessionPool sessionPool = new SessionPool(); sessionPool.setSession(session); sessionPool.setConnection(conn); poolSession.addLast(sessionPool); } } poolConnection.addLast(connPool); } catch (JMSException e) { throw new Exception("getConnection方法创建Connection异常", e); } } } return connPool; } /** * @author 王冬冬 * @Description: 池中获取producer的session * @date 2017/10/25 0025 16:32 * @version V1.0 */ private SessionPool getProducerSession() throws Exception { SessionPool sesPool = null; if (poolSession != null && poolSession.size() > 0) { ConnectionPool connPool = getConnection(); for (SessionPool sessionPool : poolSession) { if (sessionPool.getConnection() == connPool.getConnection()) { int poolProducerSize = sessionPool.getAvailableProducer(); if (poolProducerSize < maxProducerSession) { sesPool = sessionPool; } } } //会话占满的话,新建一个会话 if (sesPool == null && connPool.getActiveSessions() < maxSesstionConnection) { try { Connection conn = connPool.getConnection(); Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); sesPool = new SessionPool(); sesPool.setConnection(conn); sesPool.setSession(session); poolSession.addLast(sesPool); } catch (JMSException e) { throw new Exception("getProducerSession方法创建session出错", e); } } } return sesPool; } /** * @author 王冬冬 * @Description: 池中获取consumer的session * @date 2017/10/25 0025 16:43 * @version V1.0 */ private SessionPool getConsumerSession() throws Exception { SessionPool sespool = null; if (poolSession != null && poolSession.size() > 0) { ConnectionPool connPool = getConnection(); for (SessionPool sessionPool : poolSession) { if (sessionPool.getConnection() == connPool.getConnection()) { int poolConsumerSize = sessionPool.getAvailableConsumer(); if (poolConsumerSize < maxConsumerSession) { sespool = sessionPool; } } } //会话占满的话,新建一个会话 if (sespool == null && connPool.getActiveSessions() < maxSesstionConnection) { try { Connection conn = connPool.getConnection(); Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); sespool = new SessionPool(); sespool.setConnection(conn); sespool.setSession(session); poolSession.addLast(sespool); } catch (JMSException e) { throw new Exception("getConsumerSession方法创建session出错", e); } } } return sespool; } /** * @author 王冬冬 * @Description: 获取producer连接 * @date 2017/10/25 0025 16:45 * @version V1.0 */ public ProducerPool getProducer(String name, String messageType) throws Exception { SessionPool sessionPool = getProducerSession(); Session session = sessionPool.getSession(); try { Destination ds = null; if (messageType.equals(MessageType.Queue)) { ds = session.createQueue(name); } if (messageType.equals(MessageType.Topic)) { ds = session.createTopic(name); } MessageProducer producer = session.createProducer(ds); ProducerPool producerPool = new ProducerPool(); producerPool.setProducer(producer); producerPool.setConnection(sessionPool.getConnection()); producerPool.setSession(session); producerIncreament(sessionPool);//producer增长1 return producerPool; } catch (JMSException e) { throw new Exception("获取Producer出错", e); } } /** * @author 王冬冬 * @Description: 获取consumer连接 * @date 2017/10/25 0025 16:51 * @version V1.0 */ public ConsumerPool getConsumer(String name, String messageType) throws Exception { SessionPool sessionPool = getConsumerSession(); Session session = sessionPool.getSession(); try { Destination ds = null; if (messageType.equals(MessageType.Queue)) { ds = session.createQueue(name); } if (messageType.equals(MessageType.Topic)) { ds = session.createTopic(name); } MessageConsumer consumer = session.createConsumer(ds); ConsumerPool consumerPool = new ConsumerPool(); consumerPool.setConnection(sessionPool.getConnection()); consumerPool.setSession(session); consumerPool.setConsumer(consumer); consumerIncreament(sessionPool); return consumerPool; } catch (JMSException e) { throw new Exception("获取Consumer出错", e); } } /** * 池中可用producer递增1 * * @param sessionPool */ private void producerIncreament(SessionPool sessionPool) { if (sessionPool != null) { for (SessionPool sePool : poolSession) { if (sePool == sessionPool) { int cnt = sePool.getAvailableProducer(); cnt++; sePool.setAvailableProducer(cnt); } } } } /** * 池中可用producer递减1 * * @param producerPool */ public void producerDecreament(ProducerPool producerPool) { if (producerPool != null) { for (SessionPool sessionPool : poolSession) { if (sessionPool.getConnection() == producerPool.getConnection() && sessionPool.getSession() == producerPool.getSession()) { int cnt = sessionPool.getAvailableProducer(); cnt--; sessionPool.setAvailableProducer(cnt); } } } } /** * 池中可用consumer递增1 * * @param sessionPool */ private void consumerIncreament(SessionPool sessionPool) { if (sessionPool != null) { for (SessionPool sePool : poolSession) { if (sePool == sessionPool) { int cnt = sePool.getAvailableConsumer(); cnt++; sePool.setAvailableConsumer(cnt); } } } } /** * 池中可用consumer递减1 * * @param consumerPool */ public void consumerDecreament(ConsumerPool consumerPool) { if (consumerPool != null) { for (SessionPool sessionPool : poolSession) { if (sessionPool.getConnection() == consumerPool.getConnection() && sessionPool.getSession() == consumerPool.getSession()) { int cnt = sessionPool.getAvailableConsumer(); cnt--; sessionPool.setAvailableConsumer(cnt); } } } } /** * @author 王冬冬 * @Description:释放所有连接 * @date 2017/10/25 0025 16:53 * @version V1.0 */ public boolean disposeAll() throws Exception { try { if (poolSession != null && poolSession.size() > 0) { for (SessionPool sessionPool : poolSession) { sessionPool.getSession().close(); } poolSession.clear(); } if (poolConnection != null && poolConnection.size() > 0) { for (ConnectionPool connectionPool : poolConnection) { connectionPool.getConnection().stop(); connectionPool.getConnection().close(); } poolConnection.clear(); } return true; } catch (JMSException e) { throw new Exception("释放连接出错", e); } } /** * @author 王冬冬 * @Description: 释放producer连接 * @date 2017/10/25 0025 16:53 * @version V1.0 */ public void disposeProducer(MessageProducer producer) throws Exception { if (producer != null) { try { producer.close(); } catch (JMSException e) { throw new Exception("释放producer连接出错", e); } } } /** * @author 王冬冬 * @Description: 释放consumer连接 * @date 2017/10/25 0025 16:53 * @version V1.0 */ public void disposeConsumer(MessageConsumer consumer) throws Exception { if (consumer != null) { try { consumer.close(); } catch (JMSException e) { throw new Exception("释放consumer连接出错", e); } } }}
生产者
package com.swkj.pro;import com.swkj.pool.AMQPoolFactory;import com.swkj.pool.ProducerPool;import javax.jms.MapMessage;import javax.jms.MessageProducer;import javax.jms.Session;import javax.jms.TextMessage;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.concurrent.locks.ReentrantLock;/*** @author 王冬冬* @Description: 生产者* @date 2017/10/25 0025 17:05* @version V1.0*/public class AMQProducer { private ReentrantLock lock = new ReentrantLock();//互斥锁 /** * @author 王冬冬 * @Description: 发送Map消息 * @param dicMap map消息 * @param name 队列名称 * @param frequency 消息发送频率,多少条消息发送一次 * @date 2017/10/25 0025 17:23 * @version V1.0 */ public boolean sendMapMsg(AMQPoolFactory amqFactory, Map<String, Object> dicMap, String name, int frequency, String messageType) throws Exception{ if (null == amqFactory){ throw new Exception("工厂为空"); } if (dicMap.size() == 0) { throw new Exception("消息为空"); } if (null==name || "".equals(name)){ throw new Exception("队列名称不能为空"); } //进入锁定状态 lock.lock(); List<String> keyList = new ArrayList<String>(dicMap.keySet()); boolean hasMsg = false;//是否还有剩余没法送消息标识 ProducerPool producerPool = amqFactory.getProducer(name,messageType); Session session = producerPool.getSession(); MessageProducer producer = producerPool.getProducer(); try{ MapMessage mapMsg = session.createMapMessage(); for (int i = 0; i < keyList.size(); i++){ hasMsg = true; mapMsg.setObject(keyList.get(i), dicMap.get(keyList.get(i))); if ((i + 1) % frequency== 0){//4+1%5=0 五条一发 producer.send(mapMsg); mapMsg.clearBody(); hasMsg = false; } } //取模后如果还有余数证明还有剩余得几条没有发送,所以应该发送干净 if(hasMsg){ producer.send(mapMsg); mapMsg.clearBody(); } return true; }catch (Exception e){ amqFactory.disposeProducer(producer); amqFactory.producerDecreament(producerPool); throw new Exception("向队列发送数据异常", e); }finally{ //用完释放 amqFactory.disposeProducer(producer); amqFactory.producerDecreament(producerPool); lock.unlock(); } } /** * 发送文本消息 * @param amqFactory amq工厂实例 * @param text 文本消息 * @param name 目的地名称 */ public boolean sendTextMsg(AMQPoolFactory amqFactory, String text, String name,String messageType) throws Exception{ if (null == amqFactory){ throw new Exception("工厂为空"); } if (null == text || "".equals(text)) { throw new Exception("发送内容不能为空"); } if (null==name || "".equals(name)){ throw new Exception("队列名称不能为空"); } //进入锁定状态 lock.lock(); ProducerPool producerPool = amqFactory.getProducer(name,messageType); Session session = producerPool.getSession(); MessageProducer producer = producerPool.getProducer(); try{ TextMessage textMsg = session.createTextMessage(); textMsg.setText(text); producer.send(textMsg); return true; }catch (Exception e){ amqFactory.disposeProducer(producer); amqFactory.producerDecreament(producerPool); throw new Exception("向队列发送数据异常", e); }finally{ amqFactory.disposeProducer(producer); amqFactory.producerDecreament(producerPool); lock.unlock(); } }}
消费者
package com.swkj.conn;import com.swkj.lister.ConsumerListener;import com.swkj.pool.AMQPoolFactory;import com.swkj.pool.ConsumerPool;import javax.jms.JMSException;import javax.jms.MessageConsumer;import javax.jms.MessageListener;import java.util.concurrent.locks.ReentrantLock;/*** @author 王冬冬* @Description: 消费者* @date 2017/10/26 0026 9:09* @version V1.0*/public class AMQReceiver { private ReentrantLock lock = new ReentrantLock();//锁 /** * @author 王冬冬 * @Description:设置自定义监听类 * @date 2017/10/26 0026 9:12 * @version V1.0 */ public boolean setListener(String name, AMQPoolFactory factory, Class<?> className, String messageType) throws Exception{ if (null == factory) { throw new Exception("工厂为空"); } if (null == className) { throw new Exception("监听类为空"); } if (null == name || "".equals(name)) { throw new Exception("队列名称不能为空"); } //进入写模式锁定状态 lock.lock(); //反射机制实例化自定义监听类 ConsumerPool consumerPool = factory.getConsumer(name, messageType); MessageConsumer consumer = null; try { ConsumerListener rece = (ConsumerListener)className.newInstance(); consumer = consumerPool.getConsumer(); consumer.setMessageListener(rece); return true; } catch (InstantiationException e) { factory.disposeConsumer(consumer); factory.consumerDecreament(consumerPool); throw new Exception("监听类权限异常",e); } catch (IllegalAccessException e) { factory.disposeConsumer(consumer); factory.consumerDecreament(consumerPool); throw new Exception("实例化监听类异常",e); } finally{ lock.unlock(); } }}
自定义监听器
这块说下:使用了abstract抽象,把监听的onMessage默认实现了,
子类继承的时候,只需要处理业务逻辑就可以了,否则每个消费者都写一遍
onMessage没必要。
package com.swkj.lister;import org.apache.log4j.Logger;import javax.jms.*;import java.util.Enumeration;import java.util.HashMap;import java.util.Map;import static jdk.nashorn.internal.runtime.regexp.joni.Config.log;/** * @author 王冬冬 * @version V1.0 * @Description: 消息监听处理类,业务处理 * @date 2017/10/26 0026 9:20 */public abstract class ConsumerListener implements MessageListener { private Logger log = Logger.getLogger(ConsumerListener.class); public abstract void DealMap(Map<String, Object> dicMap); public abstract void DealText(String text); @Override @SuppressWarnings("unchecked") public void onMessage(Message message) { try { if (message instanceof MapMessage) { MapMessage mapMsg = (MapMessage) message; Map<String, Object> dicMap = new HashMap<String, Object>(); for (Enumeration<String> em = mapMsg.getMapNames(); em.hasMoreElements(); ) { String key = em.nextElement(); dicMap.put(key, mapMsg.getObject(key)); } // 调用子类接口 this.DealMap(dicMap); return; } else if (message instanceof TextMessage) { TextMessage textMsg = (TextMessage) message; String text; text = textMsg.getText(); // 调用子类接口 this.DealText(text); return; } } catch (JMSException e) { log.error("接收数据异常", e.getCause()); } }}
这块是子类处理信息
需要继承上面定义的监听类
package com.swkj.lister;import javax.jms.Message;import java.util.Map;/** * @author 王冬冬 * @version V1.0 * @Description: 具体业务处理 * @date 2017/10/26 0026 11:16 */public class BusinessImplementation extends ConsumerListener { /** * @author 王冬冬 * @Description: map类型信息处理 * @date 2017/10/26 0026 11:16 * @version V1.0 */ @Override public void DealMap(Map<String, Object> dicMap) { //写下你的业务逻辑 } /** * @author 王冬冬 * @Description: text类型信息处理 * @date 2017/10/26 0026 11:16 * @version V1.0 */ @Override public void DealText(String text) { //写下你的业务逻辑 }}
各种池对象
Connection池对象
package com.swkj.pool;import javax.jms.Connection;/** * @author 王冬冬 * @version V1.0 * @Description: Connection池对象 * @date 2017/10/25 0025 16:04 */public class ConnectionPool { private Connection connection; private int activeSessions; public Connection getConnection() { return connection; } public void setConnection(Connection connection) { this.connection = connection; } public int getActiveSessions() { return activeSessions; } public void setActiveSessions(int activeSessions) { this.activeSessions = activeSessions; }}
consumer池对象
package com.swkj.pool;import javax.jms.Connection;import javax.jms.MessageConsumer;import javax.jms.Session;/*** @author 王冬冬* @Description: consumer池对象* @date 2017/10/26 0026 11:41* @version V1.0*/public class ConsumerPool { private Connection connection; private Session session; private MessageConsumer consumer; public Connection getConnection() { return connection; } public void setConnection(Connection connection) { this.connection = connection; } public Session getSession() { return session; } public void setSession(Session session) { this.session = session; } public MessageConsumer getConsumer() { return consumer; } public void setConsumer(MessageConsumer consumer) { this.consumer = consumer; }}
producer池对象
package com.swkj.pool;import javax.jms.Connection;import javax.jms.MessageProducer;import javax.jms.Session;/*** @author 王冬冬* @Description: producer池对象* @date 2017/10/26 0026 11:41* @version V1.0*/public class ProducerPool { private Connection connection; private Session session; private MessageProducer producer; public Connection getConnection() { return connection; } public void setConnection(Connection connection) { this.connection = connection; } public Session getSession() { return session; } public void setSession(Session session) { this.session = session; } public MessageProducer getProducer() { return producer; } public void setProducer(MessageProducer producer) { this.producer = producer; }}
session池对象
package com.swkj.pool;import javax.jms.Connection;import javax.jms.Session;/** * @author wangdongdong * @version V1.0 * @Description: session池对象 * @date 2017/10/25 0025 16:08 */public class SessionPool { private Connection connection; private Session session; private int availableProducer; private int availableConsumer; public Connection getConnection() { return connection; } public void setConnection(Connection connection) { this.connection = connection; } public Session getSession() { return session; } public void setSession(Session session) { this.session = session; } public int getAvailableProducer() { return availableProducer; } public void setAvailableProducer(int availableProducer) { this.availableProducer = availableProducer; } public int getAvailableConsumer() { return availableConsumer; } public void setAvailableConsumer(int availableConsumer) { this.availableConsumer = availableConsumer; }}
阅读全文
0 0
- activeMQ消息队列连接池
- ActiveMQ实现消息队列
- ActiveMQ 消息队列
- 队列消息ActiveMq
- 深入浅出 消息队列 ActiveMQ
- 消息队列中间件ActiveMQ
- 深入浅出 消息队列 ActiveMQ
- 深入浅出 消息队列 ActiveMQ
- 深入浅出 消息队列 ActiveMQ .
- 消息队列ActiveMQ
- 深入浅出 消息队列 ActiveMQ
- 深入浅出 消息队列 ActiveMQ
- 深入浅出 消息队列 ActiveMQ
- 深入浅出 消息队列 ActiveMQ
- 深入浅出 消息队列 ActiveMQ
- 深入浅出 消息队列 ActiveMQ
- 消息队列------ActiveMQ
- 消息队列 ActiveMQ
- C# 对象初始化问题(可否像C语言的结构一样,简洁的初始化)
- codeforces 96B Lucky Numbers (easy)
- 如何跟踪确定IP地址
- Nodejs 模块
- Joone框架的神经网络如何保存和载入训练好的模型
- activeMQ消息队列连接池
- I/O复用select、poll、epoll
- Ubuntu16.04搭建HA集群hadoop-2.7.4
- MQTT SERVER 性能测试报告
- 获取cancvs上鼠标的坐标信息
- png图片透明部分点击
- Elementary OS安装Chrome
- 一个 Ajax Loading —— spin.js
- 场、熵的物理表现