RabbitMQ进阶篇【理解➕应用】

news2024/11/23 20:12:09

🥳🥳Welcome 的Huihui's Code World ! !🥳🥳

接下来看看由辉辉所写的关于RabbitMQ的相关操作吧

目录

🥳🥳Welcome 的Huihui's Code World ! !🥳🥳

 

一.什么是交换机

1.概念释义 

2.例子理解

3.例子分析

二.交换机有哪些类型

1.扇形交换机 Fanout  Exchange

2.直连交换机 Direct Exchange

3.主题交换机 Topic Exchange

4.首部交换机 Headers Exchange

5.默认交换机 Default  Exchange

6.死信交换机 Dead Letter Exchange

三.为什么要使用交换机

四.怎么使用交换机【demo演示】

1.直连交换机

生产者

消费者

测试

效果

2.主题交换机

生产者

消费者

测试

效果

3.扇形交换机

生产者

消费者

测试

效果


一.什么是交换机

1.概念释义 

        RabbitMQ交换机是RabbitMQ消息队列中间件的一部分,它负责接收生产者发送的消息并将其路由到相应的队列中,以便消费者可以消费这些消息。

        交换机通过绑定键(Binding Key)将自身与一个或多个队列关联起来,并根据消息的路由键(Routing Key)将消息发送到匹配的队列中。它起到了消息路由的作用,类似于邮局中的分拣员,根据信件的地址将信件分发到正确的邮箱中。

⭐⭐言简意赅的总结一下:交换机就是作为一个中间过渡的角色,通过绑定键和队列产生关联,然后再通过路由键与具体匹配到的队列进行信息传递


2.例子理解

        我们知道,邮局是一个信件传递的中介,它负责将寄信人发送的信件分发到收信人的邮箱中。

但是,如果邮局没有分拣员的话,就无法将信件准确地分发到相应的邮箱中,这时候,很可能会出现信件丢失或者送错邮箱的情况。

那么,在邮局中,分拣员的作用就是将寄信人发送的信件按照地址、邮编等信息进行分类和筛选,然后将信件分发到相应的邮箱中。这样,每个收信人就可以收到自己的信件了。


3.例子分析

在RabbitMQ中,交换机的作用就类似于邮局中的分拣员。它接收生产者(寄信人)发送的消息(信件),并根据消息的路由键(地址、邮编等信息)将消息分发到相应的队列(邮箱)中,以便消费者(收信人)可以消费这些消息。

二.交换机有哪些类型

1.扇形交换机 Fanout  Exchange

        扇形交换机是最基本的交换机类型,它所能做的事情非常简单———广播消息。扇形交换机会把能接收到的消息全部发送给绑定在自己身上的队列。因为广播不需要“思考”,所以扇形交换机处理消息的速度也是所有的交换机类型里面最快的。【就相当于我们群发祝福消息给他人一样】

2.直连交换机 Direct Exchange

直连交换机是最简单的交换机类型,它的算法超级简单,将消息中的 Routing Key 匹配队列中的Binding Key。如果没有匹配的队列,消息将会被丢弃。

比如下面的这张图,如果消息的路由键是orange,就会将消息给到Q1队列处理,如果路由键是blank或者green,就会将消息给到Q2队列处理。

        而且同一个绑定键可以绑定多个不同的队列,当绑定了多个队列时,消息也会被发送到多个队列中,就像下面这张图一样,如果现在有一个消息的路由键时black,那么这个消息将会同时被推送到Q1和Q2这两个队列中。【有点像扇形交换机了】

        ⭐⭐虽然说这样能够实现出像扇形交换机那样的群发效果,但是如果我们真的在实际开发中用直连交换机来完成群发的功能,那么我们就需要在这个交换机上面绑定非常多的路由键,如果每个交换机上面都绑定了一堆的路由键,那么到了消息管理的这趴就会变的很困难...

3.主题交换机 Topic Exchange

        主题交换机(Topic Exchange)是一种灵活而强大的交换机类型。它通过将消息的

