java activeMQ的应用

参考文章:rabbitMq和activeMQ的区别
JMS使用ActiveMQ实现Queue和Topic两种模式

概念

JMS,即java message service,java消息服务,是J2EE规范的一部分,跟jdbc差不多,sun只提供了接口,由各个厂商(provider)来进行具体的实现,然后使用者使用他们的jar包进行开发使用即可。

传递方式

  • Queue,点对点
    消息发送和接收是一对一的,发布者发布消息后,每个接收者会按次序接收一次消息,但不会重复接。例如发布了十条消息,有两个接受者,会一起接收10条信息,取决于哪个接收者在前,但是两者不会重复接收消息;
    不管发送者什么时候启动,接收者都会接收到发送者以前或者当前的消息,从队列里面获取
  • Topic,发布订阅订阅
    消息发送和接收是一对多的,发布者发送十条信息,每个接收者都会接收到10条信息,不会按次序接收。但是如果先运行发送者,再运行接收者,接收者可能接收的信息是不全的或者没有,相当于接收者只接收发送者开启后发送的消息。

发送工具

  • ActiveMQ消息中间件

下载activeMQ,然后再本机安装,并且启动activeMQ的服务才行。在官网下载完成之后,运行bin目录下面的activemq.bat,64位系统启动64文件夹下的,将activeMQ成功启动。启动成功之后可以运行:http://localhost:8161/admin/index.jsp 查看一下。
这里写图片描述
编写代码测试

第一种:Queue模式点对点

生产者

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.ActiveMQConnection;  
import org.apache.activemq.ActiveMQConnectionFactory;  

public class Sender {  

    public static void main(String[] args) throws JMSException, InterruptedException {  
        // ConnectionFactory :连接工厂,JMS 用它创建连接  
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(  
                                                  ActiveMQConnection.DEFAULT_USER,  
                                                  ActiveMQConnection.DEFAULT_PASSWORD,  
                                                  "tcp://localhost:61616");  

        // Connection :JMS 客户端到JMS Provider 的连接  
        Connection connection =  connectionFactory.createConnection();  

        connection.start();  
        // Session: 一个发送或接收消息的线程  
        Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);  

        // Destination :消息的目的地;消息发送给谁.  
        Destination destination =  session.createQueue("my-queue");  

        // MessageProducer:消息发送者  
        MessageProducer producer =  session.createProducer(destination);  

        // 设置不持久化,可以更改  
        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);  
        for(int i=0;i<10;i++){  
            //创建文本消息  
            TextMessage message = session.createTextMessage("hello everyone, this is a test message"+i);  
            Thread.sleep(1000);  
            //发送消息  
            producer.send(message);  
        }  
        session.commit();  
        session.close();  
        connection.close();  
    }  
}  

运行之后控制台输出:

hello everyone, this is a test message0
hello everyone, this is a test message1
hello everyone, this is a test message2
hello everyone, this is a test message3
hello everyone, this is a test message4
hello everyone, this is a test message5
hello everyone, this is a test message6
hello everyone, this is a test message7
hello everyone, this is a test message8
hello everyone, this is a test message9

消费者

public class Receiver {  
    // ConnectionFactory :连接工厂,JMS 用它创建连接  
   private static ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,  
           ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");  

   public static void main(String[] args) throws JMSException {  
        // Connection :JMS 客户端到JMS Provider 的连接  
        final Connection connection =  connectionFactory.createConnection();  

        connection.start();  
        // Session: 一个发送或接收消息的线程  
        final Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);  
        // Destination :消息的目的地;消息送谁那获取.  
        Destination destination =  session.createQueue("my-queue");  
        // 消费者,消息接收者  
        MessageConsumer consumer1 =  session.createConsumer(destination);  

        consumer1.setMessageListener(new MessageListener() {  
                @Override  
                public void onMessage(Message msg) {  
                    try {  
                        TextMessage message = (TextMessage)msg ;  
                        System.out.println("consumer1收到消息: "+message.getText());  
                        session.commit();  
                    } catch (JMSException e) {                
                        e.printStackTrace();  
                    }  

                }  
            });  

