热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

RabbitMQ入门简单模式

原文:RabbitMQ入门--简单模式本文是作者原创,版权归作者所有.若要转载,请注明出处.本文RabbitMQ版本为rabbitmq-server-3.7.17,erlang为e

原文:RabbitMQ入门--简单模式


本文是作者原创,版权归作者所有.若要转载,请注明出处.

本文RabbitMQ版本为rabbitmq-server-3.7.17,erlang为erlang-22.0.7.请各位去官网查看版本匹配和下载,也可以留言,我发安装包

 


AMQP协议

AMQP 一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。

AMQP是一个二进制协议,拥有一些现代化特点:多信道、协商式,异步,安全,扩平台,中立,高效。

RabbitMQ是AMQP协议的Erlang的实现。

 








































概念说明
连接Connection一个网络连接,比如TCP/IP套接字连接。
会话Session端点之间的命名对话。在一个会话上下文中,保证“恰好传递一次”。
信道Channel多路复用连接中的一条独立的双向数据流通道。为会话提供物理传输介质。
客户端ClientAMQP连接或者会话的发起者。AMQP是非对称的,客户端生产和消费消息,服务器存储和路由这些消息。
服务节点Broker消息中间件的服务节点;一般情况下可以将一个RabbitMQ Broker看作一台RabbitMQ 服务器。
端点AMQP对话的任意一方。一个AMQP连接包括两个端点(一个是客户端,一个是服务器)。
消费者Consumer一个从消息队列里请求消息的客户端程序。
生产者Producer一个向交换机发布消息的客户端应用程序。

 

 

 

 

 

 

 

 

 

 

 


简单队列


1.创建工程,添加依赖


技术分享图片




com.rabbitmq
amqp-client
5.6.0


技术分享图片

2. 编写生产者


技术分享图片

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class Producer {
static final String QUEUE_NAME = "simple_queue";
static final String Host = "192.168.75.163";
static final Integer Port = 5672;
static final String VirtualHost = "/hello";
static final String Username = "test01";
static final String Password = "test01";
public static void main(String[] args) throws Exception{
//创建连接工厂
ConnectionFactory cOnnectionFactory= new ConnectionFactory();
//主机地址:默认为localhost
connectionFactory.setHost(Host);
//连接端口
connectionFactory.setPort(Port);
//虚拟主机名称:默认为 /
connectionFactory.setVirtualHost(VirtualHost);
//连接用户名:默认为guest
connectionFactory.setUsername(Username);
//连接密码: 默认为guest
connectionFactory.setPassword(Password);
//创建连接
Connection cOnnection= connectionFactory.newConnection();
//创建频道
Channel channel = connection.createChannel();
//声明(创建)队列
/*
参数一:队列名称
参数二:是否定义持久化队列
参数三:是否独占本次连接
参数四:是否在不使用的时候自动删除队列
参数五:队列其他参数
*/
channel.queueDeclare(QUEUE_NAME,true,false,false,null);
//要发送的消息
String message = "hello,rabbitmq!";
/**
* 参数1:交换机名称,不能为null 如果没有指定则使用默认Default Exchage
* 参数2:路由key,简单模式可以传递队列名称
* 参数3:消息其它属性
* 参数4:消息内容
*/
channel.basicPublish("",QUEUE_NAME,null,message.getBytes());
System.out.println("已发送消息:"+message);
//释放资源
channel.close();
connection.close();
}
}

 

技术分享图片

我们debug看下消息的产生过程

技术分享图片

 

 

 在这里Connection还没创建

技术分享图片

 

 

 继续下一行

技术分享图片

 

 

 此时Connection创建了,Channel还没创建

技术分享图片

 

技术分享图片

 

 

 继续下一行

技术分享图片

 

 

 技术分享图片

 

 

 此时Channel创建了,Queue还没创建,继续跟

技术分享图片

 

 

 技术分享图片

 

技术分享图片

 

 

 

 

 

  此时Queue创建了,msg还没内容,继续跟

技术分享图片

 

 

 

技术分享图片

 

 

 此时msg已经有内容了,然后释放资源,结束.

此时connection和channel都关闭了,只有queue还在,且有一条消息

