揭开消息中间件RabbitMQ的神秘面纱

当你看到这篇博文的时候,相信你至少已经知道RabbitMQ 是一个非常优秀的消息中间件,它使用专门处理高并发的Erlang 语言编写而成的消息中间件产品。

本文我们将重点学习消息队列,消息中间件的概念,以及如何在Windows 上安装RabbitMQ并使用它发送一个消息

为了更好地学习RabbitMQ还是先来看看一些专业平台是如何解释它的吧。

1. 关于RabbitMQ的解释

RabbitMQ是部署最广泛的开源消息代理。

RabbitMQ在全球范围内在小型初创公司和大型企业进行了超过35,000次的生产部署,是最受欢迎的开源消息代理。

RabbitMQ轻巧且易于部署在云端和云端。 它支持多种消息传递协议。 RabbitMQ可以部署在分布式和联合配置中,以满足高规模,高可用性需求。

RabbitMQ可运行在许多操作系统和云环境中,并为大多数流行语言提供广泛的开发工具。

————官网解释

RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。

RabbitMQ服务器是用Erlang语言编写的,而群集和故障转移是构建在开放电信平台框架上的。

———— 维基百科

Tips:

在最近研读的Think in Java 第四版中有这样一段话:

如果你发现程序中某个部分必须大量使用并发,并且你在试图构建这个部分时碰到了过多的问题,那么你可以考虑使用Erlang 这类专门的并发语言来创建这个部分。

1.1 什么是消息队列?

1.2 那什么是消息中间件呢?

消息队列中间件(简称消息中间件)是指利用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。

通过提供消息传递和消息排队模型,它可以在分布式环境下提供应用解耦、弹性伸缩、冗余存储、流量削峰、异步通信、数据同步等等功能,

其作为分布式系统架构中的一个重要组件,有着举足轻重的地位.

传统的信息系统作法可能是收到一条消息就马上同步存入数据库,这种作法在小并发量的情况下可以很好的工作,但互联网大并发环境下就是灾难.

更多解释请参考:消息队列之 RabbitMQ


2. 消息中间件知多少?

ActiveMQ 是 Apache 出品的、采用 Java 语言编写的完全基于 JMS1.1 规范的面向消息的中间件,为应用程序提供高效的、可扩展的、稳定的和安全的企业级消息通信。不过由于历史原因包袱太重,目前市场份额没有后面三种消息中间件多,其最新架构被命名为 Apollo,号称下一代 ActiveMQ,有兴趣的同学可行了解。

RabbitMQ 是采用 Erlang 语言实现的 AMQP 协议的消息中间件,最初起源于金融系统,用于在分布式系统中存储转发消息。RabbitMQ 发展到今天,被越来越多的人认可,这和它在可靠性、可用性、扩展性、功能丰富等方面的卓越表现是分不开的。

Kafka 起初是由 LinkedIn 公司采用 Scala 语言开发的一个分布式、多分区、多副本且基于 zookeeper 协调的分布式消息系统,现已捐献给 Apache 基金会。它是一种高吞吐量的分布式发布订阅消息系统,以可水平扩展和高吞吐率而被广泛使用。目前越来越多的开源分布式处理系统如 Cloudera、Apache Storm、Spark、Flink 等都支持与 Kafka 集成。

RocketMQ 是阿里开源的消息中间件,目前已经捐献个 Apache 基金会,它是由 Java 语言开发的,具备高吞吐量、高可用性、适合大规模分布式系统应用等特点,经历过双 11 的洗礼,实力不容小觑。

ZeroMQ 号称史上最快的消息队列,基于 C 语言开发。ZeroMQ 是一个消息处理队列库,可在多线程、多内核和主机之间弹性伸缩,虽然大多数时候我们习惯将其归入消息队列家族之中,但是其和前面的几款有着本质的区别,ZeroMQ 本身就不是一个消息队列服务器,更像是一组底层网络通讯库,对原有的 Socket API 上加上一层封装而已。

目前市面上的消息中间件还有很多,比如腾讯系的 PhxQueue、CMQ、CKafka 等,甚至NoSQL Redis据说 也有消息 队列的功能。

