java activemq连接池_ActiveMQ使用线程池实现消息的生产与消费

本文介绍了如何在Java项目中利用ActiveMQ的连接池PooledConnectionFactory进行消息生产和消费。通过配置线程池,创建消息生产者和消费者,并提供了配置文件的读取方法。此外,还展示了如何在Spring配置文件中集成ActiveMQ,以及消息处理接口和消费者的实现。
摘要由CSDN通过智能技术生成

jar文件:spring3.1jar,以及

5895bce251ee506cfbab90726085bf15.png

项目src路径下文件:config.properties

ef9192e6080b00453cbaec8bcf625dd1.png

读取config.properties文件JAVA类:

package com.lejob.lejobmy.config;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.util.Properties;

public class Configuration

{

private Properties propertie;

private FileOutputStream outputFile;

/**

* 初始化Configuration类

*/

public Configuration()

{

propertie = new Properties();

}

/**

* 初始化Configuration类

* @param filePath 要读取的配置文件的路径+名称

*/

public Configuration(String filePath)

{

propertie = new Properties();

try {

InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(filePath);

propertie.load(inputStream);

inputStream.close();

} catch (FileNotFoundException ex) {

System.out.println("读取属性文件--->失败!- 原因:文件路径错误或者文件不存在");

ex.printStackTrace();

} catch (IOException ex) {

System.out.println("装载文件--->失败!");

ex.printStackTrace();

}

}//end ReadConfigInfo(...)

/**

* 重载函数,得到key的值

* @param key 取得其值的键

* @return key的值

*/

public String getValue(String key)

{

if(propertie.containsKey(key)){

String value = propertie.getProperty(key);//得到某一属性的值

return value;

}

else

return "";

}//end getValue(...)

/**

* 重载函数,得到key的值

* @param fileName properties文件的路径+文件名

* @param key 取得其值的键

* @return key的值

*/

public String getValue(String fileName, String key)

{

try {

String value = "";

InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(fileName);

propertie.load(inputStream);

inputStream.close();

if(propertie.containsKey(key)){

value = propertie.getProperty(key);

return value;

}else

return value;

} catch (FileNotFoundException e) {

e.printStackTrace();

return "";

} catch (IOException e) {

e.printStackTrace();

return "";

} catch (Exception ex) {

ex.printStackTrace();

return "";

}

}//end getValue(...)

/**

* 清除properties文件中所有的key和其值

*/

public void clear()

{

propertie.clear();

}//end clear();

/**

* 改变或添加一个key的值,当key存在于properties文件中时该key的值被value所代替,

* 当key不存在时,该key的值是value

* @param key 要存入的键

* @param value 要存入的值

*/

public void setValue(String key, String value)

{

propertie.setProperty(key, value);

}//end setValue(...)

/**

* 将更改后的文件数据存入指定的文件中,该文件可以事先不存在。

* @param fileName 文件路径+文件名称

* @param description 对该文件的描述

*/

public void saveFile(String fileName, String description)

{

try {

outputFile = new FileOutputStream(fileName);

propertie.store(outputFile, description);

outputFile.close();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException ioe){

ioe.printStackTrace();

}

}//end saveFile(...)

public static void main(String[] args)

{

Configuration rc = new Configuration("config.properties");//相对路径

String ip = rc.getValue("activemq_url");//以下读取properties文件的值

String host = rc.getValue("activemq_user");

String tab = rc.getValue("activemq_pw");

//以下输出properties读出的值

System.out.println("ip = " + ip);

System.out.println("host = " + host);

System.out.println("tab = " + tab);

// Configuration cf = new Configuration();

// String ipp = cf.getValue("./config/test.properties", "ip");

// System.out.println("ipp = " + ipp);

// cf.clear();

// cf.setValue("min", "999");

// cf.setValue("max", "1000");

// cf.saveFile("./config/save.perperties", "test");

// Configuration saveCf = new Configuration();

// saveCf.setValue("min", "10");

// saveCf.setValue("max", "1000");

// saveCf.saveFile("./config/save.perperties");

}

}

ActiveMQ消息生产者工厂类ActivemqConnectionFactory.java:

package com.lejob.lejobsearch.index.queue;

import java.io.Serializable;

import java.util.Enumeration;

import java.util.HashMap;

import java.util.Iterator;

import java.util.Map;

import java.util.Set;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import javax.jms.Connection;

import javax.jms.DeliveryMode;

import javax.jms.Destination;

import javax.jms.JMSException;

import javax.jms.MapMessage;

