P:生成者,消息产生者;

C:消息消费者;

红:消息队列;

  1. java实现

步骤:

  1. 创建连接
  2. 从连接中创建通道(相当于JDBC中的Statement)
  3. 通过channel声明(创建)队列。(如果队列存在,则返回,如果不存在,则创建队列)
  4. 向队列中发送消息;
  5. 关闭连接和通道。
package com.j1.rabbitmq.simple;

import com.j1.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

public class Send {

    private final static String QUEUE_NAME = "test_queue";

    public static void main(String[] argv) throws Exception {
        // 获取到连接以及mq通道
        Connection connection = ConnectionUtil.getConnection();
        // 从连接中创建通道
        Channel channel = connection.createChannel();

        // 声明(创建)队列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

        // 消息内容
        String message = "Hello World! 1111";
        channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
        System.out.println(" [x] Sent '" + message + "'");

        //关闭通道和连接
        channel.close();
        connection.close();
    }
}
package com.j1.rabbitmq.simple;

import com.j1.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;

public class Recv {

    private final static String QUEUE_NAME = "test_queue";

    public static void main(String[] argv) throws Exception {

        // 获取到连接以及mq通道
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();

        // 声明队列
        /**
         * 如果队列存在,则返回,如果不存在,则创建
         */
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

        // 定义队列的消费者
        QueueingConsumer consumer = new QueueingConsumer(channel);
        // 监听队列
        channel.basicConsume(QUEUE_NAME, true, consumer);

        // 获取消息
        while (true) {
            QueueingConsumer.Delivery delivery = consumer.nextDelivery();
            String message = new String(delivery.getBody());
            System.out.println(" [x] Received '" + message + "'");
        }
    }
}

  1. 工作模式

一个生成者,多个消费者。

  1. 生产者
package com.j1.rabbitmq.work;

import com.j1.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

public class Send {

    private final static String QUEUE_NAME = "test_queue_work";

    public static void main(String[] argv) throws Exception {
        // 获取到连接以及mq通道
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();

        // 声明队列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

        for (int i = 0; i < 100; i++) {
            // 消息内容
            String message = "" + i;
            channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
            System.out.println(" [x] Sent '" + message + "'");

            Thread.sleep(i * 10);
        }

        channel.close();
        connection.close();
    }
}

消费者1


package com.j1.rabbitmq.work;

import com.j1.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;

public class Recv {

    private final static String QUEUE_NAME = "test_queue_work";

    public static void main(String[] argv) throws Exception {

        // 获取到连接以及mq通道
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();

        // 声明队列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

        // 同一时刻服务器只会发一条消息给消费者,每一次服务器只会向客户端发送一条
        //channel.basicQos(1);

        // 定义队列的消费者
        QueueingConsumer consumer = new QueueingConsumer(channel);
        // 监听队列,手动返回完成
        channel.basicConsume(QUEUE_NAME, false, consumer);

        // 获取消息
        while (true) {
            QueueingConsumer.Delivery delivery = consumer.nextDelivery();
            String message = new String(delivery.getBody());
            System.out.println(" [x] Received '" + message + "'");
            //休眠
            Thread.sleep(10);
            // 返回确认状态
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
        }
    }
}

消费者2


package com.j1.rabbitmq.work;

import com.j1.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;

public class Recv2 {

    private final static String QUEUE_NAME = "test_queue_work";

    public static void main(String[] argv) throws Exception {

        // 获取到连接以及mq通道
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();

        // 声明队列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

        // 同一时刻服务器只会发一条消息给消费者,每一次服务器只会向客户端发送一条
      //  channel.basicQos(1);

        // 定义队列的消费者
        QueueingConsumer consumer = new QueueingConsumer(channel);
        // 监听队列,手动返回完成状态
        channel.basicConsume(QUEUE_NAME, false, consumer);

        // 获取消息
        while (true) {
            QueueingConsumer.Delivery delivery = consumer.nextDelivery();
            String message = new String(delivery.getBody());
            System.out.println(" [x] Received '" + message + "'");
            // 休眠1秒
            Thread.sleep(1000);

            channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
        }
    }
}
  1. 测试

消费者1:

消费者2:

  1. 结论

无论消费者处理消息的速度如何,获取到的消息数量是一致的,这样并不合理,应该是能者多劳,多劳多得。

  1. 设置每次只向客户端发送一条消息

  // 同一时刻服务器只会发一条消息给消费者,每一次服务器只会向客户端发送一条
       channel.basicQos(1);
  1. 结论

这种模式更符合实际项目需要。

  1. 订阅模式

一个生成者,多个消费者,每个消费者获取到的消息是一样的。

1、生成者发送消息到交换机。(生产者可以向队列或者交换机发送消息)

2、消费者监听消息队列,消费者永远只能从队列中获取消息。

3、队列绑定到交换机,获取消息。

  1. 发送消息

  1. 消费者

将队列绑定到交换机,如果不绑定是获取不到消息的。

后面还有

  1. 路由模式
  2. 通配符模式

这里就不在一一详述了,在工作中主要是用订阅模式.

