多个springboot整合使用rabbitmq(使用注解的方式)
一、简述
先参考单个springboot使用rabbitmq和了解rabbitmq的五种模式
单个springboot整合rabbitmq_java-zh的博客-CSDN博客
二、创建项目
1、先创建两个springboot项目,一个做生产者,一个做消费者
2、导包(生产者和消费者对应的内容都是一样)
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.1</version><relativePath/></parent><groupId>com.mq</groupId><artifactId>mqcloud</artifactId><version>0.0.1-SNAPSHOT</version><properties><spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version><java.version>1.8</java.version><spring-boot.version>2.5.3</spring-boot.version><lombok.version>1.18.14</lombok.version><mybaits.plus.version>3.3.2</mybaits.plus.version><alibaba.json.version>1.2.75</alibaba.json.version><spring-cloud-starter-bootstrap.version>3.0.2</spring-cloud-starter-bootstrap.version></properties><!-- <dependencyManagement>--><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--AOP--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><!--bootstrap 启动器--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId><version>${spring-cloud-starter-bootstrap.version}</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${alibaba.json.version}</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version><optional>true</optional></dependency><!--jjwt--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.0</version></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>31.1-jre</version></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId><version>${spring-cloud-alibaba.version}</version></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><version>${spring-cloud-alibaba.version}</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency><!--zhong 基础jar--><dependency><groupId>com.common</groupId><artifactId>base</artifactId><version>1.0-SNAPSHOT</version></dependency><!--消息队列 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId><version>3.0.4</version></dependency></dependencies><!-- </dependencyManagement>--></project>
3、编写配置文件
这里的配置文件生产者和消费者都一样
spring:rabbitmq:#如果是集群,用,隔开connection-timeout: 15000username: adminpassword: 123456#虚拟host,可以不设置virtual-host: /listener:simple:acknowledge-mode: auto #manual:手动处理 auto:自动处理#消费端监听个数(即@RabbitListenter开启几个线程去处理)concurrency: 10#消费端监听的最大个数max-concurrency: 10prefetch: 5default-requeue-rejected: true #消费不成功的消息,拒绝入队retry:enabled: true #开启消息重试max-attempts: 4 #重试次数max-interval: 10000 #重试最大间隔时间initial-interval: 2000 #重试初始间隔时间#消息确认方式,通过correlated来确认publisher-confirm-type: correlatedpublisher-returns: truehost: 192.168.139.128port: 5672
rabbitmq:#订阅模式(扇形模式) fanout:exchange:#交换机名称name1: exchange.fanoutqueue:#通道名称name1: exchange.fanout.queue_1name2: exchange.fanout.queue_2#交换机模式 direct:exchange:name1: exchange.directqueue:name1: exchange.direct.queue_1name2: exchange.direct.queue_2routing:name1: exchange.direct.routing.1name2: exchange.direct.routing.2#主题模式 topic:exchange: name1: exchange.topicqueue:name1: exchange.topic.queue_1name2: exchange.topic.queue_2routing:name1: '#.routingkey.#'name2: routingkey.*
三、编码代码和测试结果
这里以rabbitmq的订阅模式(扇形模式)、路由器模式、主题模式为案例
3.1 扇形模式
生产者
@Autowired
private RabbitTemplate rabbitTemplate;// 订阅模式的交换机名称
@Value("${rabbitmq.fanout.exchange.name1}")private String exchangeName;/*** 订阅模式(扇形模式)生产者** @param context*/
@GetMapping("/fanout/{context}")
public void sendMessage(@PathVariable String context) {System.out.println("需要发送得内容为:" + context);rabbitTemplate.convertAndSend(exchangeName, "", context);
}
消费者
注意:消费者绑定交换机和通道的值必须是固定常量值,所以我们直接从配置文件中读取
@RabbitListener(bindings = @QueueBinding(exchange = @Exchange(value = "${rabbitmq.fanout.exchange.name1}", type = ExchangeTypes.FANOUT),value = @Queue(value = "${rabbitmq.fanout.queue.name1}")))@RabbitHandlerpublic void consumerFanoutExchange(String context) {System.out.println("订阅模式,通道一接收到的内容为内容:" + context);}@RabbitListener(bindings = @QueueBinding(exchange = @Exchange(value = "${rabbitmq.fanout.exchange.name1}", type = ExchangeTypes.FANOUT),value = @Queue(value = "${rabbitmq.fanout.queue.name2}")))@RabbitHandlerpublic void consumerFanoutExchange2(String context) {System.out.println("订阅模式,通道二接收到的内容为内容:" + context);
}
3.2 路由器模式
生产者
@Autowired
private RabbitTemplate rabbitTemplate;// 路由器模式的交换机名称
@Value("${rabbitmq.direct.exchange.name1}")
private String directName;// 路由器模式的路由key1
@Value("${rabbitmq.direct.routing.name1}")
private String directRoutingKeyName1;//路由器模式的路由key2
@Value("${rabbitmq.direct.routing.name2}")
private String directRoutingKeyName2;/*** 路由器模式* @param context* @param routingkey*/
@GetMapping("/direct")
public void sendMessageDirect(@RequestParam("context") String context, @RequestParam("routingkey") Integer routingkey) {if (1 == routingkey) {rabbitTemplate.convertAndSend(directName, directRoutingKeyName1, context);} else if (2 == routingkey) {rabbitTemplate.convertAndSend(directName, directRoutingKeyName2, context);} else {System.out.println("数据非法");}
}
消费者
@RabbitListener(bindings = @QueueBinding(exchange = @Exchange(value = "${rabbitmq.direct.exchange.name1}", type = ExchangeTypes.DIRECT),value = @Queue(value = "${rabbitmq.direct.queue.name1}"),key = "${rabbitmq.direct.routing.name1}"))public void exchangeDirectRoutingKey1(String context, Message message) {System.out.println("key1:" + message.getMessageProperties().getReceivedRoutingKey());System.out.println("路由器模式1 接收到的消息为:" + context);}@RabbitListener(bindings = @QueueBinding(exchange = @Exchange(value = "${rabbitmq.direct.exchange.name1}", type = ExchangeTypes.DIRECT),value = @Queue(value = "${rabbitmq.direct.queue.name2}"),key = "${rabbitmq.direct.routing.name2}"))public void exchangeDirectRoutingKey2(String context, Message message) {System.out.println("key2:" + message.getMessageProperties().getReceivedRoutingKey());System.out.println("路由器模式2 接收到的消息为" + context);}
3.3 主题模式
生产者
// 主题模式的交换机名称@Value("${rabbitmq.topic.exchange.name1}")private String topicName;//用来匹配主题模式对应的keypublic static final String EXCHANGE_TOPIC_CASE_KEY_1 = "topic.routingkey.case1";//如果case_key_2这样写,那么绑定case_key_1的队列一样会接收到,因为case_key_2也一样和key1匹配上public static final String EXCHANGE_TOPIC_CASE_KEY_2 = "routingkey.case2";@GetMapping("/topic")public void sendMessageTopic(@RequestParam("context") String context, @RequestParam("routingkey") Integer routingkey) {if (1 == routingkey) {rabbitTemplate.convertAndSend(topicName, EXCHANGE_TOPIC_CASE_KEY_1, context + routingkey);} else if (2 == routingkey) {rabbitTemplate.convertAndSend(topicName, EXCHANGE_TOPIC_CASE_KEY_2, context + routingkey);} else {System.out.println("数据非法");}}
消费者
@RabbitListener(bindings = @QueueBinding(exchange = @Exchange(value = "${rabbitmq.topic.exchange.name1", type = ExchangeTypes.TOPIC),value = @Queue(value = "${rabbitmq.topic.queue.name1}"),key = "${rabbitmq.topic.routing.name1}"))@RabbitHandlerpublic void exchangeTopicRoutingKey1(String context, Message message) {System.out.println("key1:"+message.getMessageProperties().getReceivedRoutingKey());System.out.println("主题模式1:接收的内容为:"+ context);}@RabbitListener(bindings = @QueueBinding(exchange = @Exchange(value = "${rabbitmq.topic.exchange.name1", type = ExchangeTypes.TOPIC),value = @Queue(value = "${rabbitmq.topic.queue.name2}"),key = "${rabbitmq.topic.routing.name2}"))@RabbitHandlerpublic void exchangeTopicRoutingKey2(String context, Message message) {System.out.println("key2:"+message.getMessageProperties().getReceivedRoutingKey());System.out.println("主题模式2:接收的内容为:"+ context);}
3.4 全量代码
生产者
@RestController
@RequiredArgsConstructor
@RequestMapping("/test/mq")
public class ProductController {private final RabbitTemplate rabbitTemplate;// 订阅模式的交换机名称@Value("${rabbitmq.fanout.exchange.name1}")private String exchangeName;// 路由器模式的交换机名称@Value("${rabbitmq.direct.exchange.name1}")private String directName;// 路由器模式的路由key1@Value("${rabbitmq.direct.routing.name1}")private String directRoutingKeyName1;//路由器模式的路由key2@Value("${rabbitmq.direct.routing.name2}")private String directRoutingKeyName2;// 主题模式的交换机名称@Value("${rabbitmq.topic.exchange.name1}")private String topicName;//用来匹配主题模式对应的keypublic static final String EXCHANGE_TOPIC_CASE_KEY_1 = "topic.routingkey.case1";//如果case_key_2这样写,那么绑定case_key_1的队列一样会接收到,因为case_key_2也一样和key1匹配上public static final String EXCHANGE_TOPIC_CASE_KEY_2 = "routingkey.case2";/*** 订阅模式(扇形模式)生产者** @param context*/@GetMapping("/fanout/{context}")public void sendMessage(@PathVariable String context) {System.out.println("需要发送得内容为:" + context);rabbitTemplate.convertAndSend(exchangeName, "", context);}/*** 路由器模式* @param context* @param routingkey*/@GetMapping("/direct")public void sendMessageDirect(@RequestParam("context") String context, @RequestParam("routingkey") Integer routingkey) {if (1 == routingkey) {rabbitTemplate.convertAndSend(directName, directRoutingKeyName1, context);} else if (2 == routingkey) {rabbitTemplate.convertAndSend(directName, directRoutingKeyName2, context);} else {System.out.println("数据非法");}}@GetMapping("/topic")public void sendMessageTopic(@RequestParam("context") String context, @RequestParam("routingkey") Integer routingkey) {if (1 == routingkey) {rabbitTemplate.convertAndSend(topicName, EXCHANGE_TOPIC_CASE_KEY_1, context + routingkey);} else if (2 == routingkey) {rabbitTemplate.convertAndSend(topicName, EXCHANGE_TOPIC_CASE_KEY_2, context + routingkey);} else {System.out.println("数据非法");}}
}
消费者
@Component
public class ConsumerTest {@RabbitListener(bindings = @QueueBinding(exchange = @Exchange(value = "${rabbitmq.fanout.exchange.name1}", type = ExchangeTypes.FANOUT),value = @Queue(value = "${rabbitmq.fanout.queue.name1}")))@RabbitHandlerpublic void consumerFanoutExchange(String context) {System.out.println("订阅模式,通道一接收到的内容为内容:" + context);}@RabbitListener(bindings = @QueueBinding(exchange = @Exchange(value = "${rabbitmq.fanout.exchange.name1}", type = ExchangeTypes.FANOUT),value = @Queue(value = "${rabbitmq.fanout.queue.name2}")))@RabbitHandlerpublic void consumerFanoutExchange2(String context) {System.out.println("订阅模式,通道二接收到的内容为内容:" + context);}@RabbitListener(bindings = @QueueBinding(exchange = @Exchange(value = "${rabbitmq.direct.exchange.name1}", type = ExchangeTypes.DIRECT),value = @Queue(value = "${rabbitmq.direct.queue.name1}"),key = "${rabbitmq.direct.routing.name1}"))public void exchangeDirectRoutingKey1(String context, Message message) {System.out.println("key1:" + message.getMessageProperties().getReceivedRoutingKey());System.out.println("路由器模式1 接收到的消息为:" + context);}@RabbitListener(bindings = @QueueBinding(exchange = @Exchange(value = "${rabbitmq.direct.exchange.name1}", type = ExchangeTypes.DIRECT),value = @Queue(value = "${rabbitmq.direct.queue.name2}"),key = "${rabbitmq.direct.routing.name2}"))public void exchangeDirectRoutingKey2(String context, Message message) {System.out.println("key2:" + message.getMessageProperties().getReceivedRoutingKey());System.out.println("路由器模式2 接收到的消息为" + context);}@RabbitListener(bindings = @QueueBinding(exchange = @Exchange(value = "${rabbitmq.topic.exchange.name1", type = ExchangeTypes.TOPIC),value = @Queue(value = "${rabbitmq.topic.queue.name1}"),key = "${rabbitmq.topic.routing.name1}"))@RabbitHandlerpublic void exchangeTopicRoutingKey1(String context, Message message) {System.out.println("key1:"+message.getMessageProperties().getReceivedRoutingKey());System.out.println("主题模式1:接收的内容为:"+ context);}@RabbitListener(bindings = @QueueBinding(exchange = @Exchange(value = "${rabbitmq.topic.exchange.name1", type = ExchangeTypes.TOPIC),value = @Queue(value = "${rabbitmq.topic.queue.name2}"),key = "${rabbitmq.topic.routing.name2}"))@RabbitHandlerpublic void exchangeTopicRoutingKey2(String context, Message message) {System.out.println("key2:"+message.getMessageProperties().getReceivedRoutingKey());System.out.println("主题模式2:接收的内容为:"+ context);}}
相关文章:
多个springboot整合使用rabbitmq(使用注解的方式)
一、简述 先参考单个springboot使用rabbitmq和了解rabbitmq的五种模式 单个springboot整合rabbitmq_java-zh的博客-CSDN博客 二、创建项目 1、先创建两个springboot项目,一个做生产者,一个做消费者 2、导包(生产者和消费者对应的内容都是一样) <…...
《Effective C++中文版,第三版》读书笔记2
条款06:若不想使用编译器自动生成的函数,就该明确拒绝 为驳回编译器自动()提供的机能,可将相应的成员函数声明为私有的,同时不实现它。 #include <iostream>class MyClass { public:MyClass(int in…...