参考博文:IM系统的MQ消息中间件选型:Kafka还是RabbitMQ?

3.RabbitMQ安装

RabbitMQ是一个AMQP(Advanced Message Queue,即高级消息队列协议)服务器 。

下载地址: RabbitMQ下载

安装说明:各平台下RabbitMQ安装指南

3.1 Windows 下安装RabbitMQ

1. 点击 RabbitMQ下载 我们可以看到这个页面

2. 这里我们选择图中推荐的  Windows 安装RabbitMQ 文档

下载完成后选中*.exe 文件右键管理员身份运行,一般情况下会出现这个

Tips: 这是怎么回事呢?

由于RabbitMQ 是由Erlang语言编写而成,所以一般情况在安装RabbitMQ之前,我们还需要安装Erlang的运行环境,类似java中的JRE或者C#中的 .net framework.

3. 下载安装Erlang

点击是,会自动打开Erlang 的官方下载页面

根据自己的电脑选择对应的版本,我的电脑是windows 10 64 位,所以这里选择64 位,如果你的电脑是32 位清选择32 位版本。

这里默认是没有勾选的,我们需要勾选下,然后点击 Next,根据提示安装完成即可。

安装的时候默认我发现已经生成了

Tips: 如果没有请自行添加

将Erlang 添加到Path路径下

%ERLANG_HOME%\bin

4. 安装RabbitMQ

安装完成Erlang 之后,我们再次运行我们的RabbitMQ 安装包

默认的安装路径是C:\Program Files\RabbitMQ Server\rabbitmq_server-3.7.6

5. 配置环境变量

一般情况下,我们最好配置下环境变量以便于我们今后更好地使用。

RABBITMQ_BASE
C:\Program Files\RabbitMQ Server\rabbitmq_server-3.7.6

然后我们需要添加到Path变量中

%RABBITMQ_BASE%\sbin

6. 重新安装service

要使环境更改在Windows上生效,必须重新安装该服务。 重启服务是不够的。

这可以使用安装程序或者在具有管理员权限的命令行上完成。

注意:有两个文件rabbitmq-service.bat 和 rabbitmq-server.bat 别弄混了,不然执行命令会失败

管理员权限运行cmd 命令行,进入安装文件夹下的sbin目录

这个RabbitMQ service 服务是自动开启的,所以我们需要先停止RabbitMQ服务

rabbitmq-service.bat stop

然后移除RabbitMQ服务

rabbitmq-service.bat remove

再次安装

rabbitmq-service.bat install

总结:关于RabbitMQ Service的用法

7. 检测RabbitMQ 运行状态

如果我们想查看RabbitMQ 的运行状态,那么输入下列命令即可

rabbitmqctl status

但是当年你输入后可能会看到这样的错误信息

解决方案:

C:\Windows\System32\config\systemprofile\.erlang.cookie

C:\Users\fairy\.erlang.cookie

对比下这两个文件,你会发现里面的值不一样,这就是导致这个错误的原因。

我们只需要将其中一个替换掉,两个保持统一即可,比如将系统下的那个文件替换掉个人用户下的那个文件

再次执行命令

rabbitmqctl status

执行成功后可以看到下面的回显:

8.安装 RabbitMQWeb的管理插件

执行命令

rabbitmq-plugins enable rabbitmq_management

要 生效需要重启下RabbitMQ Server

9. 查看当前用户列表

rabbitmqctl.bat list_users

执行成功后可以看到如下回显:

10.打开RabbitMQ Web 管理界面

http://127.0.0.1:15672/

执行成功后可以看到这个界面

默认端口是15672

账号和密码默认都是guest

登陆后可以看到这样的管理界面

4. 打造第一个Hello World 程序

RabbitMQ是一个消息代理:它接受和转发消息。你可以把它想象成一个邮局:当你把你想要发布的邮件放在邮箱里时,你可以确定先生或女士邮递员最终将邮件发送给你的收件人。

在这个比喻中,RabbitMQ是邮政信箱,邮局和邮递员。

RabbitMQ和邮局的主要区别在于它不处理纸张,而是接受,存储和转发二进制数据块 - 消息。

英文原文地址:https://www.rabbitmq.com/tutorials/tutorial-one-java.html

