SpringBoot整合RabbitMQ,附案例源碼

導讀

  由於工作上需要,客戶那指定要使用RabbitMQ,之前學過RocketMQ(點我直達1點我直達2)、ActiveMQ(點我直達1點我直達2)都沒用上。項目時間又趕,今天下午先在自己的阿里雲服務器上搭建好RabbitMQ(點我直達),然後去github,百度上找一大堆資料,發現跑不通,沒辦法,快速學習,整理一套SpringBoot整合RabbitMQ的5種模式(hello worldwork queuePublish/SubscribeRoutingTopics)。

項目結構

 

項目演示

阿里雲服務器搭建RabbitMQ

點我直達

生產者項目

項目結構

 

生產者代碼

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.ybchen</groupId>
    <artifactId>springboot-rabbitmq-producer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-rabbitmq-producer</name>
    <description>SpringBoot整合RabbitMQ-生產者</description>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <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>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.75</version>
        </dependency>
        <!--SpringBoot整合RabbitMQ-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
pom.xml
server.port=8888
spring.rabbitmq.host=xxx.xxx.xxx.xxx
spring.rabbitmq.port=5672
spring.rabbitmq.username=xxxx
spring.rabbitmq.password=xxxxx
application.properties
package com.ybchen.producer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootRabbitmqProducerApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootRabbitmqProducerApplication.class, args);
    }

}
SpringbootRabbitmqProducerApplication.java
package com.ybchen.producer.entity;

public class Clz{
    private String id;
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Clz{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}
Clz.java
package com.ybchen.producer.controller;

import com.ybchen.producer.entity.Clz;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * @Description:hello world模型
 * @Author:chenyanbin
 * @Date:2021/1/6 5:35 下午
 * @Versiion:1.0
 */
@RestController
@RequestMapping("/api/v1")
public class ProducerV1Controller {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * hello world模型
     * @param data
     * @return
     */
    @PostMapping("sendMQ")
    public String sendMQ(@RequestBody Clz data) {
        System.out.println("接收到參數:"+data);
        //第一個參數:隊列名稱
        //第二個參數:javaBean
        rabbitTemplate.convertAndSend("hello", "hello ,rabbitmq, now is :" + data);
        return "ok";
    }

}
ProducerV1Controller.java
package com.ybchen.producer.controller;

import com.ybchen.producer.entity.Clz;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Description:Work queues工作隊列
 *  假設一個生產者生產2條消息
 *  有2個消費者,此時,會通過輪詢方式,每個消費者消費一條消息
 * @Author:chenyanbin
 * @Date:2021/1/6 9:32 下午
 * @Versiion:1.0
 */
@RestController
@RequestMapping("/api/v2")
public class ProducerV2Controller {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 公平消費
     * @param data
     * @return
     */
    @PostMapping("sendMQ")
    public String sendMQ(@RequestBody Clz data) {
        System.out.println("接收到參數:"+data);
        //第一個參數:隊列名稱
        //第二個參數:javaBean
        for (int i = 0; i < 10; i++) {
            rabbitTemplate.convertAndSend("work", "work模型:" + data);
        }
        return "ok";
    }
}
ProducerV2Controller.java
package com.ybchen.producer.controller;

import com.ybchen.producer.entity.Clz;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Description:發佈訂閱模型,fanout
 * @Author:chenyanbin
 * @Date:2021/1/6 9:47 下午
 * @Versiion:1.0
 */
@RestController
@RequestMapping("/api/v3")
public class ProducerV3Controller {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 公平消費
     *
     * @param data
     * @return
     */
    @PostMapping("sendMQ")
    public String sendMQ(@RequestBody Clz data) {
        System.out.println("接收到參數:" + data);
        //第一個參數:隊列名稱
        //第二個參數:javaBean
        rabbitTemplate.convertAndSend("logs", "", "fanout模型:" + data);
        return "ok";
    }
}
ProducerV3Controller.java
package com.ybchen.producer.controller;

import com.ybchen.producer.entity.Clz;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Description:路由模型
 * @Author:chenyanbin
 * @Date:2021/1/6 9:59 下午
 * @Versiion:1.0
 */
@RestController
@RequestMapping("/api/v4")
public class ProducerV4Controller {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostMapping("sendMQ")
    public String sendMQ(@RequestBody Clz data) {
        System.out.println("接收到參數:" + data);
        //第一個參數:交換機名字
        //第二個參數:info相關的信息
        //第三個參數:javaBean
        rabbitTemplate.convertAndSend("directs", "info", "路由模型:" + data);
        return "ok";
    }

