ActiveMQ配置使用

  • 介绍

ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。


  • ActiveMQ的特性
  1. 多种语言和协议编写客户端。语言: Java, C, C++, C#, Ruby, Perl, Python, PHP。应用协议: OpenWire,Stomp REST,WS Notification,XMPP,AMQP
  2. 完全支持JMS1.1和J2EE 1.4规范 (持久化,XA消息,事务)
  3. 对Spring的支持,ActiveMQ可以很容易内嵌到使用Spring的系统里面去,而且也支持Spring2.0的特性
  4. 通过了常见J2EE服务器(如 Geronimo,JBoss 4, GlassFish,WebLogic)的测试,其中通过JCA 1.5 resource adaptors的配置,可以让ActiveMQ可以自动的部署到任何兼容J2EE 1.4 商业服务器上
  5. 支持多种传送协议:in-VM,TCP,SSL,NIO,UDP,JGroups,JXTA
  6. 支持通过JDBC和journal提供高速的消息持久化
  7. 从设计上保证了高性能的集群,客户端-服务器,点对点
  8. 支持Ajax
  9. 支持与Axis的整合
  10. 可以很容易得调用内嵌JMS provider,进行测试

  • 使用场景

    多个项目之间集成
    (1) 跨平台
    (2) 多语言
    (3) 多项目
    降低系统间模块的耦合度,解耦
    (1) 软件扩展性
    系统前后端隔离
    (1) 前后端隔离,屏蔽高安全区

1、 不同语言应用集成
ActiveMQ 中间件用Java语言编写,因此自然提供Java客户端 API。但是ActiveMQ 也为C/C++、.NET、Perl、PHP、Python、Ruby 和一些其它语言提供客户端。在你考虑如何集成不同平台不同语言编写应用的时候,ActiveMQ 拥有巨大优势。在这样的例子中,多种客户端API通过ActiveMQ 发送和接受消息成为可能,无论使用的是什么语言。此外,ActiveMQ 还提供交叉语言功能,该功能整合这种功能,无需使用远程过程调用(RPC)确实是个优势,因为消息协助应用解耦。
2、 作为RPC的替代
使用RPC同步调用的应用十分普遍。假设大多数客户端服务器应用使用RPC,包括ATM、大多数WEB应用、信用卡系统、销售点系统等等。尽管很多系统很成功,但是转换使用异步消息可以带来很多好处,而且也不会放弃响应保证。使用同步请求的系统在规模上有较大的限制,因为请求会被阻塞,从而导致整个系统变慢。如果使用异步消息替代,可以很容易增加额外的消息接收者,使得消息能被并发消耗,从而加快请求处理。当然,你的系统应用间应该是解耦的。
3、 应用之间解耦
正如之前讨论的,紧耦合架构可以导致很多问题,尤其是如果他们是分布的。松耦合架构,在另一方面,证实了更少的依赖性,能够更好地处理不可预见的改变。不仅可以在系统中改变组件而不影响整个系统,而且组件交互也相当的简单。相比使用同步的系统(调用者必须等待被调用者返回信息),异步系统(调用方发送消息后就不管,即fire-and-forget)能够给我们带来事件驱动架构(event-driven architecture EDA)。
4、 作为事件驱动架构的主干
解耦,异步架构的系统允许通过代理器自己配置更多的客户端,内存等(即vertical scalability)来扩大系统,而不是增加更多的代理器(即horizontal scalability)。考虑如亚马逊这样繁忙的电子商务系统。当用户购买物品,事实上系统需要很多步骤去处理,包括下单,创建发票,付款,执行订单,运输等。但是用户下单后,会立即返回“谢谢你下单”的界面。不只是没有延迟,而且用户还会受到一封邮件表明订单已经收到。在亚马逊下单的例子就是一个多步处理的例子。每一步都由单独的服务去处理。当用户下单是,有一个同步的体积表单动作,但整个处理流程并不通过浏览器同步处理。相反地,订单马上被接受和反馈。而剩下的步骤就通过异步处理。如果在处理过程中出错,用户会通过邮件收到通知。这样的异步处理能提供高负载和高可用性。
5、 提高系统扩展性
很多使用事件驱动设计的系统是为了获得高可扩展性,例如电子商务,政府,制造业,线上游戏等。通过异步消息分开商业处理步骤给各个应用,能够带来很多可能性。考虑设计一个应用来完成一项特殊的任务。这就是面向服务的架构(service-oriented architecture SOA)。每一个服务完成一个功能并且只有一个功能。应用就通过服务组合起来,服务间使用异步消息和最终一致性。这样的设计便可以引入一个复杂事件处理概念(complex event processing CEP)。使用CEP,部件间的交互可以被记录追踪。在异步消息系统中,可以很容易在部件间增加一层处理。


  • 安装

