springboot整合rabbitmq

java使用rabbitmq的基本操作在前面两篇文章中已经讲过了,实际项目中,使用ssm框架整合rabbitmq比较常见,但对于新手来说,个人觉得spring在整合rabbitmq时候,xml的配置文件里很容易让人抓狂,但只要配置好了,基本上不需要做过多的改动

rabbitmq在实际使用中,主要的业务场景还是在分布式项目中,不同的业务处理完毕,需要异步的发送消息进行通讯的情况下,可以考虑使用rabbitmq或其他的消息中间件,这里,将演示springboot整合rabbitmq进行消息的通讯,为模拟分布式环境,直接创建两个maven工程

springboot整合rabbitmq_第1张图片

项目名称可以自己定义,一个工程模拟生产者,一个模拟消费者,

工程启动前,先将rabbitmq的服务启动起来,并根据需求提前创建工程中需要的用户,exchange,vHost,queue等

springboot整合rabbitmq_第2张图片

为使用方便,我已经提前将相关的配置信息在管控台中配置完毕;

首先看生产者端代码,这里为演示效果,将模拟几种不同的使用方式,首先看pom依赖jar包,


org.springframework.boot
spring-boot-starter-parent
2.0.1.RELEASE


    UTF-8
    UTF-8
    1.8
    4.1.0-incubating



    
        org.springframework.boot
        spring-boot-starter-web
    

    
        org.mybatis.spring.boot
        mybatis-spring-boot-starter
        1.3.2
    

    
        org.springframework.boot
        spring-boot-starter-test
        test
    

    
        org.springframework.boot
        spring-boot-starter-activemq
    

    
    
        org.apache.activemq
        activemq-pool
    

    
    
        org.apache.rocketmq
        rocketmq-client
        ${rocketmq.version}
    

    
        org.apache.rocketmq
        rocketmq-common
        ${rocketmq.version}
    

    
        org.apache.rocketmq
        rocketmq-client
        4.1.0-incubating
    

     
    
        org.projectlombok
        lombok
        provided
    

    
    

    
        com.google.code.gson
        gson
        2.8.5
    

    
        org.springframework.boot
        spring-boot-starter-amqp
    

    
        junit
        junit
        4.12
    



接下来是配置文件,连接rabbitmq的配置信息在application.properties中进行配置:
server.port=8084

rabbitmq相关配置

spring.application.name=rabbitmq-sender
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=acong
spring.rabbitmq.password=acong
spring.rabbitmq.virtual-host=/test
spring.rabbitmq.publisher-confirms=true

springboot整合rabbitmq_第3张图片

bean包下存放的是对象类文件;
config包下存放的是初始化连接rabbitmq的配置文件,会在项目启动的时候进行全局加载,比如,消费者要绑定的exchange,相关的队列,消息确认相关配置等;
controller包模拟前端发送消息,作为测试的入口文件;

接下来看具体的代码,首先看config下的配置文件:

@Component
public class TopicConfig {

final static String queueName = "hello";

@Bean
public Queue helloQueue() {
    return new Queue("hello");
}

@Bean
public Queue userQueue() {
    return new Queue("user");
}

// ===============以下是验证topic Exchange的队列==========
@Bean
public Queue queueMessage() {
    return new Queue("topic.message");
}

@Bean
public Queue queueMessages() {
    return new Queue("topic.messages");
}
// ===============以上是验证topic Exchange的队列==========

// ===============以下是验证Fanout Exchange的队列==========
@Bean
public Queue AMessage() {
    return new Queue("fanout.A");
}

@Bean
public Queue BMessage() {
    return new Queue("fanout.B");
}

@Bean
public Queue CMessage() {
    return new Queue("fanout.C");
}
// ===============以上是验证Fanout Exchange的队列==========

@Bean
TopicExchange exchange() {
    return new TopicExchange("ttoo");
}

@Bean
FanoutExchange fanoutExchange() {
    return new FanoutExchange("fanoutExchange");
}

/**
 * 将队列topic.message与exchange绑定,binding_key为topic.message,就是完全匹配
 * 
 * @param queueMessage
 * @param exchange
 * @return
 */
@Bean
Binding bindingExchangeMessage(Queue queueMessage, TopicExchange exchange) {
    return BindingBuilder.bind(queueMessage).to(exchange).with("topic.message");
}

/**
 * 将队列topic.messages与exchange绑定,binding_key为topic.#,模糊匹配
 * 
 * @param queueMessage
 * @param exchange
 * @return
 */
@Bean
Binding bindingExchangeMessages(Queue queueMessages, TopicExchange exchange) {
    return BindingBuilder.bind(queueMessages).to(exchange).with("topic.#");
}

@Bean
Binding bindingExchangeA(Queue AMessage, FanoutExchange fanoutExchange) {
    return BindingBuilder.bind(AMessage).to(fanoutExchange);
}

@Bean
Binding bindingExchangeB(Queue BMessage, FanoutExchange fanoutExchange) {
    return BindingBuilder.bind(BMessage).to(fanoutExchange);
}

@Bean
Binding bindingExchangeC(Queue CMessage, FanoutExchange fanoutExchange) {
    return BindingBuilder.bind(CMessage).to(fanoutExchange);
}

}

