rabbitmq

目录

原理

 消息生产者

1、创建一个连接工厂

2、用连接工厂设置IP/端口/登录名/密码/虚拟机,然后建立TCP连接,

3、然后用连接创建一个通道

4、用通道声明队列(1.队列名称/2.是否持久化/3.是否独占此链接/4.不再使用时是否删除/5.队列参数)

5、用通道发布消息(1.Exchange的名称/2.routingKey/3.消息包含的属性/4.消息体)

消费者

1、创建一个连接工厂

2、用工厂设置MabbitMQ所在服务器的ip和端口(IP/端口/登录名/密码/虚拟机,然后建立TCP连接,)

3、然后用连接创建一个通道

4、用通道声明队列(1.队列名称/2.是否持久化/3.是否独占此链接/4.不再使用时是否删除/5.队列参数)

5、定义消费方法

6、监听队列

工作模式

一、Work queues工作队列模式

1、一条消息只会被一个消费者接收;

2、rabbit采用轮询的方式将消息是平均发送给消费者的;

3、消费者在处理完某条消息后,才会收到下一条消息。

二、Publish/subscribe发布订阅模式:

1、每个消费者监听自己的队列。

2、生产者将消息发给broker,由交换机将消息转发到绑定此交换机的每个队列,每个绑定交换机的队列都将接收 到消息

三、Routing路由模式:

1、每个消费者监听自己的队列,并且设置routingkey。

2、生产者将消息发给交换机,由交换机根据routingkey来转发消息到指定的队列。

四、Topics路由模式

1、每个消费者监听自己的队列,并且设置带统配符的routingkey。

2、生产者将消息发给broker,由交换机根据routingkey来转发消息到指定的队列。

五、Header模式

六、RPC模式

使用(springboot集成rabbitmq)

安装erlang环境、安装rabbitmq启动服务

一、maven工程加入依赖

二、创建启动类

三、创建application.yml文件及日志文件(配置文件)

四、创建配置文件类

五、收发消息类


原理

 消息生产者

1、创建一个连接工厂

2、用连接工厂设置IP/端口/登录名/密码/虚拟机,然后建立TCP连接,

3、然后用连接创建一个通道

4、用通道声明队列(1.队列名称/2.是否持久化/3.是否独占此链接/4.不再使用时是否删除/5.队列参数)

5、用通道发布消息(1.Exchange的名称/2.routingKey/3.消息包含的属性/4.消息体)

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Producer01 {
    //队列名称
    private static final String QUEUE = "helloworld";
    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = null;
        Channel channel = null;
        try
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.setHost("localhost");
            factory.setPort(5672);
            factory.setUsername("guest");
            factory.setPassword("guest");
            factory.setVirtualHost("/");//rabbitmq默认虚拟机名称为“/”,虚拟机相当于一个独立的mq服务
            //创建与RabbitMQ服务的TCP连接
                    connection = factory.newConnection();
            //创建与Exchange的通道,每个连接可以创建多个通道,每个通道代表一个会话任务
            channel = connection.createChannel();
            /**
             * 声明队列,如果Rabbit中没有此队列将自动创建
             * param1:队列名称
             * param2:是否持久化
             * param3:队列是否独占此连接
             * param4:队列不再使用时是否自动删除此队列
             * param5:队列参数
             */
            channel.queueDeclare(QUEUE, true, false, false, null);
            String message = "helloworld小明"+System.currentTimeMillis();
            /**
             * 消息发布方法
             * param1:Exchange的名称,如果没有指定,则使用Default Exchange
             * param2:routingKey,消息的路由Key,是用于Exchange(交换机)将消息转发到指定的消息队列
             * param3:消息包含的属性
             * param4:消息体
             */
            /**
             * 这里没有指定交换机,消息将发送给默认交换机,每个队列也会绑定那个默认的交换机,但是不能显
             示绑定或解除绑定
             * 默认的交换机,routingKey等于队列名称
             */
            channel.basicPublish("", QUEUE, null, message.getBytes());
            System.out.println("Send Message is:'" + message + "'");
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
        finally
        {
            if(channel != null)
            {
                channel.close();
            }
            if(connection != null)
            {
                connection.close();
            }
        }
    }
}

