activemq消息中间件(解耦、削峰、异步)原始无框架queue/topic代码编写(单机+集群+jdbc with journal持久化)

  1. jdbc持久化配置及使用journal的方式见activemq,配置完成后便可以实现jdbc数据库持久化.
  2. zookeeper+activemq集群配置
  3. 需要导入的jar包
<!--        activemq所需jar包配置-->
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-all</artifactId>
            <version>5.15.9</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xbean</groupId>
            <artifactId>xbean-spring</artifactId>
            <version>3.16</version>
        </dependency>
  1. 使用queue消息生产者编码
package com.atguigu.activemq.queue;
import lombok.extern.log4j.Log4j;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;

@Log4j
public class JmsProduce {
    
    
//    单机
//    private static final String ACTIVEMQ_URL = "tcp://localhost:61616";
//    private static final String QUEUE_NAME = "queue01";

//    集群
//    failover:失败转移协议,当某一个activemq节点挂掉时转移到另一个,如果仅剩一个activemq节点,由于不能选举master,所以activemq不能正常运行.
    private static final String ACTIVEMQ_URL = "failover:(tcp://192.168.145.3:61616,tcp://192.168.145.3:61617,tcp://192.168.145.3:61618)?randomize=false";
    private static final String QUEUE_NAME = "queue-cluster";
    public static void main(String[] args) throws JMSException {
    
    
        // 1。创建连接工厂,按照给定的url地址,采用默认用户名和密码
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        // 2。通过连接工厂,获得连接connection并启动访问
        Connection connection = activeMQConnectionFactory.createConnection();
        connection.start();
        // 3。创建会话
        // 两个参数,第一个叫事务,第二个叫签收
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        // 4。创建目的地(队列或主题)
        Queue queue = session.createQueue(QUEUE_NAME);
        // 5。创建消息生产者
        MessageProducer messageProducer = session.createProducer(queue);
        // 6。通过使用messageProducer生产3条消息发送到MQ的队列中
        for(int i = 1; i <= 3; i++){
    
    
            // 7。 创建消息
            TextMessage textMessage = session.createTextMessage("cluster msg---" + i);  //理解为字符串
            // 8。通过messageProducer发送给mq
            messageProducer.send(textMessage);
        }
        // 9。关闭资源
        messageProducer.close();
        session.close();
        connection.close();
        log.info("******消息发送到MQ完成");
    }
}
  1. 使用queue消息消费者编码
package com.atguigu.activemq.queue;
import lombok.extern.slf4j.Slf4j;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
import java.io.IOException;

@Slf4j
public class JmsConsumer {
    
    
//    单机
//    private static final String ACTIVEMQ_URL = "tcp://localhost:61616";
//    private static final String QUEUE_NAME = "queue01";

//    集群
//    failover:失败转移协议,当某一个activemq节点挂掉时转移到另一个,如果仅剩一个activemq节点,由于不能选举master,所以activemq不能正常运行.
//    默认情况下,failover机制从URI列表中随机选择出一个URI进行连接,这可以有效地控制客户端在多个broker上的负载均衡,
//    但是,要使客户端首先连接到主节点,并在主节点不可用时只连接到辅助备份代理,需要设置randomize = false。
    private static final String ACTIVEMQ_URL = "failover:(tcp://192.168.145.3:61616,tcp://192.168.145.3:61617,tcp://192.168.145.3:61618)?randomize=false";
    private static final String QUEUE_NAME = "queue-cluster";

    public static void main(String[] args) throws JMSException, IOException {
    
    
        //1. 创建连接工厂
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        //2. 创建连接
        Connection connection = activeMQConnectionFactory.createConnection();
        connection.start();
        //3. 创建会话
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //4. 创建目的地
        Queue queue = session.createQueue(QUEUE_NAME);
        //5. 创建消费者
        MessageConsumer messageConsumer = session.createConsumer(queue);

//        消费方法1:同步堵塞方法(receive),订阅者或接受者调用MessageConsumer的receive()方法来接收消息,receive方法在能够接收消息(或超时)之前一直堵塞
//        while(true){
    
    
//            TextMessage textMessage = (TextMessage)messageConsumer.receive(10000L); // receive参数为空会一直等,可以指定最长等待时间
//            if(textMessage != null){
    
    
//                log.info("******消费者接收消息:" + textMessage.getText());
//            }else{
    
    
//                break;
//            }
//        }

//        消费方法2:通过监听的方法来消费消息
//        异步非堵塞方法(监听器onMessage),订阅者或接受者通过MessageConsumer的setMessageListener(MessageListener listener)注册一个消息监听器,
//        当消息到达后,系统自动调用监听器MessageListener的onMessage方法
        messageConsumer.setMessageListener(new MessageListener() {
    
    
            @Override
            public void onMessage(Message message) {
    
    
                if(message instanceof TextMessage){
    
    
                    TextMessage textMessage = (TextMessage)message;
                    try {
    
    
                        log.info(textMessage.getText());
                    } catch (JMSException e) {
    
    
                        e.printStackTrace();
                    }
                }
            }
        });
        // 从控制台一个字符一个字符的读取,为了保证控制台不灭,否则即使队列中有消息,也输出为空(太快直接给关了)
        System.in.read();
        //6. 关闭资源
        messageConsumer.close();
        session.close();
        connection.close();
    }
}
  1. 使用topic消息生产者编码(单机/集群+非持久化)
package com.atguigu.activemq.topic;
import lombok.extern.slf4j.Slf4j;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;

