1. 程式人生 > >(十三)springboot實戰rabbitmq --- direct模式

(十三)springboot實戰rabbitmq --- direct模式

上篇文章介紹了rabbitmq的原理實現,如果不知道rabbitmq的原理實現的童鞋推薦先看下上篇文章在繼續這章的實踐。 windows本地安裝rabbitmq介紹

springboot整合rabbitmq實戰 ------ direct模式

首先建立兩個springboot專案

一 生產者專案結構

在這裡插入圖片描述

消費者專案結構

在這裡插入圖片描述

1 pom檔案新增spring-boot-starter-amqp支援

		 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

2 配置檔案配置rabbitmq

spring.application.name=spirng-boot-rabbitmq

spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

這裡的使用者名稱密碼預設guest,spring.application.name如果生產者和消費者不是同一個專案不能相同(坑1)

3 配置佇列

package com.rabbit.produce.config;

import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitConfig {
 
    @Bean
    public Queue queue() {
        return new Queue("hello");
    }
 
}

4 建立傳送者

package com.rabbit.produce.controller;

import com.rabbit.produce.entrty.User;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import java.util.Date;

@Controller
public class HelloSender {
 
    @Autowired
    private AmqpTemplate rabbitTemplate;
 
    public void send() {
        String context = "sender object " + new Date();
        this.rabbitTemplate.convertAndSend("hello", context);
    }
 
}

5 建立接受者(在當前專案建立一個,在消費者專案中同樣建立一個接受者,pom,application同上)

當前專案

package com.rabbit.produce.controller;

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

@Component
@RabbitListener(queues = "hello")
public class HelloReceiver {
 
    @RabbitHandler
    public void process(String hello) {
        System.out.println("Receiver1  : " + hello);
    }
}

消費者專案

package com.rabbit.product.controller;

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

@Component
@RabbitListener(queues = "hello")
public class HelloReceiver {
 
    @RabbitHandler
    public void process(String hello) {
        System.out.println("Receiver2  : " + hello);
    }
 
}

測試結果

生產者專案列印

Receiver1  : sender object Tue Sep 25 15:55:54 CST 2018
Receiver1  : sender object Tue Sep 25 15:55:54 CST 2018
Receiver1  : sender object Tue Sep 25 15:55:54 CST 2018
Receiver1  : sender object Tue Sep 25 15:55:54 CST 2018
Receiver1  : sender object Tue Sep 25 15:55:54 CST 2018

消費者專案列印

Receiver2  : sender object Tue Sep 25 15:55:54 CST 2018
Receiver2  : sender object Tue Sep 25 15:55:54 CST 2018
Receiver2  : sender object Tue Sep 25 15:55:54 CST 2018
Receiver2  : sender object Tue Sep 25 15:55:54 CST 2018
Receiver2  : sender object Tue Sep 25 15:55:54 CST 2018

注意事項

注意,傳送者和接收者的queue name必須一致,不然不能接收
一個傳送者,N個接受者,經過測試會均勻的將訊息傳送到N個接收者中

多對多傳送

複製傳送者

package com.rabbit.produce.controller;

import com.rabbit.produce.entrty.User;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import java.util.Date;

@Controller
public class HelloSender2 {
 
    @Autowired
    private AmqpTemplate rabbitTemplate;

    public void send() {
        String context = "sender object2 " + new Date();
        this.rabbitTemplate.convertAndSend("hello", context);
    }
 
}

測試

package com.rabbit.produce;

import com.rabbit.produce.controller.HelloSender;
import com.rabbit.produce.controller.HelloSender2;
import com.rabbit.produce.entrty.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class BootRabbitmqProduceApplicationTests {

    @Autowired
    private HelloSender helloSender;
    @Autowired
    private HelloSender2 helloSender2;

    @Test
    public void hello() throws Exception {
        for (int i = 0; i < 10; i++) {
            helloSender.send();
            helloSender2.send();
        }
    }

}

測試結果

生產者專案測試結果

