1. Breve introducción
MQ
El nombre completo (Cola de mensajes), también conocido como cola de mensajes, es un software intermedio para la comunicación asincrónica. Se puede entender como una oficina de correos. El remitente entrega el mensaje a la oficina de correos, y luego la oficina de correos nos ayudará a enviarlo al destinatario específico del mensaje (consumidor). No necesitamos preocuparnos por el proceso de envío específico. y el tiempo, y no interferirá con mis otras cosas. Común MQ
no kafka
, activemq
, zeromq
, rabbitmq
y así sucesivamente.
RabbitMQ
Es un AMQP
protocolo que está erlanng
desarrollado por un lenguaje orientado a alta concurrencia , utilizado en mensajería en tiempo real con altos requisitos de confiabilidad, y soporta clientes multilingües.
Concepto basico
Broker
: En pocas palabras, es la entidad del servidor de cola de mensajes.Exchange
: Intercambio de mensajes, que especifica las reglas y colas a las que se enrutan los mensajesQueue
: Portador de la cola de mensajes, cada mensaje se colocará en una o más colasBinding
: Encuadernación, su función esexchange
yqueue
atarlos de acuerdo con las reglas de enrutamientoRouting Key
: Palabra clave de enrutamiento, deexchange
acuerdo con esta palabra clave para la entrega de mensajesvhost
: Host virtual,broker
puede configurar múltiples en unovhost
, usado para separar los permisos de diferentes usuariosproducer
: El productor de mensajes es el programa que entrega el mensaje.consumer
: El consumidor de mensajes es el programa que recibe el mensajechannel
: Canal de mensajes, en cada conexión del cliente, se pueden establecer múltipleschannel
, cada unochannel
representando una tarea de sesión
Escenarios de referencia comunes
- Envío de correo electrónico: después de que el usuario se registre, el mensaje se entregará al usuario
rabbitmq
y el consumidor del mensaje enviará el correo electrónico de forma asincrónica, lo que mejora la velocidad de respuesta del sistema. - Corte de picos de tráfico: generalmente, se usa ampliamente en la actividad de picos. El pico hará que la aplicación se cuelgue debido a un tráfico excesivo. Para solucionar este problema, la cola de mensajes generalmente se agrega al front-end de la aplicación. Se utiliza para controlar el número de actividades, y los pedidos que superan este umbral determinado se descartan directamente. Alivie las aplicaciones de trituración de alto flujo a corto plazo.
- Tiempo de espera del pedido: el uso
rabbitmq
de la cola de retraso puede realizar fácilmente la función de tiempo de espera del pedido, por ejemplo, el usuario cancela el pedido sin pagar 30 minutos después de realizar el pedido.
2. Prepare el entorno de RabbitMQ
Debido al RabbitMQ
problema de la instalación, la prueba aquí toma el entorno de la ventana acoplable como ejemplo. Primero Linux
instale la ventana acoplable; si no lo hace, puede consultar la instalación de la ventana acoplable / los comandos comunes de la ventana acoplable
Luego descargue y ejecuteRabbitMQ
docker run -d --hostname my-rabbit --name pikachues-rabbit -p 5672:5672 -p15672:15672 rabbitmq:3-management
3. Prueba
RabbitMQ
Hay cuatro intercambios de mensajes. Son directos (predeterminados), fanout, tema y encabezados. Los diferentes tipos de conmutadores tienen diferentes estrategias de reenvío de mensajes. Se springboot
prueban los siguientes cuatro tipos de intercambio de mensajes.
0. Prepare el entorno de prueba
confiar
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</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>
Archivo de configuración
spring.rabbitmq.host=rabbitmq安装的ip地址
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.port=5672
1.directo
El intercambio directo, que funciona de manera similar a la unidifusión, Exchange
envía mensajes a ROUTING_KEY
una cola que coincide exactamente .
configuración directa
@Configuration
public class RabbitDirectConfig {
public final static String DIRECTNAME = "pikachues-direct";
@Bean
Queue queue() {
return new Queue("hello.pikachues");
}
@Bean
DirectExchange directExchange(){
return new DirectExchange(DIRECTNAME,true,false);
}
@Bean
Binding binding(){
return BindingBuilder.bind(queue()).to(directExchange()).with("direct");
}
}
Recepción de mensajes
@Component
public class DirectReceiver {
@RabbitListener(queues = "hello.pikachues")
public void handler1(String msg){
System.out.println(">>>handler"+msg);
}
}
prueba
@RunWith(SpringRunner.class)
@SpringBootTest
public class RabbitmqDemoApplicationTests {
@Autowired
RabbitTemplate rabbitTemplate;
@Test
public void direct() {
rabbitTemplate.convertAndSend("hello.pikachues","hello pikachues");
}
}
2.fanout
La transmisión es un tipo de cambio, independientemente de la ROUTING_KEY
configuración del mensaje , Exchange
reenviará el mensaje a todos los vinculados Queue
.
configuración de fanout
@Configuration
public class RabbitFanoutConfig {
public static final String FANOUTNAME = "pikachues-fanout";
@Bean
Queue queueOne(){
return new Queue("queue-one");
}
@Bean
Queue queueTwo(){
return new Queue("queue-two");
}
@Bean
FanoutExchange fanoutExchange(){
return new FanoutExchange(FANOUTNAME,true,false);
}
@Bean
Binding bindingOne(){
return BindingBuilder.bind(queueOne()).to(fanoutExchange());
}
@Bean
Binding bindingTwo(){
return BindingBuilder.bind(queueTwo()).to(fanoutExchange());
}
}
Recepción de mensajes
@Component
public class FanoutReceiver {
@RabbitListener(queues = "queue-one")
public void handler1(String msg){
System.out.println("FanoutReceiver:handler1"+msg);
}
@RabbitListener(queues = "queue-two")
public void handler2(String msg){
System.out.println("FanoutReceiver:handler2"+msg);
}
}
prueba
@Test
public void testFanout(){
rabbitTemplate.convertAndSend(RabbitFanoutConfig.FANOUTNAME,null,"hello Fanout");
}
3.tema
El intercambiador de temas funciona como multidifusión, Exchange
reenvía los mensajes y ROUTING_KEY
el mismo patrón coincide con todas las colas, ROUTING_KEY
como user.stock
los Message
reenvíos para que coincidan con el modo de enlace * .stock, user.stock, *. * Y # .user .stock. # La cola. (* La tabla debe coincidir con una frase arbitraria, # significa coincidir con 0 o más frases)
configuración del tema
@Configuration
public class RabbitTopicConfig {
public static final String TOPICNAME = "pikachues-topic";
@Bean
TopicExchange topicExchange(){
return new TopicExchange(TOPICNAME,true,false);
}
@Bean
Queue xiaomi(){
return new Queue("xiaomi");
}
@Bean
Queue huaiwei(){
return new Queue("huawei");
}
@Bean
Queue phone(){
return new Queue("phone");
}
@Bean
Binding xiaomiBinding(){
return BindingBuilder.bind(xiaomi()).to(topicExchange()).with("xiaomi.#");
}
@Bean
Binding huaiweiBinding(){
return BindingBuilder.bind(huaiwei()).to(topicExchange()).with("huawei.#");
}
@Bean
Binding phoneBinding(){
return BindingBuilder.bind(phone()).to(topicExchange()).with("#.phone.#");
}
}
Recepción de mensajes
@Component
public class TopicReceiver {
@RabbitListener(queues = "xiaomi")
public void handler1(String msg) {
System.out.println("TopicReceiver:handler1:" + msg);
}
@RabbitListener(queues = "huawei")
public void handler2(String msg) {
System.out.println("TopicReceiver:handler2:" + msg);
}
@RabbitListener(queues = "phone")
public void handler3(String msg) {
System.out.println("TopicReceiver:handler3:" + msg);
}
}
prueba
@Test
public void testTopic(){
rabbitTemplate.convertAndSend(RabbitTopicConfig.TOPICNAME,"xiaomi.news","小米新闻");
rabbitTemplate.convertAndSend(RabbitTopicConfig.TOPICNAME,"vivo.phone","小米手机");
rabbitTemplate.convertAndSend(RabbitTopicConfig.TOPICNAME,"huawei.phone","华为手机");
}
4.cabeceras
El encabezado del cuerpo del mensaje coincide (ignorar)
configuración de encabezados
@Configuration
public class RabbitHeaderConfig {
public static final String HEADERNAME = "pikachues-header";
@Bean
HeadersExchange headersExchange(){
return new HeadersExchange(HEADERNAME, true,false);
}
@Bean
Queue queueName(){
return new Queue("name-queue");
}
@Bean
Queue queueAge(){
return new Queue("age-queue");
}
@Bean
Binding bindingName(){
Map<String,Object> map = new HashMap<>();
map.put("name","pikachues");
return BindingBuilder.bind(queueName()).to(headersExchange()).whereAny(map).match();
}
@Bean
Binding bindingAge(){
return BindingBuilder.bind(queueAge()).to(headersExchange()).where("age").exists();
}
}
Recepción de mensajes
@Component
public class HeaderReceiver {
@RabbitListener(queues = "name-queue")
public void handler1(byte[] msg) {
System.out.println("HeaderReceiver:handler1:" + new String(msg, 0, msg.length));
}
@RabbitListener(queues = "age-queue")
public void handler2(byte[] msg) {
System.out.println("HeaderReceiver:handler2:" + new String(msg, 0, msg.length));
}
}
prueba
@Test
public void testHeaders(){
Message nameMsg = MessageBuilder.withBody("hello pikachues".getBytes()).setHeader("name","pikachues").build();
Message ageMsg = MessageBuilder.withBody("hello 99".getBytes()).setHeader("age","99").build();
rabbitTemplate.convertAndSend(RabbitHeaderConfig.HEADERNAME,null,nameMsg);
rabbitTemplate.convertAndSend(RabbitHeaderConfig.HEADERNAME,null,ageMsg);
}
4. Otro
Si desea comprender RabbitMQ
los principios básicos, lea este artículo o la introducción del sitio web oficial de Springboot .