路由键与绑定的队列的主题模式进行匹配来确定消息应该发送到哪些队列中。主题模式是一个字符串,可以包含通配符 "*" 和 "#"。它使用类似于正则表达式的主题匹配规则来将消息路由到一个或多个队列中。

  • "" 用于匹配一个单词,例如 "topic." 可以匹配 "topic.a"、"topic.b",但不匹配 "topic.a.b"。
  • "#" 用于匹配零个或多个单词,例如 "topic.#" 可以匹配 "topic.a"、"topic.a.b"、"topic.a.b.c" 等。

为了有画面感一点,好理解一点,这里也使用文字+图片的方式举个例子

  •  RoutingKey:wh.orange.xw------Q1
  •  RoutingKey:wh.orange.rabbit------Q1,Q2
  •  RoutingKey:wh.bb.rabbit------Q2
  •  RoutingKey:lazy.wh------Q2
  •  RoutingKey:lazy.wh.rabbit------Q2
  •  RoutingKey:lazy.orange.wh------Q1,Q2
  •  RoutingKey:lazy.orange.rabbit------Q1,Q2

⭐⭐上面说到了主题交换机是使用类似于正则表达式的主题匹配规则来将消息路由到一个或多个队列中,但是其中也有一些特殊的极限情况👇👇

  1. 当一个队列的绑定键是#,它将会接收所有的消息,而不再考虑所接收消息的路由键
  2. 当一个队列的绑定键没有用到#和*时,它就像直连交换机一样工作

4.首部交换机 Headers Exchange

        首部交换机和扇形交换机都不需要路由键,交换机时通过Headers头部来将消息映射到队列的,有点像HTTP的Headers.

        Hash结构中要求携带一个键"x-match",这个键的value可以是any或者all

  • all:在发布消息时携带的所有Entry必须和绑定在队列上的所有Entry完全匹配
  • any:只要发布消息时携带的有一对键值对headers满足队列定义的多个参数arguments的其中一个就能匹配上,注意这里是键值对的完全匹配,只要匹配到键,值却是不一样的

5.默认交换机 Default  Exchange

        实际上默认交换机是一个由RabbitMQ预先声明好的名字为空字符串的直连交换机(direct exchange)。它有一个特殊的属性使得它对于简单应用特别有用处:那就是每个新建队列(queue)都会自动绑定到默认交换机上,绑定的路由键(routing key)名称与队列名称相同。

       类似amq.*的名称的交换机:这些是RabbitMQ默认创建的交换机。这些队列名称被预留做RabbitMQ内部使用,不能被应用使用,否则抛出403 (ACCESS_REFUSED)错误 


例如当你声明了一个名为”hello”的队列,RabbitMQ会自动将其绑定到默认交换机上,绑定的路由键名称也是为”hello”。因此,当携带着名为”hello”的路由键的消息被发送到默认交换机的时候,此消息会被默认交换机路由至名为”hello”的队列中。

6.死信交换机 Dead Letter Exchange

        在默认情况,如果消息在投递到交换机时,交换机发现此消息没有匹配的队列,则这个消息将被悄悄丢弃。为了解决这个问题,RabbitMQ中有一种交换机叫死信交换机。当消费者不能处理接收到的消息时,将这个消息重新发布到另外一个队列中,等待重试或者人工干预。这个过程中的exchange和queue就是所谓的”Dead Letter Exchange 和 Queue

        通常以下这样的消息会变成死信消息

  • 消息被拒绝,并且设置 requeue 参数为 false
  • 消息过期(默认情況下 Rabbit 中的消息不过期,但是可以设置队列的过期时间和消息的过期时间以达到消息过期的效果)
  • 队列达到最大长度(一般当设置了最大队列长度或大小并达到最大值时)


例如下图:生产者生产一条1分钟后超时的订单消息到正常交换机exchange-a中,消息匹配到队列queue-a,但一分钟后仍未消费。 此时消息就会被投递到死信交换机dlxy-exchange中,并发送到死信队列中, 死信队列dlx-queue的消费者拿到消息后,根据消息去查询订单的状态,如果仍然是未支付状态,就将订单状态更新为超时状态。