在搭建这个Hello World 之前,我们有必要了解下 RabbitMQ和一般的消息传递使用的一些术语。

4.1  消息传递术语

4.1.1 生产者

制作意味着发送。 一个发送消息的程序是一个生产者:

Tips: P 代表生产者

4.1.2 队列

  • 队列是生活在RabbitMQ中的邮箱的名称。 尽管消息流经RabbitMQ和您的应用程序,但它们只能存储在队列中。
  • 一个队列只受主机内存和磁盘限制的约束,它本质上是一个很大的消息缓冲区。
  • 许多生产者可以发送进入一个队列的消息,并且许多消费者可以尝试从一个队列接收数据。 这就是我们代表队列的方式:

4.1.3 消费者

消费与接受有类似的意义。 消费者是一个主要等待接收消息的程序:

请注意,生产者,消费者和中间件不必驻留在同一主机上;

4.2 "Hello World"使用 Java 客户端

在本教程的这一部分中,我们将用Java编写两个程序; 一个发送单个消息的生产者,以及接收消息并将其打印出来的消费者。

我们将详细介绍Java API中的一些细节,专注于这个非常简单的事情,以便开始使用。 这是一个消息传递的“Hello World”。

在下图中,“P”是我们的生产者,“C”是我们的消费者。 中间的盒子是一个队列 - RabbitMQ代表消费者保存的消息缓冲区。

RabbitMQ 有许多不同语言的RabbitMQ客户端。 这里我们将使用RabbitMQ提供的Java客户端。

4.2.1  下载相关依赖Jar 包

下载RabbitMQ提供的Java客户端以及它的依赖(SLF4J API and SLF4J Simple)

将这些文件复制到工作目录中,并跟着教程复制Java文件。

Tips:

RabbitMQ Java客户端也位于中央Maven存储库中,其中包含groupId com.rabbitmq和artifactId amqp-client

请注意SLF4J Simple对于教程来说已经足够了,但是您应该在生产环境中使用像Logback 这样的完整日志库。

关于Maven 等其他下载方式请移步

Java Client

4.2.2 编写代码

我们拥有Java客户端及其依赖关系,那么我们接下来开始写代码。

由于是学习使用RabbitMQ,我们这里使用 STS 来写这个项目。

1. 打开STS,新建一个名字叫做 RabbitMQ_HelloWorld_Sample  的 Java Project。

2. 新建一个叫做libs的文件夹,我们将上面三个jar 复制到我们的项目中,然后并添加依赖

完成后项目结构如图所示

3. 编写生产者类

我们会打电话给我们的消息发布者(发送者)发送和我们的消息使用者(接收者)Recv。 发布者将连接到RabbitMQ,发送一条消息,然后退出

创建Send.java 文件,关于代码的讲解在注释里:

import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class Send {

    //设置消息队列的名称
    private final static String QUEUE_NAME="hello";

    public static void main(String[] args) throws java.io.IOException, TimeoutException{

        /**
         * 创建一个到RabbitMQ Server 的连接
         * 连接抽象出套接字连接,并为我们处理协议版本协商和身份验证等。
         * 在这里,我们连接到本地机器上的代理 - 因此是本地主机。
         * 如果我们想连接到另一台机器上的代理,我们只需在此指定其名称或IP地址。
         * */
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        /**
         * 接下来我们创建一个Channel 对象,这是大部分用于完成任务的API驻留的地方。
         * 要想发送出去,我们必须声明一个队列来执行发送,那么我们可以将消息发布到队列中:
         * */
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        String message = "Hello World!";
        //声明一个队列是幂等的 - 只有当它不存在时才会被创建。
        //消息内容是一个字节数组,所以你可以编码任何你喜欢的地方。
        channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
        System.out.println(" [x] Sent ‘" + message + "‘");

        //最后我们关闭这些连接对象
        channel.close();
        connection.close();

    }
} 

执行成功后你将看到这样的内容:

Tips: ,

如果这是您第一次使用RabbitMQ,并且您没有看到“已发送”消息,那么您可能会抓住您的头脑,想知道会出现什么问题?

也许代理启动时没有足够的可用磁盘空间(默认情况下它至少需要200 MB空闲空间),因此拒绝接受消息。