@Slf4j
public class JmsProducer_topic {
    
    
//    private static final String ACTIVEMQ_URL = "tcp://localhost:61616";
//    private static final String TOPIC_NAME = "topic";
    private static final String ACTIVEMQ_URL = "failover:(tcp://192.168.145.3:61616,tcp://192.168.145.3:61617,tcp://192.168.145.3:61618)?randomize=false";
    private static final String TOPIC_NAME = "topic-cluster";
    public static void main(String[] args) throws JMSException {
    
    
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        Connection connection = activeMQConnectionFactory.createConnection();
        connection.start();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Topic topic = session.createTopic(TOPIC_NAME);
        MessageProducer messageProducer = session.createProducer(topic);
        for(int i=1; i <= 6; i++){
    
    
            TextMessage textMessage = session.createTextMessage("TOPIC MESSAGE---" + i);
            messageProducer.send(textMessage);
        }
        messageProducer.close();
        session.close();
        connection.close();
        log.info("******topic_name消息发布到mq完成");
    }
}
  1. 使用topic消息消费者编码(单机/集群+非持久化)
package com.atguigu.activemq.topic;
import lombok.extern.slf4j.Slf4j;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
import java.io.IOException;

@Slf4j
public class JmsConsumer_topic {
    
    
//    private static final String ACTIVEMQ_URL = "tcp://localhost:61616";
//    private static final String TOPIC_NAME = "topic";
    private static final String ACTIVEMQ_URL = "failover:(tcp://192.168.145.3:61616,tcp://192.168.145.3:61617,tcp://192.168.145.3:61618)?randomize=false";
    private static final String TOPIC_NAME = "topic-cluster";
    public static void main(String[] args) throws JMSException, IOException {
    
    
        log.info("3号消费者");
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        Connection connection = activeMQConnectionFactory.createConnection();
        connection.start();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Topic topic = session.createTopic(TOPIC_NAME);
        MessageConsumer consumer = session.createConsumer(topic);
        consumer.setMessageListener(new MessageListener() {
    
    
            @Override
            public void onMessage(Message message) {
    
    
                if(message instanceof TextMessage){
    
    
                    TextMessage textMessage = (TextMessage)message;
                    try {
    
    
                        log.info("*******消费者接收到消息:" + textMessage.getText());
                    } catch (JMSException e) {
    
    
                        e.printStackTrace();
                    }
                }
            }
        });
        System.in.read();
        consumer.close();
        session.close();
        connection.close();
    }
}

在这里插入图片描述

  1. 使用topic消息生产者编码(单机/集群+持久化)
package com.atguigu.activemq.topic;
import lombok.extern.slf4j.Slf4j;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;

@Slf4j
public class JmsProducer_topic_persist {
    
    
//    private static final String ACTIVEMQ_URL = "tcp://localhost:61616";
//    private static final String TOPIC_NAME = "topic-persist";
    private static final String ACTIVEMQ_URL = "failover:(tcp://192.168.145.3:61616,tcp://192.168.145.3:61617,tcp://192.168.145.3:61618)?randomize=false";
    private static final String TOPIC_NAME = "topic-cluster";
    public static void main(String[] args) throws JMSException {
    
    
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        Connection connection = activeMQConnectionFactory.createConnection();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Topic topic = session.createTopic(TOPIC_NAME);
        MessageProducer messageProducer = session.createProducer(topic);
        messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT);
        // 由于持久化,该行位置换了
        connection.start();
        for(int i=1; i <= 6; i++){
    
    
            TextMessage textMessage = session.createTextMessage("TOPIC MESSAGE---" + i);
            messageProducer.send(textMessage);
        }
        messageProducer.close();
        session.close();
        connection.close();
        log.info("******topic_name消息发布到mq完成");
    }
}
  1. 使用topic消息消费者编码(单机/集群+持久化)
package com.atguigu.activemq.topic;
import lombok.extern.slf4j.Slf4j;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
import java.io.IOException;

@Slf4j
public class JmsConsumer_topic_persist {
    
    
//    private static final String ACTIVEMQ_URL = "tcp://localhost:61616";
//    private static final String TOPIC_NAME = "topic-persist";
    private static final String ACTIVEMQ_URL = "failover:(tcp://192.168.145.3:61616,tcp://192.168.145.3:61617,tcp://192.168.145.3:61618)?randomize=false";
    private static final String TOPIC_NAME = "topic-cluster";
    public static void main(String[] args) throws JMSException, IOException {
    
    
        log.info("******持久化z3");
        //1. 创建连接工厂
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        //2. 创建连接
        Connection connection = activeMQConnectionFactory.createConnection();
        connection.setClientID("z3");
        //3. 创建会话
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //4. 创建目的地
        Topic topic = session.createTopic(TOPIC_NAME);
        TopicSubscriber topicSubscriber = session.createDurableSubscriber(topic, "remark...");
        connection.start();
        Message message = topicSubscriber.receive();
        while(message != null){
    
    
            TextMessage textMessage = (TextMessage)message;
            log.info("******收到的持久化topic: " + textMessage.getText());
            message = topicSubscriber.receive(5000L);
        }
        session.close();
        connection.close();
    }
}
  1. 使用topic持久化,一定要先运行一次消费者,相当于订阅,然后再运行生产者发送消息,这时不论消费者是否在线都会接收到,不在线的话,下次连接的时候会把没有收到的消息都接收下来.

猜你喜欢

转载自blog.csdn.net/qq_26496077/article/details/112152512