ActiveMQ入门

一、安装和启动

官网:http://activemq.apache.org/

1、安装启动

方式一: 

$ tar -zxvf apache-activemq-5.11.1-bin.tar.gz

$ mv apache-activemq-5.11.1 activemq

如果启动脚本 activemq 没有可执行权限,此时则需要授权(此步可选)

$ cd /activemq-01/bin/

$ chmod 755 ./activemq

$ ./activemq start/stop/status

方式二(Windows):

 下载之后解压出来,目录如下

打开bin目录下的地址可以看到有两个文件夹win32和win64,可以根据自己的电脑情况来选择。

我这里选择win64位的,点击activemq.bat进行启动,如图所示就是启动结束了。启动服务(保持黑窗口开启)

 那么接下来我们在浏览器中输入 http://localhost:8161/admin 地址,弹出输入用户名密码的页面,默认用户名密码都为admin

 

 

2、ActiveMQ 需要用到两个端口

一个是消息通讯的端口(默认为 61616)

一个是管理控制台端口(默认为 8161)可在conf/jetty.xml 中修改

<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
    <!-- the default port number for the web console -->
    <property name="host" value="0.0.0.0"/>
    <property name="port" value="8161"/>
</bean>

 

3、检查是否启动

ActiveMQ默认采用61616端口提供JMS服务,使用8161端口提供管理控制台服务,执行以下命令检验是否成功启动ActiveMQ

1.查看端口是否打开:netstat -an | grep 61616

2.查看控制台输入或者日志文件

3.访问ActiveMQ的管理页面:http://ip:8161/admin/

默认的用户名和密码是admin/admin

 

4、安全配置(消息安全)

ActiveMQ 如果不加入安全机制的话,任何人只要知道消息服务的具体地址

(包括 ip,端口,消息地址[ 队列或者主题地址] ) ,都可以肆无忌惮的发送、接收消息。

关于 ActiveMQ 安装配置http://activemq.apache.org/security.html

 

二、管理界面

进入管理界面的地址:http://localhost:8161(IP:端口号)

1、Queues(队列)

标示描述
Name队列名称
Number Of Pending Messages队列中有多少个消息等待出队列
Number Of Consumers队列中有多少个消费者
Messages Enqueued队列共有多少个信息
Messages Dequeued队列中已经出列多少个消息


2、Topics(主题模式)

 这里只有 Name、Number Of Consumers、Messages Enqueued、Messages Dequeued

 

三、ActiveMQ常用类、方法 

1、连接对象(Connection)

Connection【javax.jms.Connection】

方法返回值描述
start()void启动连接
createSession(boolean var1, int var2)Session使用连接对象创建会话(session)对象
		// 创建连接工厂
		ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory();
		// 设置服务地址
		activeMQConnectionFactory.setBrokerURL(ACTIVEMQ_URL);
		// 打开连接
		connection.start();
		Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

 


2、通道对象(Session)

Session【javax.jms.Session】

方法返回描述
createQueue(String var1)Queue创建queue模式
createTopic(String var1)Topic创建Topic模式
createProducer(Destination var1)MessageProducer创建生产者
createConsumer(Destination var1)MessageConsumer创建消费者
commit()void 
rollback()void 

 

消息类型(Message)

JAVA消息服务定义了6种JMS提供者必须支持的 Message 接口类型。尽管JMS定义了Message接口,但它并未定义它们的实现方式。这就允许提供者以它们自己的方式实现和传送消息,同时为JMS应用程序开发者维护了一个兼容的标准接口。这6个消息接口是Message和它的5个子接口:TextMessage、StreamMessage、MapMessage、ObjectMessage 和 ByteMessage

方法返回描述
createMessage()Message创建消息对象
createTextMessage()TextMessage创建文本消息对象
createTextMessage(String var1)TextMessage创建文本消息对象
createObjectMessage()ObjectMessage创建对象消息对象
createObjectMessage(Serializable var1)ObjectMessage创建对象消息对象
createMapMessage()MapMessage创建映射消息对象
createBytesMessage()BytesMessage创建字节流消息对象
createStreamMessage()StreamMessage创建流消息对象

3.1 Message