安装
首先去http://activemq.apache.org/download.html 下载最新版本
目录如下:
+bin (windows下面的bat和unix/linux下面的sh)
+conf (activeMQ配置目录,包含最基本的activeMQ配置文件)
+data (默认是空的)
+docs (index,replease版本里面没有文档,-.-b不知道为啥不带)
+example (几个例子)
+lib (activemMQ使用到的lib)
-apache-activemq-4.1-incubator.jar (ActiveMQ的binary)
-LICENSE.txt
运行信息
运行信息
-NOTICE.txt
-README.txt
-user-guide.html
这里写图片描述
启动bin/win64/activemq.bat
启动成功就可以访问管理员界面:http://localhost:8161/admin

  • 使用,消息发送方式

(1)、点对点方式(point-to-point Queue)

点对点的消息发送方式主要建立在 Message Queue,Sender,reciever上,Message Queue 存贮消息,Sneder 发送消息,receive接收消息.具体点就是Sender Client发送Message Queue ,而 receiver Cliernt从Queue中接收消息和”发送消息已接受”到Quere,确认消息接收。消息发送客户端与接收客户端没有时间上的依赖,发送客户端可以在任何时刻发送信息到Queue,而不需要知道接收客户端是不是在运行


(2)、发布/订阅 方式(publish/subscriber Messaging
Topic)

发布/订阅方式用于多接收客户端的方式.作为发布订阅的方式,可能存在多个接收客户端,并且接收端客户端与发送客户端存在时间上的依赖。一个接收端只能接收他创建以后发送客户端发送的信息。作为subscriber ,在接收消息时有两种方法,destination的receive方法,和实现message listener 接口的onMessage 方法。

发送消息的基本步骤:
(1)、创建连接使用的工厂类JMS ConnectionFactory
(2)、使用管理对象JMS ConnectionFactory建立连接Connection,并启动
(3)、使用连接Connection 建立会话Session
(4)、使用会话Session和管理对象Destination创建消息生产者MessageSender
(5)、使用消息生产者MessageSender发送消息

消息接收者从JMS接受消息的步骤
(1)、创建连接使用的工厂类JMS ConnectionFactory
(2)、使用管理对象JMS ConnectionFactory建立连接Connection,并启动
(3)、使用连接Connection 建立会话Session
(4)、使用会话Session和管理对象Destination创建消息接收者MessageReceiver
(5)、使用消息接收者MessageReceiver接受消息,需要用setMessageListener将MessageListener接口绑定到MessageReceiver消息接收者必须实现了MessageListener接口,需要定义onMessage事件方法。

这里写图片描述

【ActiveMQ配置文件】

ActiveMQ内存配置和密码设置

1.配置内存  

  bin中activemq.bat 中的第一行 加上 :
  REM 配置内存
  set ACTIVEMQ_OPTS=-Xms1G -Xmx1G

2.修改控制台密码

打开conf/jetty.xml,

