当前位置: 首页 > news >正文

【图解RabbitMQ-7】图解RabbitMQ五种队列模型(简单模型、工作模型、发布订阅模型、路由模型、主题模型)及代码实现

🧑‍💻作者名称:DaenCode
🎤作者简介:CSDN实力新星,后端开发两年经验,曾担任甲方技术代表,业余独自创办智源恩创网络科技工作室。会点点Java相关技术栈、帆软报表、低代码平台快速开发。技术尚浅,闭关学习中······
😎人生感悟:尝尽人生百味,方知世间冷暖。
📖所属专栏:图解RabbitMQ


在这里插入图片描述


专栏推荐

  • 专门为Redis入门打造的专栏,包含Redis基础知识、基础命令、五大数据类型实战场景、key删除策略、内存淘汰机制、持久化机制、哨兵模式、主从复制、分布式锁等等内容。链接>>>>>>>>>《Redis从头学》
  • SpringBoot实战相关专栏,包含SpringBoot过滤器、拦截器、AOP实现日志、整合Freemaker、整合Redis等等实战相关内容,多篇文章登入全站热榜、领域热榜、被技术社区收录。链接>>>>>>《SpringBoot实战》

文章目录

  • 专栏推荐
  • 🌟前言
  • 🌟连接工具类
  • 🌟简单工作模型
    • 介绍
    • 代码实现
  • 🌟工作队列模型
    • 介绍
    • 代码实现
  • 🌟发布订阅模型
    • 介绍
    • 代码实现
  • 🌟路由模型
    • 介绍
    • 代码实现
  • 🌟主题模型
    • 介绍
    • 代码实现
  • 🌟总结
  • 🌟写在最后

参考网站:https://www.rabbitmq.com/getstarted.html

🌟前言

在上一节学习了RabbitMQ中交换机的相关基础知识,本文来学习一下RabbitMQ中的五种队列模型的,对其有一个基本的认识。

🌟连接工具类

public class MQConnectionUtil {public static Connection createConnection() throws IOException, TimeoutException {//创建连接工厂ConnectionFactory factory = new ConnectionFactory();factory.setHost("192.168.124.23");factory.setUsername("admin");factory.setPassword("password");factory.setVirtualHost("/dev");factory.setPort(5672);return factory.newConnection();}
}

🌟简单工作模型

介绍

模型图
在这里插入图片描述
流程

  1. 生产者发送消息到队列。
  2. 如果队列存在则直接存入消息;若不存在,先进行队列的创建。
  3. 消费者监听队列。
  4. 处理完消息,通过ACK机制确认消息已经消费。

特点

  1. 只有一个消费者,并且其中没有交换机参与。

代码实现

生产者

public class Send {private final static String QUEUE_NAME="hello";public static void main(String[] args) throws IOException, TimeoutException {try (   //JDK7语法 或自动关闭 connnection和channel//创建连接Connection connection=MQConnectionUtil.createConnection();//创建信道Channel channel = connection.createChannel()) {/*** 队列名称* 持久化配置:mq重启后还在* 是否独占:只能有一个消费者监听队列;当connection关闭是否删除队列,一般是false,发布订阅是独占* 自动删除: 当没有消费者的时候,自动删除掉,一般是false* 其他参数** 队列不存在则会自动创建,如果存在则不会覆盖,所以此时的时候需要注意属性*/channel.queueDeclare(QUEUE_NAME, false, false, false, null);String message = "Hello World!";/*** 参数说明:* 交换机名称:不写则是默认的交换机,那路由健需要和队列名称一样才可以被路由,* 路由健名称* 配置信息* 发送的消息数据:字节数组*///发布消息channel.basicPublish("", QUEUE_NAME, null, message.getBytes(StandardCharsets.UTF_8));System.out.println(" [x] Sent '" + message + "'");}}
}

消费者

public class Recv {private final static String QUEUE_NAME = "hello";public static void main(String[] argv) throws Exception {//消费者一般不增加自动关闭Connection connection=MQConnectionUtil.createConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);System.out.println(" [*] Waiting for messages. To exit press CTRL+C");//回调方法,下面两种都行Consumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {// consumerTag 是固定的 可以做此会话的名字, deliveryTag 每次接收消息+1System.out.println("consumerTag消息标识="+consumerTag);//可以获取交换机,路由健等System.out.println("envelope元数据="+envelope);System.out.println("properties配置信息="+properties);System.out.println("body="+new String(body,"utf-8"));}};channel.basicConsume(QUEUE_NAME,true,consumer);//        DeliverCallback deliverCallback = (consumerTag,delivery) -> {
//            String message = new String(delivery.getBody(), "UTF-8");
//            System.out.println(" [x] Received '" + message + "'");
//        };//自动确认消息
//        channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });}
}

🌟工作队列模型

介绍

模型图
在这里插入图片描述
特点