import javax.jms.Message;

import javax.jms.MessageConsumer;

import javax.jms.MessageProducer;

import javax.jms.ObjectMessage;

import javax.jms.Session;

import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

import org.apache.activemq.pool.PooledConnectionFactory;

import org.apache.log4j.Logger;

import com.lejob.rpc.search.model.QueueModel;

public class ActivemqConnectionFactory {

private static Logger logger = Logger.getLogger(ActivemqConnectionFactory.class);

//设置连接的最大连接数

private static int maxConnections = 5;

//设置每个连接中使用的最大活动会话数

private static int maximumActiveSessionPerConnection = 300;

//线程池数量

private static int threadPoolSize = 50;

//强制使用同步返回数据的格式

private static boolean useAsyncSendForJMS = true;

private static ExecutorService threadPool;

private static PooledConnectionFactory connectionFactory;

public void init(){

try {

//设置JAVA线程池

threadPool = Executors.newFixedThreadPool(threadPoolSize);

//ActiveMQ的连接工厂

ActiveMQConnectionFactory actualConnectionFactory = new ActiveMQConnectionFactory(ActiveMQConstant.ACTIVEMQ_USER_NAME, ActiveMQConstant.ACTIVEMQ_USER_PW, ActiveMQConstant.ACTIVEMQ_URL);

actualConnectionFactory.setUseAsyncSend(useAsyncSendForJMS);

//Active中的连接池工厂

connectionFactory = new PooledConnectionFactory(actualConnectionFactory);

connectionFactory.setCreateConnectionOnStartup(true);

connectionFactory.setMaxConnections(maxConnections);

connectionFactory.setMaximumActiveSessionPerConnection(maximumActiveSessionPerConnection);

logger.info("INIT ACTIVEMQ POOL CONNECTION FACTORY SUCCESS......");

} catch (Exception e) {

logger.error("ACTIVEMQ CONNECTION INIT ERROR......", e);

}

}

public void destroy(){

try {

if(connectionFactory != null){

connectionFactory.stop();

logger.info("STOP ACTIVEMQ CONNECTION FACTORY SUCCESS......");

}

} catch (Exception e) {

logger.error("STOP ACTIVEMQ CONNECTION FACTORY ERROR!!!", e);

}

}

/**

* 从连接池获取链接

* @author 程松

* @date 2013-12-7 下午01:46:02

* @return

* @see [类、类#方法、类#成员]

*/

public static Connection getConnection(){

try {

//从连接池工厂中获取一个连接

Connection connection = connectionFactory.createConnection();

connection.start();

return connection;

} catch (JMSException e) {

e.printStackTrace();

}

return null;

}

/**

* 链接打开session回话

* @author 程松

* @date 2013-12-7 下午01:46:19

* @param conn

* @return

* @see [类、类#方法、类#成员]

*/

public static Session getSession(Connection conn){

Session session = null;

try {

//false 参数表示 为非事务型消息,后面的参数表示消息的确认类型

session = conn.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);

} catch (JMSException e) {

e.printStackTrace();

}

return session;

}

/**

* 创建一个生产者

* @author 程松

* @date 2013-12-7 下午01:48:14

* @param session

* @return

* @see [类、类#方法、类#成员]

*/

