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. dd&win32diskimager&软碟通Ultraiso 简单分析区别和长处

    在linux操作系统之中的话我们希望烧录镜像到U盘或者是其他的可移动存储设备的话,那么我们就是应当使用dd,但是我估量 在我们的论坛之中根本 之上只有很少的人使用这种工具,很多的使用linux的用户都 ...

  2. (原创)Linux下的floating point exception错误解析

    很多人也许都碰到过这样的错误:linux下程序刚一运行就报错:Floating point exception. 其实这个问题很容易排查,绝大多数情况情况都是逻辑的问题,如:c = a/b;或 c = ...

  3. (笔记)Linux下检测网卡与网线连接状态

    http://blog.chinaunix.net/space.php?uid=20357359&do=blog&cuid=1798479 Linux下检测网卡与网线连接状态,使用io ...

  4. 第三百四十二节,Python分布式爬虫打造搜索引擎Scrapy精讲—爬虫数据保存

    第三百四十二节,Python分布式爬虫打造搜索引擎Scrapy精讲—爬虫数据保存 注意:数据保存的操作都是在pipelines.py文件里操作的 将数据保存为json文件 spider是一个信号检测 ...

  5. 导入Maven项目后,Eclipse提示“Missing artifact ”类的错误

    导入Maven项目后,Eclipse提示“Missing artifact ”类的错误 标签: Maven Missing art 2016-08-15 16:05 679人阅读 评论(0) 收藏 举 ...

  6. python_装饰器模式

    装饰器模式定义:动态地给一个对象添加一些额外的职责. 在Python中Decorator mode可以按照像其它编程语言如C++, Java等的样子来实现,但是Python在应用装饰概念方面的能力上远 ...

  7. T4使用经验

    .<#@ template debug="true" hostspecific="true" language="C#" #> ...

  8. iOS: 自动增高的 textView

    如 iPhone 内应用“信息”的输入框一样,输入文字过多或者输入换行,输入框可以随着内容自动变化.主要是计算内容的尺寸并相应更改输入框的frame.具体表现在: 更改输入框的 frame.origi ...

  9. ubuntu 4.10~5.10 :古老的ubuntu上安装oracle10g的情况

    64位的: 不用想了,安装不上,因为ubuntu库里没有提供编译环境:安装不上gcc-multilib库.也没有libc6-dev-i386库! 自己这点水平,真搞不定! 32位的: 很顺利.很顺利! ...

  10. linux系统负载

    系统负载System Load:系统CPU繁忙程度的度量,即有多少进程在等待被CPU调度 平均负载(Load Average):一段时间内系统的平均负载,这个一段时间一般取1分钟.5分钟.15分钟 查 ...