初入rabbitMQ学习,以及使用java实现

RabbitMq

一 概述

1、简介

​ MQ(Messages Queue)消息队列,FIFO(First In First Out),上游生产消息进入信道(Channel),由下游消费。万级吞吐量

2、优势

(1)流量削峰

​ 如:10W订单时同时进行访问应用时,应用负载过大时,将订单消息放入MQ中,进行排队,并且消息队列中消息数量达到一定数量时,可以进行提示,当前访问人数过多。并行操作转换为串行操作。

(2)应用解耦

​ 系统应用之间调用时,如:定单服务调用支付服务时,下单支付的动作直接调用时。将下单支付动作存入MQ中,MQ监听支付服务进行消费,失败时可设置重复消费以及异常监听。

(3)异步处理

​ 如:A请求B时,B响应时间过长,A无需等待,B完成后直接通过A即可。传统时,需要使A一段时间确认B是否完成。

3、核心概念

3.1 名词介绍

img

(1)生产者

​ 将消息打包成一定格式,发送至队列/交换机

(2)交换机

​ 交换机可以将消息进行分配(bindKey)进行匹配相应的队列。

(3)队列

​ 存入队列中的消息,由消费者进行消费。

(4)消费者

​ 消费消息。

img

​ Broker:介绍和分发消息的应用。

​ Virtual Host:可以在Broker中建立多个服务应用(IP),进行不同应用的消息统一发送。

​ Connection :建立连接,Producer 、Broker以及Consumer之间需要建立TCP连接

​ Channel:由于建立连接开销较大,则建立一次连接,采用多信道(Channel)的形式,发一个消息时,只占用一个Channel,可支持发送多个消息,并且Channel采用逻辑连接的形式。

3.2 核心(六大模式)

3.2.1、HelloWorld 直连

img

在采用代码实现时,注意3.1中的结构图,首先在将消息上传至MQ时需要先完成几个步骤:

  • 通过ConnectionFactory配置连接参数创建Connection连接。其中在配置连接参数时,VirtualHost配置相当于配置交换机标识,需要事先在rabbitMq中创建。

  • Connection如3.1中所述,连接仅创建一次,需要从Connection中创建Channel进行消息传递。

  • Channel为传递消息核心类型。

    (1)其中提供绑定队列方法channel.queueDeclare(queueName,b1,b2,b3,map),参数详情其中如下:

    ①queueName:队列名称,上下游必须一致才可完成相应的发送以及接收动作,并且队列名称在Broker中不存在时会主动创建。

    ​ ②b1是否队列持久化,选择是时,会将队列存储内置mnesia数据库中,否则则是存放在内存中。

    ​ ③b2是否独占队列,建立一个队列之后,其他channel无法在创建同名队列,该机制仅限一个Connecton之下

    ​ ④b3是否自动删除

    (2)消费者监听时间basicConsume(String queueName, boolean autoAllow, DeliverCallback handler, CancelCallback cancelCallBack)方法在 Chanel类中提供多个重载方法,以上述举例。

    ​ ①queueName队列名称,绑定队列。

    ​ ②autoAllow是否开启消息的自动确认机制

    ​ ③handler监听事件,读取消息,信道中存在方法时,进行消费。

    ​ ④cancelCallBack消息通道关闭时,调用该回调方法。

    (3)生产者发送消息时,basicPublish(String exChange,String queueName,BasicProperties **otherMessages,**Byte[] message.getBytes()).

    ​ ①exChange交换机,根据实际情况进行绑定,可为空。

    ​ ②queueName 队列名称

    ​ ③otherMessage 消息额外设置。

    ​ ④message.getBytes,其中将需要转递的参数尽量转为json字符串形式,在将字符串转为Byte进行发送,减小传输成本。

采用代码试下如下,消费者代码:


/**
 * 消费者监听如下,
 */
public class Consumer1 {
  private static final String QUEUE_NAME = "Myqueue";

  public static void main(String[] args) {
    System.out.println("start+******************");
    receive();
    System.out.println("end+******************");

  }

  public static void receive() {
    //声明连接工厂
    ConnectionFactory factory = null;
    //声明连接对象
    Connection connection = null;
    //声明通道
    Channel channel = null;

    try {
      //创建连接工厂
      factory = new ConnectionFactory();
      //设置连接rabbitmq主机
      factory.setHost("localhost");
      //设置端口
      factory.setPort(5672);
      //设置虚拟主机
      factory.setVirtualHost("/");
      ///设置连接rabbitmq用户名
      factory.setUsername("guest");
      //设置连接rabbitmq密码
      factory.setPassword("guest");
      //创建连接对象
      connection = factory.newConnection();
      //创建连接通道
      channel = connection.createChannel();
      //通道绑定消息队列,参数根据消息队列参数对应
      //参数1:队列名称
      //参数2:绑定队列是否是持久化
      //参数3:绑定队列是否是独占
      //参数4:绑定队列消费完成是否会自动删除
      //参数5:绑定队列额外设置
      channel.queueDeclare(QUEUE_NAME, true, false, false, null);

      Consumer consumer = new DefaultConsumer(channel) {
        //内部类方法中,body为传送消息实体
        @Override
        public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
          System.out.println("接受消息开始~~~~~~~~~~~~");
          String message = new String(body, "UTF-8");
          System.out.println("收到消息.........." + message);
        }
      };
      //消费消息
      //参数1:消费队列的队列名称
      //参数2:开始消息的自动确认机制
      //参数3:消费时回调
      channel.basicConsume(QUEUE_NAME, true, consumer);


    } catch (IOException e) {
      e.printStackTrace();
    } catch (TimeoutException e) {
      e.printStackTrace();
    }/*finally {
            try {
                channel.close();
                connection.close();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (TimeoutException e) {
                e.printStackTrace();
            }
        }*/
  }

}