三.为什么要使用交换机

使用交换机的主要目的是实现消息的路由和分发,确保消息能够准确地传递到目标队列中。

  1. 路由功能:交换机可以根据消息的路由键将消息发送到相应的队列中。这样,生产者就可以根据消息的属性或标签来指定消息要发送到哪个队列,从而实现灵活的消息路由和过滤。

  2. 解耦合:交换机可以将生产者和消费者解耦合。生产者只需要将消息发送到交换机,而不需要关注具体的队列。消费者只需要从队列中接收消息,而不需要知道消息是如何被发送到队列的。这样,生产者和消费者之间可以独立地进行开发和扩展,提高系统的可维护性和可扩展性。

  3. 多播和广播:使用交换机可以实现消息的多播和广播。多播是指将一条消息发送到多个队列,而广播是指将一条消息发送到所有绑定了交换机的队列。这样,在某些场景下,可以方便地实现消息的复制、分发和通知。

  4. 灵活性和可扩展性:通过使用交换机,可以轻松地增加、删除和修改队列之间的消息路由规则。这样,系统可以根据实际需求进行动态调整,而不需要修改生产者和消费者的代码。

四.怎么使用交换机【demo演示】

1.直连交换机

生产者

package com.example.publisher;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@SuppressWarnings("all")
public class RabbitExchange {

    // 创建一个名为"direct-queue"的队列
    @Bean
    public Queue directQueue() {
        return new Queue("direct_queue");
    }

    // 创建一个名为"direct-exchange"的直连交换机,设置为持久化,不发布消息到交换器
    @Bean
    public DirectExchange directExchange() {
        return new DirectExchange("direct_exchange", true, false);
    }

    // 将队列绑定到直连交换机,并指定路由键为"direct_routing_key"
    @Bean
    public Binding binding() {
        return BindingBuilder.bind(directQueue())
                .to(directExchange())
                .with("direct_routing_key");
    }

}

消费者

package com.example.consumer;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component 
@RabbitListener(queues = {"direct-queue"}) // 监听名为"direct-queue"的队列
public class DirectReceiver {

    @RabbitHandler
    public void handler(Map<String, Object> json) { // 参数为接收到的消息,类型为Map<String, Object>
        System.out.println(json); // 打印接收到的消息
    }
}

测试

package com.example.publisher.controller;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController // 声明这是一个Spring控制器
public class Direct {
    @Autowired // 自动注入AmqpTemplate实例
    private AmqpTemplate rabbitTemplate;

    // 定义一个请求映射,当访问"/direct"路径时,调用sendData方法
    @RequestMapping("/direct")
    public String sendData() {
        // 创建一个Map对象,用于存储要发送的消息数据
        Map<String, Object> data = new HashMap<>();
        data.put("msg", "直连交换机"); // 将消息内容放入Map中

        // 使用rabbitTemplate的convertAndSend方法发送消息,指定交换机名称、路由键和消息数据
        rabbitTemplate.convertAndSend("direct_exchange", "direct_routing_key", data);

        // 返回一个字符串表示消息已发送
        return "😙😙";
    }
}

效果

访问测试的方法

2.主题交换机

生产者

package com.example.publisher;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@SuppressWarnings("all")
public class RabbitExchange {

    // 定义路由规则
    public static String A_KEY = "*.orange.*";
    public static String B_KEY = "*.* rabbit";
    public static String C_KEY = "lazy.#";

    /**
     * 定义队列
     * @return
     */
    @Bean
    public Queue Topicqueue() {
        return new Queue("topic-queue", true);
    }

    /**
     * 定义主题交换机
     * @return
     */
    @Bean
    public TopicExchange topicExchange() {
        return new TopicExchange("topic-exchange", true, false);
    }

    /**
     * 将队列与交换机进行绑定,并设置路由键
     * @return
     */
    @Bean
    public Binding bindingA() {
        return BindingBuilder.bind(Topicqueue())
                .to(topicExchange())
                .with(A_KEY);
    }

}

消费者

package com.example.consumer.exchange;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.Map;

