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

【RabbitMQ】Spring Boot 结合 RabbitMQ 完成应用间的通信

   🔥个人主页: 中草药

🔥专栏:【中间件】企业级中间件剖析


 Spring 框架与 RabbitMQ 的整合主要通过 Spring AMQP(Advanced Message Queuing Protocol)模块实现,提供了便捷的消息队列开发能力。

引入依赖

    <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.amqp</groupId><artifactId>spring-rabbit-test</artifactId><scope>test</scope></dependency></dependencies>

配置

#配置RabbitMQ的基本信息
spring:rabbitmq:host: 110.41.51.65port: 15673 #默认为5672username: studypassword: studyvirtual-host: bite #默认值为#或者以下这种方式rabbitmq:addresses: #amqp://username:password@Ip:port/virtual-host

一、工作队列模式(Work Queue)

场景:多个消费者共享一个队列,消息被轮询分发(Round-Robin),用于任务分发和负载均衡(如耗时任务处理)。

producer

@RestController
@RequestMapping("/producer")
public class ProducerController {@Autowiredprivate RabbitTemplate rabbitTemplate;@RequestMapping("/work")public String work(){//使用内置交换机 RoutingKey 和队列名称一致for (int i = 0; i < 10; i++) {rabbitTemplate.convertAndSend("", Constants.WORK_QUEUE,"Hello World"+i);}return "OK";}
}

@RabbitListener 是 Spring 框架中用于监听 RabbitMQ 队列的注解,通过使用这个注解,可以定义一个方法,以便从 RabbitMQ 队列中接收消息(相当于消费者)。该注解支持多种参数类型,这些参数类型代表了从 RabbitMQ 接收到的消息和相关信息。

以下是一些常用的参数类型:

  1. String:返回消息的内容。
  2. Messageorg.springframework.amqp.core.Message):Spring AMQP 的 Message 类,返回原始的消息体以及消息的属性,如消息 ID、内容、队列信息等。
  3. Channelcom.rabbitmq.client.Channel):RabbitMQ 的通道对象,可以用于进行更高级的操作,如手动确认消息 。
@Component
public class WorkListener {@RabbitListener(queues = Constants.WORK_QUEUE)public void queueListener1(Message message, Channel channel) {System.out.println("Listener1:["+Constants.WORK_QUEUE+"]"+message+",channel:"+channel);}@RabbitListener(queues = Constants.WORK_QUEUE)public void queueListener2(String message) {System.out.println("Listener2:["+Constants.WORK_QUEUE+"]"+message);}
}

观察控制台

轮询分发:默认按顺序将消息分发给不同消费者。

二、发布订阅模式(Publish/Subscribe)

场景:消息广播到所有绑定的队列(如日志广播、事件通知),使用 Fanout 交换机

声明使用交换机和队列 并绑定

@Configuration
public class RabbitMQConfig {@Bean("fanoutQueue1")public Queue funoutQueue1() {return QueueBuilder.durable(Constants.FUNOUT_QUEUE1).build();}@Bean("fanoutQueue2")public Queue funoutQueue2() {return QueueBuilder.durable(Constants.FUNOUT_QUEUE2).build();}@Bean("funoutExchange")public FanoutExchange funoutExchange(){return ExchangeBuilder.fanoutExchange(Constants.FUNOUT_EXCHANGE).durable(true).build();}@Bean("funoutQueueBinding1")public Binding funoutQueueBinding1(@Qualifier("fanoutQueue1") Queue queue,@Qualifier("funoutExchange") FanoutExchange funoutExchange){return BindingBuilder.bind(queue).to(funoutExchange);}@Bean("funoutQueueBinding2")public Binding funoutQueueBinding2(@Qualifier("fanoutQueue2") Queue queue,@Qualifier("funoutExchange") FanoutExchange funoutExchange){return BindingBuilder.bind(queue).to(funoutExchange);}
}

producer


