【02基础】- RabbitMQ基础
目录
- 2- RabbitMQ
- 2-1 介绍和安装
- 安装
- 2-2 RabbitMQ 快速入门
- 2-3 RabbitMQ 数据隔离
- 3- Java客户端
- 3-1 快速入门
- AMQP
- 快速入门
- 📑小结:SpringAMQP如何收发消息?
- 3-2 WorkQueues 任务模型
- 案例-使用 WorkQueue 单队列绑定多消费者
- 📑小结:Work模型的使用
- 3-3 Fanout 交换机
- 案例- FanouotExchange 使用
- 📑小结:交换机的作用是什么?
- 3-4 Direct 交换机
- 案例-利用 SpringAMQP 演示 DirectExchange 的使用
- 📑小结:DirectExchange 的作用是什么?
- 3-5 Topic 交换机
- 案例-利用 SpringAMQP 演示 DirectExchange 的适用
- 📑小结:描述下 Direct 交换机和 Topic 交换机的差异
- 3-6 声明队列和交换机
- 声明队列和交换机的方式(Java代码实现)
- 代码实现
- 使用注解的方式解决 Direct 交换机问题
- 📑小结
- 3-7 消息转换器
- 案例-利用 SpringAMQP 发送对象类型的消息
- 问题
- 4- 使用 MQ 改造支付业务代码
- 案例
2- RabbitMQ
2-1 介绍和安装
RabbitMQ 的整体架构以及核心概念
publisher
:消息发送者cunsumer
:消息消费者queue
:队列exchange
:交换机,负责路由消息virtual-host
:虚拟主机,起到数据隔离的作用;一个 MQ 中可以创建多个virtual-host
数据流转的模型:①生产者将数据发送给交换机 ——> ②交换机将消息路由给队列 ——> ③消费者监听队列拿到消息
安装
- 上传镜像文件
mq.tar
到 Linux 系统中 - 执行命令
docker load -i mq.tar
- 复制以下代码执行
- 其中 15672 ,是控制台端口
- 其中 5672 ,是收发消息的端口
docker run \
-e RABBITMQ_DEFAULT_USER=itheima \
-e RABBITMQ_DEFAULT_PASS=123321 \
-v mq-plugins:/plugins \
--name mq \
--hostname mq \
-p 15672:15672 \
-p 5672:5672 \
--network hmall \
-d \
rabbitmq:3.8-management
2-2 RabbitMQ 快速入门
需求
- 在
rabbitmq
的控制台完成下列操作: - 新建队列
hello.queue1
和hello.queue2
- 向默认的
amp.fanout
交换机发送一条消息 - 查看消息是否到达
hello.queue1
和hello.queue2
实现
- 需要创建队列,同时在交换机中需要绑定队列才能实现消息的路由。
总结规律
①如果交换机和队列没有绑定能否收到消息?
- 交换机:是负责路由和转发消息的。交换机通过绑定队列,之后可以将消息转发到队列中。
②如果绑定了所有队列是不是所有队列都可以收到消息?
- 是的,如果一个交换机绑定了多个队列,那类似于广播的效果所有队列都能收到消息。
2-3 RabbitMQ 数据隔离
- 在 RabbitMQ 中有虚拟主机的概念,对于交换机和队列而言都有二者自己的虚拟主机。
需求
- 在 RabbitMQ 的控制台下完成下列操作
- 新建一个用户 hmall
- 为 hmall 用户创建一个 vitual host
- 测试不同的 vitual host 之间的数据隔离现象
实现
- ① 首先在
Admin
——>Users
中创建用户 - ② 在
Admin
——>Users
中创建虚拟主机
总结
- 各个虚拟主机下都是相互隔离的。
3- Java客户端
3-1 快速入门
AMQP
什么是 AMQP?
- Advanced Message Queuing Protocol,是一种高级的消息队列协议,是用于在应用程序之间传递业务消息的开放标准。该协议与语言和平台无关,更符合微服务中独立性的要求。
Spring AMQP
Spring AMQP
是基于 AMQP 协议定义的一套 API 规范,提供了模板来发送和接收消息。包含两部分,其中Spring AMQP
是基础抽象,spring-rabbit
是底层的默认实现
快速入门
需求
- 利用控制台创建队列 simple.queue
- 在 publisher 服务中,利用 SpringAMQP 直接向 simple.queue 发送消息
- 在 consumer 服务中,利用 SpringAMQP 编写消费者监听 simple.queue 队列
实现
- ① 引入
spring-amqp
依赖,在父工程中引入spring-amqp
依赖,这样publisher
和consumer
服务都可以使用
<!-- AMQP依赖,包含RabbitMQ -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
- ② 在每个微服务中引入 MQ 服务端信息,这样微服务才能连接到 RabbitMQ
- ③ 发送消息: SpringAMQP 提供了 RabbitTemplate 工具类,方便我们发送消息,发送消息的代码如下
@Autowired
private RabbitTemplate rabbitTemplate;@Test
public void testSimpleQueue() {// 队列名称String queueName = "simple.queue";// 消息String message = "hello, spring amqp!";// 发送消息rabbitTemplate.convertAndSend(queueName, message);
}
- ④ 接收消息:
SpringAMQP
提供声明式的消息监听,我们只需要通过 注解 在方法上声明要监听的队列名称,将来SpringAMQP
就会把消息传递给当前方法。
@Slf4j
@Component
public class SpringRabbitListener {@RabbitListener(queues = "simple.queue")public void listenSimpleQueueMessage(String msg) throws InterruptedException {log.info("spring 消息接收到消息: [" + msg + "]");if (true) {throw new MessageConversionException("故意的");}log.info("消息处理完毕");}
}
📑小结:SpringAMQP如何收发消息?
3-2 WorkQueues 任务模型
- Work queues,任务模型。简单来说就是 让多个消费者绑定到一个队列,共同消费队列中的消息。
案例-使用 WorkQueue 单队列绑定多消费者
模拟 WorkQueue 实现一个队列绑定多个消费者,基本思路如下
- ① 在 RabbitMQ 的控制台创建一个队列,名为
work.queue
- ② 在 publisher 服务中定义测试方法,在 1 秒内产生 50 条消息,发送到
work.queue
- ③ 在 consumer 服务中顶级两个消息监听者,都监听
work.queue
队列 - ④ 消费者每 1 秒处理 50 条消息,消费者每 2 秒处理 5 条消息
实现
- ① 实现消费者
@Slf4j
@Component
public class MqListener {@RabbitListener(queues = "simple.queue")public void listenSimpleQueue(String msg) {System.out.println("消费者收到了simple.queue的消息: [" + msg + "]");}@RabbitListener(queues = "work.queue")public void listenWorkQueue1(String msg) {System.out.println("消费者1 收到了 work.queue的消息: [" + msg + "]");}@RabbitListener(queues = "work.queue")public void listenWorkQueue2(String msg) {System.err.println("消费者2 收到了 work.queue的消息: [" + msg + "]");}
}
- ② 实现生产者
@SpringBootTest
public class SpringAmqpTest {@Autowiredprivate RabbitTemplate rabbitTemplate;@Testvoid testSendMessage2Queue() {String queueName = "simple.queue";String msg = "hello, amqp!";rabbitTemplate.convertAndSend(queueName, msg);}@Testvoid testWorkQueue() throws InterruptedException {String queueName = "work.queue";for (int i = 1; i <= 50; i++) {String msg = "hello, worker, message_" + i;rabbitTemplate.convertAndSend(queueName, msg);Thread.sleep(20);}}
}
结果
- 发现在消费的过程中,两个消费者并没有都消费 50 条消息。
- 二者消费的过程是采用轮询的方式进行消费。
通过改变消费速度
- 即便改变了消费的速度,消费的过程中消费者1 和消费者2,也是按照轮询的方式消费任务。
@RabbitListener(queues = "work.queue")public void listenWorkQueue1(String msg) {System.out.println("消费者1 收到了 work.queue的消息: [" + msg + "]");}@RabbitListener(queues = "work.queue")public void listenWorkQueue2(String msg) {System.err.println("消费者2 收到了 work.queue的消息: [" + msg + "]");Thread.sleep(20);}
📑小结:Work模型的使用
3-3 Fanout 交换机
Fanout Exchange 交换机会将收到的消息广播到每一个跟其绑定的 queue,所以也叫 广播模式
案例- FanouotExchange 使用
实现思路如下
- ① 在 RabbitMQ 控制台中,声明队列
fanout.queue1
和fanout.queue2
- ② 在 RabbitMQ 控制台中,声明交换机
hmall.fanout
将两个队列与其绑定 - ③ 在 consumer 服务中,编写两个消费者方法,分别监听
fanout.queue1
和**fanout.queue2
- ④ 在 publisher 中编写测试方法,向
hmall.fanout
发送消息。
Fanout 交换机
- 消费者
@RabbitListener(queues = "fanout.queue1")
public void listenWorkQueue1(String msg) {System.out.println("消费者1 收到了 fanout.queue1的消息: [" + msg + "]");
}@RabbitListener(queues = "fanout.queue2")
public void listenWorkQueue2(String msg) {System.err.println("消费者2 收到了 fanout.queue2的消息: [" + msg + "]");
}
- 生产者
@Test
void testSendFanout() {String exchangeName = "hmall.fanout";String msg = "hello,everyone";rebbitTemplate.converAndSend(exchangeName,numm,msg);
}
- 运行结果
📑小结:交换机的作用是什么?
3-4 Direct 交换机
Direct Exchange 会将接收到的消息根据路由规则路由到指定的 Queue,因此可以称为定向路由。
- 每一个 Queue 都与 Exchange 设置一个 Bindingkey
- 发布者发送消息时,制定消息的 RoutingKey
- Exchange 将消息路由到 BindingKey 与消息 RoutingKey 一致的队列
案例-利用 SpringAMQP 演示 DirectExchange 的使用
需求如下
- ① 在 RabbitMQ 控制台中,声明队列 direct.queue1 和 direct.queue2
- ② 在 RabbitMQ 控制台中,声明交换机 hmall.direct,将两个队列与其绑定
- ③ 在 consumer 服务中,编写两个消费方法,分别监听 direct.queue1 和 direct.queue2
- ④ 在 publisher 中编写测试方法,利用不同的 RoutingKey 向 hmall.direct 发送消息
📑小结:DirectExchange 的作用是什么?
:::info
- DirectExchange 交换机可以通过 bindingKey 来设置,将消息通过 bindingKey 发送到指定的队列中。通过设置合适的绑定键,您可以确保特定的消息被发送到特定的微服务进行处理。这样可以实现消息的精确路由,确保消息只被需要的消费者接收和处理。
:::
3-5 Topic 交换机
TopicExchange 与 DirectExchange 类似,区别在于 routingKey 可以是多个单词的列表,并且以 .
分割。
- Queue 与 Exchange 指定 BindingKey 时可以使用通配符
#
代表 0 个 或多个单词。*
:代指一个单词
- 类似上述实现,如果一个 bindingKey 定义为了
china.#
那么,对于其而言只会接收与china.#
开头的消息。
案例-利用 SpringAMQP 演示 DirectExchange 的适用
需求如下
- ① 在 RabbitMQ 控制台中,声明队列 topic.queue1 和 topic.queue2
- ② 在 RabbitMQ 控制台中,声明交换机 hmall.topic 将两个队列与其绑定
- ③ 在 consumer 服务中,编写两个消费者方法,分别监听 topic.queue1 和 topic.queue2
- ④ 在 publisher 中编写测试方法,利用不同的 RoutingKey 向 hmall.topic 发送消息
- 消费者
@RabbitListener(queues = "topic.queue1")
public void listenTopicQueue1(String msg) throws InterruptedException {System.out.println("消费者1 收到了 topic.queue1的消息: [" + msg + "] ");
}@RabbitListener(queues = "topic.queue2")
public void listenTopicQueue2(String msg) throws InterruptedException {System.out.println("消费者2 收到了 topic.queue2的消息: [" + msg + "] ");
}
- 发送者
- 以下情况消息会被路由到
**#.news**
的队列中。
- 以下情况消息会被路由到
@Test
void testSendTopic() {String exchangeName = "hmall.topic";String msg = "蓝色通知,警报解除,哥斯拉是放的气球";rabbitTemplate.convertAndSend(exchangeName, "japan.news", msg);
}
- 发送者2
- 以下情况两个队列都会收到消息。
@Test
void testSendTopic() {String exchangeName = "hmall.topic";String msg = "蓝色通知,警报解除,哥斯拉是放的气球";rabbitTemplate.convertAndSend(exchangeName, "china.news", msg);
}
- 发送者3
- 以下情况只有队列1 会受到消息。
@Test
void testSendTopic() {String exchangeName = "hmall.topic";String msg = "蓝色通知,警报解除,哥斯拉是放的气球";rabbitTemplate.convertAndSend(exchangeName, "china.weather", msg);
}
📑小结:描述下 Direct 交换机和 Topic 交换机的差异
3-6 声明队列和交换机
- 使用 Java 代码声明队列交换机才是最靠谱的方式
声明队列和交换机的方式(Java代码实现)
SpringAMQP 提供了几个类,用来声明队列、交换机及其绑定关系
Queue
:用于声明队列,可用工厂类QueueBuilder
创建Exchange
:用于声明交换机,可以用工厂类ExchangeBuilder
构建Binding
:用于声明队列和交换机的绑定关系,可以用工厂类BindingBuilder
构建
代码实现
- 例如,声明一个 Fanout 类型的交换机,并且创建队列与其绑定
public class FanoutConfiguration {@Beanpublic FanoutExchange fanoutExchange(){// ExchangeBuilder.fanoutExchange("").build();return new FanoutExchange("hmall.fanout2");}@Beanpublic Queue fanoutQueue3(){// QueueBuilder.durable("ff").build();return new Queue("fanout.queue3");}@Beanpublic Binding fanoutBinding3(Queue fanoutQueue3, FanoutExchange fanoutExchange){return BindingBuilder.bind(fanoutQueue3).to(fanoutExchange);}@Beanpublic Queue fanoutQueue4(){// QueueBuilder.durable("ff").build();return new Queue("fanout.queue4");}@Beanpublic Binding fanoutBinding4(){return BindingBuilder.bind(fanoutQueue4()).to(fanoutExchange());}
}
使用注解的方式解决 Direct 交换机问题
- 由于 Direct 交换机可以配置对应的 key,但对于声明式方式来说,需要对每个 key 都写一个 binding 方法,这样效率很低,所以引入注解的方式实现
- SpringAMQP 还提供了基于 @RabbitListener 注解来声明队列和交换机的方式,在 Listener 的部分通过注解实现
@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "direct.queue1",durable = "true"),exchange = @Exchange(name = "hmall,direct",type = ExchangeTypes,DIRECT),key = {"red","blue"}
))
public void listenDirectQueue1(String msg) throws InterruptedException{System.out.println("消费者 1 收到了 direct.queueq 的消息:【"+msg+"】");
}
📑小结
3-7 消息转换器
案例-利用 SpringAMQP 发送对象类型的消息
- ① 声明一个队列,名为 object.queue
- ② 编写单元测试,向队列中直接发送一条消息,消息类型为 Map
- ③ 在控制台查看消息,总结你能发现的问题
// 准备消息
Map<String,Object> msg = new HashMap<>();
msg.put("name","Jack");
msg.put("age",21);
@Test
void testSendObject() {Map<String, Object> msg = new HashMap<>(2);msg.put("name", "jack");msg.put("age", 21);rabbitTemplate.convertAndSend("object.queue", msg);
}
问题
- Spring 对消息对象的处理是由 org.springframework,amqp.support.converter.MessageConveerter 来处理的。而默认实现是 SimpleMessageConverter,基于 JDK 的 ObjectOutputStream 完成序列化。
存在以下问题
- JDK 的序列化有安全风险
- JDK 序列化的消息太大
- JDK 序列化的消息可读性差
建议采用 JSON 薛丽华代替默认的的 JDK 序列化,要做两件事情:
- 在 publisher 和 consumer 中都要引入 Jackson 依赖:
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId>
</dependency>
- 在 publisher 和 consumer 中都要配置 MessageConverter
@Bean
public MessageConverter messageConverter() {return new Jackson2JsonMessageConverter();
}
4- 使用 MQ 改造支付业务代码
案例
- 需求:改造余额支付功能,不再同步调用交易服务的 OpenFeign 接口,而是采用异步的 MQ 通知交易服务更改订单状态
-
- 业务中引入 AMQP 依赖
<!-- amqp -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
- 2.配置 MQ 的地址
spring:rabbitmq:host: 192.168.150.101port: 5672virtual-host: /hmallusername: hmallpassword: 123
-
- 配置 MQ 的 Configure
@Configuration
public class MqConfig {@Beanpublic MessageConverter jackson2JsonMessageConverter() {return new Jackson2JsonMessageConverter();}
}
-
- 编写监听器
@Component
@RequiredArgsConstructor
public class PayStatusListener {private final IOrderService orderService;@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "mark.order.pay.queue", durable = "true"),exchange = @Exchange(name = "pay.topic", type = ExchangeTypes.TOPIC),key = "pay.success"))public void listenOrderPay(Long orderId) {// 标记订单状态为已支付orderService.markOrderPaySuccess(orderId);}
}
-
- 业务异步调用
rabbitTemplate.convertAndSend("pay.topic", "pay.success", po.getBizOrderNo());
相关文章:

【02基础】- RabbitMQ基础
目录 2- RabbitMQ2-1 介绍和安装安装 2-2 RabbitMQ 快速入门2-3 RabbitMQ 数据隔离 3- Java客户端3-1 快速入门AMQP快速入门📑小结:SpringAMQP如何收发消息? 3-2 WorkQueues 任务模型案例-使用 WorkQueue 单队列绑定多消费者📑小结…...

vue3中跨层传递provide、inject
前置说明 在 Vue 3 中,provide 和 inject 是一对用于跨组件树传递数据的 API。它们允许你在祖先组件中使用 provide 提供数据或服务,然后在后代组件中使用 inject 来获取这些数据或服务。这种方式特别适用于跨多个层级的组件传递数据,而不需要…...
Nacos-1.4.6升级2.3.2
一、nacos-2.3.2部署(非升级测试步骤) 1、使用nginx进行代理 # nginx-1.25.5 docker run -d --name nginx-nacos --network nacos --privilegedtrue -v /data/nacos/nginx.conf:/etc/nginx/conf.d/default.conf -p 8848:8848 nginx:latest2、创建nacos服务 # nacos-2.3.2 do…...

东识集中文印管理系统|DW-S408系统的主要功能
集中文印管理系统以涉密文件集中管理为目标,实现办公文件汇总、打印信息生成、文件打印、文件追溯等功能,将用户与打印设备分离,有效防止纸媒泄密。 集中文印管理系统是由客户端和服务端两部分构成,客户端能够将打印文件上传至服…...
text-foreground讲解
1、fore单词讲解 fore 是 “forward” 或 “front” 的简写,意思是"前面的"、“前景的”。 一些常见的相关英文词: foreground fore ground,意思是"前景" background back ground,意思是"背景&qu…...