        // 再来一个消费者,消息接收者  
        MessageConsumer consumer2 =  session.createConsumer(destination);  

        consumer2.setMessageListener(new MessageListener() {  
                @Override  
                public void onMessage(Message msg) {  
                    try {   
                        TextMessage message = (TextMessage)msg ;  
                        System.out.println("consumer2收到消息: "+message.getText());  
                        session.commit();  
                    } catch (JMSException e) {                
                        e.printStackTrace();  
                    }     
                }  
            });  
}  
}  

运行之后控制台不会退出一直监听消息库,对于消息发送者的十条信息,控制输出:

consumer1收到消息: hello everyone, this is a test message0
consumer2收到消息: hello everyone, this is a test message1
consumer1收到消息: hello everyone, this is a test message2
consumer2收到消息: hello everyone, this is a test message3
consumer1收到消息: hello everyone, this is a test message4
consumer2收到消息: hello everyone, this is a test message5
consumer1收到消息: hello everyone, this is a test message6
consumer2收到消息: hello everyone, this is a test message7
consumer1收到消息: hello everyone, this is a test message8
consumer2收到消息: hello everyone, this is a test message9

第二种:Topic模式发布订阅

发布者

package com.cad.ssm_web.util.mq;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQMapMessage;

import javax.jms.*;
import java.util.Hashtable;
import java.util.Map;

/**
 * Created by murongbin on 2018/1/27.
 */
public class Publisher  {
        protected int MAX_DELTA_PERCENT = 1;
        protected Map<String, Double> LAST_PRICES = new Hashtable<String, Double>();
        protected static int count = 1;
        protected static int total;

        protected static String brokerURL = "tcp://localhost:61616";
        protected static transient ConnectionFactory factory;
        protected transient Connection connection;
        protected transient Session session;
        protected transient Destination destination;
        protected transient MessageProducer producer;

        public Publisher() throws JMSException {
            factory = new ActiveMQConnectionFactory(brokerURL);  //创建连接工场
            connection = factory.createConnection();   //创建连接
            try {
                connection.start();   //打开连接
            } catch (JMSException jmse) {
                connection.close();
                throw jmse;
            }
            //创建session 不带事务
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            //创建topic
            destination = session.createTopic("STOCKS.topic");
            //创建publisher
            producer = session.createProducer(destination);
        }

        public void close() throws JMSException {
            if (connection != null) {
                connection.close();
            }
        }

        public static void main(String[] args) throws JMSException {
            Publisher publisher = new Publisher();
            while (total < 50) {
                for (int i = 0; i < count; i++) {
                    publisher.sendMessage();
                }
                total += count;
                System.out.println("Published '" + count + "' of '" + total + "' price messages");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException x) {
                }
            }
            publisher.close();
        }

        protected void sendMessage() throws JMSException {
            Message message = createStockMessage(session);
            System.out.println("Sending: " + ((ActiveMQMapMessage)message).getContentMap() + " on destination: " + destination);
            producer.send(destination, message);
        }

        protected Message createStockMessage(Session session) throws JMSException {
            Double value = LAST_PRICES.get("topic");
            if (value == null) {
                value = new Double(Math.random() * 100);
            }

            double oldPrice = value.doubleValue();
            //value = new Double(mutatePrice(oldPrice));
            value = new Double(oldPrice+1);
            LAST_PRICES.put("topic", value);
            double price = value.doubleValue();
            double offer = price * 1.001;
            boolean up = (price > oldPrice);

            MapMessage message = session.createMapMessage();
            message.setString("topic", "topic");
            message.setDouble("price", price);
            message.setDouble("offer", offer);
            message.setBoolean("up", up);
            return message;
        }
}

输出启动后,输出结果为