public static MessageProducer getProducer(Session session, String queue_name){

try {

Destination destination = session.createQueue(queue_name);

MessageProducer producer = session.createProducer(destination);

producer.setDeliveryMode(DeliveryMode.PERSISTENT);

return producer;

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

/**

* 创建一个消费者

* @author 程松

* @date 2013-12-7 下午01:53:28

* @param session

* @param queue_name

* @return

* @see [类、类#方法、类#成员]

*/

public static MessageConsumer getConsumer(Session session, String queue_name){

try {

Destination destination = session.createQueue(queue_name);

MessageConsumer consumer = session.createConsumer(destination);

return consumer;

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

/**

* 创建文本消息

* @author 程松

* @date 2013-12-7 下午02:05:05

* @param session

* @param msg

* @return

* @throws JMSException

* @see [类、类#方法、类#成员]

*/

public static TextMessage getMessage(Session session, String msg) throws JMSException {

TextMessage message = session.createTextMessage(msg);

return message;

}

/**

* 创建对象消息

* @author 程松

* @date 2013-12-7 下午02:06:51

* @param session

* @param obj

* @return

* @throws JMSException

* @see [类、类#方法、类#成员]

*/

public static ObjectMessage getMessage(Session session, Serializable obj) throws JMSException {

ObjectMessage message = session.createObjectMessage(obj);

return message;

}

/**

* 创建map消息

* @author 程松

* @date 2013-12-7 下午02:17:58

* @param session

* @param map

* @return

* @throws JMSException

* @see [类、类#方法、类#成员]

*/

public static MapMessage getMessage(Session session, Map map) throws JMSException {

MapMessage message = session.createMapMessage();

Set set = map.keySet();

Iterator it = set.iterator();

while(it.hasNext()){

String key = it.next();

String value = String.valueOf(map.get(key));

message.setString(key, value);

}

return message;

}

/**

* 发送文本消息

* @author 程松

* @date 2013-12-7 下午02:30:46

* @param model

* @see [类、类#方法、类#成员]

*/

public static void send(final String msg, final String queue_name) {

//直接使用线程池来执行具体的调用

threadPool.execute(new Runnable(){

public void run() {

try {

sendMsg(msg, queue_name);

} catch (Exception e) {

e.printStackTrace();

}

}

});

}

/**

* 真正的执行消息发送

* @author 程松

* @date 2013-12-7 下午02:33:02

* @param msg

* @param queue_name

* @throws Exception

* @see [类、类#方法、类#成员]

*/

private static void sendMsg(String msg, String queue_name) throws Exception {

Connection connection = null;

Session session = null;

try {

//从连接池工厂中获取一个连接

connection = ActivemqConnectionFactory.getConnection();

session = ActivemqConnectionFactory.getSession(connection);

MessageProducer producer = ActivemqConnectionFactory.getProducer(session, queue_name);

Message message = ActivemqConnectionFactory.getMessage(session, msg);

producer.send(message);

} finally {

ActivemqConnectionFactory.closeSession(session);

ActivemqConnectionFactory.closeConnection(connection);

}

}

/**

* 发送对象消息

* @author 程松

* @date 2013-12-7 下午02:33:40

* @param model

* @param queue_name

* @see [类、类#方法、类#成员]

*/

public static void send(final QueueModel model, final String queue_name) {

//直接使用线程池来执行具体的调用

threadPool.execute(new Runnable(){

public void run() {

try {

sendMsg(model, queue_name);

} catch (Exception e) {

e.printStackTrace();

}

}

});

}

/**

* 真正的执行消息发送

* @author 程松

* @date 2013-12-7 下午02:36:44

* @param model

* @param queue_name

* @throws Exception

* @see [类、类#方法、类#成员]

*/

private static void sendMsg(QueueModel model, String queue_name) throws Exception {

Connection connection = null;

Session session = null;

try {

//从连接池工厂中获取一个连接

connection = ActivemqConnectionFactory.getConnection();

session = ActivemqConnectionFactory.getSession(connection);

MessageProducer producer = ActivemqConnectionFactory.getProducer(session, queue_name);

Message message = ActivemqConnectionFactory.getMessage(session, model);

producer.send(message);

} finally {

ActivemqConnectionFactory.closeSession(session);

ActivemqConnectionFactory.closeConnection(connection);

}

}

/**

* 发送MAP消息

* @author 程松

* @date 2013-12-7 下午02:34:29

* @param model

* @see [类、类#方法、类#成员]

*/

public static void send(final Map map, final String queue_name) {

//直接使用线程池来执行具体的调用

threadPool.execute(new Runnable(){

public void run() {

try {

sendMsg(map, queue_name);

} catch (Exception e) {

e.printStackTrace();

}

}

});

}

/**

* 真正的执行消息发送

* @author 程松

* @date 2013-12-7 下午02:36:14

* @param map

* @param queue_name

* @throws Exception

* @see [类、类#方法、类#成员]

*/

private static void sendMsg(Map map, String queue_name) throws Exception {

Connection connection = null;

Session session = null;

try {

//从连接池工厂中获取一个连接

connection = ActivemqConnectionFactory.getConnection();

session = ActivemqConnectionFactory.getSession(connection);

MessageProducer producer = ActivemqConnectionFactory.getProducer(session, queue_name);

Message message = ActivemqConnectionFactory.getMessage(session, map);

producer.send(message);

} finally {

ActivemqConnectionFactory.closeSession(session);

ActivemqConnectionFactory.closeConnection(connection);

}

}

/**

* 获取文本消息

* @author 程松

* @date 2013-12-7 下午02:18:13

* @param message

* @return

* @see [类、类#方法、类#成员]

*/

public static String getText(Message message){

if (message instanceof TextMessage) {

//强制转换一下

TextMessage txtMsg = (TextMessage) message;

//输出接收到的消息

String model = null;

try {

model = txtMsg.getText();

return model;

} catch (JMSException e) {

e.printStackTrace();

}

}

return null;

}

/**

* 获取对象消息

* @author 程松

* @date 2013-12-7 下午02:18:41

* @param message

* @return

* @see [类、类#方法、类#成员]

*/

public static Object getObject(Message message){

if (message instanceof ObjectMessage) {

//强制转换一下

ObjectMessage txtMsg = (ObjectMessage) message;

//输出接收到的消息

Object model = null;

try {

model = txtMsg.getObject();

return model;

} catch (JMSException e) {

e.printStackTrace();

}

}

return null;

}

/**

* 获取map消息

* @author 程松

* @date 2013-12-7 下午02:19:00

* @param message

* @return

* @see [类、类#方法、类#成员]

*/

public static Map getMap(Message message){

if (message instanceof MapMessage) {

//强制转换一下

MapMessage txtMsg = (MapMessage) message;

//输出接收到的消息

Map map = new HashMap();

try {

Enumeration e = txtMsg.getMapNames();

while(e.hasMoreElements()){

String key = e.nextElement();

map.put(key, txtMsg.getString(key));

}

return map;

} catch (JMSException e) {

e.printStackTrace();

}

}

return null;

}

/**

* 关闭回话

* @author 程松

* @date 2013-12-7 下午01:46:55

* @param session

* @see [类、类#方法、类#成员]

*/

public static void closeSession(Session session) {

try {

if (session != null) {

session.close();

}

} catch (Exception e) {

e.printStackTrace();

}

}

/**

* 关闭链接

* @author 程松

* @date 2013-12-7 下午01:47:06

* @param connection

* @see [类、类#方法、类#成员]

*/

public static void closeConnection(Connection connection) {

try {

if (connection != null) {

connection.close();

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

spring.xml中配置:

,项目启动时加载初始化ActivemqConnectionFactory。

项目中ActivemqConnectionFactory.send(param,queue_name);发送消息。

下面是消息消费者:IMessageHandler.java(消息处理任务接口)、RecrQueueMessageHandler.java(消息处理类)、RecrQueueConsumer.java(JMS消息消费者)、MultiThreadMessageListener.java(消息消费者中使用的多线程消息监听服务)、FixedAndBlockedThreadPoolExecutor.java(支持阻塞的固定大小的线程池)

IMessageHandler.java

package com.lejob.lejobsearch.index.queue;

import javax.jms.Message;

/**

* 提供消息操作的回调接口

*

* @author 程松

* @date 2013-12-7上午10:49:49

* @company 乐享网络(5lejob)北京研发中心

* @version [Copyright (c) 2013 V001]

* @see [相关类/方法]

* @since [产品/模块版本]

*/

public interface IMessageHandler {

/**

* 消息回调提供的调用方法

* @author 程松

* @date 2013-12-7 上午10:28:58

* @param message

* @see [类、类#方法、类#成员]

*/

public void handle(Message message);

}

RecrQueueConsumer.java

package com.lejob.lejobsearch.index.queue.recruitment;

import javax.jms.Connection;

import javax.jms.ExceptionListener;

import javax.jms.JMSException;

import javax.jms.MessageConsumer;

import javax.jms.Session;

import org.apache.log4j.Logger;

import com.lejob.lejobsearch.index.queue.ActiveMQConstant;

import com.lejob.lejobsearch.index.queue.ActivemqConnectionFactory;

import com.lejob.lejobsearch.index.queue.IMessageHandler;

import com.lejob.lejobsearch.index.queue.MultiThreadMessageListener;

/**

* JMS消息消费者

*

* @author 程松

* @date 2013-11-30下午04:00:09

* @company 乐享网络(5lejob)北京研发中心

* @version [Copyright (c) 2013 V001]

* @see [相关类/方法]

* @since [产品/模块版本]

*/

public class RecrQueueConsumer implements ExceptionListener {

private Logger logger = Logger.getLogger(RecrQueueConsumer.class);

/**

* 监听消息线程最大值

*/

private static final int THREAD_COUNT = 1;

/**

* 消息处理类

*/

private IMessageHandler messageHandler;

private Connection connection;

private Session session;

public void init(){

try {

connection = ActivemqConnectionFactory.getConnection();

//会话采用非事务级别,消息到达机制使用自动通知机制

session = ActivemqConnectionFactory.getSession(connection);

MessageConsumer consumer = ActivemqConnectionFactory.getConsumer(session, ActiveMQConstant.RECR_QUEUE);

consumer.setMessageListener(new MultiThreadMessageListener(THREAD_COUNT, messageHandler));

logger.info(ActiveMQConstant.RECR_QUEUE + " LISTENER INIT SUCCESS......");

} catch (Exception e) {

logger.error("处理队列" + ActiveMQConstant.RECR_QUEUE + "信息 异常", e);

}

}

public void destroy(){

try {

ActivemqConnectionFactory.closeSession(session);

ActivemqConnectionFactory.closeConnection(connection);

logger.info(ActiveMQConstant.RECR_QUEUE + " LISTENER DESTROY SUCCESS......");

} catch (Exception e) {

logger.error("关闭监听队列" + ActiveMQConstant.RECR_QUEUE + " 异常", e);

}

}

public void onException(JMSException e) {

e.printStackTrace();

}

public void setMessageHandler(IMessageHandler messageHandler) {

this.messageHandler = messageHandler;

}

}

MultiThreadMessageListener.java

package com.lejob.lejobsearch.index.queue.recruitment;

import java.util.concurrent.ExecutorService;

import javax.jms.JMSException;

import javax.jms.Message;

import javax.jms.MessageListener;

import javax.jms.ObjectMessage;

import com.lejob.lejobsearch.index.queue.MessageHandler;

import com.lejob.rpc.search.model.QueueModel;

/**

* 消息消费者中使用的多线程消息监听服务

*

*/

public class MultiThreadMessageListener implements MessageListener {

//默认线程池数量

public final static int DEFAULT_HANDLE_THREAD_POOL=10;

//最大的处理线程数.

private int maxHandleThreads;

//提供消息回调调用接口

private MessageHandler messageHandler;

private ExecutorService handleThreadPool;

public MultiThreadMessageListener(MessageHandler messageHandler){

this(DEFAULT_HANDLE_THREAD_POOL, messageHandler);

}

public MultiThreadMessageListener(int maxHandleThreads,MessageHandler messageHandler){

this.maxHandleThreads=maxHandleThreads;

this.messageHandler=messageHandler;

//支持阻塞的固定大小的线程池(自行手动创建的)

this.handleThreadPool = new FixedAndBlockedThreadPoolExecutor(this.maxHandleThreads);

}

/**

* 监听程序中自动调用的方法

*/

public void onMessage(final Message message) {

//使用支持阻塞的固定大小的线程池来执行操作

this.handleThreadPool.execute(new Runnable() {

public void run() {

try {

if (message instanceof ObjectMessage) {

//强制转换一下

ObjectMessage txtMsg = (ObjectMessage) message;

//输出接收到的消息

QueueModel model = null;

try {

model = (QueueModel) txtMsg.getObject();

MultiThreadMessageListener.this.messageHandler.handle(model);

} catch (JMSException e) {

e.printStackTrace();

}

}

} catch (Exception e) {

e.printStackTrace();

}

}

});

}

}

FixedAndBlockedThreadPoolExecutor.java

package com.lejob.lejobsearch.index.queue.recruitment;

import java.util.concurrent.LinkedBlockingQueue;

import java.util.concurrent.ThreadPoolExecutor;

import java.util.concurrent.TimeUnit;

import java.util.concurrent.locks.Condition;

import java.util.concurrent.locks.ReentrantLock;

/**

* 支持阻塞的固定大小的线程池

*

*/

public class FixedAndBlockedThreadPoolExecutor extends ThreadPoolExecutor {

//一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。

//使用 lock 块来调用 try,在之前/之后的构造中

private ReentrantLock lock = new ReentrantLock();

private Condition condition = this.lock.newCondition();

public FixedAndBlockedThreadPoolExecutor(int size) {

super(size, size, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());

}

/**

* 当线程池中没有空闲线程时,会挂起此方法的调用线程.直到线程池中有线程有空闲线程.

*/

@Override

public void execute(Runnable command) {

//进行同步锁定

this.lock.lock();

super.execute(command);

try {

//如果线程池的数量已经达到最大线程池的数量,则进行挂起操作

if (getPoolSize() == getMaximumPoolSize()) {

this.condition.await();

}

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

this.lock.unlock();

}

}

@Override

protected void afterExecute(Runnable r, Throwable t) {

super.afterExecute(r, t);

try {

this.lock.lock();

this.condition.signal();

} finally {

this.lock.unlock();

}

}

}

项目spring.xml文件中配置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值