<bean id="securityConstraint" class="org.eclipse.jetty.http.security.Constraint">
    <property name="name" value="BASIC" />
    <property name="roles" value="admin" />
    <property name="authenticate" value="false" />
</bean>


将property name为authenticate的属性value="false" 改为"true",高版本的已经默认为true了。

控制台的登录用户名密码保存在conf/jetty-realm.properties文件中,内容如下:

# Defines users that can access the web (console, demo, etc.)
# username: password [,rolename ...]
admin: admin, admin

值得注意的是 用户名和密码的格式是:用户名 : 密码 ,角色名

此处我使用的apache-activemq-5.13.2 已经为true不用更改了。

3.修改客户端连接密码

3.1修改activemq.xml配置,需要新增一个插件,在节点里面节点前面添加如下

<plugins> 
   <simpleAuthenticationPlugin> 
         <users> 
              <authenticationUser username="${activemq.username}" password="${activemq.password}" groups="users,admins"/> 
         </users> 
   </simpleAuthenticationPlugin> 
</plugins>

或者直接修改为(即直接将username和password赋值,所赋的值即为用户名和密码。如果使用这一种方式的话,下面的3.2步则不需要了):

<plugins> 
   <simpleAuthenticationPlugin> 
         <users> 
              <authenticationUser username="testUserName" password="testPassword" groups="users,admins"/> 
         </users> 
   </simpleAuthenticationPlugin> 
</plugins>

3.2用户名密码文件为:credentials.properties

## --------------------------------------------------------------------------- 
## Licensed to the Apache Software Foundation (ASF) under one or more 
## contributor license agreements. See the NOTICE file distributed with 
## this work for additional information regarding copyright ownership. 
## The ASF licenses this file to You under the Apache License, Version 2.0 
## (the "License"); you may not use this file except in compliance with 
## the License. You may obtain a copy of the License at 
## 
## http://www.apache.org/licenses/LICENSE-2.0 
## 
## Unless required by applicable law or agreed to in writing, software 
## distributed under the License is distributed on an "AS IS" BASIS, 
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
## See the License for the specific language governing permissions and 
## limitations under the License. 
## --------------------------------------------------------------------------- 

# Defines credentials that will be used by components (like web console) to access the broker 

activemq.username=system    # 用户名
activemq.password=manager   # 密码
guest.password=password

代码:

这里写图片描述

点对点方式(point-to-point Queue):

消费者:

package com.h3c.activMQ;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

public class QueueConsumer {