虫情测报系统的工作原理及功能优势
KH-CQPest虫情测报系统能够在不对虫体造成任何破坏的情况下,无公害的杀死虫子,利用高倍显微镜和高清摄像头拍摄虫体照片,并将虫体照片发送到远端平台,让工作人员无需要到现场,通过平台就可以观察害虫的种类和数量&…...
UWB定位技术详细介绍
UWB(Ultra-Wideband)定位技术是一种通过利用信号的超宽频带特性进行高精度定位的技术。其原理是通过测量信号在空间传播中的时间延迟差异来计算物体的位置。 UWB技术与传统无线通信技术不同,它利用非常宽的频带进行通信,通常超过…...

PiplineADC学习一:
PiplineADC结构: PiplineADC起源之FlashADC PiplineADC起源之Sub-Ranging-ADC 比较器存在失调: 因此每级1bit不实用,需要做冗余位设计。 多比较一次,两个阈值,三个区间,分别对于输出00,01,10。正常2bit应该…...
Linux elasticsearch设置为开机自启动服务
Linux elasticsearch怎么设置为设置为开机自启动服务 1、进入/etc/init.d目录 cd /etc/init.d 2、新建文件elasticsearch,注意,没有扩展名 vi elasticsearch 3、新建文件elasticsearch的内容如下 说明: (1)“su…...
WinForm内嵌Unity3D
Unity3D可以C#脚本进行开,使用vstu2013.msi插件,可以实现在VS2013中的调试。在开发完成后,由于项目需要,需要将Unity3D嵌入到WinForm中。WinForm中的UnityWebPlayer Control可以载入Unity3D。先看效果图。 一、为了能够动态设置ax…...
关于vue中v-for绑定数据重新渲染的问题
我修改被v-for绑定的数据,发现居然不能重新渲染。 查找后得知一下方法: $set 是 Vue 提供的一个全局方法,用于向响应式对象中添加或更新属性,并触发视图更新。它接受三个参数:对象、要添加/更新的属性名或索引,以及新…...