  1. 生产者将消息发送到队列,并由多个消费者进行消费。

两种消费策略
1 . 轮训策略:将消息平均分配给多个消费者进行消费,不考虑消费者的处理能力;采用自动ACK消息机制。
2. 公平策略:消费者每次只能处理一个消息。一定时间内,能力强者消费的多,否则少;采用手动ACK消息机制。


代码实现

轮询策略

//生产者
public class Send {private final static String QUEUE_NAME="work_rr";public static void main(String[] args) throws IOException, TimeoutException {try (   //JDK7语法 或自动关闭 connnection和channel//创建连接Connection connection= MQConnectionUtil.createConnection();//创建信道Channel channel = connection.createChannel()) {/*** 队列名称* 持久化配置:mq重启后还在* 是否独占:只能有一个消费者监听队列;当connection关闭是否删除队列,一般是false,发布订阅是独占* 自动删除: 当没有消费者的时候,自动删除掉,一般是false* 其他参数** 队列不存在则会自动创建,如果存在则不会覆盖,所以此时的时候需要注意属性*/channel.queueDeclare(QUEUE_NAME, false, false, false, null);for (int i = 0; i < 10; i++) {String message = "Hello World!";/*** 参数说明:* 交换机名称:不写则是默认的交换机,那路由健需要和队列名称一样才可以被路由,* 路由健名称* 配置信息* 发送的消息数据:字节数组*///发布消息channel.basicPublish("", QUEUE_NAME, null, message.getBytes(StandardCharsets.UTF_8));System.out.println(" [x] Sent '" + message + "'");}}}
}
//消费者
public class Recv {private final static String QUEUE_NAME = "work_rr";public static void main(String[] argv) throws Exception {//消费者一般不增加自动关闭Connection connection= MQConnectionUtil.createConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);System.out.println(" [*] Waiting for messages. To exit press CTRL+C");//回调方法,下面两种都行Consumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {throw new RuntimeException(e);}// consumerTag 是固定的 可以做此会话的名字, deliveryTag 每次接收消息+1System.out.println("consumerTag消息标识="+consumerTag);//可以获取交换机,路由健等System.out.println("envelope元数据="+envelope);System.out.println("properties配置信息="+properties);System.out.println("body="+new String(body,"utf-8"));channel.basicAck(envelope.getDeliveryTag(), false);}};channel.basicConsume(QUEUE_NAME,false,consumer);//        DeliverCallback deliverCallback = (consumerTag,delivery) -> {
//            String message = new String(delivery.getBody(), "UTF-8");
//            System.out.println(" [x] Received '" + message + "'");
//        };//自动确认消息
//        channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });}
}
//消费者2
public class Recv2 {private final static String QUEUE_NAME = "work_rr";public static void main(String[] argv) throws Exception {Connection connection= MQConnectionUtil.createConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);System.out.println(" [*] Waiting for messages. To exit press CTRL+C");//回调方法,下面两种都行Consumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {// consumerTag 是固定的 可以做此会话的名字, deliveryTag 每次接收消息+1System.out.println("consumerTag消息标识="+consumerTag);//可以获取交换机,路由健等System.out.println("envelope元数据="+envelope);System.out.println("properties配置信息="+properties);System.out.println("body="+new String(body,"utf-8"));channel.basicAck(envelope.getDeliveryTag(), false);}};channel.basicConsume(QUEUE_NAME,false,consumer);//        DeliverCallback deliverCallback = (consumerTag,delivery) -> {
//            String message = new String(delivery.getBody(), "UTF-8");
//            System.out.println(" [x] Received '" + message + "'");
//        };//自动确认消息
//        channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });}
}

公平策略
通过channel.basicQos(1);确保每个消费者每次只能处理一个未确认的消息。

public class Send {private final static String QUEUE_NAME="work_fair";public static void main(String[] args) throws IOException, TimeoutException {try (   //JDK7语法 或自动关闭 connnection和channel//创建连接Connection connection = MQConnectionUtil.createConnection();//创建信道Channel channel = connection.createChannel()) {/*** 队列名称* 持久化配置:mq重启后还在* 是否独占:只能有一个消费者监听队列;当connection关闭是否删除队列,一般是false,发布订阅是独占* 自动删除: 当没有消费者的时候,自动删除掉,一般是false* 其他参数** 队列不存在则会自动创建,如果存在则不会覆盖,所以此时的时候需要注意属性*/channel.queueDeclare(QUEUE_NAME, false, false, false, null);for (int i = 0; i < 10; i++) {String message = "Hello World!";/*** 参数说明:* 交换机名称:不写则是默认的交换机,那路由健需要和队列名称一样才可以被路由,* 路由健名称* 配置信息* 发送的消息数据:字节数组*///发布消息channel.basicPublish("", QUEUE_NAME, null, message.getBytes(StandardCharsets.UTF_8));System.out.println(" [x] Sent '" + message + "'");}}}
}
//消费者1
public class Recv {private final static String QUEUE_NAME = "work_fair";public static void main(String[] argv) throws Exception {Connection connection= MQConnectionUtil.createConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);System.out.println(" [*] Waiting for messages. To exit press CTRL+C");channel.basicQos(1);//回调方法,下面两种都行Consumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {throw new RuntimeException(e);}// consumerTag 是固定的 可以做此会话的名字, deliveryTag 每次接收消息+1System.out.println("consumerTag消息标识="+consumerTag);//可以获取交换机,路由健等System.out.println("envelope元数据="+envelope);System.out.println("properties配置信息="+properties);System.out.println("body="+new String(body,"utf-8"));channel.basicAck(envelope.getDeliveryTag(), false);}};channel.basicConsume(QUEUE_NAME,false,consumer);//        DeliverCallback deliverCallback = (consumerTag,delivery) -> {
//            String message = new String(delivery.getBody(), "UTF-8");
//            System.out.println(" [x] Received '" + message + "'");
//        };//自动确认消息
//        channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });}
}
//消费者2
public class Recv2 {private final static String QUEUE_NAME = "work_fair";public static void main(String[] argv) throws Exception {Connection connection=MQConnectionUtil.createConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);System.out.println(" [*] Waiting for messages. To exit press CTRL+C");channel.basicQos(1);//回调方法,下面两种都行Consumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {// consumerTag 是固定的 可以做此会话的名字, deliveryTag 每次接收消息+1System.out.println("consumerTag消息标识="+consumerTag);//可以获取交换机,路由健等System.out.println("envelope元数据="+envelope);System.out.println("properties配置信息="+properties);System.out.println("body="+new String(body,"utf-8"));channel.basicAck(envelope.getDeliveryTag(), false);}};channel.basicConsume(QUEUE_NAME,false,consumer);//        DeliverCallback deliverCallback = (consumerTag,delivery) -> {
//            String message = new String(delivery.getBody(), "UTF-8");
//            System.out.println(" [x] Received '" + message + "'");
//        };//自动确认消息
//        channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });}
}

🌟发布订阅模型

介绍

模型图
在这里插入图片描述

特点