/**
 * 生产者发送消息
 */
public class Sender {
  private final static String QUEUE_NAME = "Myqueue";

  public static void main(String[] args) {
    send();

  }

  public static void send() {
    //声明连接工厂
    ConnectionFactory factory = null;
    //声明连接对象
    Connection connection = null;
    //声明信息通道
    Channel channel = null;


    try {
      //创建mq连接工厂
      factory = new ConnectionFactory();
      //设置连接rabbittmq连接主机
      factory.setHost("localhost");
      //设置连接端口
      factory.setPort(5672);
      //设置连那个虚拟主机(此处名为默认的虚拟主机exChange)
      factory.setVirtualHost("/");
      //设置rabbitmq连接用户名
      factory.setUsername("guest");
      //设置rabbitmq连接密码
      factory.setPassword("guest");
      //获取连接对象
      connection = factory.newConnection();
      //获取连接中通道
      channel = connection.createChannel();
      //通道绑定消息队列
      //参数1:队列名称,如果不存在会自动创建
      //参数2:定义队列是否持久化, true:持久化  false:不持久化
      //参数3:是否独占队列   true:独占   false:不独占
      //参数4:是否消费完成后自动删除队列   true自动删除  false不自动删除
      //参数5:额外附加参数
      channel.queueDeclare(QUEUE_NAME, true, false, false, null);

      String message = "my first rabbitmq transfer1";
      //消息传输
      //参数1:指定交换机
      //参数2:队列名称
      //参数3:消息的额外设置
      //参数4:消息的具体内容
      channel.basicPublish("", QUEUE_NAME, null, message.getBytes());


    } catch (IOException e) {
      e.printStackTrace();
    } catch (TimeoutException e) {
      e.printStackTrace();
    } finally {
      try {
        //关闭资源
        channel.close();
        connection.close();
      } catch (IOException e) {
        e.printStackTrace();
      } catch (TimeoutException e) {
        e.printStackTrace();
      }
    }

  }

}

3.2.2 Work Queues(资源的竞争)

在这里插入图片描述

工作模式,可以在简单模式基础之上,加入多个生产者多个消费者对同一个队列进行发送或接收消息。默认会采用轮询的方式进行消费。

public class ProducerTask {
  private static final String QUEUE_NAME="Myqueue";

  public static void main(String[] args) throws Exception {
    try(Channel channel= RabbitUtil.getChannel();)
    { channel.queueDeclare(QUEUE_NAME,true,false,false,null);
    //从控制台当中接受信息
      Scanner scanner = new Scanner(System.in);
      while (scanner.hasNext()){
        String message = scanner.next();
        channel.basicPublish("",QUEUE_NAME,null,message.getBytes());
        System.out.println("发送消息完成:"+message);
      }
    }
  }
}

3.3 消息应答


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RabbitMQ是一个流行的开源消息代理,它实现了高性能、可靠的消息队列协议。在Java使用RabbitMQ,你需要进行以下步骤: 1. 首先,你需要下载并安装RabbitMQ服务器。你可以从官方网站(https://www.rabbitmq.com/)下载并按照文档中的指导进行安装。 2. 接下来,你需要在Java项目中引入RabbitMQ的依赖。你可以通过在你的构建文件(如pom.xml)中添加以下Maven依赖来实现: ```xml <dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client</artifactId> <version>版本号</version> </dependency> ``` 3. 创建RabbitMQ连接和信道。在Java中,你可以使用`ConnectionFactory`类来创建RabbitMQ连接,使用`Channel`类来创建信道。示例代码如下: ```java import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.client.Connection; import com.rabbitmq.client.Channel; public class RabbitMQDemo { private final static String QUEUE_NAME = "hello"; public static void main(String[] args) throws Exception { ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); // 创建一个队列 channel.queueDeclare(QUEUE_NAME, false, false, false, null); // 发送消息到队列 String message = "Hello, RabbitMQ!"; channel.basicPublish("", QUEUE_NAME, null, message.getBytes()); System.out.println(" [x] Sent '" + message + "'"); channel.close(); connection.close(); } } ``` 4. 接收消息。你可以使用`Consumer`接口和`DefaultConsumer`类来实现消息的消费。示例代码如下: ```java import com.rabbitmq.client.*; public class ReceiveMessageDemo { private final static String QUEUE_NAME = "hello"; public static void main(String[] args) throws Exception { ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); // 创建一个队列 channel.queueDeclare(QUEUE_NAME, false, false, false, null); // 创建消费者对象 Consumer consumer = new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body, "UTF-8"); System.out.println(" [x] Received '" + message + "'"); } }; // 监听队列并消费消息 channel.basicConsume(QUEUE_NAME, true, consumer); } } ``` 这只是RabbitMQJava中的简单使用示例,你可以根据自己的需求进行更复杂的操作,例如使用交换机进行消息路由、使用持久化队列、设置消息确认机制等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值