@RestController
@RequestMapping("/producer")
public class ProducerController {@Autowiredprivate RabbitTemplate rabbitTemplate;@RequestMapping("/funout")public String funout(){rabbitTemplate.convertAndSend(Constants.FUNOUT_EXCHANGE,"","Hello Spring funout");return "OK";}
}

listener

@Component
public class FunoutListener {@RabbitListener(queues = Constants.FUNOUT_QUEUE1)public void queueListener1(String message) {System.out.println("Listener1:["+Constants.FUNOUT_QUEUE1+"]"+message);}@RabbitListener(queues = Constants.FUNOUT_QUEUE2)public void queueListener2(String message) {System.out.println("Listener2:["+Constants.FUNOUT_QUEUE2+"]"+message);}
}

在实际开发之中,一个 listener 监听一个 queue 

三、路由模式(Routing)

场景:根据 路由键(Routing Key) 精准匹配,将消息发送到指定队列,使用 Direct 交换机

声明使用交换机和队列 并绑定

@Configuration
public class RabbitMQConfig {//direct@Bean("directQueue1")public Queue directQueue1() {return QueueBuilder.durable(Constants.DIRECT_QUEUE1).build();}@Bean("directQueue2")public Queue directQueue2() {return QueueBuilder.durable(Constants.DIRECT_QUEUE2).build();}@Bean("directExchange")public DirectExchange directExchange(){return ExchangeBuilder.directExchange(Constants.DIRECT_EXCHANGE).durable(true).build();}@Bean("directQueueBinding1")public Binding directQueueBinding1(@Qualifier("directQueue1") Queue queue,@Qualifier("directExchange") DirectExchange directExchange){return BindingBuilder.bind(queue).to(directExchange).with("orange");}@Bean("directQueueBinding2")public Binding directQueueBinding2(@Qualifier("directQueue2") Queue queue,@Qualifier("directExchange") DirectExchange directExchange){return BindingBuilder.bind(queue).to(directExchange).with("black");}@Bean("directQueueBinding3")public Binding directQueueBinding3(@Qualifier("directQueue2") Queue queue,@Qualifier("directExchange") DirectExchange directExchange){return BindingBuilder.bind(queue).to(directExchange).with("orange");}
}

producer


@RestController
@RequestMapping("/producer")
public class ProducerController {@Autowiredprivate RabbitTemplate rabbitTemplate;@RequestMapping("/direct/{routingKey}")public String direct(@PathVariable String routingKey){rabbitTemplate.convertAndSend(Constants.DIRECT_EXCHANGE,routingKey,"Hello Spring direct "+routingKey);return "direct OK";}
}

listener

@Component
public class DirectListener {@RabbitListener(queues = Constants.DIRECT_QUEUE1)public void queueListener1(String message) {System.out.println("Listener1:["+Constants.DIRECT_QUEUE1+"]"+message);}@RabbitListener(queues = Constants.DIRECT_QUEUE2)public void queueListener2(String message) {System.out.println("Listener2:["+Constants.DIRECT_QUEUE2+"]"+message);}
}

如果某一个队列即绑定了black和orange,将会分别发送到队列

四、通配符模式(Topics)

场景:根据路由键的 通配符规则 匹配队列,使用 Topic 交换机,支持 *(匹配一个单词)和 #(匹配多个单词)。

Topics 和 Routing 模式的区别是:

  1. topics 模式使用的交换机类型为 topic (Routing 模式使用的交换机类型为 direct)
  2. topic 类型的交换机在匹配规则上进行了扩展,Binding Key 支持通配符匹配

声明使用交换机和队列 并绑定