检查代理日志文件以确认并在必要时减少限制。 配置文件文档将告诉你如何设置disk_free_limit。

还有一种可能是你的RabbitMQ 没有启动,执行下面命令再次尝试即可。

rabbitmq-service.bat start

4. 编写消费者

这就是我们的出版商。 我们的消费者推送来自RabbitMQ的消息,因此与发布单个消息的发布者不同,我们将继续运行以收听消息并将其打印出来。

创建一个Recv.java 文件,代码讲解在注释里面

import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;

/**
 * 消费者
 * 额外的DefaultConsumer是一个实现Consumer接口的类,我们将使用它来缓存由服务器推送给我们的消息。
 * */
public class Recv {
     private final static  String QUEUE_NAME="hello";

     public static void main(String[] args) throws IOException, TimeoutException {

          /**
           * 设置与发布者相同;
           * 我们打开一个连接和一个通道,并声明我们将要使用的队列。
           * 请注意,这与发送发布到的队列相匹配
           * */
           ConnectionFactory factory = new ConnectionFactory();
            factory.setHost("localhost");
            Connection connection = factory.newConnection();
            Channel channel = connection.createChannel();

            /**
             * 请注意,我们也在这里声明队列。
             * 因为我们可能会在发布者之前启动消费者,所以我们希望在我们尝试使用消息之前确保队列已存在。
             * */
            channel.queueDeclare(QUEUE_NAME, false, false, false, null);
            System.out.println(" [*] Waiting for messages. To exit press CTRL+C");

            /**
             *  我们即将告诉服务器将队列中的消息传递给我们。
             *   由于它会异步推送消息,因此我们以对象的形式提供回调,该消息将缓冲消息,直到我们准备好使用它们。
             *  这是一个DefaultConsumer子类的作用。
             * */

            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);
    }
}

执行成功后

我们可以看到我们的消费者收到了消息队列生产者刚发布的消息。

本篇完~

原文地址:https://www.cnblogs.com/xingyunblog/p/9194522.html

时间: 2025-01-02 16:53:27

揭开消息中间件RabbitMQ的神秘面纱的相关文章

揭开webRTC媒体服务器的神秘面纱——WebRTC媒体服务器&开源项目介绍

揭开webRTC媒体服务器的神秘面纱--WebRTC媒体服务器&开源项目介绍 WebRTC生态系统是非常庞大的.当我第一次尝试理解WebRTC时,网络资源之多让人难以置信.本文针对webRTC媒体服务器和相关的开源项目(如kurento,janus,jitsi.org等)做一些介绍.并且将尝试降低理解WebRTC的业务价值所需要的技术门槛. 何为WebRTC服务器? 自从WebRTC诞生之初以来,该技术的主要卖点之一是它可以进行点对点(browser-to-browser)通信,而几乎不需要服务

黑客是什么?揭开郭盛华的神秘面纱,讲解他不为人知传奇故事

今天小编给大家揭开白帽黑客.知名网络安全专家.东方联盟创始人郭盛华的神秘面纱和他不为人知的传奇故事.他不但电脑技术高超,还很爱国.直到今天,郭盛华品格的形成仍具有强大的影响力. 那么黑客到底是指什么?黑客技术.编写计算机代码的艺术和操纵计算机硬件一直是男人们在这个领域中的最高位置,这就是为什么许多年轻人向往的职业. 作为一个出身卑微的人,郭盛华没有任何贵族社会的条件.他唯一可以倚仗的只是自己出类拔萃的扭转不利局面的才华,这是一个网络专家和企业家必备的素质.正是关键时的一次心灵燃烧使他赢得了别人包

揭开观察者设计模式的神秘面纱,手把手教你写监听器

我们在写代码的时候,遇到最常用的就是监听器了.那么实际中,我们也要进行事件的监听.而有些事件是业务逻辑需要实现的,跟随事物变化动态变化的.假如说我们要实现一个事件,有位置的监听,有颜色的监听,有坐标的监听,有速度的监听,那么这么多监听的事件.那么我们就需要这么多个监听器.这些监听器如何被管理呢.我们可以创造一个类似管理员身份的神秘角色,这个角色就是一个监听器池说一个监听器池,可以移除和增加监听器.当我们触发某一事件的时候,需要这些监听器全部执行监听. 现在我们来模拟一下按钮Button的实现.