技术分享图片

 

 

 


3. 编写消费者

抽取创建connection的工具类


技术分享图片

import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class ConnectionUtil {
private static final String QUEUE_NAME = "simple_queue";
private static final String Host = "192.168.75.163";
private static final Integer Port = 5672;
private static final String VirtualHost = "/hello";
private static final String Username = "test01";
private static final String Password = "test01";
public static Connection getConnection() throws Exception {
//创建连接工厂
ConnectionFactory cOnnectionFactory= new ConnectionFactory();
//主机地址;默认为 localhost
connectionFactory.setHost(Host);
//连接端口;默认为 5672
connectionFactory.setPort(Port);
//虚拟主机名称;默认为 /
connectionFactory.setVirtualHost(VirtualHost);
//连接用户名;默认为guest
connectionFactory.setUsername(Username);
//连接密码;默认为guest
connectionFactory.setPassword(Password);
//创建连接
return connectionFactory.newConnection();
}
}

技术分享图片

编写消息的消费者


技术分享图片

import com.itheima.rabbitmq.util.ConnectionUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
public class Consumer {
public static void main(String[] args) throws Exception {
//获取连接
Connection cOnnection= ConnectionUtil.getConnection();
//创建频道
Channel channel = connection.createChannel();
//创建队列:并设置消息处理
/**
* 参数1:队列名称
* 参数2:是否定义持久化队列
* 参数3:是否独占本次连接
* 参数4:是否在不使用的时候自动删除队列
* 参数5:队列其它参数
*/
channel.queueDeclare(Producer.QUEUE_NAME,
true,false,false,null);
//监听消息
DefaultConsumer cOnsumer= new DefaultConsumer(channel) {
@Override
/*
consumerTag :消息者标签,在channel.basicConsume时候可以指定
envelope: 消息包内容,可从中获取消息id,消息routingkey,交换机,消息和重转标记(收到消息失败后是否需要重新发送)
properties: 消息属性
body: 消息
*/
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//路由key
System.out.println("路由key为:" + envelope.getRoutingKey());
//交换机
System.out.println("交换机为:" + envelope.getExchange());
//消息id
System.out.println("消息id为:" + envelope.getDeliveryTag());
//收到的消息
System.out.println("接收到的消息:" + new String(body, "UTF-8"));
System.out.println(
"");
System.out.println(
"================================================================");
System.out.println(
"");
}
};
/**
* 参数1:队列名称
* 参数2:是否自动确认,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置为false则需要手动确认
* 参数3:消息接收到后回调
*/
channel.basicConsume(Producer.QUEUE_NAME,
true, consumer);
//不应该关闭资源,应该一直监听消息
//channel.close();
//connection.close();
}
}

技术分享图片

这里就不debug看了,直接看结果

技术分享图片

 

 技术分享图片

 

 可以看到,消费者是不应该关闭资源的,并且消息已经消费到了

 


4. 小结

上述的入门案例中中其实使用的是官网如下的简单模式:

技术分享图片

 

 

在上图的模型中,有以下概念:



  • P:生产者,也就是要发送消息的程序

  • C:消费者:消息的接受者,会一直等待消息到来。

  • queue:消息队列,图中红色部分。类似一个邮箱,可以缓存消息;生产者向其中投递消息,消费者从其中取出消息。

在此案例中RabbitMQ运转流程:



  • 生产者发送消息



    1. 生产者创建连接(Connection),开启一个信道(Channel),连接到RabbitMQ Broker;

    2. 声明队列并设置属性;如是否排它,是否持久化,是否自动删除;

    3. 将路由键(空字符串)与队列绑定起来;

    4. 发送消息至RabbitMQ Broker;

    5. 关闭信道;

    6. 关闭连接;


  • 消费者接收消息



    1. 消费者创建连接(Connection),开启一个信道(Channel),连接到RabbitMQ Broker

    2. 向Broker 请求消费相应队列中的消息,设置相应的回调函数;

    3. 等待Broker回应闭关投递响应队列中的消息,消费者接收消息;

    4. 确认(ack,自动确认)接收到的消息;

    5. RabbitMQ从队列中删除相应已经被确认的消息;

    6. 关闭信道;

    7. 关闭连接;


 