@Configuration
public class RabbitMQConfig {//TOPIC@Bean("topicExchange")public TopicExchange topicExchange(){return ExchangeBuilder.topicExchange(Constants.TOPIC_EXCHANGE).durable(true).build();}@Bean("topicQueue1")public Queue topicQueue1(){return QueueBuilder.durable(Constants.TOPIC_QUEUE1).build();}@Bean("topicQueue2")public Queue topicQueue2(){return QueueBuilder.durable(Constants.TOPIC_QUEUE2).build();}@Bean("topicQueueBinding1")public Binding topicQueueBinding1(@Qualifier("topicExchange")TopicExchange topicExchange,@Qualifier("topicQueue1") Queue topicQueue){return BindingBuilder.bind(topicQueue).to(topicExchange()).with("*.orange.*");}@Bean("topicQueueBinding2")public Binding topicQueueBinding2(@Qualifier("topicExchange")TopicExchange topicExchange,@Qualifier("topicQueue2") Queue topicQueue){return BindingBuilder.bind(topicQueue).to(topicExchange).with("*.*.rabbit");}@Bean("topicQueueBinding3")public Binding topicQueueBinding3(@Qualifier("topicExchange")TopicExchange topicExchange,@Qualifier("topicQueue2") Queue topicQueue){return BindingBuilder.bind(topicQueue).to(topicExchange).with("lazy.#");}
}

producer


@RestController
@RequestMapping("/producer")
public class ProducerController {@Autowiredprivate RabbitTemplate rabbitTemplate;@RequestMapping("/topic/{routingKey}")public String topic(@PathVariable String routingKey){rabbitTemplate.convertAndSend(Constants.TOPIC_EXCHANGE,routingKey,"Hello Spring topic "+routingKey);return "topic OK";}
}

listener

@Component
public class TopicListener {@RabbitListener(queues = Constants.TOPIC_QUEUE1)public void queueListener1(String message) {System.out.println("Listener1:["+Constants.TOPIC_QUEUE1+"]"+message);}@RabbitListener(queues = Constants.TOPIC_QUEUE2)public void queueListener2(String message) {System.out.println("Listener2:["+Constants.TOPIC_QUEUE2+"]"+message);}
}

五、完成应用通信

SpringBoot 整合 RabbitMQ 实现应用通信是微服务/分布式系统中常见的异步解耦方案。

以此图为实例

订单系统

@Configuration
public class RabbitMQConfig {@Bean("orderQueue")public Queue orderQueue() {return QueueBuilder.durable("order.create").build();}
}@RestController
@RequestMapping("/order")
public class OrderController {@Autowiredprivate RabbitTemplate rabbitTemplate;@RequestMapping("/create")public String create(){rabbitTemplate.convertAndSend("","order.create","订单信息,订单ID:"+ UUID.randomUUID());//这里仅仅是模拟演示,实际的下单操作比较复杂,包括参数的校验,数据库存储等等 业务代码省略return "下单成功";}
}

 物流系统

@Component
@RabbitListener(queues = "order.create")
public class OrderListener {@RabbitHandler//该注解根据所识别的数据类型不同自动分配不同的方法public void handleOrder(String orderInfo) {System.out.println("接收到新的订单消息:"+orderInfo);//接收到订单消息后,进行相应的业务出路 代码省略}@RabbitHandler//在此处为方便演示我们将order-service 让此项目应用//正确的做法是将OrderInfo抽取出来单独作为一个包,两个service都引用这个包public void handleOrder2(OrderInfo orderInfo) {System.out.println("接收到新的订单消息:"+orderInfo);}
}

@RabbitHandler 注解用于标记方法,这些方法会根据消息的类型来处理接收到的消息。当一个消息监听器容器接收到消息时,它会根据消息的类型选择合适的 @RabbitHandler 注解的方法来处理该消息。 

测试结果

当在发送的是一个对象时,为保证对象的可读性,我们要保证对象可被序列化,且通过 Jackson2JsonMessageConverter 将其从原生序列化改为Json格式

@Configuration
public class RabbitMQConfig {@Beanpublic Jackson2JsonMessageConverter messageConverter() {return new Jackson2JsonMessageConverter();}@Beanpublic RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);rabbitTemplate.setMessageConverter(messageConverter());return rabbitTemplate;}
}

对于Listener,为保证同样具有解读json的能力,也应该去加上相同的配置 

@Data
public class OrderInfo implements Serializable {//实现序列化接口private String orderId;private String name;
}

 可观察结果


对时间的慷慨,就等于慢性自杀。——奥斯特洛夫斯基

🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀

