ActiveMQ--核心

概念

特点

安全,可靠,解耦合,异步,高吞吐,低延迟

MQ常用应用场景

异步通信,缓冲,解耦,冗余,扩展性,可恢复性,顺序保证,过载保护,数据流处理

一般处理方式(不使用MQ)

MQ消息处理方式

缓冲,解耦,异步通信,扩展性,可恢复性,顺序保证,过载保护

异构系统,解耦

数据流处理(kafka),日志处理

一般的MQ连接使用基础(Queue)

发送端

package com.study;

import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;

//消息发送
public class Sender {
    public static void main(String[] args) throws Exception {
        //1. 获取连接工厂
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
                ActiveMQConnectionFactory.DEFAULT_USER,
                ActiveMQConnectionFactory.DEFAULT_PASSWORD,
                "tcp://localhost:61616"
        );
        //2. 获取一个向ActiveMQ的连接
        Connection connection = connectionFactory.createConnection();
        //3. 获取session
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //4. 找目的地,获取destination,消费端,也会从这个目的地取数据
        Queue queue = session.createQueue("user");
        //5.1 消息创建者
        MessageProducer producer = session.createProducer(queue);
        //consumer -> 消费者
        //producer -> 创建者
        //5.2 创建消息
        for (int i = 0; i < 100; i++) {
            TextMessage textMessage = session.createTextMessage("hi~" + i);
            //5.3 向目的地写入数据
            producer.send(textMessage);
            Thread.sleep(1000);
        }
        //6. 关闭连接
        connection.close();
        System.out.println("System exit ...");
    }
}

消费端

package com.study;

import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;

//消息接收
public class Receiver {
    public static void main(String[] args) throws Exception {
        //1. 获取连接工厂
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
                ActiveMQConnectionFactory.DEFAULT_USER,
                ActiveMQConnectionFactory.DEFAULT_PASSWORD,
                "tcp://localhost:61616"
        );
        //2. 获取一个向ActiveMQ的连接
        Connection connection = connectionFactory.createConnection();
        connection.start();
        //3.获取session
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //4. 找目的地,获取destination
        Queue queue = session.createQueue("user");
        //5.1 创建消费者
        MessageConsumer consumer = session.createConsumer(queue);
        while (true) {
            TextMessage message = (TextMessage) consumer.receive();
            System.out.println("message = " + message.getText());
        }
    }
}

同步

过程

监听器方式代码实现

package com.activemq;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;
import java.util.ArrayList;
import java.util.List;

public class Receiver {
    public static void main(String[] args) throws Exception {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
                ActiveMQConnectionFactory.DEFAULT_USER,
                ActiveMQConnectionFactory.DEFAULT_PASSWORD,
                "tcp://localhost:61616"
        );
        List<String> list = new ArrayList<String>();
        list.add(User.class.getPackage().getName());
        connectionFactory.setTrustedPackages(list);
        Connection connection = connectionFactory.createConnection();
        connection.start();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Queue queue = session.createQueue("user");
        MessageConsumer consumer = session.createConsumer(queue);
        consumer.setMessageListener(new MyListener());
    }
}

class MyListener implements MessageListener {
    public void onMessage(Message message) {
        if (message instanceof TextMessage) {
            TextMessage textMessage = (TextMessage) message;
            try {
                System.out.println(textMessage.getText());
            } catch (JMSException e) {
                e.printStackTrace();
            }
        } else if (message instanceof ObjectMessage) {
            ObjectMessage objectMessage = (ObjectMessage) message;
            try {
                User user = (User) objectMessage.getObject();
                System.out.println(user);
            } catch (JMSException e) {
                e.printStackTrace();
            }
        }
    }
}

确认机制

问题

选择器

分组

#发送端分组
MapMessage msg1 = session.createMapMessage();
msg1.setString("name", "qiqi");
msg1.setString("age", "18");
		
msg1.setStringProperty("name", "qiqi");
msg1.setIntProperty("age", 18);
MapMessage msg2 = session.createMapMessage();
msg2.setString("name", "lucy");
msg2.setString("age", "18");
msg2.setStringProperty("name", "lucy");
msg2.setIntProperty("age", 18);
MapMessage msg3 = session.createMapMessage();
msg3.setString("name", "qianqian");
msg3.setString("age", "17");
msg3.setStringProperty("name", "qianqian");
msg3.setIntProperty("age", 17);

#接收端分组
String selector1 = "age > 17";
String selector2 = "name = 'lucy'";
MessageConsumer consumer = session.createConsumer(queue,selector2);