  1. 一条消息可以被多个消费者同时接收。
  2. 采用扇形(Fanout)交换机。
  3. 无需路由Key
  4. 类似于公众号的订阅。

代码实现

生产者

public class Send {private final static String EXCHANGE_NAME="exchange_fanout";public static void main(String[] args) throws IOException, TimeoutException {try (   //JDK7语法 或自动关闭 connnection和channel//创建连接Connection connection = MQConnectionUtil.createConnection();//创建信道Channel channel = connection.createChannel()) {channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT);String message="daencode rabbitmq pub";channel.basicPublish(EXCHANGE_NAME," ",null,message.getBytes(StandardCharsets.UTF_8));System.out.println("广播消息已经发送!!!!");}}
}

消费者:两个消费者都是一样的代码,都需要绑定相同的扇形交换机。

public class Recv {private final static String EXCHANGE_NAME="exchange_fanout";public static void main(String[] argv) throws Exception {Connection connection = MQConnectionUtil.createConnection();Channel channel = connection.createChannel();//绑定交换机,fanout扇形,即广播类型channel.exchangeDeclare(EXCHANGE_NAME,BuiltinExchangeType.FANOUT);//获取队列(排它队列)String queueName = channel.queueDeclare().getQueue();//绑定队列和交换机,fanout交换机不用指定routingkeychannel.queueBind(queueName,EXCHANGE_NAME,"");DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x] Received '" + message + "'");};//自动确认消息channel.basicConsume(queueName, true, deliverCallback, consumerTag -> { });}
}

🌟路由模型

介绍

模型图
在这里插入图片描述
特点