以上,就是本期的全部内容啦,若有错误疏忽希望各位大佬及时指出💐

  制作不易,希望能对各位提供微小的帮助,可否留下你免费的赞呢🌸 

相关文章:

【RabbitMQ】Spring Boot 结合 RabbitMQ 完成应用间的通信

&#x1f525;个人主页&#xff1a; 中草药 &#x1f525;专栏&#xff1a;【中间件】企业级中间件剖析 Spring 框架与 RabbitMQ 的整合主要通过 Spring AMQP&#xff08;Advanced Message Queuing Protocol&#xff09;模块实现&#xff0c;提供了便捷的消息队列开发能力。 引…...

DeepSeek本地化部署(DeepSeek+olloma+Dify)

文章目录 概要需要准备的工具Ollama准备内容Docker准备内容Dify准备内容本地访问Dify 概要 提示&#xff1a;本篇文章主要讲述如何部署本地Deepseek私有大模型&#xff0c;使用Windows无显卡环境进行部署 需要准备的工具 Ollama、Docker Desktop 下载地址&#xff1a; Ollama…...

Spring boot3-WebClient远程调用非阻塞、响应式HTTP客户端

来吧&#xff0c;会用就行具体理论不讨论 1、首先pom.xml引入webflux依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId> </dependency> 别问为什么因为是响应式....…...

Ubuntu22.04安装数据

数据库安装步骤&#xff1a; sudo apt-get update sudo apt install mysql-server mysql-client sudo systemctl start mysql sudo systemctl status mysql &#xff08;1&#xff09;在命令行登录 MySQL 数据库&#xff0c;并使用 mysql 数据库 &#xff08;必须使用这个…...

【python-uiautomator2】手机上的ATX应用界面报错问题处理:无法提供服务,非am instrument启动

目录 一、前期准备 1.1 插入设备 1.2 安装atx-agent 二、解决报错&#xff1a;无法提供服务&#xff0c;非am instrument启动 2.1 出现报错 2.2 尝试解决 2.3 最终解决 三、开启ATX的悬浮窗权限 一、前期准备 1.1 插入设备 本地插入待执行设备&#xff0c;待执行设备…...

自动化测试介绍及学习路线

目录 一、自动化测试 1.1 自动化测试的概念 1.2 自动化测试的主流领域 接口自动化测试 UI自动化测试 持续集成 二、学习路线 一、自动化测试 1.1 自动化测试的概念 自动化测试是指利用软件工具或脚本来执行测试用例和比较实际结果与预期结果的过程&#xff0c;通过运行…...

Python:函数(一)

python函数相关的知识点 1. 函数定义与调用 定义&#xff1a;使用 def 关键字&#xff0c;后接函数名和参数列表。 def greet(name):"""打印问候语&#xff08;文档字符串&#xff09;"""print(f"Hello, {name}!") 调用&#xff1a…...

qml c++混合编程注意事项

在Qml和C类进行数据交互时&#xff0c;通用的办法都是注册C到Qml中&#xff0c;但是很多时候C的对象是在C中进行创建&#xff0c;如果在Qml中创建了&#xff0c;数据之间的交互就会出现无法控制的问题。 信号与槽、上下文等都是数据交互的方式&#xff0c;但是当嵌套多层时&…...

Leetcode6-Z字形变换

题目链接&#xff1a;6. Z 字形变换 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 定义numRows个字符数组&#xff0c;用于存每一行的字符&#xff1b;再定义一个标志行数的变量cnt&#xff0c;cnt在0到numRows-1之间不停的加一或减一&#xff08;当cnt到0了&am…...

【eNSP实战】配置交换机端口安全

拓扑图 目的&#xff1a;让交换机端口与主机mac绑定&#xff0c;防止私接主机。 主机PC配置不展示&#xff0c;按照图中配置即可。 开始配置之前&#xff0c;使用PC1 ping 一遍PC2、PC3、PC4、PC5&#xff0c;让交换机mac地址表刷新一下记录。 LSW1查看mac地址表 LSW1配置端…...