// 定义一个名为TopicReceiver的类,用于接收RabbitMQ消息
@Component
@RabbitListener(queues = {"topic-queue"})
public class TopicReceiver {

    // 使用@RabbitHandler注解标记handler方法,用于处理接收到的消息
    @RabbitHandler
    public void handler(Map<String,Object> json){
        // 打印接收到的消息
        System.out.println(json);
    }

}

测试

package com.example.publisher.controller;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

// 定义一个名为Sender的类,用于发送消息到RabbitMQ
@RestController
public class Topic {
    // 自动注入AmqpTemplate对象,用于发送消息
    @Autowired
    private AmqpTemplate rabbitTemplate;

    // 定义一个名为sendTopic的方法,用于发送主题消息
    @RequestMapping("/sendTopic")
    public String sendTopic() {
        // 创建一个Map对象,用于存储消息内容
        Map<String,Object> data=new HashMap<>();
        data.put("msg","主题交换机");
        // 使用rabbitTemplate的convertAndSend方法发送消息,指定交换机名称、路由键和消息内容
        rabbitTemplate.convertAndSend("topic-exchange","aa.orange.bb", data);
        // 返回一个字符串表示发送成功
        return "😙😙";
    }
}

效果

3.扇形交换机

生产者

package com.example.publisher;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@SuppressWarnings("all")
public class RabbitExchange {
    // 定义一个名为queueX的队列,用于接收消息
    @Bean
    public Queue queueX() {
        return new Queue("queue-x");
    }

    // 定义一个名为queueY的队列,用于接收消息
    @Bean
    public Queue queueY() {
        return new Queue("queue-y");
    }

    // 定义一个名为queueZ的队列,用于接收消息
    @Bean
    public Queue queueZ() {
        return new Queue("queue-z");
    }

    /**
     * 定义扇形交换机,与路由键无关
     * @return
     */
    @Bean
    public FanoutExchange fanoutExchange() {
        return new FanoutExchange("fanout-exchange", true, false);
    }

    // 将queueX绑定到fanoutExchange上
    @Bean
    public Binding bindingX() {
        return BindingBuilder.bind(queueX())
                .to(fanoutExchange());
    }

    // 将queueY绑定到fanoutExchange上
    @Bean
    public Binding bindingY() {
        return BindingBuilder.bind(queueY())
                .to(fanoutExchange());
    }

    // 将queueZ绑定到fanoutExchange上
    @Bean
    public Binding bindingZ() {
        return BindingBuilder.bind(queueZ())
                .to(fanoutExchange());
    }

}

消费者

package com.example.consumer.exchange;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
public class FanoutReceiver {

    // 监听队列queue-x的消息,当接收到消息时,调用handlerY方法处理
    @RabbitListener(queues = {"queue-x"})
    @RabbitHandler
    public void handlerY(Map<String,Object> json){
        System.out.println("已接受到队列queue-x传递过来的消息:"+json);
    }

    // 监听队列queue-y的消息,当接收到消息时,调用handlerX方法处理
    @RabbitListener(queues = {"queue-y"})
    @RabbitHandler
    public void handlerX(Map<String,Object> json){
        System.out.println("已接受到队列queue-y传递过来的消息:"+json);
    }

    // 监听队列queue-z的消息,当接收到消息时,调用handlerZ方法处理
    @RabbitListener(queues = {"queue-z"})
    @RabbitHandler
    public void handlerZ(Map<String,Object> json){
        System.out.println("已接受到队列queue-z传递过来的消息:"+json);
    }
}

测试

package com.example.publisher.controller;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
public class Fanout {
    // 自动注入AmqpTemplate对象
    @Autowired
    private AmqpTemplate rabbitTemplate;

    // 定义发送扇形交换机消息的方法
    @RequestMapping("/sendFanout")
    public String sendFanout() {
        // 创建一个Map对象,用于存储消息数据
        Map<String,Object> data=new HashMap<>();
        data.put("msg","扇形交换机");
        // 使用rabbitTemplate的convertAndSend方法发送消息,指定交换机名称和路由键(这里为null,表示不指定路由键)
        rabbitTemplate.convertAndSend("fanout-exchange",null, data);
        // 返回一个字符串,表示发送成功
        return "😙😙;";
    }
}