数字IC后端实现之Innovus Place跑完density爆涨案例分析
下图所示为咱们社区a7core后端训练营学员的floorplan。 数字IC后端实现 | Innovus各个阶段常用命令汇总 该学员跑placement前density是59.467%,但跑完place后density飙升到87.68%。 仔细查看place过程中的log就可以发现Density一路飙升! 数字IC后端物…...

【牛客刷题实战】二叉树遍历
大家好,我是小卡皮巴拉 文章目录 目录 牛客题目: 二叉树遍历 题目描述 输入描述: 输出描述: 示例1 解题思路 问题理解 算法选择 具体思路 解题要点 完整代码(C语言) 兄弟们共勉 !&…...

消息队列mq有哪些缺点?
大家好,我是锋哥。今天分享关于【消息队列mq有哪些缺点?】面试题?希望对大家有帮助; 消息队列mq有哪些缺点? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 消息队列(MQ)的缺点 消…...

【CENet】多模态情感分析的跨模态增强网络
在MSA领域,文本的准确度远远高于音频和视觉,如果文本能达到90%,那么音频和视觉的准确度只有60%~80%,但是过往研究很少针对情感分析的背景下去提高音频和视频的准确度。 abstract: 多模态情感分析(MSA&…...

动态代理:面向接口编程,屏蔽RPC处理过程
RPC远程调用 使用 RPC 时,一般的做法是先找服务提供方要接口,通过 Maven把接口依赖到项目中。在编写业务逻辑的时候,如果要调用提供方的接口,只需要通过依赖注入的方式把接口注入到项目中,然后在代码里面直接调用接口…...
HTTP 405 Method Not Allowed:解析与解决
HTTP 405 Method Not Allowed:解析与解决 引言 在Web开发中,HTTP状态码是服务器与客户端之间通信的重要组成部分。当我们使用Python进行网络请求时,经常会遇到各种HTTP状态码。其中,HTTP 405 “Method Not Allowed” 错误是一个…...

推荐一款CAD/CAM设计辅助工具:Mastercam
Mastercam是一款非常好用的软件,我们的这款软件是由美国CNC软件公司开发,集平面制图、三维设计、曲面设计、数 控编程、刀具处理等多项强大功能于一体。软件的使用过程具有非常直观的特点,用户可以很方便地对自己的作品进行设计。 Mastercam不…...
位运算刷题记录
1. 使两个整数相等的位更改次数 3226. 使两个整数相等的位更改次数 给你两个正整数 n 和 k。 你可以选择 n 的 二进制表示 中任意一个值为 1 的位,并将其改为 0。 返回使得 n 等于 k 所需要的更改次数。如果无法实现,返回 -1。 class Solution {pub…...

爬虫技术——小白入狱案例
知孤云出岫 目录 1. 案例概述2. 案例需求分析3. 实现步骤Step 1: 环境准备Step 2: 分析百度图片URL请求规律Step 3: 编写爬虫代码代码解析 4. 运行代码5. 注意事项6. 案例总结 要实现大批量爬取百度图片,可以使用Python编写一个网络爬虫,通过发送HTTP请求…...

vue 果蔬识别系统百度AI识别vue+springboot java开发、elementui+ echarts+ vant开发
编号:R03-果蔬识别系统 简介:vuespringboot百度AI实现的果蔬识别系统 版本:2025版 视频介绍: vuespringboot百度AI实现的果蔬识别系统前后端java开发,百度识别,带H5移动端,mysql数据库可视化 1 …...

全新更新!Fastreport.NET 2025.1版本发布,提升报告开发体验
在.NET 2025.1版本中,我们带来了巨大的期待功能,进一步简化了报告模板的开发过程。新功能包括通过添加链接报告页面、异步报告准备、HTML段落旋转、代码文本编辑器中的文本搜索、WebReport图像导出等,大幅提升用户体验。 FastReport .NET 是…...

信息学科平台系统设计与实现:Spring Boot技术手册
5系统详细实现 5.1 用户信息管理 基于保密信息学科平台系统的系统管理员可以对用户信息查询。具体界面的展示如图5.1所示。 图5.1 用户信息管理界面 5.2 教师信息管理 管理员可以对教师信息进行查下和删除。具体界面如图5.2所示。 图5.2 教师信息界面 5.3 学科动态管理 管理…...

conda下jupyterlab安装问题以及交互绘图问题记录
安装 1. 直接conda install jupyterlab就好,只要在base环境下安装就行,可以在任意环境下执行jupyter lab启动。 2. 打开jupyter lab后显示Could not determine jupyterlab build status without nodejs,可以执行conda install nodejs安装no…...

尚硅谷react教程_扩展_setState更新状态的2种写法
1.setState setState更新状态的2种写法(1).setState(stateChange,[callback])----对象式的setState1.stateChange为状态改变对象(该对象可以体现出状态的更改)2.callback是可选的回调函数,它在状态更新完毕、界面也更新…...

C语言编写的自动取款机模拟程序
#include〈stdio。h> #include<string。h> #include <stdio.h> #include〈stdlib.h〉 #include〈direct.h〉 #include<io.h> #include 〈errno。h> /********************************************************…...

IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...

RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...

UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...

高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...