React.js 基础与进阶教程

React.js 基础与进阶教程 React.js 是由 Facebook 开发的流行前端 JavaScript 库&#xff0c;专为构建用户界面&#xff08;UI&#xff09;设计&#xff0c;尤其适用于单页面应用&#xff08;SPA&#xff09;。它采用组件化开发模式&#xff0c;使 UI 结构更加清晰、可维护性更…...

Docker基础入门(一)

初识Docker 什么是Docker Docker是一个快速交付应用、运行应用的技术&#xff1a; 可以将程序及其依赖、运行环境一起打包为一个镜像&#xff0c;可以迁移到任意Linux操作系统运行时利用沙箱机制形成隔离容器&#xff0c;各个应用互不干扰启动、移除都可以通过一行命令完成&…...

moment.js时间处理库

目录 一、moment().isValid()验证时间是否有效 二、moment().second()获取秒数或者设置秒数 三、moment().day()获取星期或者设置星期 四、moment().add()加法操作 五、moment().subtract()减法操作 六、moment.max()最大值 七、moment.min()最小值 八、克隆时间 一、mo…...

基于hive的电信离线用户的行为分析系统

标题:基于hive的电信离线用户的行为分析系统 内容:1.摘要 随着电信行业的快速发展&#xff0c;用户行为数据呈现出海量、复杂的特点。为了深入了解用户行为模式&#xff0c;提升电信服务质量和精准营销能力&#xff0c;本研究旨在构建基于 Hive 的电信离线用户行为分析系统。通…...

循环神经网络(RNN):时序建模的核心引擎与演进之路

在人工智能处理序列数据的战场上&#xff0c;循环神经网络&#xff08;RNN&#xff09;如同一个能够理解时间的智者。从 2015 年谷歌神经机器翻译系统颠覆传统方法&#xff0c;到 2023 年 ChatGPT 实现对话连续性&#xff0c;这些突破都植根于 RNN 对时序建模的深刻理解。本文将…...

docker 安装常用镜像

我们在上篇文章中已经修改了daemon.json 安装镜像时如果search超时就直接pull 安装mysql docker pull mysql:5.7 启动命令 docker run --name mysql-docker -p 3306:3306 -e MYSQL_ROOT_PASSWORDroot1234 -d mysql:5.7 ocker run&#xff1a;运行docker容器命令 --name my…...

大数据学习(63)- Zookeeper详解

&&大数据学习&& &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一下博主哦&#x1f91e; &#x1f…...

安卓Compose中accompanist库使用详解

安卓Compose中accompanist库使用详解 文章目录 安卓Compose中accompanist库使用详解一、Accompanist 库概览二、核心组件详解三、总结与建议 本文首发地址 https://h89.cn/archives/348.html 最新更新地址 https://gitee.com/chenjim/chenjimblog 一、Accompanist 库概览 Acco…...

Gateway:网关路由与登录鉴权

在微服务架构中&#xff0c;用户登录和身份校验的处理方式确实与单体应用有所不同。在单体架构中&#xff0c;一旦用户通过身份验证&#xff0c;其会话信息可以在整个应用范围内共享&#xff0c;所有模块都能访问到用户信息。然而&#xff0c;在微服务架构下&#xff0c;每个服…...

【MySQL篇】MySQL内置函数

目录 1&#xff0c;日期函数 2&#xff0c;字符串函数 3&#xff0c;数学函数 4&#xff0c;其他函数 实战OJ 1&#xff0c;日期函数 日期类型在之前文章【数据类型】中有描述 传送门&#xff1a;【MySQL篇】数据类型_mysql 数据类型-CSDN博客 函数名称描述current_dat…...

爬虫案例十三js逆向模拟登录中大网校

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、网站分析二、代码 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; js 逆向模拟登录中大网校 提示&#xff1a;以下是本篇文章正文内…...

高效编程指南:PyCharm与DeepSeek的完美结合