全面解析 Axios 请求库的基本使用方法
Axios 是一个流行的基于 Promise 的 HTTP 请求库,用于在浏览器和 Node.js 中进行 HTTP 请求。它提供了简单易用的 API,可以发送各种类型的请求(如 GET、POST、PUT、DELETE等),并处理响应数据,Axios 在前端工…...
rust踩雷笔记3——生命周期的理解
目录 概念和基本使用一个例子彻底理解最基本的内容 一个例子理解函数签名为什么要有生命周期标注⭐️能不能对编译器蒙混过关? 生命周期是rust中最难的概念——鲁迅 这一块内容即便是看rust圣经,第一遍也有点懵。今天早上二刷突然有了更直观的认识&…...

windows权限维持—黄金白银票据隐藏用户远控RustDeskGotoHttp
windows权限维持—黄金白银票据&隐藏用户&远控&RustDesk&GotoHttp 1. 前置1.1. 初始问题1.1.1. 解决办法 2. 隐藏用户2.1. 工具原理2.2. 案例操作2.2.1. 单机添加用户2.2.1.1. 工具添加用户2.2.1.2. 工具查看隐藏用户2.2.1.3. 本地查看隐藏用户 2.2.2. 域内添加…...
vscode conda activate激活环境出错
vscode conda activate 出错 conda-script.py: error: argument COMMAND: invalid choice: ‘activate’ To initialize your shell, run$ conda init <SHELL_NAME>Currently supported shells are:- bash- fish- tcsh- xonsh- zsh- powershellSee conda init --help f…...