    public static void main(String[] args) {
        //连接信息设置
        String username = "zhangsan";
        String password = "123";
        String brokerURL = "failover://tcp://localhost:61616";
        //连接工厂
        ConnectionFactory connectionFactory = null;
        //连接
        Connection connection = null;
        //会话 接受或者发送消息的线程
        Session session = null;
        //消息的目的地
        Destination destination = null;
        //消息消费者
        MessageConsumer messageConsumer = null;
        //实例化连接工厂
        connectionFactory = new ActiveMQConnectionFactory(username, password, brokerURL);

        try {
            //通过连接工厂获取连接
            connection = connectionFactory.createConnection();
            //启动连接
            connection.start();
            //创建session
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            //创建一个连接QueueTest的消息队列
            destination = session.createQueue("QueueTest");
            //创建消息消费者
            messageConsumer = session.createConsumer(destination);

            while (true) {
                TextMessage textMessage = (TextMessage) messageConsumer.receive(100000);
                System.out.println("-----------");
                if(textMessage != null){
                    System.out.println("成功接收消息:" + textMessage.getText());
                }else {
                    break;
                }
            }
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}

生产者 :

package com.h3c.activMQ;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

public class QueueProducer {

    public static void main(String[] args) {
        //连接信息设置
        String username = "zhangsan";
        String password = "123";
        String brokerURL = "failover://tcp://localhost:61616";
        //连接工厂
        ConnectionFactory connectionFactory = null;
        //连接
        Connection connection = null;
        //会话 接受或者发送消息的线程
        Session session = null;
        //消息的目的地
        Destination destination = null;
        //消息生产者
        MessageProducer messageProducer = null;
        //实例化连接工厂
        connectionFactory = new ActiveMQConnectionFactory(username, password, brokerURL);

        try {
            //通过连接工厂获取连接
            connection = connectionFactory.createConnection();
            //启动连接
            connection.start();
            //创建session
            session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
            //创建一个名称为QueueTest的消息队列
            destination = session.createQueue("QueueTest");
            //创建消息生产者
            messageProducer = session.createProducer(destination);
            //发送消息
            TextMessage message = null;
            for (int i=0; i<10; i++) {
                //创建要发送的文本信息
                message = session.createTextMessage("Queue消息测试" +(i+1));
                //通过消息生产者发出消息 
                messageProducer.send(message);
                System.out.println("发送成功:" + message.getText());
            }
            session.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if(null != connection){
                try {
                    connection.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }

    }

}

发布/订阅 方式(publish/subscriber Messaging Topic)

生产者:

package com.h3c.Topic;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;

import org.apache.activemq.ActiveMQConnectionFactory;

public class TopicProducer {

    public static void main(String[] args) {
        //连接信息设置
        String username = "zhangsan";
        String password = "123";
        String brokerURL = "failover://tcp://localhost:61616";
        //连接工厂
        ConnectionFactory connectionFactory = null;
        //连接
        Connection connection = null;
        //会话 接受或者发送消息的线程
        Session session = null;
        //消息的主题
        Topic topic = null;
        //消息生产者
        MessageProducer messageProducer = null;
        //实例化连接工厂
        connectionFactory = new ActiveMQConnectionFactory(username, password, brokerURL);
        try {
            //通过连接工厂获取连接
            connection = connectionFactory.createConnection();
            //启动连接
            connection.start();
            //创建session
            session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
            //创建名为TopicTest的主题
            topic = session.createTopic("TopicTest");  
            //创建主题生产者
            messageProducer = session.createProducer(topic);
            messageProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);//不将数据持久化
            //发送主题
            TextMessage message = null;
            for (int i=0; i<10; i++) {
                //创建要发送的文本信息
                message = session.createTextMessage("Topic主题测试" +(i+1));
                //通过主题生产者发出消息 
                messageProducer.send(message);
                System.out.println("发送成功:" + message.getText());
            }
            session.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if(null != connection){
                try {
                    connection.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }  
    }

}

消费者:

package com.h3c.Topic;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;

import org.apache.activemq.ActiveMQConnectionFactory;

public class TopicConsumer {

    public static void main(String[] args) {
        //连接信息设置
        String username = "zhangsan";
        String password = "123";
        String brokerURL = "failover://tcp://localhost:61616";
        //连接工厂
        ConnectionFactory connectionFactory = null;
        //连接
        Connection connection = null;
        //会话 接受或者发送消息的线程
        Session session = null;
        //主题的目的地
        Topic topic = null;
        //主题消费者
        MessageConsumer messageConsumer = null;
        //实例化连接工厂
        connectionFactory = new ActiveMQConnectionFactory(username, password, brokerURL);

        try {
            //通过连接工厂获取连接
            connection = connectionFactory.createConnection();
            //启动连接
            connection.start();
            //创建session
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            //创建一个连接TopicTest的主题
            topic = session.createTopic("TopicTest");  
            //创建主题消费者
            messageConsumer = session.createConsumer(topic);

            messageConsumer.setMessageListener(new MyMessageListener());
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }

}

class MyMessageListener implements MessageListener {

    @Override
    public void onMessage(Message message) {  
        TextMessage textMessage = (TextMessage) message;  
        try {  
            System.out.println("接收订阅主题:" + textMessage.getText());  
        } catch (JMSException e) {  
            e.printStackTrace();  
        }  
    } 

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值