DeepSeek接入Pycharm 前几天DeepSeek的充值窗口又悄悄的开放了&#xff0c;这也就意味着我们又可以丝滑的使用DeepSeek的API进行各种辅助性工作了。本文我们来聊聊如何在代码编辑器中使用DeepSeek自动生成代码。 注&#xff1a;本文适用于所有的JetBrains开发工具&#xff0c…...

前馈神经网络 - 参数学习(优化问题)

神经网络的参数学习比线性模型要更加困难&#xff0c;主要原因有两点:&#xff08;1)非凸优化问题和 &#xff08;2)梯度消失问题&#xff0c;本文我们来学习和分析这两类问题。 一、非凸优化问题 1、非凸优化问题演示&#xff1a; 神经网络的优化问题是一个非凸优化问题。 …...

AI 大模型统一集成|如何封装多个大模型 API 调用

&#x1f31f; 在这系列文章中&#xff0c;我们将一起探索如何搭建一个支持大模型集成项目 NexLM 的开发过程&#xff0c;从 架构设计 到 代码实战&#xff0c;逐步搭建一个支持 多种大模型&#xff08;GPT-4、DeepSeek 等&#xff09; 的 一站式大模型集成与管理平台&#xff…...

C语言学习day25:WinAPI编程进阶06-游戏辅助窗体监视热键讲解

我们上一章已经绘制出了植物大战僵尸的一个页面 但是我们要怎么样去判断&#xff0c;用户是否按了F1呢。好的接下来就是我们的内容&#xff0c;监视热键。 思路&#xff1a; 我们按下的是键盘&#xff0c;因此我们得用键盘消息&#xff0c;也是&#xff1a;WM_KEYDOWN 同时要…...

JVM常用概念之常量

问题 final修饰的字段就一定是不能重新赋值吗? 基础知识 常量变量是使用常量表达式初始化的原始类型或 String 类型的最终变量。变量是否为常量变量可能对类初始化、二进制兼容性和明确赋值有影响。 —Java 语言规范 实验 用例源码-重新赋值 import java.lang.reflect.Fie…...

【Vue】el-dialog的2种封装方法(父子组件双向通信),$emit触发父事件/.sync修饰符双向绑定

🤵 作者:coderYYY 🧑 个人简介:前端程序媛,目前主攻web前端,后端辅助,其他技术知识也会偶尔分享🍀欢迎和我一起交流!🚀(评论和私信一般会回!!) 👉 个人专栏推荐:《前端项目教程以及代码》 前言 在现代Vue.js开发中,el-dialog组件作为ElementUI库中的一个…...

解决远程主机允许路由转发 【原理扫描】:将/proc/sys/net/ipv4/ip_forward 置为0

解决远程主机允许路由转发 【原理扫描】&#xff1a;将/proc/sys/net/ipv4/ip_forward 置为0 解决远程主机允许路由转发 【原理扫描】&#xff1a;将/proc/sys/net/ipv4/ip_forward 置为0问题描述解决方案临时修改永久生效验证配置 影响 解决远程主机允许路由转发 【原理扫描】…...

c++20 Concepts的简写形式与requires 从句形式

c20 Concepts的简写形式与requires 从句形式 原始写法&#xff08;简写形式&#xff09;等效写法&#xff08;requires 从句形式&#xff09;关键区别说明&#xff1a;组合多个约束的示例&#xff1a;两种形式的编译结果&#xff1a;更复杂的约束示例&#xff1a;标准库风格的约…...

安装oVirt环境

1. oVirt Engine 硬件要求 资源最低推荐 中央处理器 双核 x86_64 CPU. 一个四核 x86_64 CPU 或多个双核 x86_64 CPU。 记忆 4 GB 的可用系统 RAM&#xff08;如果未安装 Data Warehouse 且现有进程未占用内存&#xff09;。 16 GB 的系统 RAM。 硬盘 25 GB 本地可访问的…...

【 <一> 炼丹初探:JavaWeb 的起源与基础】之 Tomcat 的工作原理:从启动到请求处理的流程