信息与通信工程面试准备——数学知识|正态分布|中心极限定理
目录 正态分布 正态分布的参数 正态分布的第一个参数是均值 正态分布的第二个参数是标准差SD 所有正态分布的共同特征 标准正态分布:正态分布的特例 中心极限定理 理解定义 示例# 1 示例# 2 知道样本均值总是正态分布的实际含义是什么? 正态分…...

Mybatis多表查询与动态SQL的使用
目录 1. Mybatis多表查询 1.1 添加文章表实体类 1.2 文章Interface 1.3 文章.xml 1.4 lombok的toString()有关对象打印的说明 1.5 场景: 一个用户查询多篇文章 2. 复杂情况: 动态SQL的使用 2.1 为什么要使用动态SQL? 2.2 <if>标签 2.3 <trim>标签 2.4 <where&g…...
url 和 uri 有什么区别?
URL(Uniform Resource Locator)和URI(Uniform Resource Identifier)是两个与网络资源定位和标识相关的概念,它们有一些区别,但也存在一些重叠。 URI(Uniform Resource Identifier)是…...

HCIP VLAN实验
VLAN实验 拓扑图配置和分析分析配置LSW1LSW2R1 测试dhcp获取ipICMP测试 拓扑图 配置和分析 分析 从题目来看,因为 pc 1 3都是vlan2而且还是不同网段,pc 2 4 5 6在同一网段,所以可以将pc 1 2 5 4 6分在一个网段 pc4不通5 6 ,那就…...

