ActiveMQ(1)-初探

1.JMS

当前,CORBA,DCOM,RMI等RPC中间件技术已经广泛应用于各个领域。但是面对规模和复杂度都越来越高的分布式系统,这些技术也显示出其局限性。
1.同步通信:客户发出调用后,必须等待服务对象完成处理并返回结果才能够继续执行;
2.客户和服务对象的生命周期紧密耦合:客户进程和服务对象进程都必须正常运行,如果由于服务对象崩溃或者网络故障导致客户的请求不可达,客户会接收到异常;
3.点对点通信:客户的一次调用只发送给某个单独的目标对象。
面向消息的中间件(Message Oriented MiddleWare,MOM)较好的解决了以上问题。发送者将消息发送到消息服务器,消息服务器将消息存放在若干队列中,在合适的时候再将消息转发给接受者。这种模式下,发送和接收是异步的,发送者无需等待,二者的生命周期未必相同,发送消息的时候接收者不一定运行,接收消息的时候发送者也不一定运行;一对多通信,对于一个消息可以有多个接收者。
JAVA消息服务JMS定义了JAVA中访问消息中间件的接口。JMS只是接口,并没有给予实现,实现JMS接口的消息中间件称为JMS Provider,已有的MOM系统包括Apache的ActiveMQ,以及阿里巴巴的RocketMQ,IBM的MQSeries,Microsoft的MSMQ和BEA的MessageMQ,RabbitMQ等等。他们基本都准寻JMS规范。

2.实现JMS接口

Provider:生产者
Consumer:消费者
PTP:Point to Point,即点对点的消息模型
Pub/Sub:publish/subscribe,即发布/订阅的消息模型
Queue:队列目标
Topic:主题目标
ConnectionFactory:连接工厂,JMS用它创建连接
Connection:JMS客户端到JMS provider的连接
Destination:消息的目的地
Session:会话,一个发送或者接收消息的线程

3.JMS接口介绍

ConnectionFactory接口(连接工厂)
用户用来创建到JMS提供者的连接的被管对象。JMS客户通过可移植的接口访问连接,这样当下层的实现改变时,代码不需要进行修改。管理员的JNDI名字空间中配置连接工厂,这样,JMS客户才能够查找到它们。根据消息类型的不同,用户将使用队列连接工厂,或者主题连接工厂。
Connection接口(连接)
连接代表了应用程序和消息服务器之间的通信链路。在获得了连接工厂后,就可以创建一个与JMS提供者的连接。根据不同的连接类型,连接允许用户创建会话,以发送和接收队列和主题到目标。
Destination接口(目标)
目标是一个包装了消息目标标识符的被管对象,消息目标是指消息发布和接收的地点,或者是队列,或者是主题。JMS管理员创建这些对象,然后用户通过JNDI发现他们。和连接工厂一样,管理员可以创建两种类型的目标,点对点模型的队列,以及发布者/订阅者模型的主题。
MessageConsumer接口(消息消费者)
由会话创建的对象,用于接收发送到目标的消息。消费者可以同步地(阻塞模式),或异步(非阻塞)接收队列和主题类型的消息。
MessageProducer接口(消息生产者)
由会话创建的对象,用于发送消息到目标。用户可以创建某个目标的发送者,也可以创建一个通用的发送者,在发送消息时指定目标。
Message接口(消息)
是在消费者和生产者之间传送的对象,也就是说从一个应用程序传送到另一个应用程序。一个消息有三个主要部分:
消息头(必须):包含用于识别和为消息寻找路由的操作设置。
一组消息属性(可选):包含额外的属性,支持其他提供者和用户的兼容。可以创建定制的字段和过滤器(消息选择器)。
一个消息体(可选):允许用户创建五中类型的消息(文本消息,映射消息,字节消息,流消息和对象消息)。
消息接口非常灵活,并提供了许多方式来定制消息内容。

JMS定义了五种不同的消息正文格式,以及调用的消息类型,允许你发送并接收以一些不同形式的数据,提供现有消息格式的一些级别的兼容性。

StreamMessage java原始值的数据流
MapMessage 一套名称-值对
TextMessage 一个字符串对象
ObjectMessage 一个序列化的java对象
BytesMessage 一个未解释字节的数据流
Session接口(会话)
表示一个单线程的上下文,用户发送和接收消息。由于会话是单线程的,所以消息时连续的,就是说消息时按照发送的顺序一个一个接收的。会话的好处是它支持事务。如果用户选择了事务支持,会话上下文将保存一组消息,直到事务被提交才发送这些消息。在提交事务之前,用户可以使用回滚操作取消这些消息。一个会话允许用户创建消息生产者来发送消息,创建消息消费者来接收消息。