效果

好啦,今天的分享就到这了,希望能够帮到你呢!😊😊  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1406516.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

聚观早报 | 苹果将开放第三方NFC支付;华为P70系列参数曝光

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 1月23日消息 苹果将开放第三方NFC支付 华为P70系列参数曝光 Celestiq已正式开始量产 岚图汽车官宣与华为合作 美…

LLM + RecSys 初体验(上)

最近在逛小红书的时候&#xff0c;发现了一个新的GPU算力租赁平台&#xff0c;与AutoDL和恒源云等平台类似。正巧&#xff0c;官网有活动&#xff0c;注册即送RTX 4090三个小时&#xff0c;CPU 5 小时。正巧最近在测试 LLM推荐系统的 OpenP5 平台&#xff0c;果断入手测试! 用…

力扣精选算法100道——x的平方根(二分查找专题)

x的平方根 首先看到这个题目的时候&#xff0c;我们需要对上一个二分查找专题的题目进行深度理解&#xff0c;然后了解模板&#xff0c;这题是完全利用的上一题的模板知识进行&#xff0c;如果直接看这个题目可能是有点懵的&#xff0c;因为我这里直接利用模板进行解题。力扣…

nexus清理docker私库

下载nexus-cli客户端&#xff0c;并非必须下载到服务器&#xff0c;理论上只要能访问到nexus就行 wget https://s3.eu-west-2.amazonaws.com/nexus-cli/1.0.0-beta/linux/nexus-cli这个链接下载不了了&#xff0c;末尾有资源下载&#xff0c;里面包含了完整包和脚本&#xff0…

Mysql主从复制、读写分离、分库分表

大数据处理 1.主从复制1.1 概述1.2 原理1.3 搭建 1.主从复制 主从复制 1.1 概述 主从复制指: 将主数据库的DDL和DML操作通过二进制日志传递到从库服务器中, 然后从库根据日志重新执行(也叫重做), 从而使从库和主库的数据保存同步 MYSQL支持一台主库同时向多台从库进行复制,…

Kafka-服务端-KafkaController

Broker能够处理来自KafkaController的LeaderAndIsrRequest、StopReplicaRequest、UpdateMetadataRequest等请求。 在Kafka集群的多个Broker中&#xff0c;有一个Broker会被选举为Controller Leader,负责管理整个集群中所有的分区和副本的状态。 例如&#xff1a;当某分区的Le…

解密.dataru被困的数据:如何应对.dataru勒索病毒威胁

导言&#xff1a; 在数字时代&#xff0c;勒索病毒如.dataru正在不断演变&#xff0c;威胁着用户的数据安全。本文91数据恢复将深入介绍.dataru勒索病毒的特点、被加密数据的恢复方法&#xff0c;以及预防措施&#xff0c;帮助您更好地了解并对抗这一数字威胁。当面对被勒索病…

Armv8-M的TrustZone技术之SAU寄存器总结

每个SAU寄存器是32位宽。下表显示了SAU寄存器概要。 5.1 SAU_CTRL register SAU_CTRL寄存器的特征如下图和表所示&#xff1a; 5.2 SAU_TYPE register 5.3 SAU_RNR register 5.4 SAU_RBAR register 5.5 SAU_RLAR register 5.6 SAU区域配置 当SAU启用时&#xff0c;未由已启用…

深度学习技巧应用33-零门槛实现模型在多个GPU的分布式流水线训练的应用技巧

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下深度学习技巧应用33零门槛实现模型在多个GPU的分布式流水线训练的应用技巧&#xff0c;本文将帮助大家零门槛的实现模型在多个GPU的并行训练&#xff0c;如果你手头上没有GPU资源&#xff0c;根据本文的介绍也可实现…

Redis应用(1)缓存(1.2)------Redis三种缓存问题