独占消费者

Queue queue = session.createQueue("xxoo?consumer.exclusive=true");

还可以设置优先级

Queue queue = session.createQueue("xxoo?consumer.exclusive=true&consumer.priority=10");

同步异步

producer和broker,consumer和broker同步异步

connectionFactory.setSendAcksAsync(true);
ActiveMQConnection activeMQConnection = (ActiveMQConnection) connection;
activeMQConnection.setUseAsyncSend(true);
 开启事务关闭事务
持久化异步同步
非持久化异步异步

producer和consumer同步(QueueRequestor)

request方法源码

    public Message request(Message message) throws JMSException {
        message.setJMSReplyTo(getTemporaryQueue());
        getSender().send(message);
        return getReceiver().receive();
    }

同步消息失去性能,牺牲了大部分的性能, QueueRequestor极强的一致性

journal持久化方式

通信

textMessage.setJMSReplyTo(new ActiveMQQueue("reply"));

集成springboot使用

application.properties

server.port=8080
spring.activemq.broker-url=tcp://localhost:61616
spring.activemq.user=admin
spring.activemq.password=admin
spring.activemq.pool.enabled=true
spring.activemq.pool.max-connections=5
spring.activemq.pool.idle-timeout=0
spring.activemq.packages.trust-all=true
spring.jms.pub-sub-domain=true

ActiveMQConfig

package com.activemq.springboot.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;

import javax.jms.ConnectionFactory;

@Configuration
@EnableJms
public class ActiveMQConfig {
    //pub/sub
    @Bean
    public JmsListenerContainerFactory<?> jmsListenerContainerFactoryTopic(ConnectionFactory connectionFactory) {
        DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
        bean.setPubSubDomain(true);
        bean.setConnectionFactory(connectionFactory);
        return bean;
    }

    //queue
    @Bean
    public JmsListenerContainerFactory<?> jmsListenerContainerFactoryQueue(ConnectionFactory connectionFactory) {
        DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
        bean.setConnectionFactory(connectionFactory);
        return bean;
    }
}

SenderServer

package com.activemq.springboot.service;

import org.apache.activemq.command.ActiveMQQueue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Service;
import javax.jms.*;
import java.util.ArrayList;
import java.util.List;

@Service
public class SenderServer {
    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;
    @Autowired
    private JmsTemplate jmsTemplate;

    public void send(String destination, String msg) {
        List<String> list = new ArrayList<>();
        list.add("malaoshi");
        list.add("lian");
        list.add("zhanglaoshi");
        jmsMessagingTemplate.convertAndSend(destination, list);
    }

    public void send2(String destination, String msg) {
        ConnectionFactory connectionFactory = jmsTemplate.getConnectionFactory();
        Connection connection = null;
        try {
            connection = connectionFactory.createConnection();
            connection.start();
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        } catch (JMSException e) {
            e.printStackTrace();
        }
        jmsTemplate.send(destination, new MessageCreator() {
            @Override
            public Message createMessage(Session session) throws JMSException {
                TextMessage textMessage = session.createTextMessage("xxoo");
                textMessage.setStringProperty("hehe", "enen");
                return textMessage;
            }
        });
    }

    public void send3(String destination, String msg) {
        List<String> list = new ArrayList<>();
        list.add("malaoshi");
        list.add("lian");
        list.add("zhanglaoshi");
        jmsMessagingTemplate.convertAndSend(new ActiveMQQueue(destination), list);
    }
}

ReceiverServer

package com.activemq.springboot.service;

import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Service;

@Service
public class ReceiverServer {
    @JmsListener(destination = "springboot", containerFactory = "jmsListenerContainerFactoryTopic")
    public void receiver(String msg) {
        System.out.println("收到消息: " + msg);
    }
}

MainController

package com.activemq.springboot.controller;

import com.activemq.springboot.service.SenderServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MainController {
    @Autowired
    SenderServer senderServer;

    @RequestMapping("/send")
    public String send() {
        senderServer.send3("springboot", "hello~~");
        return "ok";
    }
}

消息之间的关联会话

多个消息一个CID,就可以产生分组了

推拉消息

异步的发消息

异步的消费消息

慢消费问题

Request/Response模型实现

1.临时队列实现

2.通过CorrelationID来实现

3.通过QueueRequestor同步阻塞来实现

高可用

通过共用数据源来实现

集群(主主模型)

消息回流

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值