<前文回顾> 点击此处查看 合集 https://blog.csdn.net/foyodesigner/category_12907601.html?fromshareblogcolumn&sharetypeblogcolumn&sharerId12907601&sharereferPC&sharesourceFoyoDesigner&sharefromfrom_link <今日更新> 一、Tomcat…...

【认识OpenThread协议】

OpenThread 是一种基于 IPv6 、IEEE 802.15.4 标准的低功耗无线 Mesh 网络协议&#xff0c;主要用于智能家居、物联网设备等场景。它的设计目标是实现设备之间的高效通信、低功耗运行和高可靠性。 OpenThread官方文档 ① 特性 低功耗: 适合电池供电的设备。 Mesh 网络: 支持多…...

Qt入门笔记

目录 一、前言 二、创建Qt项目 2.1、使用向导创建 2.2、最简单的Qt应用程序 2.2.1、main函数 2.2.2、widget.h文件 2.2.3、widget.cpp文件 2.3、Qt按键Botton 2.3.1、创建一个Botton 2.3.2、信号与槽 2.3.3、按键使用信号与槽的方法 2.4、文件Read与Write-QFile类 2…...

【前端】【nuxt】几种在 Nuxt 客户端使用console的方式

方法1&#xff1a;在Vue生命周期钩子中使用 只在客户端执行的钩子&#xff08;如mounted&#xff09;中打印&#xff1a; export default {mounted() {console.log(仅在客户端显示, this.$route.path)} }方法2&#xff1a;通过环境判断 使用process.client判断当前环境&…...

安装 ubuntu 2404 LTS 服务器 设置 服务器名称

安装 ubuntu服务器 设置 服务器名称 hostname 打开终端&#xff08;Terminal&#xff09;&#xff0c;通过快捷键CtrlAltT或在应用程序中搜索"终端"来打开&#xff1b;在终端中输入以下命令&#xff1a;hostname&#xff0c;然后按下回车键即可查看本机服务器名称。…...

C语言一维数组

学习任何数据结构,都可以分为三个主要步骤: 了解基本概念:首先,我们需要理解数据结构的基本概念。以数组为例,首先要知道什么是数组,数组的定义是什么。数组是一种存储固定大小的元素集合的数据结构,它的元素类型是统一的,且通过索引访问。 了解数组的构造和内存分布:…...

霍夫变换法是基于传统视觉特征的道路车道线检测算法中的一种经典方法

霍夫变换法是基于传统视觉特征的道路车道线检测算法中的一种经典方法&#xff0c;以下是对它的详细介绍&#xff1a; 基本原理 霍夫变换的基本思想是将图像空间中的点映射到参数空间中&#xff0c;通过在参数空间中寻找峰值来确定图像中特定形状的参数。在车道线检测中&#…...

静态时序分析:SDC约束命令set_ideal_latency详解

相关阅读 静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm1001.2014.3001.5482 当使用set_ideal_network命令将当前设计中的一组端口或引脚标记为理想网络源后&#xff0c;理想属性会沿着组合逻辑进行传播&#xff0c;理想网络中的线网和单元…...

DeepSeek引领端侧AI革命,边缘智能重构AI价值金字塔

目录 一、AI从“技术炫耀”到“价值兑现” 二、边缘侧部署&#xff1a;从技术挑战到商业必然 三、小规模模型&#xff1a;精度与效率的再平衡 四、Coovally的前瞻性&#xff1a;降低边缘AI开发门槛 五、生产级部署&#xff1a;跨越从实验室到车间的鸿沟 六、未来演进&…...

完整例子和调用关系qt OpenGL

项目结构 首先&#xff0c;你需要在 Qt 项目中创建一个类&#xff0c;继承自 QOpenGLWidget 来进行 OpenGL 渲染。文件结构如下&#xff1a; - main.cpp - MyOpenGLWidget.h - MyOpenGLWidget.cpp - vertex_shader.glsl - fragment_shader.glsl 1. main.cpp 这是 Qt 项目的入口…...

SpringBoot缓存抽象:@Cacheable与缓存管理器配置

