Rabbitmq的基本概念
官方文档:https://www.rabbitmq.com/documentation.html
利用SpringBoot方式
pom.xml 导入starter
<?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.polenger</groupId>
<artifactId>MyRabbitMQ</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compile.source>1.8</maven.compile.source>
<maven.compile.target>1.8</maven.compile.target>
<skipTests>true</skipTests>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
<spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
<nacos.client.version>1.4.1</nacos.client.version>
<gson.version>2.8.6</gson.version>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!--Spring Cloud 相关依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--Spring Cloud Alibaba 相关依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.client.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
创建RabbitConfiguration
package com.polenger.rabbitmq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author polenger
*/
@Slf4j
@Configuration
public class RabbitConfiguration {
@Bean
public RabbitTemplate createRabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate();
rabbitTemplate.setConnectionFactory(connectionFactory);
//设置开启Mandatory,才能触发回调函数,无论消息推送结果怎么样都强制调用回调函数
rabbitTemplate.setMandatory(true);
rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
log.info("ConfirmCallback: 相关数据:{}", correlationData);
log.info("ConfirmCallback: 确认情况:{}", ack);
log.info("ConfirmCallback: 原因:{}", cause);
});
rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
log.info("ReturnCallback: 消息:{}", message);
log.info("ReturnCallback: 回应码:{}", replyCode);
log.info("ReturnCallback: 回应信息:{}", replyText);
log.info("ReturnCallback: 交换机:{}", exchange);
log.info("ReturnCallback: 路由键:{}", routingKey);
});
return rabbitTemplate;
}
@Bean
public RabbitAdmin rabbitAdmin(ConnectionFactory factory){
return new RabbitAdmin(factory);
}
}
RabbiDirectConfig类
package com.polenger.rabbitmq;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* @author polenger
*/
@Configuration
@EnableRabbit
public class RabbitDirectConfig {
private final RabbitAdmin rabbitAdmin;
public RabbitDirectConfig(RabbitAdmin rabbitAdmin) {
this.rabbitAdmin = rabbitAdmin;
}
/**
* 初始化队列
*/
private LinkedList<Queue> createQueue() {
RabbitEnum[] values = RabbitEnum.values();
LinkedList<Queue> queues = new LinkedList<>();
for (RabbitEnum value : values) {
Queue queue = new Queue(value.getQueue());
queues.add(queue);
}
return queues;
}
/**
* 创建交换机
*/
private LinkedList<DirectExchange> createDirectExchange() {
LinkedList<DirectExchange> list = new LinkedList<>();
RabbitEnum[] values = RabbitEnum.values();
for (RabbitEnum rabbitEnum : values) {
DirectExchange directExchange = new DirectExchange(rabbitEnum.getExchange(), true, false);
list.add(directExchange);
}
return list;
}
/**
* 将队列与交换机绑定
*/
@Bean
public void bindingDirectExchange() {
// 初始化队列
LinkedList<Queue> queues = createQueue();
// 初始化交换机
LinkedList<DirectExchange> exchanges = createDirectExchange();
for (int i = 0; i < queues.size(); i++) {
// 队列
Queue queue = queues.get(i);
// 交换机
DirectExchange exchange = exchanges.get(i);
// 队列与交换机进行板顶
Binding binding = BindingBuilder.bind(queue).to(exchange).with(RabbitEnum.getByQueueName(queue.getName()).getRouting());
// 声明队列
rabbitAdmin.declareQueue(queue);
// 声明交换机
rabbitAdmin.declareExchange(exchange);
// 声明绑定关系
rabbitAdmin.declareBinding(binding);
}
}
/**
* 公共使用的配置
*
* @param connectionFactory ConnectionFactory
* @return RabbitListenerContainerFactory
*/
@Bean(name = "commonListenerContainerFactory")
public RabbitListenerContainerFactory<?> commonListenerContainerFactory(ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setConcurrentConsumers(1);
return factory;
}
}
rabbitEnum
package com.polenger.rabbitmq;
import lombok.Getter;
/**
* @author polenger
* */
@Getter
public enum RabbitEnum {
/**
* 业务队列
*/
BIZ_QUEUE(RabbitQueue.CUSTOM_QUEUE, "biz_exchange", "biz_routing");
/**
* 队列名称
*/
private final String queue;
/**
* 队列绑定的交换机
*/
private final String exchange;
/**
* 队列使用匹配的key
*/
private final String routing;
RabbitEnum(String queue, String exchange, String routing) {
this.queue = queue;
this.exchange = exchange;
this.routing = routing;
}
public static RabbitEnum getByQueueName(String queueName) {
for (RabbitEnum rabbitEnum : values()) {
if (rabbitEnum.getQueue().equals(queueName)) {
return rabbitEnum;
}
}
return BIZ_QUEUE;
}
}
RabbitQueue
package com.polenger.rabbitmq;
/**
* @author polenger
*/
public final class RabbitQueue {
public final static String CUSTOM_QUEUE = "custom_queue";
}
生产者:
package com.polenger.producer;
import com.polenger.rabbitmq.RabbitEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;
/**
* @author polenger
*/
@Slf4j
@Component
public class CustomProducer {
private final RabbitTemplate rabbitTemplate;
public CustomProducer(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
}
public void produce(){
String message = "this is a message";
RabbitEnum rabbitmqenum = RabbitEnum.BIZ_QUEUE;
rabbitTemplate.convertAndSend(rabbitmqenum.getExchange(), rabbitmqenum.getRouting(), message);
}
}
消费者
package com.polenger.consumer;
import com.polenger.rabbitmq.RabbitQueue;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* @author polenger
*/
@Slf4j
@Component
@RabbitListener(queues = RabbitQueue.CUSTOM_QUEUE, containerFactory = "commonListenerContainerFactory")
public class CustomConsumer {
@RabbitHandler
public void consume(String msg, Message message) {
System.out.println("消费:" + msg);
}
}
队列测试:
package com.polenger.controller;
import com.polenger.producer.CustomProducer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
/**
*
* @author polenger
*/
@RestController
public class QueueController {
@Autowired
private CustomProducer producer;
@RequestMapping("/produce")
public ResponseEntity<?> produce(){
producer.produce();
return ResponseEntity.ok(LocalDateTime.now());
}
}
bootApplication
package com.polenger;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
*
* @author polenger
*/
@Slf4j
@SpringBootApplication
public class BootApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(BootApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
log.info("BootApplication");
}
}
使用SpringCloud Stream
定义:
Spring官方对Stream
框架的定义:事件驱动微服务、共享信息系统
Spring Cloud Stream is a framework for building highly scalable event-driven microservices connected with shared messaging systems.
The framework provides a flexible programming model built on already established and familiar Spring idioms and best practices, including support for persistent pub/sub semantics, consumer groups, and stateful partitions.
框架核心组件:
The core building blocks of Spring Cloud Stream are:
Destination Binders: Components responsible to provide integration with the external messaging systems.
Destination Bindings: Bridge between the external messaging systems and application code (producer/consumer) provided by the end user.
Message: The canonical data structure used by producers and consumers to communicate with Destination Binders (and thus other applications via external messaging systems).