RabbitMQ(一)——入门

2023-10-29

前言

原来公司项目的消息中间件一直在用RabbitMQ,今天抽出时间简单总结梳理一下关于RabbitMQ的相关知识点。我们知道消息队列在分布式系统中应用的的地方有很多,它也有很多种类型,除了今天重点介绍的RabbitMQ,还有像ActiveMQ,阿里的RocketMQ,在大数据场景中经常用到的Kafka,还有一些其他的诸如ZeroMQ,MetaMQ等等。ActiveMQ在之前其实一直很火,许多公司的项目也都在使用,但近来它的社区变得不太活跃,因此工作中遇到相关问题的时候,对应的解决方案不是太好找,所以现在ActiveMQ慢慢变得不如从前那么流行了,而RabbitMQ、Kafka等正在慢慢的占据主流。

不废话了,开始讲解我们今天的重点RabbitMQ吧。今天入门主要讲解下面三个部分:

目录

一、RabbitMQ的下载安装

二、RabbitMQ的工作原理

三、RabbitMQ入门测试


一、RabbitMQ的下载安装

RabbitMQ由Erlang语言开发的,所以我们要向在项目中用RabbitMQ,除了要安装RabbitMQ外还需要安装erlong语言以确保对RabbitMQ的环境支持。另外需要注意的一点是在安装RabbitMQ和erlong的时候,要确保二者的版本相互匹配兼容,我用的RabbitMQ是3.7.10版本erlong是21.3版本。

1.下载erlong

erlong下载地址:http://www.erlang.org/downloads

下载好以后,以管理员方式运行此文件,安装,除了安装目录可以自己选择一下外,其他的一路下一步即可。

同java一样,erlang安装完成需要配置erlang的环境变量:

ERLANG_HOME=D:\others\erlong\erl10.3

在path中添加%ERLANG_HOME%\bin

2.下载RabbitMQ

RabbitMQ的下载地址:http://www.rabbitmq.com/download.html

下载完成后,以管理员方式运行此文件,安装。

3.启动RabbitMQ

安装成功后会自动创建RabbitMQ服务并且启动。我们可以到系统服务列表中找一下,如下图已经启动了

如果没有启动则进入安装目录下的sbin目录手动启动:

4.安装RabbitMQ的管理插件

安装rabbitMQ的管理插件,主要是方便我们在浏览器端输入网址后进入RabbitMQ的后台管理RabbitMQ。

在命令行下进入RabbitMQ安装目录的sbin目录下,输入指令:rabbitmq-plugins.bat enable rabbitmq_management

之后我们就可以通过http://localhost:15672进入到RabbitMQ的管理后台了,如下(账号密码默认的均为guest):

 

 

二、RabbitMQ的工作原理

上图是RabbitMQ的基本结构,我们来对其中的各个部分做简单说明:

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

首先消息生产者想要发送消息给RabbitMQ必须先与其建立连接(connect)这个连接的底层是通过socket实现的,我们不必太过关心。在连接的内部其实有很多通道(Channel),具体的消息发送其实就是通过这些通道发送到RabbitMQ的。而消息的消费者一方要想拿到RabbitMQ中的消息也必须与其建立连接,这个连接(包括里面的通道)和生产者一方是一样的。对上方的几个概念有大体的了解即可,我们会在接下来的部分结合实际案例来详细说明各个部分的功能作用。

总结——消息发布接收流程:

    发送消息:

  1. 生产者和Broker建立TCP连接
  2. 生产者和Broker建立通道
  3. 生产者通过通道消息发送给Broker,由Exchange将消息进行转发
  4. Exchange将消息转发到指定的Queue(队列)

    接收消息:

  1. 消费者和Broker建立TCP连接
  2. 消费者和Broker建立通道
  3. 消费者监听指定的Queue(队列)
  4. 当有消息到达Queue时Broker默认将消息推送给消费者
  5. 消费者接收到消息

三、RabbitMQ入门测试