无涯教程-Perl - waitpid函数
描述 该函数等待ID为PID的子进程终止,返回已故进程的进程ID。如果PID不存在,则返回-1。进程的退出状态包含在$?中。 可以将标志设置为各种值,这些值等于waitpid()UNIX系统调用使用的值。 FLAGS的值为0应该在支持进程的所有操作系统上工作。 语法 以下是此函数的简单语法- …...

Redis之缓存雪崩、缓存击穿、缓存穿透问题
文章目录 前言一、缓存雪崩1.1、原因分析2.2、常用解决方案 二、缓存击穿2.1、原因分析2.2、常用解决方案2.2.1、使用互斥锁2.2.2、逻辑过期方案2.3、方案对比 三、缓存穿透3.1、原因分析3.2、解决方案3.2.1、缓存空对象3.2.3、布隆过滤3.3、方案对比 总结 前言 本文谈谈Redis…...

九五从零开始的运维之路(其三十五)
文章目录 前言一、概述1.概念2.组成3.特点4.工作原理5.优点: 二、各节点及其ip地址三、构建MHA1.ssh免密登录2.构建mysql主从复制(一)安装mariadb数据库并启动(二)master服务器(三)slave服务器&…...

5G科技防汛,助力守护一方平安
“立秋虽已至,炎夏尚还在”,受台风席卷以及季节性影响全国多地正面临强降水的严峻挑战。“落雨又顺秋,绵绵雨不休”,正值“七下八上” 防汛关键时期,贵州省水文水资源局已全面进入备战状态。 为确保及时响应做好防汛抢…...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...

linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...