  1. 交换机类型采用直连交换机,特定的路由key由特定的消费者进行消费。
  2. 交换机根据特定的路由key与队列进行绑定。

代码实现

以记录不同日志级别为例,不同的消费者进行不同日志级别的记录。

生产者

public class Send {private final static String EXCHANGE_NAME="exchange_direct";public static void main(String[] args) throws IOException, TimeoutException {try (   //JDK7语法 或自动关闭 connnection和channel//创建连接Connection connection = MQConnectionUtil.createConnection();//创建信道Channel channel = connection.createChannel()) {channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);String debugLog="[debug]daencode rabbitmq direct";String errorLog="[error]出现error错误";channel.basicPublish(EXCHANGE_NAME,"errorRoutingKey",null,errorLog.getBytes(StandardCharsets.UTF_8));channel.basicPublish(EXCHANGE_NAME,"debugRoutingKey",null,debugLog.getBytes(StandardCharsets.UTF_8));System.out.println("消息已经发送!!!!");}}
}

消费者1:只记录ERROR级别日志。

public class Recv1 {private final static String EXCHANGE_NAME="exchange_direct";public static void main(String[] argv) throws Exception {Connection connection = MQConnectionUtil.createConnection();Channel channel = connection.createChannel();//绑定交换机,fanout扇形,即广播类型channel.exchangeDeclare(EXCHANGE_NAME,BuiltinExchangeType.DIRECT);//获取队列(排它队列)String queueName = channel.queueDeclare().getQueue();//绑定队列和交换机,fanout交换机不用指定routingkeychannel.queueBind(queueName,EXCHANGE_NAME,"errorRoutingKey");DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x] Received '" + message + "'");};//自动确认消息channel.basicConsume(queueName, true, deliverCallback, consumerTag -> { });}
}

消费者2:只记录Debug级别日志。

public class Recv2 {private final static String EXCHANGE_NAME="exchange_direct";public static void main(String[] argv) throws Exception {Connection connection = MQConnectionUtil.createConnection();Channel channel = connection.createChannel();//绑定交换机,fanout扇形,即广播类型channel.exchangeDeclare(EXCHANGE_NAME,BuiltinExchangeType.DIRECT);//获取队列(排它队列)String queueName = channel.queueDeclare().getQueue();//绑定队列和交换机,fanout交换机不用指定routingkeychannel.queueBind(queueName,EXCHANGE_NAME,"debugRoutingKey");DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x] Received '" + message + "'");};//自动确认消息channel.basicConsume(queueName, true, deliverCallback, consumerTag -> { });}
}

🌟主题模型

介绍

模型图
在这里插入图片描述
特点