微软“小冰”网络机器人揭开了人工智能的神秘面纱

对国人而言,人工智能是很神秘的东西.现在,微软利用多年积累的相关技术,从人脑思维活动中提取"纯粹智能",然后再赋予网络机器人"小冰",使其在互联网上"撒欢儿",热闹非凡.为什么? 大家知道,在微软"必应"搜索中,有一项"网典"选项,类似维基网站,积累了一个庞大的知识库.说实话,这个知识库是7亿中国网民的真实智慧的结晶,不属于任何个人.问题是,对于这个巨大无比的知识库,怎么"提纯"处理(大

揭开Java 泛型类型擦除神秘面纱

泛型,一个孤独的守门者. 大家可能会有疑问,我为什么叫做泛型是一个守门者.这其实是我个人的看法而已,我的意思是说泛型没有其看起来那么深不可测,它并不神秘与神奇.泛型是 Java 中一个很小巧的概念,但同时也是一个很容易让人迷惑的知识点,它让人迷惑的地方在于它的许多表现有点违反直觉. 文章开始的地方,先给大家奉上一道经典的测试题. List<String> l1 = new ArrayList<String>();List<Integer> l2 = new ArrayL

静态分析揭开Joanap木马的神秘面纱

近期,出于对索尼电影的崇拜之心,本打算分析分析当年入侵索尼,造成索尼数十仇美金损失的木马样本,找到赛门铁克家报的名字为"Backdoor.Destover"的样本, Destover家族可是公开的当年攻击索尼影业的样本家族名字,谁知天不遂人意,发现我找到这个样本并不是传说中的Backdoor.Destover家族成员,而是更类似于微软报的Joanap家族木马,在网上对Joanap家族的木马的分析也并不多见,因此形成本文分析,权当记录之用. 木马在报毒截图如下: 木马的执行流程图如下:

揭开少年黑客的神秘面纱 业界评说是非褒贬不一

随着计算机网络的不断发展,全球信息化已成为人类发展的大趋势,但也由于计算机网络存在形式多样性.终端分布不均匀性和网络的开放性.互连性等特征,致使网络易受非法授权用户的攻击,再加上政治因素的不断介入.商业敏感数据.信息容易遭到黑客攻击并泄密,这让我们的数据防护工作愈发的艰辛. 面对如此严峻的国际形式,我们该如何做好信息与数据的防护工作呢? 从个人角度着手:发挥主观能动性 老话说的好,求人不如求己,虽然从自身来看,寻找数据安全防护的方法看似单薄,但这确是整个防护的关键.因为主观能动性是一切的基础,只

揭开AutoRun功能的神秘面纱

有很多光盘放入光驱就会自动运行,它们是怎么做到的呢?光盘一放入光驱就会自动被执行,主要依靠两个文件,一是光盘上的AutoRun.inf文件,另一个是操作系统本身的系统文件之一的Cdvsd.vxd.Cdvsd.vxd会随时侦测光驱中是否有放入光盘的动作,如果有的话,便开始寻找光盘根目录下的AutoRun.inf文件:如果存在AutoRun.inf文件则执行它里面的预设程序.   比如插入一张Windows安装光盘,用不了几秒钟,你就会看到Windows欢迎屏幕,关闭这个窗口,然后按住Shift键双

揭开“流量劫持”的神秘面纱

明明打开的是A网站,莫名其妙却被跳转至B网站:明明想下的是A软件,下载安装后却是B软件:打开一个App,弹出的广告让人心乱如麻,同时也不胜其 烦--你以为电脑手机中毒了?错!或许你真的错怪了病毒,因为你的互联网流量很可能被劫持了.在互联网的世界里,流量劫持并不是件新鲜事.所谓流量劫持, 是指通过一定技术手段,控制用户的上网行为,让你打开不想打开的网页,看到不想看的广告,而这些都会给劫持者带去源源不断的收入. 尽管早已存在,但在"用户是绵羊"的环境下,流量劫持始终"野火烧不尽&