RabbitMQ之总结的更多相关文章

  1. 消息队列——RabbitMQ学习笔记

    消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...

  2. RabbitMq应用二

    在应用一中,基本的消息队列使用已经完成了,在实际项目中,一定会出现各种各样的需求和问题,rabbitmq内置的很多强大机制和功能会帮助我们解决很多的问题,下面就一个一个的一起学习一下. 消息响应机制 ...

  3. 如何优雅的使用RabbitMQ

    RabbitMQ无疑是目前最流行的消息队列之一,对各种语言环境的支持也很丰富,作为一个.NET developer有必要学习和了解这一工具.消息队列的使用场景大概有3种: 1.系统集成,分布式系统的设 ...

  4. RabbitMq应用一的补充(RabbitMQ的应用场景)

    直接进入正题. 一.异步处理 场景:发送手机验证码,邮件 传统古老处理方式如下图 这个流程,全部在主线程完成,注册->入库->发送邮件->发送短信,由于都在主线程,所以要等待每一步完 ...

  5. RabbitMq应用一

    RabbitMq应用一 RabbitMQ的具体概念,百度百科一下,我这里说一下我的理解,如果有少或者不对的地方,欢迎纠正和补充. 一个项目架构,小的时候,一般都是传统的单一网站系统,或者项目,三层架构 ...

  6. 缓存、队列(Memcached、redis、RabbitMQ)

    本章内容: Memcached 简介.安装.使用 Python 操作 Memcached 天生支持集群 redis 简介.安装.使用.实例 Python 操作 Redis String.Hash.Li ...

  7. 消息队列性能对比——ActiveMQ、RabbitMQ与ZeroMQ(译文)

    Dissecting Message Queues 概述: 我花了一些时间解剖各种库执行分布式消息.在这个分析中,我看了几个不同的方面,包括API特性,易于部署和维护,以及性能质量..消息队列已经被分 ...

  8. windows下 安装 rabbitMQ 及操作常用命令

    rabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业消息系统.它遵循Mozilla Public License开源协议,采用 Erlang 实现的工业级的消息队列(MQ)服务器,Rab ...

  9. RabbitMQ + PHP (三)案例演示

    今天用一个简单的案例来实现 RabbitMQ + PHP 这个消息队列的运行机制. 主要分为两个部分: 第一:发送者(publisher) 第二:消费者(consumer) (一)生产者 (创建一个r ...

  10. RabbitMQ + PHP (二)AMQP拓展安装

    上篇说到了 RabbitMQ 的安装. 这次要在讲案例之前,需要安装PHP的AMQP扩展.不然可能会报以下两个错误. 1.Fatal error: Class 'AMQPConnection' not ...

随机推荐

  1. HBase原理、设计与优化实践

    转自:http://www.open-open.com/lib/view/open1449891885004.html 1.HBase 简介 HBase —— Hadoop Database的简称,G ...

  2. 多线程系列八:线程安全、Java内存模型(JMM)、底层实现原理

    一.线程安全 1.  怎样让多线程下的类安全起来 无状态.加锁.让类不可变.栈封闭.安全的发布对象 2. 死锁 2.1 死锁概念及解决死锁的原则 一定发生在多个线程争夺多个资源里的情况下,发生的原因是 ...

  3. Java如何获得运行线程的优先级?

    在Java编程中,如何获得运行线程的优先级? 以下示例使用setPriority()方法打印正在运行的线程的优先级. package com.yiibai; public class GettingT ...

  4. e831. 从JTabbedPane中删除一个卡片

    // To create a tabbed pane, see e828 创建JTabbedPane // Remove the last tab pane.remove(pane.getTabCou ...

  5. Error configuring application listener of class org.springframework.web.context.ContextLoaderListener

    严重:   Error   configuring   application   listener   of   class   org.springframework.web.context.Co ...

  6. MyMathLib系列(行列式计算)

    靠人不如靠己,准备做自己得MathLib,在学校的时候,就想过把数学数理的东西都计算机化.但一直没有时间去做这件事情,如今认为空余 时间比較闲,就做做这件事情,先从线性代数開始,毕竟这里面的非常多算法 ...

  7. Xianfeng轻量级Java中间件平台:功能管理

    功能管理:从功能类型来看,不属于用户使用的功能,而属于系统维护使用的功能,因为对于用户来说,是不可见的.功能管理的作用是定义一套规则,用来处理权限等业务,比如常见的菜单权限控制.按钮权限控制等情景 在 ...

  8. Python:查看矩阵大小,查看列表大小

    对于Python3.5 查看矩阵大小 >>>import numpy as np >>>from numpy import random >>>m ...

  9. DataTable内容导出为CSV文件

    CSVHelper.cs内容: using System; using System.Collections.Generic; using System.Linq; using System.Text ...

  10. MVC多语言设置 实战简洁版

    此方式可以通过更改进行更改进程语言设定,支持从系统获取默认的区域设定,支持自定义,自定义的方式可以为cookie,可为资料库获取,session等方式. 具体怎么设定就看个人需要了. 第一步: 添加资 ...