Sending: {offer=51.207413478968554, price=51.15625722174681, topic=topic, up=true} on destination: topic://STOCKS.topic
Published '1' of '1' price messages
Sending: {offer=52.20841347896855, price=52.15625722174681, topic=topic, up=true} on destination: topic://STOCKS.topic
Published '1' of '2' price messages
Sending: {offer=53.20941347896856, price=53.15625722174681, topic=topic, up=true} on destination: topic://STOCKS.topic
Published '1' of '3' price messages
Sending: {offer=54.210413478968555, price=54.15625722174681, topic=topic, up=true} on destination: topic://STOCKS.topic
Published '1' of '4' price messages
Sending: {offer=55.21141347896855, price=55.15625722174681, topic=topic, up=true} on destination: topic://STOCKS.topic
Published '1' of '5' price messages
Sending: {offer=56.21241347896856, price=56.15625722174681, topic=topic, up=true} on destination: topic://STOCKS.topic
Published '1' of '6' price messages
Sending: {offer=57.213413478968555, price=57.15625722174681, topic=topic, up=true} on destination: topic://STOCKS.topic
Published '1' of '7' price messages
Sending: {offer=58.21441347896855, price=58.15625722174681, topic=topic, up=true} on destination: topic://STOCKS.topic
Published '1' of '8' price messages
Sending: {offer=59.21541347896855, price=59.15625722174681, topic=topic, up=true} on destination: topic://STOCKS.topic
Published '1' of '9' price messages
Sending: {offer=60.216413478968555, price=60.15625722174681, topic=topic, up=true} on destination: topic://STOCKS.topic
Published '1' of '10' price messages
Sending: {offer=61.21741347896855, price=61.15625722174681, topic=topic, up=true} on destination: topic://STOCKS.topic
Published '1' of '11' price messages

订阅者

package com.cad.ssm_web.util.mq;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;
import java.text.DecimalFormat;

/**
 * Created by murongbin on 2018/1/27.
 */
public class Subscriber {
    private static String brokerURL = "tcp://localhost:61616";
    private static transient ConnectionFactory factory;
    private transient Connection connection;
    private transient Session session;
    private transient Destination destination;
    private transient MessageConsumer messageConsumer;

    public Subscriber() throws JMSException {
        factory = new ActiveMQConnectionFactory(brokerURL);
        connection = factory.createConnection();
        connection.start();
        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        destination = session.createTopic("STOCKS.topic" );
        messageConsumer = session.createConsumer(destination);

    }

    public MessageConsumer getMessageConsumer() {
        return messageConsumer;
    }


    public void close() throws JMSException {
        if (connection != null) {
            connection.close();
        }
    }

    public static void main(String[] args) throws JMSException {
    //这里定义了两个订阅者
        Subscriber consumer1 = new Subscriber();
        consumer1.messageConsumer.setMessageListener(new Listener());

        /*Subscriber consumer2 = new Subscriber();
        consumer2.messageConsumer.setMessageListener(new Listener());*/


        Subscriber consumer3 = new Subscriber();
        consumer3.messageConsumer.setMessageListener(new Listener());
    }


    private static class Listener implements MessageListener {

        @Override
        public void onMessage(Message message) {
            try {
                MapMessage map = (MapMessage)message;
                String topic = map.getString("topic");
                double price = map.getDouble("price");
                double offer = map.getDouble("offer");
                boolean up = map.getBoolean("up");
                DecimalFormat df = new DecimalFormat( "#,###,###,##0.00" );
                System.out.println(topic + "\t" + df.format(price) + "\t" + df.format(offer) + "\t" + (up?"up":"down"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

启动后监听到以下信息,两个订阅者都会收到信息,当然如果先启动发布者,后启动订阅者,那就不一定了

topic   86.16   86.24   up
topic   86.16   86.24   up
topic   87.16   87.24   up
topic   87.16   87.24   up
topic   88.16   88.24   up
topic   88.16   88.24   up
topic   89.16   89.25   up
topic   89.16   89.25   up
topic   90.16   90.25   up
topic   90.16   90.25   up
topic   91.16   91.25   up
topic   91.16   91.25   up
topic   92.16   92.25   up
topic   92.16   92.25   up
topic   93.16   93.25   up
topic   93.16   93.25   up
topic   94.16   94.25   up
topic   94.16   94.25   up
  • kafa消息中间件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值