三者出现的根本原因是&#xff1a;Redis缓存命中率下降&#xff0c;请求直接打到DB上了。 一、 缓存穿透&#xff1a; 1、定义&#xff1a; 缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在&#xff0c;这样缓存永远不会生效&#xff0c;这些请求都会打到数据库。…

C++面试宝典第24题:袋鼠过河

题目 一只袋鼠要从河这边跳到河对岸,河很宽,但是河中间打了很多桩子。每隔一米就有一个桩子,每个桩子上都有一个弹簧,袋鼠跳到弹簧上就可以跳得更远。每个弹簧力量不同,用一个数字代表它的力量,如果弹簧力量为5,就代表袋鼠下一跳最多能够跳5米;如果为0,就会陷进去无法…

《WebKit 技术内幕》学习之十一(3):多媒体

3 音频 3.1 音频元素 说完视频之后&#xff0c;接下来就是HTML5中对音频的支持情况。音频支持不仅指对声音的播放&#xff0c;还包括对音频的编辑和合成&#xff0c;以及对乐器数字接口&#xff08;MIDI&#xff09;等的支持&#xff0c;下面逐次介绍并分析它们。 3.1.1 H…

更改wpf原始默认按钮的样式

样式 代码 <Window x:Class"WpfApp4.Window1"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expression/blend/2008…

【linux】Debian挂起和休眠

一、挂起和休眠 在Debian桌面系统中&#xff0c;挂起和休眠是两种不同的状态&#xff0c;它们之间有一些区别。 挂起&#xff08;Suspend&#xff09;是将当前系统的状态保存到RAM&#xff08;内存&#xff09;中&#xff0c;然后关闭所有硬件设备&#xff0c;除了RAM之外。在…

详细分析Java中的list.foreach()和list.stream().foreach()

目录 前言1. 基本知识2. 差异之处2.1 执行顺序2.2 串行并行2.3 复杂数据处理2.4 CRUD集合2.5 迭代器 3. 总结4. 彩蛋 前言 典故来源于项目中使用了两种方式的foreach&#xff0c;后面尝试体验下有何区别&#xff01; 先看代码示例&#xff1a; 使用List的forEach&#xff1a…

风丘车辆热管理测试方案

车辆热管理是在能源危机出现、汽车排放法规日益严格以及人们对汽车舒适性要求更高的背景下应运而生的。将各个系统或部件如冷却系统、润滑系统和空调系统等集成一个有效的热管理系统&#xff1b;控制和优化车辆的热量传递过程&#xff0c;保证各关键部件和系统安全高效运行&…

麒麟系统—— openKylin 安装到虚拟机以及开放SSH通过工具连接

麒麟系统—— openKylin 安装到虚拟机以及开放SSH通过工具连接 1. 在VMware中安装openKylin麒麟系统步骤1&#xff1a;准备VMware环境步骤2&#xff1a;创建新的虚拟机步骤3&#xff1a;安装openKylin麒麟系统步骤4&#xff1a;调整分别率步骤5&#xff1a;安装SSH 2. 使用Open…

安卓自动缩放布局

AutoScalingLayout 适用于 Android 的自动缩放布局。 替换布局&#xff1a; 我们只需要替换根布局所需的自动缩放&#xff0c;子布局也将实现自动缩放。 原始布局AutoScalingLayout相对布局ASRelativeLayout线性布局ASLinearLayoutFrameLayout&#xff08;框架布局&#xff…

SpringCloud Bus动态刷新全局广播

文章目录 代码地址配置项目配置修改测试 SpringCloud Bus动态刷新定点通知 代码地址 地址:https://github.com/13thm/study_springcloud/tree/main/days11_%20Bus 配置项目 必须先具备良好的RabbitMQ环境先 演示广播效果&#xff0c;增加复杂度&#xff0c;再以3355为模板再…

Python基础第九篇(Python可视化的开发)

文章目录 一、json数据格式&#xff08;1&#xff09;.转换案例代码&#xff08;2&#xff09;.读出结果 二、pyecharts模块介绍三、pyecharts模块入门&#xff08;1&#xff09;.pyecharts模块安装&#xff08;2&#xff09;.pyecharts模块操作&#xff08;1&#xff09;.代码…