【学成在线】项目学习笔记day05

RabbitMQ

  • 全称为Message Queue,即消息队列, RabbitMQ是由erlang语言开发,基于AMQP协议实现的消息队列,它是一种应用程序之间的通信方法,消息队列在分布式系统开发中应用非常广泛。

特点

  • 1、使得简单,功能强大。
    2、基于AMQP协议。
    3、社区活跃,文档完善。
    4、高并发性能好,这主要得益于Erlang语言。
    5、Spring Boot默认已集成RabbitMQ

AMQP

  • AMQP(高级消息队列协议)是一个线路层的协议规范,而不是API规范(如JMS)。由于是线路层协议规范,因此它是天然跨平台的,就像smtp,http等协议一样,只要开发者按照它的规范发送数据,任何平台都可以通过AMQP进行消息交互。

JMS消息服务

  • JMS是java提供的一套消息服务API标准,其目的是为所有的java应用程序提供统一的消息通信的标准,类似java的jdbc,只要遵循jms标准的应用程序之间都可以进行消息通信。它和AMQP有什么 不同,jms是java语言专属的消息服务标准,它是在api层定义标准,并且只能用于java应用;而AMQP是在协议层定义的标准,是跨语言的 。

RabbitMQ工作原理图

【学成在线】项目学习笔记day05_第1张图片

  • 总体分为生产者和消费者,发送消息的一方为生产者,接受消息的一方为消费者。
组成说明
  1. Broker :消息队列服务进程,此进程包括两个部分:Exchange和Queue。
  2. Exchange :消息队列交换机,按一定的规则将消息路由转发到某个队列,对消息进行过虑。
  3. Queue :消息队列,存储消息的队列,消息到达队列并转发给指定的消费方。
  4. Producer :消息生产者,即生产方客户端,生产方客户端将消息发送到MQ。
  5. Consumer :消息消费者,即消费方客户端,接收MQ转发的消息。

案例实现

添加依赖
 <dependencies>
        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>4.0.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </dependency>
    </dependencies>
producer类
public class Producer01 {
     
    private final static 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:队列参数
             */
            channel.queueDeclare(QUEUE, true, false, false, null);
            //定义消息内容
            String message = "hello 999黑马程序员!" + System.currentTimeMillis();
                     /**
                      * 消息发布方法
                      * param1:Exchange的名称,如果没有指定,则使用Default Exchange
                      * param2:routingKey,消息的路由Key,是用于Exchange(交换机)将消息转发到指定的消息队列
                      * param3:消息包含的属性
                      * param4:消息体
                      */
            channel.basicPublish("", QUEUE, null, message.getBytes());
            //输出发送的消息
            System.out.println("Send Message is'" + message + "'");
        } catch (Exception e) {
     
            e.printStackTrace();
        } finally {
      //关闭相关的通道和连接
            if (channel != null) {
     
                channel.close();
            }
            if (connection != null) {
     
                connection.close();
            }
        }
    }
}

consumer类

/**
 * 类描述:
 * 消费者类
 *
 * @author xiaoyu
 * on 2020/3/4
 */
public class Consumer01 {
     
    private final static String QUEUE = "helloworld";
    public static void main(String[] args) throws IOException, TimeoutException {
     
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("127.0.0.1");
        factory.setPort(5672);
        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
             */
            @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, "utf-8");
                System.out.println(exchange + "-----" + routingKey + "------" + deliveryTag);
                System.out.println("receive message.." + msg);
            }
        };
            /**
              * 监听队列String queue, boolean autoAck,Consumer callback
              * 参数明细
              * 1、队列名称
              * 2、是否自动回复,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置
     为false则需要手动回复
              * 3、消费消息的方法,消费者接收到消息后调用此方法
            */
            channel.basicConsume(QUEUE,false,consumer);
    }
}

消费者信息展示

【学成在线】项目学习笔记day05_第2张图片

你可能感兴趣的:(【微服务项目】学成在线)