  1. 交换机类型采用主题交换机。
  2. 路由key根据通配符规则,限定消息消费规则。*匹配一个词,#匹配一个或者多个词。
  3. 交换机通过通配符路由KEY将消息绑定到不同的队列,以此实现不同的消费者进行消息消费。
  4. 同时满足路由模型和发布订阅模型。

代码实现

生产者:生产者通过路由KEY向交换机发送消息。

public class Send {private final static String EXCHANGE_NAME="exchange_topic";public static void main(String[] args) throws IOException, TimeoutException {try (   //JDK7语法 或自动关闭 connnection和channel//创建连接Connection connection= MQConnectionUtil.createConnection();//创建信道Channel channel = connection.createChannel()) {channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC);String debugLog="[debug]daencode rabbitmq direct";String errorLog="[error]出现error错误";channel.basicPublish(EXCHANGE_NAME,"log.error",null,errorLog.getBytes(StandardCharsets.UTF_8));channel.basicPublish(EXCHANGE_NAME,"log.debug",null,debugLog.getBytes(StandardCharsets.UTF_8));System.out.println("广播消息已经发送!!!!");}}
}

消费者

public class Recv1 {private final static String EXCHANGE_NAME="exchange_topic";public static void main(String[] argv) throws Exception {Connection connection= MQConnectionUtil.createConnection();Channel channel = connection.createChannel();//绑定交换机,fanout扇形,即广播类型channel.exchangeDeclare(EXCHANGE_NAME,BuiltinExchangeType.TOPIC);//获取队列(排它队列)String queueName = channel.queueDeclare().getQueue();//绑定队列和交换机,fanout交换机不用指定routingkeychannel.queueBind(queueName,EXCHANGE_NAME,"*.debug");DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x] Received '" + message + "'");};//自动确认消息channel.basicConsume(queueName, true, deliverCallback, consumerTag -> { });}
}

消费者2


public class Recv2 {private final static String EXCHANGE_NAME="exchange_topic";public static void main(String[] argv) throws Exception {Connection connection= MQConnectionUtil.createConnection();Channel channel = connection.createChannel();//绑定交换机,fanout扇形,即广播类型channel.exchangeDeclare(EXCHANGE_NAME,BuiltinExchangeType.TOPIC);//获取队列(排它队列)String queueName = channel.queueDeclare().getQueue();//绑定队列和交换机,fanout交换机不用指定routingkeychannel.queueBind(queueName,EXCHANGE_NAME,"*.error");DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x] Received '" + message + "'");};//自动确认消息channel.basicConsume(queueName, true, deliverCallback, consumerTag -> { });}
}

🌟总结

模型是否交换机参与交换机类型需要路由键描述
简单模型消息直接发送到队列,最基本的消息传递模型。
工作模型多个消费者共同处理一个队列中的消息。
发布订阅模型fanout将消息广播给所有绑定到交换机的队列,多个消费者同时订阅。
路由模型direct根据消息的路由键将消息发送到与之匹配的队列。
主题模型topic使用通配符进行灵活的路由,根据主题和通配符规则进行匹配。

🌟写在最后

有关于图解RabbitMQ五种队列模型介绍及代码实现到此就结束了。感谢大家的阅读,希望大家在评论区对此部分内容散发讨论,便于学到更多的知识。


请添加图片描述

相关文章:

【图解RabbitMQ-7】图解RabbitMQ五种队列模型(简单模型、工作模型、发布订阅模型、路由模型、主题模型)及代码实现

&#x1f9d1;‍&#x1f4bb;作者名称&#xff1a;DaenCode &#x1f3a4;作者简介&#xff1a;CSDN实力新星&#xff0c;后端开发两年经验&#xff0c;曾担任甲方技术代表&#xff0c;业余独自创办智源恩创网络科技工作室。会点点Java相关技术栈、帆软报表、低代码平台快速开…...

Linux命令200例:write用于向特定用户或特定终端发送信息

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0…...

javaee spring整合mybatis spring帮我们创建dao层

项目结构 pom依赖 <?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/P…...

修改Tomcat的默认端口号

1、找到Tomcat的安装路径。 2、打开conf文件夹。 3、用记事本打开server.xml文件 4、找到 <Connector port"8080" protocol"HTTP/1.1"&#xff0c;其中的8080就是tomcat的默认端口&#xff0c;将其修改为你需要的端口即可。...

Open3D Ransac拟合空间直线(python详细过程版)

RANSAC拟合直线 一、算法原理1、算法简介2、参考文献二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法原理 1、算法简介 见:Open3D——RANSAC 三维点云空间直线拟合 2、参考文献...

题目:2729.判断一个数是否迷人

​​题目来源&#xff1a; leetcode题目&#xff0c;网址&#xff1a;2729. 判断一个数是否迷人 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 对 n&#xff0c;2*n&#xff0c;3*n 中的数字出现次数计数&#xff0c;若数字 0 出现 0 次&#xff0c;数字 1~9…...

微服务模式:服务发现模式

由于微服务应用的动态性&#xff0c;很难调用具有固定 IP 地址的服务。这就是服务发现的概念出现的背景。服务发现有助于客户端了解服务实例的位置。在这种情况下&#xff0c;服务发现组件将充当服务注册表。 服务注册表是一个包含服务实例位置的集中式服务器/数据库。在微服务…...

9.4 数据库 TCP

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//判断数据库对象是否包含了自己使用的数据库if(!db.contains("Stu.db")){//不存在数据库&#xff0…...

普通用户使用spark的client无法更新Ranger策略

普通用户使用spark的client无法更新Ranger策略 报错图片&#xff1a; WARN org.apache.ranger.admin.client.RangerAdminRESTClient: Error getting Roles. secureModetrue, usercaojianxiangUCDIPA.VIATRIS.CC (auth:KERBEROS)&#xff0c;responsef"httpStatusCode&quo…...

Git超详细教程

文章目录 一、安装并配置Git二、Git的基本操作三、Github/GitLab/Gitee四、分支 一、安装并配置Git 查看所有的全局配置项 git config --list --global查看指定的全局配置项 git config user.name git config user.email配置用户信息 git config --global user.name "…...

C++ 回调函数

一、使用方法 1.定义一个函数指针 typedef int (*pCallback)(int a, int b);2.定义一个带参的回调函数&#xff08;注释部分是普通回调函数&#xff0c;不用定义第一步里的函数指针&#xff09; //带参 int oneCallback(int a, int b, pCallback p) //int oneCallback(int a, i…...

xilinx FPGA IOB约束使用以及注意事项

文章目录 一、什么是IOB约束二、为什么要使用IOB约束1、在约束文件中加入下面约束&#xff1a;2、直接在代码中加约束&#xff0c; 三、IOB约束使用注意事项 一、什么是IOB约束 在xilinx FPGA中&#xff0c;IOB是位于IO附近的寄存器&#xff0c;是FPGA上距离IO最近的寄存器&am…...

如何统计iOS产品不同渠道的下载量?

一、前言 在开发过程中&#xff0c;Android可能会打出来很多的包&#xff0c;用于标识不同的商店下载量。原来觉得苹果只有一个商店&#xff1a;AppStore&#xff0c;如何做出不同来源的统计呢&#xff1f;本篇文章就是告诉大家如何做不同渠道来源统计。 二、正文 先看一下苹…...

大模型学习

大模型 大规模语言模型&#xff08;Large Language Model&#xff09;简称&#xff0c;具有庞大的参数规模和复杂程度的机器学习模型。在深度学习领域&#xff0c;指具有数百万到数十亿参数的神经网络模型。 优点&#xff1a; 更强大、更准确的模型性能&#xff0c;可面对复杂…...

Redis原理:IntSet

&#xff08;笔记总结自b站黑马程序员课程&#xff09; 一、结构 IntSet是Redis中set集合的一种实现方式&#xff0c;基于整数数组来实现&#xff0c;并且具备长度可变、有序等特征。 结构如下&#xff1a; typedef struct intset {uint32_t encoding; //编码方式uint32_t l…...

【已解决】Splunk 8.2.X 升级ES 后红色报警

1: 背景: 由于splunk ES 占有很大的computing resource, 所以,Splunk ES 升级到7.1.1 后,有红色的alert. 2: 解决方法: 降低iowait 的 threshold: Investigation The default threshold setting for IOWait is pre-set to a low value and may not be relevant to the …...

香橙派使用外设驱动库wiringOP 配合定时器来驱动舵机

舵机认识和硬件接线 关于舵机也是使用过很多次了&#xff0c;详见&#xff1a; 使用PWM波控制开发SG90-CSDN博客 同时再次回顾香橙派的物理引脚对应&#xff1a; 所以舵机的VCC接 2&#xff0c;GND接 6&#xff0c;PWM接 7&#xff08;此处写的是物理引脚编号&#xff09; Li…...

C++学习笔记--函数重载(2)

文章目录 1.3、Function Templates Handling1.3.1、Template Argument Deduction1.3.2、Template Argument Substitution 1.4、Overload Resolution1.4.1、Candidate functions1.4.2、Viable functions1.4.3、Tiebreakers 1.5、走一遍完整的流程1.6、Name Mangling1.7、总结 1.…...

代码随想录算法训练营Day56 || ● 583. 两个字符串的删除操作 ● 72. 编辑距离

今天接触到了真正的距离&#xff0c;但可以通过增删改操作来逼近。 问题1&#xff1a;583. 两个字符串的删除操作 - 力扣&#xff08;LeetCode&#xff09; 给定两个单词 word1 和 word2 &#xff0c;返回使得 word1 和 word2 相同所需的最小步数。 每步 可以删除任意一个字…...

chrome_elf.dll丢失怎么办?修复chrome_elf.dll文件的方法

Chrome是目前最受欢迎的网络浏览器之一&#xff0c;然而有时用户可能会遇到Chrome_elf.dll丢失的问题。该DLL文件是Chrome浏览器的一个重要组成部分&#xff0c;负责启动和管理程序的各种功能。当Chrome_elf.dll丢失时&#xff0c;用户可能无法正常启动Chrome或执行某些功能。本…...

代码随想录32|738.单调递增的数字,968.监控二叉树,56. 合并区间

738.单调递增的数字 链接地址 class Solution { public:int monotoneIncreasingDigits(int n) {string str to_string(n);int flag str.size();for (int i str.size() - 1; i > 0; i--) {if (str[i] < str[i - 1]) {str[i - 1] - 1;flag i;}}for (int j flag; j <…...

BIO NIO AIO演变

Netty是一个提供异步事件驱动的网络应用框架&#xff0c;用以快速开发高性能、高可靠的网络服务器和客户端程序。Netty简化了网络程序的开发&#xff0c;是很多框架和公司都在使用的技术。 Netty并非横空出世&#xff0c;它是在BIO&#xff0c;NIO&#xff0c;AIO演变中的产物…...

JVM GC垃圾回收

一、GC垃圾回收算法 标记-清除算法 算法分为“标记”和“清除”阶段&#xff1a;标记存活的对象&#xff0c; 统一回收所有未被标记的对象(一般选择这种)&#xff1b;也可以反过来&#xff0c;标记出所有需要回收的对象&#xff0c;在标记完成后统一回收所有被标记的对象 。它…...

【数据结构】队列知识点总结--定义;基本操作;队列的顺序实现;链式存储;双端队列;循环队列

欢迎各位看官^_^ 目录 1.队列的定义 2.队列的基本操作 2.1初始化队列 2.2判断队列是否为空 2.3判断队列是否已满 2.4入队 2.5出队 2.6完整代码 3.队列的顺序实现 4.队列的链式存储 5.双端队列 6.循环队列 1.队列的定义 队列&#xff08;Queue&#xff09;是一种先…...

嵌入式学习之链表

对于链表&#xff0c;要重点掌握链表和数组区别和实现&#xff0c;链表静态添加和动态遍历&#xff0c;链表中pointpoint-next,链表节点个数的查找&#xff0c;以及链表从指定节点后方插入新节点的知识。...

静态代理和动态代理笔记

总体分为: 1.静态代理: 代理类和被代理类需要实现同一个接口.在代理类中初始化被代理类对象.在代理类的方法中调 用被代理类的方法.可以选择性的在该方法执行前后增加功能或者控制访问 2.动态代理: 在程序执行过程中,实用JDK的反射机制,创建代理对象,并动态的指定要…...

[SM6225][Android13]user版本默认允许root和remount

开发平台基本信息 芯片: 高通SM6225版本: Android 13kernel: msm-5.15 问题描述 刚刚从Framework踏入性能的小殿堂&#xff0c;User版本默认是不会开启root权限的&#xff0c;而且一般调试需要设置一下CPU GPU DDR performance模式或者修改一些schedule util等调核调频节点去…...

pyinstaller打包exe,使用wexpect的问题

参考github首先打包wexpect 1.进入wexpect目录执行 pyinstaller __main__.py -n wexpect 会生成dist文件夹 2.python代码A.py中使用wexpect&#xff0c;注意wexpect.spawn前后必须按照下面添加代码 import sys,os,wexpect #spawn前 real_executable sys.executable try:if sy…...

OpenCV(三十三):计算轮廓面积与轮廓长度

1.介绍轮廓面积与轮廓长度 轮廓面积&#xff08;Contour Area&#xff09;是指轮廓所包围的区域的总面积。通常情况下&#xff0c;轮廓面积的单位是像素的平方。 轮廓长度&#xff08;Contour Length&#xff09;又称周长&#xff08;Perimeter&#xff09;&#xff0c;表示轮廓…...

9.11作业

实现一个对数组求和的函数&#xff0c;数组通过实参传递给函数 sum0 arr(11 22 33 44 55) Sum() {for i in ${arr[*]}do$((sumi))donereturn $sum } Sum ${arr[*]} var$? echo $var写一个函数&#xff0c;输出当前用户的uid和gid&#xff0c;并使用变量接收结果 Sum() {aid -…...

简述建立一个网站模板步骤/百度站长app

CentOS的yum源中没有git&#xff0c;只能自己编译安装&#xff0c;现在记录下编译安装的内容&#xff0c;留给自己备忘。 确保已安装了依赖的包 yum install curl yum install curl-devel yum install zlib-devel yum install openssl-devel yum install perl yum install cpio…...

p2p网贷网站建设方案/山东济南seo整站优化费用

CPA全国青少年编程能力等级测评值得参加。CPA全国青少年编程能力等级测评考试内容难度适中&#xff0c;且分级考试&#xff0c;适合不同阶段的青少年参加。同时&#xff0c;从《青少年编程能力等级》标准中可以看到&#xff0c;“图形化编程“标准将分为三级&#xff0c;依次考…...

idc 网站备案/制作网站软件

#参考资料大型分布式网站架构设计与实践 #感悟&#xff1a;书读百遍&#xff0c;其意自见 #QQ群北京it—推荐–交流&#xff1a;300458205 #群专注内推、大数据、云计算、Java、Android、UI等技术交流&#xff0c;欢迎你的加入。 看的越多&#xff0c;发现会的越少&#xff…...

网站鼠标代码/郑州网站seo服务

Java基本介绍Java基本介绍 Java基本介绍 1、什么是JDK&#xff1f; * Java Development Kits* Java开发工具箱【Java开发必备】* 可以从Oracle的官网上下载。http://www.oracle.com* 目前2016-08-30最高版本Java8【Java SE 8u101 / 8u102】* 下载JDK的时候需要注意&#xff1a;…...

建网站空间的详细说明/seo网站推广计划

概念在Java中&#xff0c;对象的生命周期包括以下几个阶段&#xff1a;创建阶段(Created)应用阶段(In Use)不可见阶段(Invisible)不可达阶段(Unreachable)收集阶段(Collected)终结阶段(Finalized)对象空间重分配阶段(De-allocated)Java对象在JVM中的生命周期当你通过new语句创建…...

企业门户网站开发代码/湘潭关键词优化服务

美国国家健康与营养调查&#xff08; NHANES, National Health and Nutrition Examination Survey&#xff09;是一项基于人群的横断面调查&#xff0c;旨在收集有关美国家庭人口健康和营养的信息。 地址为&#xff1a;https://wwwn.cdc.gov/nchs/nhanes/Default.aspx 既往我们…...