推荐阅读
  • 本文详细介绍了如何解决 Microsoft SQL Server 中用户 'sa' 登录失败的问题。错误代码为 18470,提示该帐户已被禁用。我们将通过 Windows 身份验证方式登录,并启用 'sa' 帐户以恢复其访问权限。 ... [详细]
  • 本文探讨了C++编程中理解代码执行期间复杂度的挑战,特别是编译器在程序运行时生成额外指令以确保对象构造、内存管理、类型转换及临时对象创建的安全性。 ... [详细]
  • 深入剖析JVM垃圾回收机制
    本文详细探讨了Java虚拟机(JVM)中的垃圾回收机制,包括其意义、对象判定方法、引用类型、常见垃圾收集算法以及各种垃圾收集器的特点和工作原理。通过理解这些内容,开发人员可以更好地优化内存管理和程序性能。 ... [详细]
  • RabbitMQ 核心组件解析
    本文详细介绍了RabbitMQ的核心概念,包括其基本原理、应用场景及关键组件,如消息、生产者、消费者、信道、交换机、路由键和虚拟主机等。 ... [详细]
  • 本文介绍了如何通过Java代码计算一个整数的位数,并展示了多个基础编程示例,包括求和、平均分计算、条件判断等。 ... [详细]
  • 本题要求在一组数中反复取出两个数相加,并将结果放回数组中,最终求出最小的总加法代价。这是一个经典的哈夫曼编码问题,利用贪心算法可以有效地解决。 ... [详细]
  • 本篇文章介绍如何将两个分别表示整数的链表进行相加,并生成一个新的链表。每个链表节点包含0到9的数值,如9-3-7和6-3相加得到1-0-0-0。通过反向处理链表、逐位相加并处理进位,最终再将结果链表反向,即可完成计算。 ... [详细]
  • MongoDB的核心特性与架构解析
    本文深入探讨了MongoDB的核心特性,包括其强大的查询语言、灵活的文档模型以及高效的索引机制。此外,还详细介绍了MongoDB的体系结构,解释了其文档、集合和数据库的层次关系,并对比了MongoDB与传统关系型数据库(如MySQL)的逻辑结构。 ... [详细]
  • 本文深入探讨了MySQL中常见的面试问题,包括事务隔离级别、存储引擎选择、索引结构及优化等关键知识点。通过详细解析,帮助读者在面对BAT等大厂面试时更加从容。 ... [详细]
  • Django Token 认证详解与 HTTP 401、403 状态码的区别
    本文详细介绍了如何在 Django 中配置和使用 Token 认证,并解释了 HTTP 401 和 HTTP 403 状态码的区别。通过具体的代码示例,帮助开发者理解认证机制及权限控制。 ... [详细]
  • 本文探讨了过度依赖咖啡对生物钟的影响,以及如何合理划分学习和娱乐时间。通过反思,我们认识到即使是快乐的事情也需要适度,培养兴趣爱好应注重沉浸感和心流体验。文章还提供了一些具体的调整建议。 ... [详细]
  • 解决Spring Boot项目创建失败的问题
    在尝试创建新的Spring Boot项目时遇到了一些问题,具体表现为在项目创建过程中的两个关键步骤出现错误。本文将详细探讨这些问题及其解决方案。 ... [详细]
  • 一个登陆界面
    预览截图html部分123456789101112用户登入1314邮箱名称邮箱为空15密码密码为空16登 ... [详细]
  • 本文详细解释了涨停板交易(俗称“打板”)的定义、操作步骤及注意事项。涨停板交易是一种高风险高回报的投资策略,尤其在牛市中表现出色。文中不仅介绍了如何选择和买入涨停股票,还提供了三大纪律以规避风险。 ... [详细]
  • Shell脚本中变量操作详解
    本文基于《鸟哥的Linux私房菜》一书,详细介绍了Shell脚本中变量的使用方法,包括变量的赋值规则、字符串处理技巧以及环境变量的管理等,旨在帮助读者更好地理解和使用Shell中的变量。 ... [详细]
author-avatar
许小晴晴原_890
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有