    @PostMapping("sendMQ2")
    public String sendMQ2(@RequestBody Clz data) {
        System.out.println("接收到參數:" + data);
        //第一個參數:交換機名字
        //第二個參數:info相關的信息
        //第三個參數:javaBean
        rabbitTemplate.convertAndSend("directs", "error", "路由模型:" + data);
        return "ok";
    }
}
ProducerV4Controller.java
package com.ybchen.producer.controller;

import com.ybchen.producer.entity.Clz;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Description:訂閱模式,topic
 * @Author:chenyanbin
 * @Date:2021/1/6 10:22 下午
 * @Versiion:1.0
 */
@RestController
@RequestMapping("/api/v5")
public class ProducerV5Controller {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostMapping("sendMQ")
    public String sendMQ(@RequestBody Clz data) {
        System.out.println("接收到參數:" + data);
        //第一個參數:交換機名字
        //第二個參數:info相關的信息
        //第三個參數:javaBean
        rabbitTemplate.convertAndSend("topics", "user.save", "訂閱模型:" + data);
        return "ok";
    }
    @PostMapping("sendMQ2")
    public String sendMQ2(@RequestBody Clz data) {
        System.out.println("接收到參數:" + data);
        //第一個參數:交換機名字
        //第二個參數:info相關的信息
        //第三個參數:javaBean
        rabbitTemplate.convertAndSend("topics", "order.save", "訂閱模型:" + data);
        return "ok";
    }
}
ProducerV5Controller.java

消費者項目

項目結構

 

消費者代碼

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.ybchen</groupId>
    <artifactId>springboot-rabbitmq-consumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-rabbitmq-consumer</name>
    <description>SpringBoot整合RabbitMQ-消費者</description>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <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>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.75</version>
        </dependency>
        <!--SpringBoot整合RabbitMQ-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
pom.xml
server.port=9999
spring.rabbitmq.host=xxx.xxx.xxx.xxx
spring.rabbitmq.port=5672
spring.rabbitmq.username=xxx
spring.rabbitmq.password=xxx
View Code
package com.ybchen.consumer;

import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableRabbit
public class SpringbootRabbitmqConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootRabbitmqConsumerApplication.class, args);
    }

}
SpringbootRabbitmqConsumerApplication.java
package com.ybchen.consumer.controller;

import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * @Description:hello world模型
 * @Author:chenyanbin
 * @Date:2021/1/6 6:03 下午
 * @Versiion:1.0
 */
//被spring掃描到
@Component
//@Queue:沒有的話,創建隊列
//declare:不持久化,默認:true
//autoDelete:是否自動刪除
//@Queue(value = "hello",declare = "false",autoDelete = "true")
@RabbitListener(queuesToDeclare = @Queue(value = "hello",declare = "false",autoDelete = "true"))
public class ConsumerV1 {
    //監聽mq裏的隊列,接收那個隊列裏的消息,沒有隊列的話,去聲明一個隊列

    /**
     * @RabbitHandler:從隊列中拿到消息的回調方法
     * @param message
     */
    @RabbitHandler
    public void helloWorld(String message) {
        System.out.println(message);
    }
}
ConsumerV1.java
package com.ybchen.consumer.controller;

import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * @Description:Work queues工作隊列
 * @Author:chenyanbin
 * @Date:2021/1/6 9:33 下午
 * @Versiion:1.0
 */
@Component
public class ConsumerV2 {
    //加在方法上,代表會監聽這個方法的回調
    //消費者-1
    @RabbitListener(queuesToDeclare = @Queue("work"))
    public void receive_1(String message) {
        System.out.println("work模型 receive_1====>" + message);
    }