消费者

1、创建一个连接工厂

2、用工厂设置MabbitMQ所在服务器的ip和端口(IP/端口/登录名/密码/虚拟机,然后建立TCP连接,)

3、然后用连接创建一个通道

4、用通道声明队列(1.队列名称/2.是否持久化/3.是否独占此链接/4.不再使用时是否删除/5.队列参数)

5、定义消费方法

6、监听队列

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Consumer01 {
    private static final String QUEUE = "helloworld";
    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory factory = new ConnectionFactory();
//设置MabbitMQ所在服务器的ip和端口
        factory.setHost("localhost");
        factory.setPort(5672);
        factory.setUsername("guest");
        factory.setPassword("guest");
        factory.setVirtualHost("/");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();
//声明队列
        channel.queueDeclare(QUEUE, true, false, false, null);
//定义消费方法
        DefaultConsumer consumer = new DefaultConsumer(channel) {
            /**
             * 消费者接收消息调用此方法
             * @param consumerTag 消费者的标签,在channel.basicConsume()去指定
             * @param envelope 消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志
            *(收到消息失败后是否需要重新发送)
             * @param properties
             * @param body
             * @throws IOException
             * */
            //北京市昌平区建材城西路金燕龙办公楼一层 电话:400-618-9090
            //2.2.4 总结
            //1、发送端操作流程
            //1)创建连接
            //2)创建通道
            //3)声明队列
            //4)发送消息
            //2、接收端
            //1)创建连接
            //2)创建通道
            //3)声明队列
            //4)监听队列
            //5)接收消息
            @Override
            public void handleDelivery(String consumerTag,Envelope envelope,AMQP.BasicProperties properties,byte[] body)throws IOException {
//交换机
                String exchange = envelope.getExchange();
//路由key
                String routingKey = envelope.getRoutingKey();
//消息id
                long deliveryTag = envelope.getDeliveryTag();
//消息内容
                String msg = new String(body);
                System.out.println("receive message.." + msg);
            }
        };
/**
 * 监听队列String queue, boolean autoAck,Consumer callback
 * 参数明细
 * 1、队列名称
 * 2、是否自动回复,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置
 为false则需要手动回复
 * 3、消费消息的方法,消费者接收到消息后调用此方法
 */
        channel.basicConsume(QUEUE, true, consumer);
    }
}

工作模式

一、Work queues工作队列模式

1、一条消息只会被一个消费者接收;

2rabbit采用轮询的方式将消息是平均发送给消费者的;

3、消费者在处理完某条消息后,才会收到下一条消息。

二、Publish/subscribe发布订阅模式:

1、每个消费者监听自己的队列。

2、生产者将消息发给broker,由交换机将消息转发到绑定此交换机的每个队列,每个绑定交换机的队列都将接收 到消息

标题

 

三、Routing路由模式:

1、每个消费者监听自己的队列,并且设置routingkey

2、生产者将消息发给交换机,由交换机根据routingkey来转发消息到指定的队列。

四、Topics路由模式

路由模式:

1、每个消费者监听自己的队列,并且设置带统配符的routingkey

2、生产者将消息发给broker,由交换机根据routingkey来转发消息到指定的队列。

五、Header模式

header模式与routing不同的地方在于,header模式取消routingkey,使用header中的 key/value(键值对)匹配

队列。

案例:

根据用户的通知设置去通知用户,设置接收Email的用户只接收Email,设置接收sms的用户只接收sms,设置两种

通知类型都接收的则两种通知都有效。

六、RPC模式

RPC即客户端远程调用服务端的方法 ,使用MQ可以实现RPC的异步调用,基于Direct交换机实现,流程如下:

1、客户端即是生产者就是消费者,向RPC请求队列发送RPC调用消息,同时监听RPC响应队列。