进过第一步的RabbitMQ安装和第二步RabbitMQ原理的简单介绍,现在我们简单的写个测试,让消息生产端发送一个“hello world”到MQ,然后由MQ转到消息消费端。这里需要注意一点:不管是消息的生产者和还是消费者,相对于RabbitMQ它们二者都属于客户端。所以在创建对应的对应时要添加RabbitMQ的客户端依赖,我们这里先用 rabbitMQ官方提供的java client测试,目的是对RabbitMQ的交互过程有个清晰的认识。

1.创建maven工程

创建生产者工程和消费者工程,分别加入RabbitMQ客户端 java client的依赖。

test-rabbitmq-producer:生产者工程
test-rabbitmq-consumer:消费者工程

二者的pom.xml文件相同,都为如下内容

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
        http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <!--每一个springboot工程都必须有这个依赖-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <artifactId>test-rabbitmq-producer</artifactId>

    <dependencies>
        <!--RabbitMQ的客户端依赖-->
        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>5.7.0</version>
        </dependency>
        <!--记录日志-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </dependency>
    </dependencies>
</project>

2.生产者Producer01

在生产者工程下的test中创建测试类如下:

这里是作为入门程序为了让大家对RabbitMQ的工作过程有大体了解,并对每个参数大体有个印象,所以代码有点多。其实在实际项目中通过在springboot中引入别的客户端依赖,我们只需要写很少的代码就可以完成下面同样的功能。

