RabbitMQ | 基础

参看连接:java

springboot(八):RabbitMQ详解--Author@纯洁的微笑spring

一、sender,queue,receiver

队列服务有三个概念: 发消息者、队列、收消息者。springboot

  • 左侧 P 表明 生产者,也就是往 RabbitMQ 发消息的程序。
  • 中间 RabbitMQ,其中包括了 交换机 X 和 队列 Q。
  • 右侧 C 表明 消费者,也就是往 RabbitMQ 拿消息的程序。

比较重要的概念有 4 个:虚拟主机,交换机,队列和绑定。bash

  • 虚拟主机:一个虚拟主机持有一组交换机、队列和绑定。为何须要多个虚拟主机呢?很简单,RabbitMQ当中,用户只能在虚拟主机的粒度进行权限控制。 所以,若是须要禁止A组访问B组的交换机/队列/绑定,必须为A和B分别建立一个虚拟主机。每个RabbitMQ服务器都有一个默认的虚拟主机“/”。
  • 交换机:Exchange 用于转发消息,可是它不会作存储 ,若是没有 Queue bind 到 Exchange 的话,它会直接丢弃掉 Producer 发送过来的消息。 这里有一个比较重要的概念:路由键 。消息到交换机的时候,交互机会转发到对应的队列中,那么究竟转发到哪一个队列,就要根据该路由键。
  • 绑定:也就是交换机须要和队列相绑定,这其中如上图所示,是多对多的关系。

二、交换机(Exchange)

交换机的功能主要是接收消息而且转发到绑定的队列,交换机不存储消息,在启用ack模式后,交换机找不到队列会返回错误。交换机有四种类型:Direct, topic, Headers and Fanout服务器

  • Direct:direct 类型的行为是"先匹配, 再投送". 即在绑定时设定一个 routing_key, 消息的routing_key 匹配时, 才会被交换器投送到绑定的队列中去.
  • Topic:按规则转发消息(最灵活)
  • Headers:设置header attribute参数类型的交换机
  • Fanout:转发消息到全部绑定队列

2.一、Direct Exchange

Direct Exchange是RabbitMQ默认的交换机模式,也是最简单的模式,根据key全文匹配去寻找队列。app

第一个 X - Q1 就有一个 binding key,名字为 orange; X - Q2 就有 2 个 binding key,名字为 black 和 green。当消息中的 路由键 和 这个 binding key 对应上的时候,那么就知道了该消息去到哪个队列中。 spring-boot

2.二、Topic Exchange

Topic Exchange 转发消息主要是根据通配符。 在这种交换机下,队列和交换机的绑定会定义一种路由模式,那么,通配符就要在这种路由模式和路由键之间匹配后交换机才能转发消息。 在这种交换机模式下:测试

  • 路由键必须是一串字符,用句号(.) 隔开:如 agreements.us, agreements.eu.stockholm  
  • 路由模式必须包含一个 星号(*),主要用于匹配路由键指定位置的一个单词,好比说,一个路由模式是这样子:agreements..b.*,那么就只能匹配路由键是这样子的:第一个单词是 agreements,第四个单词是 b。 井号(#)就表示至关于一个或者多个单词,例如一个匹配模式是agreements.eu.berlin.#,那么,以agreements.eu.berlin开头的路由键都是能够的。

具体代码发送的时候仍是同样,第一个参数表示交换机,第二个参数表示routing key,第三个参数即消息。以下:this

rabbitTemplate.convertAndSend("testTopicExchange","key1.a.c.key2", " this is RabbitMQ!");

topic 和 direct 相似, 只是匹配上支持了"模式", 在"点分"的 routing_key 形式中, 可使用两个通配符:spa

  • *表示一个词.
  • #表示零个或多个词.

2.三、Headers Exchange

headers 也是根据规则匹配, 相较于 direct 和 topic 固定地使用 routing_key , headers 则是一个自定义匹配规则的类型. 在队列与交换器绑定时, 会设定一组键值对规则, 消息中也包括一组键值对( headers 属性), 当这些键值对有一对, 或所有匹配时, 消息被投送到对应队列.

2.四、Fanout Exchange

Fanout Exchange 消息广播的模式,无论路由键或者是路由模式,会把消息发给绑定给它的所有队列,若是配置了routing_key会被忽略。

三、In Action

3.1 springboot集成rabbitmq(Hello World)

经过start.spring.io生成含有spring-boot-starter-amqp依赖的项目,结构以下:

application.properties

spring.application.name=DdoubleRabbit
debug=true

spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=ddouble
spring.rabbitmq.password=Tong2014

RabbitConfig.java

package com.ddouble.DdoubleRabbit.rabbit;

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 helloQueue() {
        return new Queue("hello");
    }
}

HelloSender.java

package com.ddouble.DdoubleRabbit.rabbit.hello;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;

@Component
public class HelloSender {
    @Autowired
    private AmqpTemplate rabbitTemplate;

    public void send() {
        String context = "hello" + new Date();
        System.out.println("Sender : " + context);
        this.rabbitTemplate.convertAndSend("hello", context);
    }
}

HelloReceiver.java

package com.ddouble.DdoubleRabbit.rabbit.hello;

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 str) {
        System.out.println("Receiver : " + str);
    }
}

测试类

package com.ddouble.DdoubleRabbit;

import com.ddouble.DdoubleRabbit.rabbit.hello.HelloSender;
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 DdoubleRabbitApplicationTests {
	@Autowired
	private HelloSender helloSender;

	@Test
	public void contextLoads() {
		helloSender.send();
	}
}

控制台打印:

RabbitMQ能够看到一个“hello”的Queue

相关文章
相关标签/搜索