文章目录 引言一、SpringBoot缓存抽象概述二、Cacheable注解详解2.1 Cacheable的关键属性 三、缓存管理器配置四、自定义键生成策略五、缓存同步与失效策略六、SpringBoot缓存最佳实践总结 引言 缓存是提升应用性能的关键技术&#xff0c;SpringBoot提供了强大的缓存抽象层&am…...

环路广播风暴演示图

以下是环路广播风暴的演示图及其说明&#xff1a; 环路广播风暴演示图 ----------------- ----------------- | Switch A | | Switch B | | | | | | [Port1]--------------------------[Port1] |…...

【webrtc debug tools】 rtc_event_log_to_text

一、rtc_event_log 简介 在学习分析webrtc的过程中&#xff0c;发现其内部提供了一个实时数据捕获接口RtcEventLog。通过该接口可以实时捕获进出webrtc的RTP报文头数据、音视频配置参数、webrtc的探测数据等。其内容实现可参考RtcEventLogImpl类的定义。其文件所在路径 loggin…...

【统计至简】【古典概率模型】联合概率、边缘概率、条件概率、全概率

联合概率、边缘概率、条件概率 联合概率边缘概率条件概率全概率 一副标准扑克牌有 54 张&#xff0c;包括 52 张常规牌&#xff08;13 个点数&#xff0c;每个点数有 4 种花色&#xff09;和 2 张王&#xff08;大、小王&#xff09;。我们从中随机抽取一张牌&#xff0c;定义以…...

Linux 字符设备驱动实例

编写驱动程序&#xff0c;并将内核模块加载到内核中&#xff0c;等待被用户程序调用。 在控制台中借助第一步申请到的设备号&#xff0c;使用 mknod 命令创建一个设备节点&#xff0c;并拟一个设备名称。 在用户程序中&#xff0c;使用 open 打开第二步中的设备名称&#xff…...

【git】【网络】【项目配置运行】HTTP 协议的微型简易 Web 服务器---tinyEasyMuduoWebServer

【git】【网络】【项目配置运行】HTTP 协议的微型简易 Web 服务器—tinyEasyMuduoWebServer csdn项目&#xff1a; 原文链接&#xff1a;https://blog.csdn.net/weixin_45178775/article/details/122257814 github链接&#xff1a;https://github.com/wyewyewye/tinyEasyMuduo…...

STM32驱动OLED屏幕全解析:从原理到温度显示实战(上) | 零基础入门STM32第五十三步

主题内容教学目的/扩展视频OLED显示屏重点课程电路原理&#xff0c;手册分析&#xff0c;驱动程序。初始化&#xff0c;清屏&#xff0c;ASCII字库&#xff0c;显示分区。调用显示函数。做带有加入图形和汉字显示的RTC时钟界面。讲字库的设计原理。 师从洋桃电子&#xff0c;杜…...

2024年9月中国电子学会青少年软件编程(Python)等级考试试卷(三级)答案 + 解析

更多真题在线练习系统&#xff1a;历年真题在线练习系统 一、单选题 1、以下表达式的值为True的是&#xff1f;&#xff08; &#xff09; A. all( ,1,2,3) B. any([]) C. bool(abc) D. divmod(6,0) 正确答案&#xff1a;C 答案解析&#xff1a;A和B选项&#xff0c;Fal…...

苍穹外卖实战附源码-DAY1

一、打开项目的Nginx 1.通过nginx成功打开包装后的前端网页 二、导入sky的数据库 sky.sql 数据 CREATE DATABASE IF NOT EXISTS sky_take_out ; USE sky_take_out;DROP TABLE IF EXISTS address_book; CREATE TABLE address_book (id bigint NOT NULL AUTO_INCREMENT COMMEN…...

Spring 框架学习

技术体系结构 总体技术体系 单一架构 一个项目&#xff0c;一个工程&#xff0c;导出为一个 war 包&#xff0c;在一个 Tomcat 上运行&#xff0c;也叫 all in one。 单一架构&#xff0c;项目主要应用技术框架为&#xff1a;Spring、SpringMVC 、Mybatis。 分布式架构 一个…...