在这个配置文件中,初始化定义了项目中可能要用到的队列名称,exchange绑定的队列名,以及定义的路由规则,这些写法属于固定的模式和套路,只是在springboot中,在原本的声明式的写法下进行了进一步的封装,属于换汤不换药,这个里面的配置写好了后面只需拿来即可使用,

配置完毕,接下来编写生产者端的代码,这里演示一种使用方式,即topic的使用方式,其他的类似,参考即可,
springboot整合rabbitmq_第4张图片

首先在topicConfig中,
springboot整合rabbitmq_第5张图片

这两处的代码的意思是,为某个exchange绑定两个不同的queue,不同的是这两个队列订阅的消息策略有所不同,queueMessage匹配的topic.message开头的消息,而queueMessages匹配的以topic开头的所有消息,一会儿在消费端可以看出效果;

接下来是具体发送消息的代码;

@Component
public class TopicSender {

@Autowired
private AmqpTemplate rabbitTemplate;

public void send() {
    String msg1 = "我是主题发送的消息1   --->>>> I am topic.mesaage msg======";
    System.out.println("sender1 : " + msg1);
    this.rabbitTemplate.convertAndSend("exchange", "topic.message", msg1);

    String msg2 = "我是主题发送的消息2   --->>>> I am topic.mesaages msg########";
    System.out.println("sender2 : " + msg2);
    this.rabbitTemplate.convertAndSend("exchange", "topic.messages",msg2);
}

}

注意导包的时候不要导错了;

接下来编写测试代码,在TopicSendController写一段测试的发送的消息代码,很简单,发送成功返回success,而且控制台也会打印出来,

@Controller
@RequestMapping(“/topic”)
public class TopicSendController {

@Autowired
private TopicSender topicSender;

@ResponseBody
@RequestMapping("/sendTopicMsg")
public String sendTopicMsg(){
    topicSender.send();
    return "topic send success";
}

}

接下来看消费者端的代码,消费端pom文件不变,application.properites的配置文件基本一致,
server.port=8085

rabbitmq相关配置

spring.application.name=rabbitmq-consumer
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=acong
spring.rabbitmq.password=acong
spring.rabbitmq.virtual-host=/test

主要看接收消息的代码,消费者一段不需要做其他配置,在excehange下,只需要把要监听的队列名称写正确即可,因为在生产者一段,项目启动的时候,对应的exchange以及与之绑定的queue已经生效了,所以消费者一段不需再做配置,如果单独测试rabbimq的时候,是需要声明式配置的,

这里定义了两个消费者,模拟不同的路由键接收到的消息,

@Component
@RabbitListener(queues = “topic.message”)
public class TopicMessageReceiver {

@RabbitHandler
public void process(String msg) {
    System.out.println("topicMessageReceiver 接收到了消息 : " +msg);
}

}

@Component
@RabbitListener(queues = “topic.messages”)
public class TopicMessageReceiver2 {

@RabbitHandler
public void process(String msg) {
    System.out.println("topicMessageReceiver2 我能收到所有匹配的消息   ---- 接收到了消息 : " +msg);
}

}
需要注意,这里的注解写法不要随便修改,否则会报奇葩的错误,因为springboot底层已经对此作了进一步的封装,只需要拿来用即可,比如此处的:
@RabbitListener(queues = “topic.messages”)这个注解配合@RabbitHandler其实和单独使用rabbitmq时候,那个handlerDelivery的监听方法的效果是一样的,一旦生产者发送了消息,就能收到;

接下来,首先启动消费者端APP,

springboot整合rabbitmq_第6张图片

启动完毕,消费者监听程序生效,

再启动生产者APP,

springboot整合rabbitmq_第7张图片

接下来,在浏览器输入:
http://localhost:8084/topic/sendTopicMsg

看控制台打印结果:
springboot整合rabbitmq_第8张图片

可以看到,消费者端成功接收到了消息,同时可以验证topic模式下,通过在exchange中定义不同的queue的消息匹配策略,接收到的消息是不一样的,第一个消费者由于匹配的消息格式是:topic.message精准匹配,第二个是topic.#即模糊匹配,所以第一个消费者接收了一个消息,第二个消费者接收到了两条消息;

其他模式下,稍作修改即可,至此,springboot整合rabbitmq到此基本完毕,不足之处,敬请见谅,提出宝贵意见。

你可能感兴趣的:(消息中间件,springboot,rabbitmq的使用,rabbitmq)