public class Producer01 {
    //申明队列
    private static final String QUEUE = "helloworld";
    public static void main(String[] args) {
        //第一步:生产者和Broker建立TCP连接。
        //通过连接工厂创建新的连接和mq建立连接
        ConnectionFactory connectionFactory = new ConnectionFactory();
        //设置ip地址,我们在本地所以直接是127.0.0.1
        connectionFactory.setHost("127.0.0.1");
        //设置端口,RabbitMQ默认端口即为5672
        connectionFactory.setPort(5672);
        //设置账号和密码
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        //设置虚拟机,一个mq服务可以设置多个虚拟机,每个虚拟机就相当于一个独立的mq。这里不理解可以暂时略过
        connectionFactory.setVirtualHost("/");

        Connection connection = null;
        Channel channel = null;
        try {
            //建立新连接
            connection = connectionFactory.newConnection();
            //第二步:生产者和Broker建立通道。
            //创建会话通道,生产者和mq服务所有通信都在channel通道中完成
            channel = connection.createChannel();
            //声明队列,如果队列在mq中已经存在则使用已有的,如果没有则创建新的
            /**
             * 参数明细:String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments
             * 1、queue 队列名称
             * 2、durable 是否持久化,如果持久化,mq重启后队列还在
             * 3、exclusive 是否独占连接,队列只允许在该连接中访问,如果connection连接关闭队列则自动删除,如果将此参数设置true可用于临时队列的创建
             * 4、autoDelete 自动删除,队列不再使用时是否自动删除此队列,如果将此参数和exclusive参数设置为true就可以实现临时队列(队列不用了就自动删除)
             * 5、arguments 参数,可以设置一个队列的扩展参数,比如:可设置存活时间等
             */
            channel.queueDeclare(QUEUE,true,false,false,null);
            //第三步:生产者通过通道消息发送给Broker,由Exchange将消息进行转发。
            /**
             * 参数明细:String exchange, String routingKey, BasicProperties props, byte[] body
             * 1、exchange,交换机,如果不指定将使用mq的默认交换机(设置为"")
             * 2、routingKey,路由key,交换机根据路由key来将消息转发到指定的队列,如果使用默认交换机,routingKey设置为队列的名称
             * 3、props,消息的属性
             * 4、body,消息内容
             */
            //消息内容
            String message = "hello world!";
            channel.basicPublish("",QUEUE,null,message.getBytes());
            System.out.println("send to mq "+message);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭连接
            //先关闭通道
            try {
                channel.close();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (TimeoutException e) {
                e.printStackTrace();
            }
            try {
                //再关闭连接
                connection.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

3.生产者Consumer01

在消费者工程下的test中创建测试类如下:

public class Consumer01 {
    //申明队列,要与生产者的保持一致
    private static final String QUEUE = "helloworld";
    public static void main(String[] args) throws IOException, TimeoutException {
        //第一步:消费者和Broker建立TCP连接
        //通过连接工厂创建新的连接和mq建立连接
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        //设置虚拟机,一个mq服务可以设置多个虚拟机,每个虚拟机就相当于一个独立的mq
        connectionFactory.setVirtualHost("/");

        //建立新连接
        Connection connection = connectionFactory.newConnection();
        //第二步:消费者和Broker建立通道。
        //创建会话通道,消费者和mq服务所有通信都在channel通道中完成
        Channel channel = connection.createChannel();

        //第三步:消费者监听指定的Queue(队列)
        //声明队列,如果队列在mq中已经存在则使用已有的,如果没有则创建新的
        /**
         * 参数明细:String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments
         * 1、queue 队列名称
         * 2、durable 是否持久化,如果持久化,mq重启后队列还在
         * 3、exclusive 是否独占连接,队列只允许在该连接中访问,如果connection连接关闭队列则自动删除,如果将此参数设置true可用于临时队列的创建
         * 4、autoDelete 自动删除,队列不再使用时是否自动删除此队列,如果将此参数和exclusive参数设置为true就可以实现临时队列(队列不用了就自动删除)
         * 5、arguments 参数,可以设置一个队列的扩展参数,比如:可设置存活时间
         */
        channel.queueDeclare(QUEUE,true,false,false,null);
        //第四步:实现消费方法,当有消息到达Queue时Broker默认将消息推送给消费者。
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel){
            /**
             * 当接收到消息后此方法将被调用,
             * @param consumerTag  消费者标签,用来标识消费者的,在监听队列时设置channel.basicConsume
             * @param envelope 信封,通过envelope
             * @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();
                //消息id,mq在channel中用来标识消息的id,可用于确认消息已接收
                long deliveryTag = envelope.getDeliveryTag();
                //消息内容
                String message= new String(body,"utf-8");
                System.out.println("receive message:"+message);
            }
        };
        //监听队列
        /**
         * 参数明细:String queue, boolean autoAck, Consumer callback
         * 1、queue 队列名称
         * 2、autoAck 自动回复,当消费者接收到消息后要告诉mq消息已接收,如果将此参数设置为tru表示会自动回复mq,如果设置为false要通过编程实现回复
         * 3、callback,消费方法,当消费者接收到消息要执行的方法
         */
        channel.basicConsume(QUEUE,true,defaultConsumer);
    }
}

4.运行测试

现在我们先把Producer01类运行起来,然后通过浏览器登录到RabbitMQ的后台,可以看到总共有一条待发送的消息,如下:

这时我们再把Consumer01这个类启动起来,在控制台看到如下日志,说明消费端启动起来以后,mq就把其队列中从producer01接收到的消息发送给了Consumer01。再到RabbitMQ的后台看一看发现现在的待发送消息已经变为了0条

receive message:hello world!

5.流程总结

通过上面的代码编写,我们简单的总结一下生产端和消费端的操作流程。

生产端:

  • 创建连接
  • 创建通道
  • 声明队列
  • 发送消息

消费端:

  • 创建连接
  • 创建通道
  • 声明队列
  • 监听队列
  • 接收消息
  • ack回复

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RabbitMQ(一)——入门 的相关文章

  • 每次发布后我应该关闭通道/连接吗?

    我在 Node js 中使用 amqplib 但我不清楚代码中的最佳实践 基本上 我当前的代码调用amqp connect 当 Node 服务器启动时 然后为每个生产者和每个消费者使用不同的通道 而不会真正关闭它们中的任何一个 我想知道这是
  • RabbitMQ 中多个消费者如何订阅同一主题并获取同一消息

    首先 我知道类似问题已经有答案了here https stackoverflow com questions 10620976 rabbitmq amqp single queue multiple consumers for same m
  • Spring AMQP RabbitMQ 如何直接发送到Queue而不需要Exchange

    我正在使用 Spring AMQP 和 Rabbitmq 模板 如何直接将消息发送到队列而不使用Exchange 我该怎么做 我该怎么做 你不能 发布者不知道队列 只是交换和路由密钥 但是 所有队列都绑定到默认交换器 以队列名称作为其路由键
  • 如何在多租户系统中的 RabbitMQ 中使队列私有/安全?

    我已阅读开始使用 http www rabbitmq com getstarted htmlRabbitMQ 提供的指南 甚至还贡献了第六个示例暴风雨 amqp https github com paolo losi stormed amq
  • 死信交换 RabbitMQ 丢弃消息

    我正在尝试在 RabbitMQ 中实现 dlx 队列 场景很简单 我有 2 个队列 1 活着 2 死亡 x dead letter exchange 立即 x message ttl 5000 以及 立即 交换 这必然是 1 活着 我尝试运
  • 在 Windows 10 和 PHP 7.3 中安装 AMQP

    我想在 Windows 10 中使用 PHP 7 3 安装 AMQP 以便在 symfony 4 中使用 Windows 不使用任何 apache iis nginx 并直接由 symfony 运行 一切还好 直到 我决定在项目中使用rab
  • Celery 与rabbitmq 创建结果多个队列

    我已经用 RabbitMQ 安装了 Celery 问题是 对于返回的每个结果 Celery 都会在 Rabbit 中创建队列 并在交换 celeryresults 中使用任务 ID 我仍然想得到结果 但在一个队列上 我的芹菜配置 from
  • 即使设置了 cookie,RabbitMQ 身份验证也会失败

    我最近在运行 lattePanda 的 Windows 10 上安装了带有 ErlanOTP 的rabbitmq 我运行rabbitmqctl status并收到以下错误 C Program Files RabbitMQ Server ra
  • 更改 RabbitMQ 队列中的参数

    我有一个 RabbitMQ 队列 最初声明如下 var result channel QueueDeclare NewQueue true false false null 我正在尝试添加死信交换 因此我将代码更改为 channel Exc
  • 面向服务的架构 - AMQP 或 HTTP

    一点背景 非常大的整体 Django 应用程序 所有组件都使用相同的数据库 我们需要分离服务 以便我们可以独立升级系统的某些部分而不影响其余部分 我们使用 RabbitMQ 作为 Celery 的代理 现在我们有两个选择 使用 REST 接
  • rabbitmq 的 REST API

    有没有办法从 ajax 向 RabbitMQ 发送数据 我的应用程序由数千个 Web 客户端 用 js 编写 和 WCF REST 服务组成 现在我试图弄清楚如何为我的应用程序创建可扩展点 这个想法是有一个rabbitmq实例 它从放置在一
  • 从 Java/Spring 检索 RabbitMQ 队列中未确认消息的数量

    有没有办法返回未确认的消息数 我正在使用此代码来获取队列中的消息数 DeclareOk declareOk amqpAdmin getRabbitTemplate execute new ChannelCallback
  • 从 RabbitMQ 迁移到 Amazon SQS [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我们的初创公司目前正在使用RabbitMQ with Python Django 对于消息队列 现在我们计划转移到Amazon SQS其高可用性
  • 使用 Spring 与 RabbitMQ 集成

    我正在为我们的一个应用程序开发消息传递界面 该应用程序是一种服务 旨在接受 作业 进行一些处理并返回结果 实际上以文件的形式 这个想法是使用 RabbitMQ 作为消息传递基础设施 并使用 Spring AMQP 来处理协议特定的细节 我不
  • RabbitMQ 中的 celeryev 队列变得非常大

    我在rabbitmq上使用celery 我已经向队列发送了数千条消息 它们正在成功处理 一切正常 然而 几个rabbitmq队列中的消息数量增长得相当大 队列中有数十万个项目 队列被命名为celeryev 见下面的截图 这是适当的行为吗 这
  • RabbitMQ 3.1.3 和丢失的时间戳头

    如果消息中缺少时间戳头 是否可以将代理配置为插入时间戳头 因此 如果发布客户端没有添加时间戳标头 代理是否可以插入与交易所收到消息的时刻相匹配的时间戳值 我应该在哪里寻找该配置 或者这是一个坏主意 截至2015年 原来的问题有了新的答案 这
  • 使用 Spring Boot 的多个 Rabbitmq 队列

    来自 Spring Boot 教程 https spring io guides gs messaging rabbitmq https spring io guides gs messaging rabbitmq 他们给出了创建 1 个队
  • 如何停止rabbitmq服务器

    我正在尝试启动一个节点应用程序 但我认为rabbitmq 妨碍了我 与此线程类似 名为 rabbit 的节点已经在运行 但也 无法连接到节点 rabbit https stackoverflow com questions 8737754
  • 使用 Celery 时出现错误消息“无法找到记录器“多处理”的处理程序”

    RabbitMQ http en wikipedia org wiki RabbitMQ现在似乎工作正常 然而 当我尝试 python m celery bin celeryd loglevel INFO 常规的celeryd不起作用 我收
  • rabbitmq和spring-rabbitmq中的DLX——拒绝消息的一些注意事项

    我确实读过这个参考资料 https www rabbitmq com dlx html https www rabbitmq com dlx html 但这并不能解决我的疑问 即 如果接受消息没有问题 spring rabbitmq发送 a

随机推荐

  • mybatis使用时出现:对实体 “useSSL“ 的引用必须以 ‘;‘ 分隔符结尾问题的解决方法

    文章目录 问题描述 解决方法 问题描述 最近在学习mybatis 访问数据库时idea报错 解决方法 后来查了一下才发现 原来在 xml文件中写 符号时会引起冲突 需要把 改为 amp 才行 下面这个代码报错
  • 手把手带你打造自己的UI样式库(第三章)之常用样式组件的设计与开发

    常用样式组件的设计与开发 Search搜索框样式的设计与开发 搜索组件的需求 搜索框的功能比较简单 最基本的就是输入和提交两个逻辑 但是我们这个搜索框要额外的加一些细节 输入框分为输入状态和非输入状态 两种状态下输入框表现要有所不同 我们对
  • 虚拟机内部错误如何解决·?

    a 因为上一次开机是可以使用的 故初步推测是vm服务关闭所致 按住win R输入cmd打开cmd命令行 a 输入services msc进入服务界面 找到vm开头的服务 启动
  • 将本地的公钥复制到服务器的authorized_keys文件

    ssh git ip cat gt gt ssh authorized keys lt ssh id rsa pub
  • 1.4 ROS集成开发环境搭建

    ROS入门学习 1 4 ROS集成开发环境搭建 ROS入门教程 理论与实践 视频教程镇楼 和大多数开发环境一样 理论上 在 ROS 中 只需要记事本就可以编写基本的 ROS 程序 但是工欲善其事必先利其器 为了提高开发效率 可以先安装集成开
  • Android中OkHttp的使用(详解)

    1 先在项目中添加OkHttp库的依赖 dependencies compile com squareup okhttp3 okhttp 3 4 1 2 初始化 OkHttp框架的核心类是OkHttpClient 此类可直接实例化 由于Ok
  • 基于python,虹软sdk3.0实现的实时人脸识别

    前言 虹软sdk3 0是目前用过的最方便 效果最好的且免费的离线人脸识别SDK 提供的编程语音没有python 有大佬用c 代码接口转成python调用的 我在此基础上完善了一些功能 能够实现高精度多人脸实时人脸识别 并提供了年龄 性别识别
  • 用ChatGPT一分钟自动产出一份高质量PPT

    如何用ChatGPT一分钟自动产出一份高质量PPT 节约时间摸鱼呢 废话少说 直接上案例 一 用ChatGPT做一下提问 这里我用的小程序万事知天下 根据自己PPT的需求 制作chatgpt的prompt就行了 请帮我创建一个以 大学生如何
  • csv修改单元格格式后无法保存_Excel教程——excel如何使用条件格式?

    Microsoft excel条件格式可是你分析数据的好帮手 但该如何査看和分析这些数据呢 macw小编带来了excel如何使用条件格式的教程 希望对你有帮助 这款excel Mac版有一项常常被忽视 却非常实用的工具 条件格式 它能自动根
  • XMind思维导图介绍与下载安装使用教程

    文章目录 介绍 下载 安装 千人全栈VIP答疑群推荐 介绍 XMind 是一款非常实用的商业思维导图软件 应用Eclipse RCP 软件架构 打造易用 高效的可视化思维软件 强调软件的可扩展 跨平台 稳定性和性能 致力于帮助用户提高生产率
  • imos v5 web api说明文档_B站视频api整理

    此文档为非官方接口文档 无法保证接口有效性 以下接口为本项目目前使用的接口 也可以直接看src api 文件目录下的接口 仿B站视频网站项目源码 进入项目源码仓库 首页模块 推荐视频 https www bilibili com index
  • JDBC 和数据库连接

    JDBC 和数据库连接 基本介绍 JDBC为访问不同的数据库提供了统一的接口 为使用者屏蔽了细节问题 Java程序员使用JDBC 可以连接任何提供了JDBC驱动程序的数据库系统 从而完成对数据库的各种操作 JDBC的基本原理图 重要 JDB
  • core audio采集音频

    涉及的接口有 IMMDeviceEnumerator IMMDevice IAudioClient IAudioCaptureClient 主要过程 创建多媒体设备枚举器 IMMDeviceEnumerator 通过多媒体设备枚举器获取声卡
  • 如何设计一个电商平台积分兑换系统?

    目录 1 拉开差距的一类面试题 2 业务需求描述 3 对业务流程的思考 4 物流配送进度查询 考虑到了吗 5 事务的保证 6 消息中间件的引入 7 重试机制的引入 8 引入幂等性机制 9 对这类面试题的总结 1 拉开差距的一类面试题 现在面
  • idea安装findBugs 报idea运行项目报错Cannot run program

    装了findbugs之后报错 Malformed argument has embedded quote Djava endorsed dirs 打开帮助 编辑自定义VM选项 在最后一列添加下列代码 Djdk lang Process al
  • long(Long)与int(Integer)之间的转换

    1 将long型转化为int型 这里的long型是基础类型 long a 10 int b int a 2 将Long型转换为int 型的 这里的Long型是包装类型 Long a 10 int b a intValue 3 将Long型转
  • 面试题:HashMap高频面试题

    面试题 HashMap 1 底层数据结构 1 7和1 8有什么区别 1 7是数组 链表 1 8是数组 链表 红黑树 链表元素多时转换成红黑树 元素少时转换成链表 2 为何要用红黑树 为何一上来不树化 树化阈值为何是8 何时会树化 何时会退化
  • DB2客户端连接不上db2默认端口50000

    DB2客户端连接不上db2默认端口50000 1 添加组和用户 root localhost expc groupadd g 2000 upp root localhost expc useradd m g upp d home upp u
  • Java中map的分类和常见的情况

    Java为数据结构中定义了一个接口Java util Map 它有四个实现类 分别是HashMap Hash table LinkedHashMap 和 TreeMap Map主要用于存储键值对 根据键得到值 因此不允许键重复 重复了覆盖了
  • RabbitMQ(一)——入门

    前言 原来公司项目的消息中间件一直在用RabbitMQ 今天抽出时间简单总结梳理一下关于RabbitMQ的相关知识点 我们知道消息队列在分布式系统中应用的的地方有很多 它也有很多种类型 除了今天重点介绍的RabbitMQ 还有像Active