4.ActiveMQ

activeMQ是Apache出品,最流行,能力强劲的开源消息总线。
ActiveMQ是一个完全支持JMS1.1和J2EE1.4规范的JMS Provider实现,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位,可以说ActiveMQ在业界应用最广泛,如果想要有更强大的性能和海量数据处理能力,ActiveMQ还需要不断的升级版本,80%以上的业务我们使用ActiveMQ以及足够满足需求,当然后续如天猫,淘宝网这种大型的电商网站,尤其是1111,ActiveMQ需要进行很复杂的优化源码以及架构设计才能完成,比如阿里的RocketMQ。

5.ActiveMQ下载

建议去apache官方网站下载
版本号选择5.1x,具体没有要求

这里写图片描述

下载完成解压后的目录:

这里写图片描述

6.ActiveMQ启动

进入到bin目录下,可以看到32位和64位的版本,我这里操作系统使用的64位,所以使用64位启动。启动脚本为activemq.bat。
这里写图片描述

执行后

这里写图片描述

也可以通过浏览器查看启动状态:
浏览器访问http://localhost:8161/admin/
端口8161是默认端口,也可以在jetty.xml文件中自行配置
访问后会提示输入用户名和密码,默认是admin/admin,user/user,可以在配置文件jetty-realm.properties配置

这里写图片描述

登录之后界面如下:

这里写图片描述

activemq启动完成。

7.ActiveMQ生产者

package com.mq.activemq_01;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
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 Sender {


    public static void main(String[] args) throws JMSException {

        //1.建立ConnectionFactory工厂对象,连接地址tcp://localhost:61616,在activemq.xml文件中配置
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnectionFactory.DEFAULT_USER,
                                                                            ActiveMQConnectionFactory.DEFAULT_PASSWORD,
                                                                            "tcp://localhost:61616");

        //2.通过ConnectionFactory创建Connection连接,并通过start开启连接
        Connection connection = connectionFactory.createConnection();
        connection.start();

        //3.通过Connection创建Session会话,参数1表示是否启动事务,参数2表示签收模式封装在Session中
        Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);

        //4.通过Session创建Destination目的地,参数生产者和消费者的约束名字,消费者需要知道该名字
        Destination destination = session.createQueue("queue2");

        //5.创建消息发送或者接收对象
        MessageProducer messageProducer = session.createProducer(destination);

        //6.设置持久化和非持久化对象,这里设置是非持久化
        messageProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

        //7.通过session创建message,JMS定义了五种正文格式
        for (int i = 1; i <= 10; i++) {

            TextMessage textMessage = session.createTextMessage();

            textMessage.setText("我是消息内容,id="+i);

            messageProducer.send(textMessage);

            System.out.println("生产者:生产了"+textMessage.getText());
        }

        //8.释放连接
        if(connection != null){
            connection.close();
        }

    }
}

执行完成后,打开浏览器,查看发送消息的情况,这里已经在queue2中存放了10条消息。

这里写图片描述

8.ActiveMQ消费者

package com.mq.activemq_01;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

public class Receiver {


    public static void main(String[] args) throws JMSException {


        //1.建立ConnectionFactory工厂对象,连接地址tcp://localhost:61616,在activemq.xml文件中配置
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnectionFactory.DEFAULT_USER,
                                                                            ActiveMQConnectionFactory.DEFAULT_PASSWORD,
                                                                            "tcp://localhost:61616");

        //2.通过ConnectionFactory创建Connection连接,并通过start开启连接
        Connection connection = connectionFactory.createConnection();
        connection.start();

        //3.通过Connection创建Session会话,参数1表示是否启动事务,参数2表示签收模式封装在Session中
        Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);

        //4.通过Session创建Destination目的地,参数生产者和消费者的约束名字,消费者需要知道该名字
        Destination destination = session.createQueue("queue2");

        //5.创建消息发送或者接收对象
        MessageConsumer messageConsumer = session.createConsumer(destination);

        //6.设置持久化和非持久化对象,这里设置是非持久化
        while (true) {
            Message receive = (TextMessage)messageConsumer.receive();
            if(receive == null){
                break;
            }

            System.out.println("消费者:收到消息"+receive);
        }

        //7.释放连接
        if(connection != null){
            connection.close();
        }
    }
}

执行之后再次查看控制台,数据已经被消费掉

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值