消息队列RabbitMQ

服务之间最常见的通信方式是直接调用彼此来通信。

消息从一端发出后立即就可以达到另一端,称为即时消息通讯(同步通信)。

消息从某一端发出后,首先进入一个容器进行临时存储,当达到某种条件后,再由这个容器发送给另一端,称为延迟消息通讯(异步通信)。

AMQP

一个提供统一消息服务的应用层标准高级消息队列协议,是一个通用的应用层协议。

消息发送与接受的双方遵守这个协议可以实现异步通讯,这个协议约定了消息的格式和工作方式。

消息队列RabbitMQ_第1张图片

RabbitMQ

是一个实现了AMQP(Advanced Message Queuing Protocol)高级消息队列协议的消息队列服务,用Erlang语言。

消息队列RabbitMQ_第2张图片

Server(Broker):接收客户端连接,实现AMQP协议的消息队列和路由功能的进程。

Virtual Host:虚拟主机的概念,类似权限控制组,一个Virtual Host里可以有多个Exchange和 Queue。

Exchange:交换机,接收生产者发送的消息,并根据Routing Key将消息路由到服务器中的队列 Queue。

ExchangeType:交换机类型决定了路由消息行为,RabbitMQ中有三种类型Exchange,分别是 fanout、direct、topic. Message Queue:消息队列,用于存储还未被消费者消费的消息。

Message:由Header和body组成,Header是由生产者添加的各种属性的集合,包括Message是 否被持久化、优先级是多少、由哪个Message Queue接收等。body是真正需要发送的数据容。

 BindingKey:绑定关键字,将一个特定的Exchange和一个特定的Queue绑定起来。

docker 部署RabbitMQ


docker pull rabbitmq:management

注意:获取镜像的时候要获取management版本的,不要获取last版本的,management版本的才 带有管理界面 。

docker run -d \

--name my-rabbitmq \

-p 5672:5672 -p 15672:15672 \

-v /home/rabbitmq:/var/lib/rabbitmq \

--hostname my-rabbitmq-host \

-e RABBITMQ_DEFAULT_VHOST=my_vhost \

-e RABBITMQ_DEFAULT_USER=admin \

-e RABBITMQ_DEFAULT_PASS=admin \

--restart=always \

rabbitmq:management

  --hostname:主机名(RabbitMQ的一个重要注意事项是它根据所谓的 “节点名称” 存储数据,默认                           为主机名)

  -e:指定环境变量

  RABBITMQ_DEFAULT_VHOST:默认虚拟机名

  RABBITMQ_DEFAULT_USER:默认的用户名

  RABBITMQ_DEFAULT_PASS:默认用户名的密码

容器启动后,可以通过 docker logs 容器 查看日志

docker logs my-rabbitmq

进入管理后台

http://ip:15672

登录 用户admin 密码admin

消息队列RabbitMQ_第3张图片

新建用户add a user  

消息队列RabbitMQ_第4张图片

 切记需要授权!

 新建之后  点击springboot设置虚拟机

消息队列RabbitMQ_第5张图片

 如图ok~ 登录springboot即可

消息队列RabbitMQ_第6张图片

 接下来搭建springboot项目

消息队列RabbitMQ_第7张图片

 所需依赖


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

 yml文件配置

server:
    port: 8080
spring:
    application:
        name: provider
    rabbitmq:
        host: 192.168.23.131
        password: 123456
        port: 5672
        username: springboot
        virtual-host: my_vhost

生产者 Provider

package com.example.pri;

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

@Configuration
@SuppressWarnings("all")
public class RabbitConfig {

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

}
package com.example.pri;

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

@Component
@SuppressWarnings("all")
public class Sender {
    
    @Autowired
    private AmqpTemplate rabbitTemplate;

    public void sendFirst() {
        rabbitTemplate.convertAndSend("firstQueue", "Hello World");
    }
    
}

 运行Test

package com.example.pri;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class ProviderApplicationTests {

    @Autowired
    private Sender sender;

    @Test
    void contextLoads() {
        sender.sendFirst();
    }

}

 运行成功后 RabbitMQ会有一条队列

消息队列RabbitMQ_第8张图片

消费者 Consumer

server:
    port: 8081
spring:
    application:
        name: consumer
    rabbitmq:
        host: 192.168.23.131
        password: 123456
        port: 5672
        username: springboot
        virtual-host: my_vhost

package com.example.cum;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@SuppressWarnings("all")
@Slf4j
@RabbitListener(queues = "firstQueue")
public class Receiver {
    
    @RabbitHandler
    public void process(String msg) {
        log.warn("接收到:" + msg);
    }
    
}

 自定义数据发送

新建user类

package com.example.pri;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@SuppressWarnings("all")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User{
    
    private String username;
    private String userpwd;
    
}

 方法

public void send(User user) {
    rabbitTemplate.convertAndSend("first", user);
}

 运行之后控制台报错了

消息队列RabbitMQ_第9张图片

解决方式: 实现序列化接口

消息队列RabbitMQ_第10张图片

你可能感兴趣的:(docker,容器,java,rabbitmq)