    //加在方法上,代表會監聽這個方法的回調
    //消費者-2
    @RabbitListener(queuesToDeclare = @Queue("work"))
    public void receive_2(String message) {
        System.out.println("work模型 receive_2====>" + message);
    }
}
ConsumerV2.java
package com.ybchen.consumer.controller;

import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * @Description:發佈訂閱模型,fanout
 * @Author:chenyanbin
 * @Date:2021/1/6 9:47 下午
 * @Versiion:1.0
 */
@Component
public class ConsumerV3 {
    //加在方法上,代表會監聽這個方法的回調
    //消費者-1
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,  //創建臨時隊列
                    exchange = //交換機
                        @Exchange(
                                value = "logs",type = "fanout" //交換機名字,類型
                        )
            )
    })
    public void receive_1(String message) {
        System.out.println("發佈訂閱模型 receive_1====>" + message);
    }
    //加在方法上,代表會監聽這個方法的回調
    //消費者-1
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,  //創建臨時隊列
                    exchange = //交換機
                    @Exchange(
                            value = "logs",type = "fanout" //交換機名字,類型
                    )
            )
    })
    public void receive_2(String message) {
        System.out.println("發佈訂閱模型 receive_2====>" + message);
    }
}
ConsumerV3.java
package com.ybchen.consumer.controller;

import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * @Description:路由模型
 * @Author:chenyanbin
 * @Date:2021/1/6 10:00 下午
 * @Versiion:1.0
 */
@Component
public class ConsumerV4 {
    /**
     * 會接受info、error、warn信息
     * @param message
     */
    @RabbitListener(
            bindings = {
                    @QueueBinding(
                            value = @Queue, //創建臨時隊列
                            exchange = @Exchange(
                                    value = "directs", type = "direct" //交換機名稱和類型
                            ),
                            key = {"info", "error", "warn"} //接收路由的信心
                    )
            }
    )
    public void receive_1(String message) {
        System.out.println("路由-1:" + message);
    }

    /**
     * 只會接受error的路由信息
     * @param message
     */
    @RabbitListener(
            bindings = {
                    @QueueBinding(
                            value = @Queue, //創建臨時隊列
                            exchange = @Exchange(
                                    value = "directs", type = "direct" //交換機名稱和類型
                            ),
                            key = {"error"} //接收路由的信心
                    )
            }
    )
    public void receive_2(String message) {
        System.out.println("路由-2:" + message);
    }
}
ConsumerV4.java
package com.ybchen.consumer.controller;

import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * @Description:訂閱模式,topic
 * @Author:chenyanbin
 * @Date:2021/1/6 10:25 下午
 * @Versiion:1.0
 */
@Component
public class ConsumerV5 {

    @RabbitListener(
            bindings = @QueueBinding(
                    value = @Queue, //創建臨時隊列
                    exchange =
                    @Exchange( //交換機
                            type = "topic", name = "topics" //類型和名稱
                    ),
                    key = {"user.save", "user.*"}
            )
    )
    public void receive_1(String message) {
        System.out.println("訂閱模型 receive_1====>" + message);
    }

    @RabbitListener(
            bindings = @QueueBinding(
                    value = @Queue, //創建臨時隊列
                    exchange =
                    @Exchange( //交換機
                            type = "topic", name = "topics" //類型和名稱
                    ),
                    key = {"order.#", "produce.#","user.*"} //可以使用正則方式
            )
    )
    public void receive_2(String message) {
        System.out.println("訂閱模型 receive_2====>" + message);
    }
}
ConsumerV5.java

案例源碼下載

鏈接: https://pan.baidu.com/s/1SnutjcAJlQG9Io1Z_F9kJA  密碼: itn4

尾聲

  滿打滿算RabbitMQ算是告一段落,今天只是停留在會簡單的使用,具體配置項還不是很瞭解,各種調優啥的,未來還是要在認真的系統學習一遍滴,今天先到這,洗洗睡啦,ヾ(ToT)Bye~Bye~

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章