ActiveMQ_001

一.简介


1.什么是消息队列

    activeMQ是基于java的JMS应用程序接口实现的消息队列

2.什么时候用消息队列

    1) 异步处理场景 : 邮件服务,订阅服务

    2) 高并发场景 : 短时间内大量访问,服务器无法及时处理,

                            可以将一些处理放到队列中,后续处理

    3) 应用间解耦 : 生产者端和消费者端可以实现解耦,

                            不管一端有没有问题,另一端还可以正常工作.

3.ActiveMQ的特性:(前提:由于ActiveMQ是一个网络服务)

    1)多语言:支持多种语言:Java,C,C++,C#,Python,PHP

    2)跨平台:支持绝大多数JavaEE服务器

    3)多项目:可以多个项目同时连接

4.ActiveMQ的代码流程

    1)获取JMS ConnectionFactory.通过提供特定环境的链接信息构造工厂

    2)通过factory构造JMS Connection并启动

    3)通过Connection创建JMS Session

    4)指定JMS destination

    5)创建JMS producer或者创建JMS Message并提供destination

    6)创建JMS consumer或者注册JMS Message listener

    7)发送和接收JMS Message

    8)关闭所有JMS资源

 

2.前期准备步骤:

    1.下载ActiveMQ到local文件夹,并拷贝到/usr/local/activemq

    2.控制台 cd /usr/local/activemq/bin

       运行./activemq start

    3.在浏览器输入http://127.0.0.1:8161/

        点击左边连接第一个链接

        密码,用户名都是admin

    4.导入依赖        

    <dependency>

      <groupId>org.apache.activemq</groupId>

      <artifactId>activemq-all</artifactId>

      <version>5.15.0</version>

    </dependency>

 

 

二.编写步骤


1.建立一个activemq包,创建两个类,Producer和Consumer

  • Producer : 消息生产者


public class Producer {

//全局变量   

    //1.ActiveMQ默认的用户名,密码,URL

    private static String USERNAME =ActiveMQConnection.DEFAULT_USER;

    private static String PASSWORD =ActiveMQConnection.DEFAULT_PASSWORD;

    private static String BROKER_URL =ActiveMQConnection.DEFAULT_BROKER_URL;

    //2.连接工厂

    ConnectionFactory connectionFactory = null;

    //3.连接对象

    Connection connection = null;

    //4.会话

    Session session = null;

    //5.针对线程的容器

    //目的:同一个变量复制给多个线程使用,使他们都有自己的局部变量

    ThreadLocal<MessageProducer> threadLocal =

            new ThreadLocal<MessageProducer>();

    //6.线程安全的integer(一个线程操作完,才轮到另一个线程)

    AtomicInteger count =new AtomicInteger(0);



//初始化

    public void init(){

        try {

            //1.通过连接信息创建连接工厂

            connectionFactory = 

                    new ActiveMQConnectionFactory(USERNAME,PASSWORD,BROKER_URL);

            //2.通过连接工厂创建一个连接对象

            connection = connectionFactory.createConnection();

            //3.开启连接

            connection.start();

            //4.设置回话

            //当第一个参数填true,后面一般都使用SESSION_TRANSACTED

            //当第一个参数填false,后面有两种选择:

            //          1.AUTO_ACKNOWLEDGE:自动签收

            //          2.CLIENT_ACKNOWLEDGE:客户端代码签收

            session = connection.createSession(true,Session.SESSION_TRANSACTED);

        } catch (JMSException e) {

            e.printStackTrace();

        }

    }



//发送方法   

    public void sendMessage(String queueName){

        try {

            //1.创建一个队列

            Queue queue = session.createQueue(queueName);

            //2.消息生产者

            MessageProducer messageProducer = null;

            //3.判断线程容器是否包含变量

            if (threadLocal.get() !=null){

                messageProducer = threadLocal.get();

            }else {

                //如果threadLocal取值为空

                //就使用session创建一个消息生产者

                messageProducer = session.createProducer(queue);

                threadLocal.set(messageProducer);

            }

            //4.利用死循环不间断的发送消息(必须可控:1.不能太快 2.得有出口)

            while (true){

                //设置发送频率,每秒发送一个请求

                Thread.sleep(1000);

                //计数

                int num = count.getAndIncrement();

                //创建消息

                TextMessage msg = session.createTextMessage(Thread.currentThread().getName()+"producer:生产消息!!!,count:"+num);               

                System.out.println(Thread.currentThread().getName()+"producer:生产消息!!!,count:"+num);

                //发送消息

                messageProducer.send(msg);

                //提交事务

                session.commit();

            }           

        } catch (JMSException e) {

            e.printStackTrace();

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

    }

}

 

  • Consumer : 消息的消费者

注 : 除了接收请求有一些区别,其他地方和Producer完全一样


public class Consumer {

    private static String USERNAME = ActiveMQConnection.DEFAULT_USER;

    private static String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;

    private static String BROKER_URL = ActiveMQConnection.DEFAULT_BROKER_URL;

    ConnectionFactory connectionFactory = null;

    Connection connection = null;

    Session session = null;

    ThreadLocal<MessageConsumer> threadLocal =

                                                            new ThreadLocal<MessageConsumer>();

    AtomicInteger count =new AtomicInteger(0);



    public void init(){

        try {

            connectionFactory = 

                    new ActiveMQConnectionFactory(USERNAME,PASSWORD,BROKER_URL);

            connection = connectionFactory.createConnection();

            connection.start();

            session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);

        } catch (JMSException e) {

            e.printStackTrace();

        }

    }

    //接受消息的方法

    public void getMessage(String queueName){

        try {

            Queue queue = session.createQueue(queueName);

            MessageConsumer messageConsumer = null;

            if(threadLocal.get()!=null){

                messageConsumer = threadLocal.get();

            }else {

                messageConsumer = session.createConsumer(queue);

                threadLocal.set(messageConsumer);

            }

            //接受请求

            while (true){

                //每秒处理一个请求,可以和发送端不同

                Thread.sleep(1000);

                //接受消息

                TextMessage msg =

                        (TextMessage) messageConsumer.receive();

                if (msg!=null){

                    System.out.println("接受到消息:"+msg.getText());

                    //确认消息,告诉中间件消息处理完毕

                    msg.acknowledge();

                }else {

                    //如果msg是空值,说明没有消息可以处理,跳出循环

                    break;

                }

            }

        } catch (JMSException e) {

            e.printStackTrace();

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

    }

}

 

2.编写线程ProducerThread和ConsumerThread

    1)实现Runnable接口

     2)复写run( )方法

     3)添加构造方法和对应的类对象

     4)在run中调用发送和接受方法

public class ProducerThread implements Runnable {



    private Producer producer;



    public ProducerThread(Producer producer) {

        this.producer = producer;

    }



    public void run() {

        producer.sendMessage("0602");

    }

}

public class ConsumerThread implements Runnable {

    private Consumer consumer;



    public ConsumerThread(Consumer consumer) {

        this.consumer = consumer;

    }



    public void run() {

        consumer.getMessage("0602");

    }

}

3.编写测试类

public class ProducerTest {

    public static void main(String[] args) {

        Producer producer = new Producer();

        producer.init();

        new Thread(new ProducerThread(producer)).start();

    }

}

    

public class ConsumerTest {

    public static void main(String[] args) {

        Consumer consumer = new Consumer();

        consumer.init();

        new Thread(new ConsumerThread(consumer)).start();

        new Thread(new ConsumerThread(consumer)).start();

        new Thread(new ConsumerThread(consumer)).start();

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值