ActiveMQ入门(一)

消息中间件的必要性:

        1.场景一:我们可以想象一个淘宝的双十一,无数用户同时下订单,先不说有没有分布式&集群,但可以肯定的是,淘宝的代码肯定不是同小型项目一样(纯想象,没在淘宝工作过),直接Controller->Service->Dao,会阻塞死的。所以,急需将这些模块分开,Controller只用来接受简单请求,做数据转发,其它啥都不干,然后把收到的消息直接扔给消息中间件,Service收到消息后,做业务处理,至于Dao嘛……这样的话,至少用户能够下单成功,而不是点击下单后,页面直接卡住。

        2.场景二:有大波定时业务需要处理,放在Redis&DataBase然后用定时任务扫描?怎么想都感觉很low啊,失去了及时性,而且对性能影响也很大。暂且不论Spring全家桶系列的定时任务,也有很多坑,阻塞模式吧,效率不行,中途异常处理不当的话坑定比较坑BOSS,非阻塞模式吧,一致性很难保证,如果再用分布式锁,效率会急剧下降。我们更需要一种机制,可以指定特定时间去执行,而不是傻乎乎的扫描,刚好,ActiveMQ支持,下面的入门Demo可以看到代码实现。

入门代码:

第一步:

                去apache官网下载软件包,根据自己的系统选择Win或者Linux,我是Win系统(Linux老出现引导失败,啊)。直接解压,然后进入到:

.\apache-activemq-5.15.0-bin\apache-activemq-5.15.0\bin\win64

直接执行:

activemq.bat

当然,也可以自定编辑这个文件,指定一些配置文件路径之类的,双击直接启动,正常启动的画面应该是如下:

