`
cuisuqiang
  • 浏览: 3963243 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
3feb66c0-2fb6-35ff-968a-5f5ec10ada43
Java研发技术指南
浏览量:3672541
社区版块
存档分类
最新评论

编码实现MQ连接池实现JMS消息发送连接管理

阅读更多
  1. 今天来说一下在使用到MQ时如果使用MQ的链接池。之前我也是没有注意到MQ也是有连接池的,后来因为系统之前实现每次创建和关闭链接消耗资源、宕机频繁,所以领导要求解决我才接触到。
    我在网上看到的关于JMS的讲解还挺多,但是对于MQ连接池的讲解时大家都是讲如何在spring中配置连接池。首先采用spring配置后原系统加密配置的密码就成明文了,另外如果要改成spring发送那改动就大了。如果在不使用spring,不大改动代码的情况下完成采用MQ连接池来获得链接呢?
    现在哥已经养成了好的习惯,每次发博客都会将源码和工程直接发布的,不会让你看了半天连个例子也没有的。
  2. 首先要创建工程加入JAR包,要加的包都是工程内,哥不多说了,这些包是必须的。至于activemq-pool-5.2.0.jar,你一定要找到加进去,你懂的。
    你还要到官方下载一个MQ服务器,我使用的是5.2,下载后运行起来以备使用。
  3.  第二步我们要实现如何获得链接的。这里我做了两个实现,用于更直观的了解MQ连接池。
    其中连接池工厂的活跃数我们设置为1,方便测试。这个活跃数实际上是会话的数量,而不是数据库连接池一样的链接数量。
    package com.mq.service;
    import org.apache.activemq.ActiveMQConnectionFactory;
    import org.apache.activemq.pool.PooledConnectionFactory;
    /**
     * 链接工厂管理类
     * 自己工厂定义成了单例模式,连接池是静态块进行初始化,具体实现自己看着办
     */
    public class MQPooledConnectionFactory {
    	private static ActiveMQConnectionFactory connectionFactory;
    	/**
    	 * 获得自己创建的链接工厂,这个工厂只初始化一次
    	 */
    	public static ActiveMQConnectionFactory getMyActiveMQConnectionFactory() {
    		if (null == connectionFactory) {
    			connectionFactory = new ActiveMQConnectionFactory("system","manage", "tcp://127.0.0.1:61616");
    		}
    		return connectionFactory;
    	}
    	private static PooledConnectionFactory pooledConnectionFactory;
    	static {
    		try {
    			// 需要创建一个链接工厂然后设置到连接池中
    			ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory();
    			activeMQConnectionFactory.setUserName("system");
    			activeMQConnectionFactory.setPassword("manage");
    			activeMQConnectionFactory.setBrokerURL("tcp://127.0.0.1:61616");
    			// 如果将消息工厂作为属性设置则会有类型不匹配的错误,虽然Spring配置文件中是这么配置的,这里必须在初始化的时候设置进去
    			pooledConnectionFactory = new PooledConnectionFactory(activeMQConnectionFactory);
    			// 链接最大活跃数,为了在测试中区别我们使用的到底是不是一个对象和看是否能控制连接数(实际上是会话数),我们在这里设置为1
    			int maximumActive = 1;
    			pooledConnectionFactory.setMaximumActive(maximumActive);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	/**
    	 * 获得链接池工厂
    	 */
    	public static PooledConnectionFactory getPooledConnectionFactory() {
    		return pooledConnectionFactory;
    	}
    	/**
    	 * 对象回收销毁时停止链接
    	 */
    	@Override
    	protected void finalize() throws Throwable {
    		pooledConnectionFactory.stop();
    		super.finalize();
    	}
    }
     这个类会提供连接池工厂和MQ链接工厂的创建和获得方式。特别要注意到的是,在初始化连接池时要设置一个链接工厂进去,而且只能在初始化时作为参数传递进去,如果你看过spring的配置你会以为要做为属性传递,而且他确实有这个属性。
  4. 然后我们创建发送消息的基础类,在该类中得到链接然后创建消息进行发送,关闭会话等一些列操作。为了防止变量干扰,这些操作是在一个方法里面完成的。
    package com.mq.service;
    import java.util.Map;
    import java.util.Set;
    import javax.jms.Connection;
    import javax.jms.MapMessage;
    import javax.jms.MessageProducer;
    import javax.jms.Queue;
    import javax.jms.Session;
    import org.apache.activemq.ActiveMQConnectionFactory;
    /**
     * 数据发送类,用于发送数据
     * 如果获得链接,请查看被注释的代码
     */
    public class MQ_Service {
    	// 发送消息
    	@SuppressWarnings("static-access")
    	public void send(Map<String, String> map) throws Exception {
    		ActiveMQConnectionFactory connectionFactory = null;
    		Connection connection = null;
    		Session session = null;
    		Queue queue = null;
    		MessageProducer producer = null;
    		MapMessage messagep = null;	
    		// ====================================
    		try {
    			// 获得我们自己初始化的链接工厂然后创建链接
    			connectionFactory = MQPooledConnectionFactory.getMyActiveMQConnectionFactory();
    			connection = connectionFactory.createConnection();
    			
    			// 链接直接从链接池工厂进行获得
    			//connection = MQPooledConnectionFactory.getPooledConnectionFactory().createConnection();
    			
    			session = connection.createSession(false, session.AUTO_ACKNOWLEDGE);			
    			queue = session.createQueue("CUI_JMS");
    			producer = session.createProducer(queue);
    			// 链接开始,如果我们使用的是连接池,那么即使你不开始,也是没有问题的
    			connection.start();			
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		// ====================================
    		messagep = session.createMapMessage();
    		Set<String> keySet = map.keySet();
    		for (String key : keySet) {
    			String value = map.get(key);
    			messagep.setBytes(key, value.getBytes("UTF-8"));
    			System.out.println(key + "-->" + value);
    		}		
    		producer.send(messagep);		
    		messagep.clearBody();
    		messagep.clearProperties();		
    		// ===================================
    		// 通过打印会话的内存地址和链接的客户端编号就可以知道我们使用的是不是同一个会话和链接
    		System.out.println(session.toString());
    		System.out.println(connection.getClientID());
    		// 无论使用的自己的工厂还是连接池的,都要将会话关闭
    		// 如果不关闭,在使用连接池的时可以看到效果,发送两次时只能发送一次,造成堵塞
    		session.close();
    		// 使用自己的工厂和连接池的区别是,运行后自己工厂链接调用关闭程序结束
    		// 而调用连接池链接进行关闭实际上没有关闭,因为连接池要维护这个链接
    		connection.close();
    		messagep = null;
    	}
    	private MQ_Service() {
    	}
    	// 发送对象每次创建一个,用以区别我们使用的对象
    	public static MQ_Service getInstance() {
    		return new MQ_Service();
    	}
    	// 对外开发发送消息方法
    	@SuppressWarnings("unchecked")
    	public synchronized void sendMessage(Map map)
    			throws Exception {
    		this.send(map);
    	}
    }
     取消注释内容,并注释掉获得我们自己初始化的链接工厂然后创建链接下面的两行代码,我们的链接就是从连接池获得了。
    你可以打印链接、会话等各个对象的内存地址来查看是否是同一个对象内容。
  5. 多次调用发送消息,查看是否能发送消息和是否能控制链接,当然准确来说是会话数
    package com.mq.service;
    import java.util.HashMap;
    import java.util.Map;
    /**
     * 调用发送
     */
    public class MQ_Sender {
    	public static void main(String[] args) throws Exception {
    		// 循环调用,这里定义调用两次
    		for (int i = 0; i < 2; i++) {
    			MQ_Service sender = MQ_Service.getInstance();
    			Map<String, String> map = new HashMap<String, String>();
    			map.put("MESS_NUM", "112110119");
    			map.put("MESS_DEPT", "本部");
    			sender.sendMessage(map);
    			System.out.println("数据已经发送完毕!");
    		}
    	}
    }
     通过上面的例子,你就可以在不使用配置的情况下,在代码中也使用MQ连接池。并且更明了的俩接MQ连接池和数据库连接池的不同之处。

请您到ITEYE看我的原创:http://cuisuqiang.iteye.com

或支持我的个人博客,地址:http://www.javacui.com

 

3
0
分享到:
评论
4 楼 cuisuqiang 2012-05-18  
a365390931 写道
哥 我爱死你了, 源码下载下来 边看文章边看源码  一会就清晰了 ~~ 

你知道的太多了
3 楼 cuisuqiang 2012-05-18  
lvwenwen88 写道
哥 我爱死你了, 源码下载下来 边看文章边看源码  一会就清晰了 ~~ 

你知道的太多了
2 楼 lvwenwen88 2012-05-18  
哥 我爱死你了, 源码下载下来 边看文章边看源码  一会就清晰了 ~~ 
1 楼 a365390931 2012-05-03  
哥 我爱死你了, 源码下载下来 边看文章边看源码  一会就清晰了 ~~ 

相关推荐

    jms远程IBM MQ 收发消息

    在IT行业中,Java消息服务(Java Message Service,简称JMS)是一种标准,它定义了应用程序如何创建、发送、接收和读取消息的标准API。IBM MQ是IBM提供的一个强大的消息中间件,它允许分布式系统中的不同组件通过...

    基于WebSphere MQ发送消息的简单JMS实例

    在WebSphere MQ中,我们可以通过以下步骤创建一个简单的JMS发送消息的实例: 1. **配置WebSphere MQ**:首先,你需要安装并配置WebSphere MQ服务器。这包括设置队列管理器、定义队列以及配置通道以允许客户端连接。...

    RabbitMQ客户端连接池的原理及源码

    然而,频繁地创建和销毁客户端连接会带来性能开销,因此,使用连接池(Connection Pool)来管理RabbitMQ客户端连接是提高系统效率的关键。本文将深入探讨RabbitMQ客户端连接池的工作原理,并分析其源码,以期帮助...

    WebsphereMQ.rar_JMS MQ_MQ_MQ JMS_java mq jms_websphereMQ downloa

    在本场景中,"用jms向WebSphere mq里发送消息"是指使用JMS接口来与WebSphere MQ进行交互,实现消息的发布和订阅。 首先,我们需要理解JMS的核心概念。JMS提供两种消息模型:点对点(Point-to-Point)和发布/订阅...

    JMS获取与发送MQ信息 MQ命令

    【JMS获取与发送MQ信息 MQ命令】 Java消息服务(JMS)是应用程序之间进行异步通信的一种标准API,而MQ(Message Queuing)是一种消息中间件,它允许应用程序在分布式环境中交换消息。JMS通常用于MQ的编程接口,而MQ...

    MQ 队列管理器创建及消息发送示例

    在IBM的Message Queuing (MQ)技术中,队列管理器是核心组件,负责管理和调度消息的存储和传输。队列是MQ系统中消息的实际存储位置,根据其用途和位置,队列可以分为本地队列、远程队列和传输队列。 1. 队列管理器...

    Delphi向MQ远程队列发送消息

    本篇文章将深入探讨如何使用古老的编程语言Delphi 7与IBM WebSphere MQ集成,实现向远程消息队列发送消息的功能。 首先,要进行这种开发工作,你需要确保已安装了IBM WebSphere MQ客户端库,因为Delphi程序需要依赖...

    C# 实现消息的收发IBM WebSphere MQ 消息队列

    在本文中,我们将深入探讨如何使用C#编程语言与IBM WebSphere MQ进行交互,实现消息的发送和接收。IBM WebSphere MQ(前身为MQSeries)是一种企业级的消息中间件,它提供了一种可靠且可扩展的方式,使得应用程序可以...

    MQ发送接收消息完整版本下载

    开发者可以通过这个工具学习如何在Java中使用JMS API创建客户端,连接到MQ服务器,发送消息,并接收来自队列或主题的消息。具体而言,以下几个关键知识点是值得深入探讨的: 1. **连接管理**:了解如何使用JMS的...

    spring下实现MQ

    在Spring框架下实现消息队列(MQ)服务,可以极大地简化JMS(Java Message Service)的集成和管理,提供更高效、可维护的解决方案。本文将深入探讨如何使用Spring结合MQ6.0来实现JMS异步通信,并比较Spring与传统JMS...

    JMS实现 IBM MQ的请求回复

    目的:通过JMS 实现 IBM MQ的请求应答功能 工作原理:消息生产者发送消息到队列IN1,然后可以异步或者同步等待消费者接收到IN1消息后,生成应答消息,并发布到IN2队列中。生产者通过messageid在IN2队列中进行消息...

    mq、jms消息处理jar包

    在IT行业中,消息队列(Message Queue,MQ)和Java消息服务(Java Message Service,JMS)是两个关键的概念,特别是在构建分布式系统和实现异步通信时。IBM的MQ是业界广泛使用的消息中间件,而JMS是Java平台上的一个...

    在spring boot中使用jms集成IBM-MQ和TLQ,包含普通队列和主题订阅两种模式,并实现按需加载

    1) 本工程主要演示在SPRING BOOT工程中怎样使用JMS集成IBM-MQ及TLQ两种消息中间件产品 2) 使用SPRING BOOT Conditional机制实现了两种产品按需加载,工程会根据配置文件开关动态加载 3) 实现了普通队列消息发送与...

    基于soap over jms 的websphere mq与axis2的实现

    JMS是Java平台上的一个标准API,用于在分布式环境中发送、接收和管理消息。它提供了一种解耦的通信方式,允许应用程序通过消息队列进行异步交互,提高了系统的可靠性和可扩展性。JMS支持两种消息模型:点对点(Point...

    JAVA实现MQ发送接收消息详解

    本篇文章将详细介绍如何使用 Java 实现 MQ(Message Queue)发送和接收消息,包括 MQ 的配置、队列管理器的创建、队列的创建、发送和接收消息的 Java 代码。 MQ 配置 要使用 MQ 发送和接收消息,首先需要配置 MQ ...

    mq-连接管理

    "mq-连接管理"是MQ技术中的核心部分,它涉及到如何建立、维护和管理MQ连接,确保消息的高效、稳定传输。以下是对这一主题的详细阐述: 1. **MQ连接的建立**:在应用系统中使用MQ时,首先需要建立与MQ服务器的连接。...

    IBM MQ将消息发送至远程队列

    ### IBM MQ将消息发送至远程队列的知识点详解 #### 一、安装MQ IBM MQ的安装过程是在两台不同的主机上进行的。首先需要确保介质目录已经准备好,并且能够执行安装所需的命令。 ##### 安装步骤: 1. **接受...

    JMS调用IBM MQ监听模式

    2. **IBM MQ连接**:配置IBM MQ的连接参数,如主机名、端口号、队列管理器名、通道名和凭证信息,以建立到MQ的连接。 3. **创建QueueConnectionFactory**:使用JMS API的ConnectionFactory类创建一个连接工厂,以便...

Global site tag (gtag.js) - Google Analytics