2、服务端监听RPC请求队列的消息,收到消息后执行服务端的方法,得到方法返回的结果

3、服务端将RPC方法 的结果发送到RPC响应队列

4、客户端(RPC调用方)监听RPC响应队列,接收到RPC调用结果。

使用(springboot集成rabbitmq)

安装erlang环境、安装rabbitmq启动服务

一、maven工程加入依赖

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

二、创建启动类

三、创建application.yml文件及日志文件(配置文件)

例:application.yml

server:
    port: 44000
spring:
    application:
        name: test‐rabbitmq‐producer
    rabbitmq:
        host: 127.0.0.1
        port: 5672
        username: guest
        password: guest
        virtualHost: /

四、创建配置文件类

1.配置交换机

2.声明队列

3.绑定队列到交换机

例:

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitConfig {
    public static final String QUEUE_INFORM_EMAIL = "queue_inform_email";
    public static final String QUEUE_INFORM_SMS = "queue_inform_sms";
    public static final String EXCHANGE_TOPICS_INFORM="exchange_topics_inform";
    /**
     * 交换机配置
     * ExchangeBuilder提供了fanout、direct、topic、header交换机类型的配置
     * @return the exchange
     */
    @Bean(EXCHANGE_TOPICS_INFORM)
    public Exchange EXCHANGE_TOPICS_INFORM() {
//durable(true)持久化,消息队列重启后交换机仍然存在
        return ExchangeBuilder.topicExchange(EXCHANGE_TOPICS_INFORM).durable(true).build();
    }
    //声明队列
    @Bean(QUEUE_INFORM_SMS)
    public Queue QUEUE_INFORM_SMS() {
        Queue queue = new Queue(QUEUE_INFORM_SMS);
        return queue;
    }
    //声明队列
    @Bean(QUEUE_INFORM_EMAIL)
    public Queue QUEUE_INFORM_EMAIL() {
        Queue queue = new Queue(QUEUE_INFORM_EMAIL);
        return queue;
    }
    /** channel.queueBind(INFORM_QUEUE_SMS,"inform_exchange_topic","inform.#.sms.#");
     * 绑定队列到交换机 .
     *
     * @param queue the queue
     * @param exchange the exchange
     * @return the binding
     */
    @Bean
    public Binding BINDING_QUEUE_INFORM_SMS(@Qualifier(QUEUE_INFORM_SMS) Queue queue,
                                            @Qualifier(EXCHANGE_TOPICS_INFORM) Exchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with("inform.#.sms.#").noargs();
    }
    @Bean
    public Binding BINDING_QUEUE_INFORM_EMAIL(@Qualifier(QUEUE_INFORM_EMAIL) Queue queue,
                                              @Qualifier(EXCHANGE_TOPICS_INFORM) Exchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with("inform.#.email.#").noargs();
    }
}

五、收发消息类

import com.xuecheng.test.rabbitmq.config.RabbitConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest
@RunWith(SpringRunner.class)
public class Producer05_topics_springboot {
    @Autowired
    RabbitTemplate rabbitTemplate;
    @Test
    public void testSendByTopics(){
        for (int i=0;i<5;i++){
            String message = "sms email inform to user"+i;
            rabbitTemplate.convertAndSend(RabbitConfig.EXCHANGE_TOPICS_INFORM,"inform.sms.email",message);
            System.out.println("Send Message is:'" + message + "'");
        }
    }
}
import com.rabbitmq.client.Channel;
import com.xuecheng.test.rabbitmq.config.RabbitConfig;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class ReceiveHandler {
    //监听email队列
    @RabbitListener(queues = {RabbitConfig.QUEUE_INFORM_EMAIL})
    public void receive_email(String msg, Message message, Channel channel){
        System.out.println(msg);
    }
    //监听sms队列
    @RabbitListener(queues = {RabbitConfig.QUEUE_INFORM_SMS})
    public void receive_sms(String msg,Message message,Channel channel){
        System.out.println(msg);
    }
}

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值