Receiver1  : sender object2 Tue Sep 25 16:03:09 CST 2018
Receiver1  : sender object2 Tue Sep 25 16:03:09 CST 2018
Receiver1  : sender object2 Tue Sep 25 16:03:09 CST 2018
Receiver1  : sender object2 Tue Sep 25 16:03:09 CST 2018
Receiver1  : sender object2 Tue Sep 25 16:03:09 CST 2018
Receiver1  : sender object2 Tue Sep 25 16:03:09 CST 2018
Receiver1  : sender object2 Tue Sep 25 16:03:09 CST 2018
Receiver1  : sender object2 Tue Sep 25 16:03:09 CST 2018
Receiver1  : sender object2 Tue Sep 25 16:03:09 CST 2018
Receiver1  : sender object2 Tue Sep 25 16:03:09 CST 2018

消費者專案測試結果

Receiver2  : sender object Tue Sep 25 16:03:09 CST 2018
Receiver2  : sender object Tue Sep 25 16:03:09 CST 2018
Receiver2  : sender object Tue Sep 25 16:03:09 CST 2018
Receiver2  : sender object Tue Sep 25 16:03:09 CST 2018
Receiver2  : sender object Tue Sep 25 16:03:09 CST 2018
Receiver2  : sender object Tue Sep 25 16:03:09 CST 2018
Receiver2  : sender object Tue Sep 25 16:03:09 CST 2018
Receiver2  : sender object Tue Sep 25 16:03:09 CST 2018
Receiver2  : sender object Tue Sep 25 16:03:09 CST 2018
Receiver2  : sender object Tue Sep 25 16:03:09 CST 2018

有童鞋可能會問生產者專案列印的都是sender object2啊?嗯你說的沒錯但是看下列印數量10個,在看下消費者列印結果也是10個,嗯rabbit根據自身策略會平均轉發到接受者的

高階使用傳輸物件

定義實體類

package com.rabbit.produce.entrty;

import java.io.Serializable;
import java.util.Date;

/**
 * @author : lqf
 * @description :
 * @date : Create in 14:04 2018/9/25
 */
public class User implements Serializable {

    private Integer id;
    private String name;
    private Integer age;

    public User(Integer id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

定義傳送者

package com.rabbit.produce.controller;

import com.rabbit.produce.entrty.User;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import java.util.Date;

@Controller
public class HelloSender {
 
    @Autowired
    private AmqpTemplate rabbitTemplate;
 
    public void send(User user) {
        this.rabbitTemplate.convertAndSend("hello", user);
    }

}

生產者專案定義接受者

package com.rabbit.produce.controller;

import com.rabbit.produce.entrty.User;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@RabbitListener(queues = "hello")
public class HelloReceiver {
 
    @RabbitHandler
    public void process(User user) {
        System.out.println("Receiver1  : " + user);
    }
}

消費者專案定義接受者

package com.rabbit.produce.controller;

import com.rabbit.produce.entrty.User;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@RabbitListener(queues = "hello")
public class HelloReceiver {
 
    @RabbitHandler
    public void process(User user) {
        System.out.println("Receiver2  : " + user);
    }
 
}

測試

package com.rabbit.produce;

import com.rabbit.produce.controller.HelloSender;
import com.rabbit.produce.controller.HelloSender2;
import com.rabbit.produce.entrty.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class BootRabbitmqProduceApplicationTests {

    @Autowired
    private HelloSender helloSender;

    @Test
    public void hello() throws Exception {
        for (int i = 0; i < 10; i++) {
            helloSender.send(new User(123, "測試", 18));
        }
    }

}

生產者專案測試結果

Receiver1  : User{id=123, name='測試', age=18}
Receiver1  : User{id=123, name='測試', age=18}
Receiver1  : User{id=123, name='測試', age=18}
Receiver1  : User{id=123, name='測試', age=18}
Receiver1  : User{id=123, name='測試', age=18}

消費者專案測試結果

Receiver2  : User{id=123, name='測試', age=18}
Receiver2  : User{id=123, name='測試', age=18}
Receiver2  : User{id=123, name='測試', age=18}
Receiver2  : User{id=123, name='測試', age=18}
Receiver2  : User{id=123, name='測試', age=18}

注意問題

上述程式碼中實體類的報名大家可能注意到了是一樣的,報名如果不一樣是不能同步接收到物件傳遞的(坑2)