wrapper  | --> Wrapper Started as Console
wrapper  | Launching a JVM...
jvm 1    | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
jvm 1    |   Copyright 1999-2006 Tanuki Software, Inc.  All Rights Reserved.
jvm 1    |
jvm 1    | Java Runtime: Oracle Corporation 1.8.0_121 C:\Program Files\Java\jdk1.8.0_121\jre
jvm 1    |   Heap sizes: current=251392k  free=236973k  max=932352k
jvm 1    |     JVM args: -Dactivemq.home=../.. -Dactivemq.base=../.. -Djavax.net.ssl.keyStorePassword=password -Djavax.net.ssl.trustStorePassword=password -Djavax.net.ssl.keyStore=../../conf/broker.ks -Djavax.net.ssl.trustStore=../../conf/broker.ts -Dcom.sun.management.jmxremote -Dorg.apache.activemq.UseDedicatedTaskRunner=true -Djava.util.logging.config.file=logging.properties -Dactivemq.conf=../../conf -Dactivemq.data=../../data -Djava.security.auth.login.config=../../conf/login.config -Xmx1024m -Djava.library.path=../../bin/win64 -Dwrapper.key=aesu3DOUh14DC35B -Dwrapper.port=32000 -Dwrapper.jvm.port.min=31000 -Dwrapper.jvm.port.max=31999 -Dwrapper.pid=21996 -Dwrapper.version=3.2.3 -Dwrapper.native_library=wrapper -Dwrapper.cpu.timeout=10 -Dwrapper.jvmid=1
jvm 1    | Extensions classpath:
jvm 1    |   [..\..\lib,..\..\lib\camel,..\..\lib\optional,..\..\lib\web,..\..\lib\extra]
jvm 1    | ACTIVEMQ_HOME: ..\..
jvm 1    | ACTIVEMQ_BASE: ..\..
jvm 1    | ACTIVEMQ_CONF: ..\..\conf
jvm 1    | ACTIVEMQ_DATA: ..\..\data
jvm 1    | Loading message broker from: xbean:activemq.xml
jvm 1    |  INFO | Refreshing org.apache.activemq.xbean.XBeanBrokerFactory$1@521a9779: startup date [Sun Jul 30 15:23:13 CST 2017]; root of context hierarchy
jvm 1    |  INFO | Using Persistence Adapter: KahaDBPersistenceAdapter[D:\Soft\mq\apache-activemq-5.15.0-bin\apache-activemq-5.15.0\bin\win64\..\..\data\kahadb]
jvm 1    |  INFO | KahaDB is version 6
jvm 1    |  INFO | Recovering from the journal @1:144358
jvm 1    |  INFO | Recovery replayed 135 operations from the journal in 0.053 seconds.
jvm 1    |  INFO | PListStore:[D:\Soft\mq\apache-activemq-5.15.0-bin\apache-activemq-5.15.0\bin\win64\..\..\data\localhost\tmp_storage] started
jvm 1    |  INFO | JobSchedulerStore: ..\..\data\localhost\scheduler started.
jvm 1    |  INFO | Apache ActiveMQ 5.15.0 (localhost, ID:DESKTOP-J9I9CUI-8400-1501399395220-0:1) is starting
jvm 1    |  INFO | Listening for connections at: tcp://DESKTOP-J9I9CUI:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600
jvm 1    |  INFO | Connector openwire started
jvm 1    |  INFO | Listening for connections at: amqp://DESKTOP-J9I9CUI:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600
jvm 1    |  INFO | Connector amqp started
jvm 1    |  INFO | Listening for connections at: stomp://DESKTOP-J9I9CUI:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600
jvm 1    |  INFO | Connector stomp started
jvm 1    |  INFO | Listening for connections at: mqtt://DESKTOP-J9I9CUI:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600
jvm 1    |  INFO | Connector mqtt started
jvm 1    |  WARN | ServletContext@o.e.j.s.ServletContextHandler@6cc5f5db{/,null,STARTING} has uncovered http methods for path: /
jvm 1    |  INFO | Listening for connections at ws://DESKTOP-J9I9CUI:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600
jvm 1    |  INFO | Connector ws started
jvm 1    |  INFO | Apache ActiveMQ 5.15.0 (localhost, ID:DESKTOP-J9I9CUI-8400-1501399395220-0:1) started
jvm 1    |  INFO | For help or more information please see: http://activemq.apache.org
jvm 1    |  WARN | Store limit is 102400 mb (current store usage is 0 mb). The data directory: D:\Soft\mq\apache-activemq-5.15.0-bin\apache-activemq-5.15.0\bin\win64\..\..\data\kahadb only has 13765 mb of usable space. - resetting to maximum available disk space: 13765 mb
jvm 1    |  WARN | Temporary Store limit is 51200 mb (current store usage is 0 mb). The data directory: D:\Soft\mq\apache-activemq-5.15.0-bin\apache-activemq-5.15.0\bin\win64\..\..\data\localhost only has 13765 mb of usable space. - resetting to maximum available disk space: 13765 mb
jvm 1    |  INFO | No Spring WebApplicationInitializer types detected on classpath
jvm 1    |  INFO | ActiveMQ WebConsole available at http://0.0.0.0:8161/
jvm 1    |  INFO | ActiveMQ Jolokia REST API available at http://0.0.0.0:8161/api/jolokia/
jvm 1    |  INFO | Initializing Spring FrameworkServlet 'dispatcher'
jvm 1    |  INFO | No Spring WebApplicationInitializer types detected on classpath
jvm 1    |  INFO | jolokia-agent: Using policy access restrictor classpath:/jolokia-access.xml
jvm 1    |  WARN | Transport Connection to: tcp://127.0.0.1:8436 failed: java.net.SocketException: Connection reset

第二步:

        构建一个简单的maven工程:pom.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.ripple</groupId>
    <artifactId>activemq</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-all</artifactId>
            <version>5.15.0</version>
        </dependency>
    </dependencies>


</project>

第三步:

        写一个生产者,用来干嘛?生产消息(好苍白的解释),代码比较简单,所以也不过多解释了(无Spring环境集成)

package com.ripple.activemq;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.ScheduledMessage;

import javax.jms.*;
import java.util.Date;