最简单的消息类型是javax.jms.Message,它担当了其他消息类型基接口(base interface)的角色。可按一下方式创建Message类型,并将它用作一条不含有效负载的JMS消息:

//使用者发布者创建并发送消息
       Message message = pubSession .createTextMessage();
       publisher.publish(message );
    //接受消息
       @Override
       public void onMessage(Message message) {

这种类型的消息仅仅包含了JMS消息头和消息属性,而且,它仅限用于事件通知,它仅用于事件通知。一个事件通知就是出现某些情况的一个广播、告警或者通知。如果业务场景需要一个不含有效负载的简单通知,轻量级消息类型就是实现它的最有效方式。
例如为了广播通知某个特定类中的一个异常,你可以发布一条不含有效负载的异常文本消息,如下所示:

    //发送异常
    ...
    try{
    ...
    }catch(Exception up){
        Message message = Sesstion.createMessage();
        message.setStringProperty("Exception",up.getMessage());
        publisher.publish(message);
        throw up;
    }
    //接受异常
    ...
    public void onMessage(Message message){
    ...
    System.out.println("Exception:"+message.getStringProperty());
    ...
    }
    ...

3.2 TextMessage

文本消息可以使用Session接口中定义的两个工厂方法之一来创建。其中一个工厂方法没有使用参数,就会产生出不含有效负载的TextMessage对象。另一个工厂方法则使用一个string类型的有效负载作为参数,生产出“准备就绪可传送”的TextMessage对象

    TextMessage textMessage = Session.createTextMessage();
    textMessage.setText("Hello World!");
    topicPublisher.publish(textMessage);
    ...
    TextMessage textMessage = session.createTextMessage("Hello!");
    queueSender.send(textMessage);

3.3 ObjectMessage

对象消息可以使用Session接口中的两个工厂方法中的一个来创建

    //订单一个可序列化对象
    Order order = new Order();
    ...
    ObjectMessage objectMessage = Session.createObjectMessage();
    objectMessage.setObject(order);
    queueSender.send(objectMessage);
    ...
    ObjectMessage objectMessage = Session.createObjectMessage(order);
    topicPublisher.publish(objectMessage);

在消费者接受objectMessage时,它可以使用getObject()方法提取出有效负载。如果传送的ObjectMessage不含有效负载,getObject()方法将返回一个null值。

    public void onMessage(Message message){
        try{
            ObjectMessage objectMessage =(ObjectMessage)message;
            Order order =(Order)objectMessage.getObject();
            ...
        }catch(JMSException jmse){
        ...
    }

注意:使用ObjectMessages时,消息生产者和消费者二者都必须是JMS兼容的。

3.4 BytesMessage

这种类型懈怠了一组原始类型字节流作为有效负载。
它可以使用应用程序的本机格式来交换数据,这种格式可能不兼容其他现有的Message类型。当JMS纯粹用于两个系统之间的消息传送时,也可以使用这种类型,而且该消息的有效负载对JMS客户端来说是透明的。
如果你使用java.io.DataInputStream和java.io.DataOutputStream,那么以这些I/O类为基础的ByteMessage接口方法,就会让你觉得熟悉。

    BytesMessage bytesMessage = Session.createBytesMessage();

    bytesMessage.writeChar('R');
    byteMessage.writeInt(10);
    byteMessage.writeUTF("Hello");

消息响应

    public void onMessage(Message message){
        try{
            BytesMessage byteMessage =(BytesMessage)message;
            char c = byteMessage.readChar();
            int i = byteMessage.readInt();
            String s = byteMessage.readUTF();
        }catch(JMSException jmse){
        ....
        }
    }

ByteMessage是可移植性最好的而一种消息类型,因此他在于非JMS消息类型传送客户端通信时非常有用。有些情况下,一个JMS客户端可以是一类路由器,它消费来自某个消息源的消息,并将他们传送给一个目的地。路由选择应用程序可能不需要知道它们传输的数据内容,并因此可以选择使用ByteMessage将有效负载作为二进制数据,从一个位置传送到其他位置。

3.5 MapMessage

这种类型携带了一组键/值对作为有效负载。有效负载类似与一个Java.util.Properties对象,除了有效负载值必须是Java原始数据类型和Strings型之外。
本质上,MapMessage的工作方式类似于JMS属性:任何键/值对都可以写入有效负载。其中名称必须是一个String对象,而值则可以是String类型或原始数据类型。

    MapMessage mapMessage =Session.createMapMessage();
    mapMessage.setInt("Age",88);
    mapMessage.setFloat("Weight",234);
    mapMessage.setString("Name","Smith");
    mapMessage.setObject("Height",new Double(150.32));
    ...

    int age = mapMessage.getInt("Age");
    float weight = mapMessage.getFloat("Weight");
    String name = mapMessage.getString("Name");\
    Double height = (Double)mapmessage.getObject("Height");

3.6 StreamMessage

StreamMesage携带了一个Java原始数据类型流作为有效负载。它提供了一套将格式化字节流映射为Java原始数据类型的简便方法。
StreamMessage保持了写入流时的顺序和原始数据类型,因此它适用于形式转换规则。

 

 

四、消息确认机制ACK

消息消费者有没有接收到消息,需要有一种机制让消息提供者知道,这个机制就是消息确认机制。

ACK(Acknowledgement)即确认字符,在数据通信中,接收站发给发送站的一种传输类控制字符。表示发来的数据已确认接收无误。

 

1、ACK_MODE有几类

我们在开发JMS应用程序的时候,会经常使用到上述ACK_MODE,其中"INDIVIDUAL_ACKNOWLEDGE "只有ActiveMQ支持,当然开发者也可以使用它. ACK_MODE描述了Consumer与broker确认消息的方式(时机),比如当消息被Consumer接收之后,Consumer将在何时确认消息。对于broker而言,只有接收到ACK指令,才会认为消息被正确的接收或者处理成功了,通过ACK,可以在consumer与Broker之间建立一种简单的“担保”机制. 

JMS API中约定了Client端可以使用四种ACK_MODE,在javax.jms.Session接口中:

AUTO_ACKNOWLEDGE = 1    自动确认
CLIENT_ACKNOWLEDGE = 2    客户端手动确认   
DUPS_OK_ACKNOWLEDGE = 3    自动批量确认
SESSION_TRANSACTED = 0    事务提交并确认

此外AcitveMQ补充了一个自定义的ACK_MODE:

INDIVIDUAL_ACKNOWLEDGE = 4    单条消息确认

 

2、ACK_TYPE有几类

Client端指定了ACK_MODE,但是在Client与broker在交换ACK指令的时候,还需要告知ACK_TYPE,ACK_TYPE表示此确认指令的类型,不同的ACK_TYPE将传递着消息的状态,broker可以根据不同的ACK_TYPE对消息进行不同的操作。

比如Consumer消费消息时出现异常,就需要向broker发送ACK指令,ACK_TYPE为"REDELIVERED_ACK_TYPE",那么broker就会重新发送此消息。在JMS API中并没有定义ACT_TYPE,因为它通常是一种内部机制,并不会面向开发者。ActiveMQ中定义了如下几种ACK_TYPE(参看MessageAck类):

  • DELIVERED_ACK_TYPE = 0    消息"已接收",但尚未处理结束
  • STANDARD_ACK_TYPE = 2    "标准"类型,通常表示为消息"处理成功",broker端可以删除消息了
  • POSION_ACK_TYPE = 1    消息"错误",通常表示"抛弃"此消息,比如消息重发多次后,都无法正确处理时,消息将会被删除或者DLQ(死信队列)
  • REDELIVERED_ACK_TYPE = 3    消息需"重发",比如consumer处理消息时抛出了异常,broker稍后会重新发送此消息
  • INDIVIDUAL_ACK_TYPE = 4    表示只确认"单条消息",无论在任何ACK_MODE下    
  • UNMATCHED_ACK_TYPE = 5    BROKER间转发消息时,接收端"拒绝"消息,在Topic中,如果一条消息在转发给“订阅者”时,发现此消息不符合Selector过滤条件,那么此消息将 不会转发给订阅者,消息将会被存储引擎删除(相当于在Broker上确认了消息)

到目前为止,我们已经清楚了大概的原理: Client端在不同的ACK_MODE时,将意味着在不同的时机发送ACK指令,每个ACK Command中会包含ACK_TYPE,那么broker端就可以根据ACK_TYPE来决定此消息的后续操作.

 

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值