/**
 * @author RippleChan
 * @date 2017-07-30
 * @time 13:33
 * 生产者
 */
public class Producer {

    public static void main(String[] args) throws JMSException {
        /**
         * 参照activemq.xml配置
         <transportConnectors>
            <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
         </transportConnectors>
         */
        String tcpURI = "tcp://127.0.0.1:61616";
        //通过activemq.xml配置用户名和密码,如果不配置,默认全部为null即可
        /**
         <plugins>
             <simpleAuthenticationPlugin anonymousAccessAllowed="false">
             <users>
             <authenticationUser username="username" password="password" groups="users,admins"/>
             </users>
             </simpleAuthenticationPlugin>
         </plugins>
         */
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("username", "password", tcpURI);
        Connection connection = connectionFactory.createConnection();
        connection.start();
        //Boolean.FALSE不开启事务
        //Session.AUTO_ACKNOWLEDGE自动签收机制
        Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
        //队列名称
        Queue queue = session.createQueue("q1");
        MessageProducer producer = session.createProducer(queue);
        //DeliveryMode.NON_PERSISTENT不缓存消息(重启MQ服务后保存的消息全部丢失)
        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
        //TextMessage类消息
        TextMessage textMessage = session.createTextMessage();
        long time = 20 * 1000;
        /**
         * 延迟推送需要配置activemq.xml文件
         *  <broker …… schedulerSupport="true">
         *  ScheduledMessage.AMQ_SCHEDULED_DELAY延迟推送20秒
         */
        textMessage.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, time);
        textMessage.setText("发送时间"+new Date());
        producer.send(textMessage);
        System.out.println("发送消息");
        if (connection != null) {
            //关闭连接
            connection.close();
        }
    }

}

 

第四步:

           消费者,消费者,用来消费消息,真实环境,这玩意就是用来真实处理业务的。

package com.ripple.activemq;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.ScheduledMessage;

import javax.jms.*;
import java.util.Date;

/**
 * @author RippleChan
 * @date 2017-07-30
 * @time 13:33
 * 生产者
 */
public class Producer {

    public static void main(String[] args) throws JMSException {
        /**
         * 参照activemq.xml配置
         <transportConnectors>
            <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
         </transportConnectors>
         */
        String tcpURI = "tcp://127.0.0.1:61616";
        //通过activemq.xml配置用户名和密码,如果不配置,默认全部为null即可
        /**
         <plugins>
             <simpleAuthenticationPlugin anonymousAccessAllowed="false">
             <users>
             <authenticationUser username="username" password="password" groups="users,admins"/>
             </users>
             </simpleAuthenticationPlugin>
         </plugins>
         */
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("username", "password", tcpURI);
        Connection connection = connectionFactory.createConnection();
        connection.start();
        //Boolean.FALSE不开启事务
        //Session.AUTO_ACKNOWLEDGE自动签收机制
        Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
        //队列名称
        Queue queue = session.createQueue("q1");
        MessageProducer producer = session.createProducer(queue);
        //DeliveryMode.NON_PERSISTENT不缓存消息(重启MQ服务后保存的消息全部丢失)
        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
        //TextMessage类消息
        TextMessage textMessage = session.createTextMessage();
        long time = 20 * 1000;
        /**
         * 延迟推送需要配置activemq.xml文件
         *  <broker …… schedulerSupport="true">
         *  ScheduledMessage.AMQ_SCHEDULED_DELAY延迟推送20秒
         */
        textMessage.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, time);
        textMessage.setText("发送时间"+new Date());
        producer.send(textMessage);
        System.out.println("发送消息");
        if (connection != null) {
            //关闭连接
            connection.close();
        }
    }

}

 

小总结:流程一定要熟悉,P:生产者,S:ActiveMQ服务器,C:消费者,那么流程应该是这样的

P生产一条消息,发送给了S,S接受到消息后,发送给C,C签收了这条消,S把已经签收的消息删除

转载于:https://my.oschina.net/vright/blog/1492328

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值