SpringCloud消息总线:Bus事件广播与配置动态刷新
文章目录
- 引言
- 一、Spring Cloud Bus基本架构
- 二、配置动态刷新实现
- 2.1 基础配置
- 2.2 刷新流程
- 2.3 定向刷新
- 三、自定义事件广播
- 3.1 定义自定义事件
- 3.2 注册和监听事件
- 3.3 发布事件
- 四、高级配置与优化
- 4.1 消息持久化
- 4.2 事件追踪
- 4.3 安全控制
- 总结
引言
在微服务架构中,配置变更的实时传播是一个关键挑战,尤其当服务实例数量庞大时。Spring Cloud Bus通过轻量级消息代理(如RabbitMQ、Kafka)连接分布式系统中的各个节点,形成一个消息总线,实现配置变更的动态广播和更新。本文将深入探讨Spring Cloud Bus的工作原理、实现机制和应用场景,聚焦于如何利用Bus实现配置的动态刷新和系统级事件的广播。
一、Spring Cloud Bus基本架构
Spring Cloud Bus基于轻量级消息代理构建,通过消息通道将分布式系统的各个节点连接起来,形成消息传递网络。每个应用实例作为总线上的一个节点,既可以向总线发布消息,也可以从总线接收消息,实现节点间的互联互通。
/*** 启用Spring Cloud Bus* 需引入相关依赖:spring-cloud-starter-bus-amqp或spring-cloud-starter-bus-kafka*/
@SpringBootApplication
@EnableDiscoveryClient
public class MicroserviceApplication {public static void main(String[] args) {SpringApplication.run(MicroserviceApplication.class, args);}
}
Bus的核心配置主要涉及消息代理的连接设置:
spring:application:name: order-servicerabbitmq: # 使用RabbitMQ作为消息代理host: localhostport: 5672username: guestpassword: guest# 或者使用Kafka# kafka:# bootstrap-servers: localhost:9092# consumer:# group-id: ${spring.application.name}cloud:bus:enabled: true # 启用消息总线trace:enabled: true # 启用总线跟踪,记录消息传播过程
Spring Cloud Bus的底层通过Spring Cloud Stream实现消息的发送和接收,而Spring Cloud Stream又是基于消息中间件的抽象层,支持不同的消息中间件实现,实现了消息驱动的微服务架构。
二、配置动态刷新实现
Spring Cloud Bus最常见的应用场景是结合Spring Cloud Config实现配置的动态刷新。当配置发生变更时,只需向一个服务实例发送刷新请求,该实例会通过消息总线将刷新事件广播给所有相关服务,从而实现配置的集中更新。
2.1 基础配置
首先,确保相关服务引入了必要依赖:
<!-- 配置中心客户端 -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId>
</dependency><!-- 消息总线(基于RabbitMQ) -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency><!-- Actuator,提供刷新端点 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
然后,配置Actuator端点:
management:endpoints:web:exposure:include: 'bus-refresh,bus-env,refresh,info,health' # 暴露Bus相关端点endpoint:bus-refresh:enabled: true
2.2 刷新流程
当配置中心的配置发生变更时,刷新流程如下:
- 向任一服务实例发送
POST
请求,触发/actuator/bus-refresh
端点。 - 该实例接收到请求后,发布
RefreshRemoteApplicationEvent
事件到消息总线。 - 订阅该事件的所有服务实例收到事件,执行本地配置刷新。
- 每个实例的
@RefreshScope
注解的Bean会重新初始化,加载最新配置。
/*** 需要动态刷新配置的Bean*/
@Service
@RefreshScope // 标记此Bean需要在配置刷新时重新创建
public class OrderConfigService {@Value("${order.payment-timeout}")private int paymentTimeout;@Value("${order.max-retry-count}")private int maxRetryCount;public Map<String, Object> getOrderConfig() {Map<String, Object> config = new HashMap<>();config.put("paymentTimeout", paymentTimeout);config.put("maxRetryCount", maxRetryCount);return config;}
}
2.3 定向刷新
在大型系统中,可能只需刷新部分服务的配置。Spring Cloud Bus支持定向刷新,即只向特定的服务或实例广播刷新事件:
# 刷新特定服务的所有实例
curl -X POST http://localhost:8080/actuator/bus-refresh/order-service:**# 刷新特定实例
curl -X POST http://localhost:8080/actuator/bus-refresh/order-service:8081
定向刷新的实现原理是在刷新事件中包含目标服务或实例的标识,只有匹配的节点才会处理该事件:
/*** 自定义条件刷新处理器* 根据特定条件决定是否处理刷新事件*/
@Component
public class ConditionalRefreshListener {@EventListenerpublic void onRefreshEvent(RefreshRemoteApplicationEvent event) {// 根据事件源和目标判断是否需要处理String originService = event.getOriginService();String destinationService = event.getDestinationService();// 判断逻辑...}
}
三、自定义事件广播
除了配置刷新,Spring Cloud Bus还支持自定义事件的广播,使服务间能够通过消息总线传递业务事件,实现解耦的事件驱动架构。
3.1 定义自定义事件
首先,定义一个自定义远程事件:
/*** 自定义远程事件* 继承RemoteApplicationEvent,可通过总线广播*/
public class OrderCreatedEvent extends RemoteApplicationEvent {private String orderId;private Double amount;// 无参构造函数,用于反序列化public OrderCreatedEvent() {}public OrderCreatedEvent(Object source, String originService, String destinationService, String orderId, Double amount) {// source: 事件源// originService: 发出事件的服务// destinationService: 目标服务,":"为通配符super(source, originService, destinationService);this.orderId = orderId;this.amount = amount;}// getter和setterpublic String getOrderId() {return orderId;}public Double getAmount() {return amount;}
}
3.2 注册和监听事件
注册自定义事件类型,使其能够在总线上传输:
/*** 事件配置*/
@Configuration
public class EventConfig {@Beanpublic RemoteApplicationEventScan remoteApplicationEventScan() {return new RemoteApplicationEventScan("com.example.events"); // 事件类所在包}
}
在目标服务中监听事件:
/*** 事件监听器*/
@Component
public class OrderEventListener {private static final Logger log = LoggerFactory.getLogger(OrderEventListener.class);@EventListenerpublic void handleOrderCreatedEvent(OrderCreatedEvent event) {log.info("Received order created event, orderId: {}, amount: {}", event.getOrderId(), event.getAmount());// 处理订单创建事件,如触发后续业务流程processOrder(event.getOrderId(), event.getAmount());}private void processOrder(String orderId, Double amount) {// 具体的业务处理逻辑}
}
3.3 发布事件
在需要的地方发布事件到总线:
/*** 订单服务*/
@Service
public class OrderService {@Autowiredprivate ApplicationContext context;@Autowiredprivate ServiceRegistry serviceRegistry;public String createOrder(String productId, int quantity, Double price) {// 创建订单的业务逻辑String orderId = generateOrderId();Double amount = price * quantity;// 保存订单saveOrder(orderId, productId, quantity, amount);// 发布订单创建事件到总线publishOrderCreatedEvent(orderId, amount);return orderId;}private void publishOrderCreatedEvent(String orderId, Double amount) {// 构建事件// source: 当前应用上下文// originService: 当前服务ID// destinationService: 目标服务模式,":**"表示所有服务的所有实例OrderCreatedEvent event = new OrderCreatedEvent(this.context,serviceRegistry.getAppId(),":**",orderId,amount);// 发布事件到上下文,会被BusAutoConfiguration处理并广播context.publishEvent(event);}// 其他辅助方法
}
四、高级配置与优化
随着系统规模的扩大,可能需要对Spring Cloud Bus进行一些高级配置和优化,以提升性能和可靠性。
4.1 消息持久化
为避免消息丢失,可以配置消息持久化:
spring:cloud:stream:bindings:springCloudBusInput:destination: springCloudBusgroup: ${spring.application.name} # 消费者组,确保消息只被同名服务消费一次consumer:durableSubscription: true # 持久订阅springCloudBusOutput:destination: springCloudBusproducer:required-groups: ${spring.application.name} # 确保消息存储直到被消费
4.2 事件追踪
启用事件追踪可以监控事件的传播过程:
spring:cloud:bus:trace:enabled: true # 启用事件追踪
通过/actuator/httptrace
端点可以查看事件传播的日志,包括源服务、目标服务、事件类型等信息。
4.3 安全控制
在生产环境中,应对Bus相关的端点进行安全控制,防止未授权访问:
spring:security:user:name: adminpassword: '{cipher}AQA...' # 加密密码management:endpoints:web:exposure:include: 'bus-refresh' # 仅暴露必要端点endpoint:bus-refresh:enabled: true
总结
Spring Cloud Bus作为Spring Cloud家族中的核心组件,通过消息总线机制连接分布式系统中的各个节点,实现了配置的动态刷新和事件的高效广播。它与Spring Cloud Config的结合使用,显著提升了微服务系统配置管理的灵活性和效率。通过自定义事件广播机制,Spring Cloud Bus还能够支持业务事件的传递,为实现事件驱动架构提供基础设施。
在实际应用中,根据系统规模和性能要求,可以选择合适的消息中间件(RabbitMQ或Kafka),并进行适当的配置优化。对于敏感环境,还应注意端点的安全控制和访问权限管理。随着微服务架构的不断发展,Spring Cloud Bus凭借其简单易用的特性,为解决分布式系统中的通信和协调问题提供了有效的解决方案。
相关文章:
SpringCloud消息总线:Bus事件广播与配置动态刷新
文章目录 引言一、Spring Cloud Bus基本架构二、配置动态刷新实现2.1 基础配置2.2 刷新流程2.3 定向刷新 三、自定义事件广播3.1 定义自定义事件3.2 注册和监听事件3.3 发布事件 四、高级配置与优化4.1 消息持久化4.2 事件追踪4.3 安全控制 总结 引言 在微服务架构中ÿ…...
家庭网络结构之局域网通信
整个互联网非常复杂,涉及到很多知识,学习互联网不能一蹴而就,所以这里从最简单的家庭网络开始学习 家庭网络一般是通过Modem( 作用:进行数字信号和模拟信号的转换 ) 拨号上网,然后通过家庭路由器,将网络连接…...
突破反爬困境:SDK架构设计,为什么选择独立服务模式(四)
声明 本文所讨论的内容及技术均纯属学术交流与技术研究目的,旨在探讨和总结互联网数据流动、前后端技术架构及安全防御中的技术演进。文中提及的各类技术手段和策略均仅供技术人员在合法与合规的前提下进行研究、学习与防御测试之用。 作者不支持亦不鼓励任何未经授…...
java 设置操作系统编码、jvm平台编码和日志文件编码都为UTF-8的操作方式
以下是 Java中设置操作系统编码、JVM平台编码和日志文件编码为UTF-8 的详细步骤和代码示例: 一、设置操作系统编码为UTF-8 1. Windows系统 修改系统区域设置: 进入 控制面板 → 时钟和区域 → 区域。在“管理”选项卡中,点击“更改系统区域…...
SpringBoot:几种常用的接口日期格式化方法
全局时间格式化 通过在配置文件中设置可以实现全局时间格式化。在 Spring Boot 的配置文件 application.properties(或 application.yml)中添加以下两行配置: #?格式化全局时间字段 spring.jackson.date-formatyyyy-MM-dd?HH:mm:ss #?指…...
解题思路:LeetCode 2711. 对角线上不同值的数量差
解题思路:LeetCode 2711. 对角线上不同值的数量差 在LeetCode的题目2711中,我们需要计算一个矩阵中每个单元格的左上角对角线和右下角对角线上不同值的数量差。这个问题可以通过暴力法解决,但效率较低。本文将介绍一种更高效的解决方案&…...
Jackson实现JSON数据的合并
JSON数据的操作,系列文章: 《Jackson的核心类与API方法:ObjectMapper、JsonNode、ObjectNode、ArrayNode》 《Jackson的使用与创建Jackson工具类》 《Jackson使用ObjectNode对象实现JSON对象数据(一):增、删…...
Elasticsearch 倒排索引 和 正排索引
一、倒排索引 倒排索引是 Elasticsearch 实现高效全文搜索的核心技术。它通过将词项与文档 ID 关联,支持快速检索、短语查询、布尔查询和相关性评分。尽管倒排索引在存储和更新方面有一定的开销,但通过词典优化、倒排列表压缩、分片和缓存等技术&#x…...
Cocos Creator Shader入门实战(五):材质的了解、使用和动态构建
引擎:3.8.5 您好,我是鹤九日! 回顾 前面的几篇文章,讲述的主要是Cocos引擎对Shader使用的一些固定规则,这里汇总下: 一、Shader实现基础是OpenGL ES可编程渲染管线,开发者只需关注顶点着色器和…...
【Python】pillow库学习笔记1-Image类
《Python语言程序设计基础 》第3版,嵩天 黄天羽 杨雅婷著,P293 1.pillow库概述 Pillow 库是Python图像处理重要的第三方库。 Pillow库是PIL (Python image library) 库的一个扩展,需要通过pip工具安装。安装PIL库需要注意,安装…...
解决 MySQL 的 sql_mode 中包含 only_full_group_by模式导致group by SQL报错
sql 报错: Cause: java.sql.SQLSyntaxErrorException: Expression #6 of SELECT list is not in GROUP BY clause and contains nonaggregated column ev_data_transmission.p.push_type which is not functionally dependent on columns in GROUP BY clause; this…...
【微服务架构】本地负载均衡的实现(基于随机算法)
前言 负载均衡 概念:一种将网络流量或业务请求均匀分配到多个服务器或服务实例上的技术,旨在提高系统的可用性、性能和可伸缩性。作用: 提高性能:通过将请求分散到多个实例上,避免单个实例因请求过多而过载ÿ…...
记一次线上SQL死锁事故
一、 引言 SQL死锁是一个常见且复杂的并发控制问题。当多个事务在数据库中互相等待对方释放锁时,就会形成死锁,从而导致事务无法继续执行,影响系统的性能和可用性。死锁不仅会导致数据库操作的阻塞,增加延迟,还可能对…...
电机控制常见面试问题(十八)
文章目录 一.电机控制高级拓扑结构1.LLC 二.谈谈电压器饱和后果三.电压器绕组连接方式的影响四.有源逆变的条件 一.电机控制高级拓扑结构 1.LLC LLC是什么?—— 一个会"变魔术"的电源盒子 想象你有一个魔法盒子,能把电池的电压变大或变小&…...
数据结构之双链表
目录 1 简介 2 双链表的基本概念 2.1 节点结构 2.2 头插法和尾插法 3 代码实现 4 代码解析(部分) 4.1 初始化双链表 4.2 添加节点 4.3 删除节点 4.4 获取节点 4.5 插入节点 4.6 反转链表 4.7 打印链表 4.8 核心操作分析 5 总结 1 简介 …...
dell 台式机 电脑 纽扣电池 如何取下?
dell 台式机 电脑 纽扣电池 如何取下? 戴尔-optiplex-3060-塔式机-服务手册...
JSON二次序列化问题分析
正常的JSON应该是: json Apply to VectorServic... { "id": "d471c19c-70eb-4f29-8604-b8284e8a9400", "text": "人为干预, 降低生产成本...", "metadata": { "chunkIndex": 2, …...
WebSocket 传输大量数据好不好?稳定不稳定
使用 WebSocket 传输大量数据 是可行的,但在实际应用中需要注意一些限制和优化策略。以下是关于 WebSocket 传输大量数据的详细分析: 1. WebSocket 传输大量数据的可行性 优点 实时性:WebSocket 是全双工通信协议,适合实时传输数…...
代码随想录刷题day52|(二叉树篇)106.从中序与后序遍历序列构造二叉树(▲
目录 一、二叉树理论知识 二、构造二叉树思路 2.1 构造二叉树流程(给定中序后序 2.2 整体步骤 2.3 递归思路 2.4 给定前序和后序 三、相关算法题目 四、易错点 一、二叉树理论知识 详见:代码随想录刷题day34|(二叉树篇)二…...
无人设备遥控器之调度自动化技术篇
一、技术原理 信息采集与处理: 通过传感器、仪表等设备采集无人设备的各种数据,如位置、速度、状态等。 将采集到的数据传输到调度自动化系统中进行处理和分析,以获取设备的实时状态。 系统建模与优化: 调度自动化系统会根据…...
红宝书第十五讲:详解JavaScript迭代器与生成器:Symbol.iterator与yield
红宝书第十五讲:详解JavaScript迭代器与生成器:Symbol.iterator与yield 资料取自《JavaScript高级程序设计(第5版)》。 查看总目录:红宝书学习大纲 一、迭代器(Iterator)的“传送带”模式 迭代…...
【AI】NLP
不定期更新,建议关注收藏点赞。 目录 transformer大语言模型Google Gemma疫情网民情绪识别 整体框架 baseline构建 模型调参、模型优化、其他模型 数据trick、指标优化、magic feature 数据增强、伪标签、迁移学习 模型融合sklearn中TFIDF参数详解 频率阈值可以去掉…...
ENSP学习day10
NAT地址转换技术(一) NAT(Network Address Translation)地址转换技术是一种在计算机网络中常用的技术,在数据包从一个网络传输到另一个网络时,会对数据包中的源IP地址和目的IP地址进行修改的过程。这种技术…...
文件上传绕过的小点总结(4)
9.末尾点删除处理缺陷 给出源码: $file_name trim($_FILES[upload_file][name]); $file_name deldot($file_name);//删除文件名末尾的点 $file_ext strrchr($file_name, .); $file_ext strtolower($file_ext); //转换为小写 $file_ext str_ireplace(::$DATA,…...
实战-MySQL5.7升级8.0遇到的四个问题
近期几个项目的MySQL由5.7升级到8.0,升级过程中遇到四个问题,记录下来分享一下: 第一个问题详见之前的文章: MySQL 5.7升级8.0报异常:处理新增关键字 第二个问题详见之前的文章: MySQL 5.7升级8.0报异常…...
卷积神经网络的原理、实现及变体
卷积神经网络convolutional neural network,CNN 是为处理图像数据而生的网络,主要由卷积层(填充和步幅)、池化层(汇聚层)、全连接层组成。 卷积 虽然卷积层得名于卷积(convolution)…...
java 线程创建Executors 和 ThreadPoolExecutor 和 CompletableFuture 三者 区别
Executors是一个线程池的工具类,而ThreadPoolExecutor是Executor接口的一个实现,是线程池的核心类。 Executors提供了多种快速创建线程池的方法,而ThreadPoolExecutor则提供了更高的自定义和控制能力。 Executors是一个工具类࿰…...
Redisson 实现分布式锁简单解析
目录 Redisson 实现分布式锁业务方法:加锁逻辑LockUtil 工具类锁余额方法:工具类代码枚举代码 RedisUtil 工具类tryLock 方法及重载【分布式锁具体实现】Supplier 函数式接口调用分析 Redisson 实现分布式锁 业务方法: 如图,简单…...
Python条件处理,新手入门到精通
Python条件处理,新手入门到精通 对话实录 **小白**:(崩溃)我写了if x 1:,为什么Python会报错? **专家**:(推眼镜)**是赋值,才是比较**!想判断相…...
详细比较StringRedisTemplate和RedisTemplate的区别及使用方法,及解决融合使用方法
前言 感觉StringRedisTemplate和RedisTemplate非常的相识,到底有什么区别和联系呢?点开idea,打开其依赖关系,可以看出只需使用maven依赖包spring-boot-starter-data-redis,然后在service中注入StringRedisTemplate或者…...
开源模型应用落地-语音转文本-whisper模型-AIGC应用探索(五)
一、前言 在上一节中,学习了如何使用vLLM来部署Whisper-large-v3-turbo模型。不过,在实际使用时,模型一次只能处理30秒的音频。今天,将结合实际业务,介绍如何处理一段完整的音频,并生成相应的字幕文件。 相…...
python每日十题(10)
在Python语言中,源文件的扩展名(后缀名)一般使用.py。 保留字,也称关键字,是指被编程语言内部定义并保留使用的标识符。Python 3.x有35个关键字,分别为:and,as,assert&am…...
安装和部署Tomcat并在idea创建web文件
一、背景 实验任务为安装Tomcat并创建web文件 为提高安装效率并且通俗易懂,免得大量文字浪费时间,这里我们采用图片加文字的方式来给大家讲解这个安装教程。 二、安装过程 首先第一步一定要注意你是否下载了JDK,如果你是像我一样下载一个…...
【Linux】Ubuntu 24.04 LTS 安装 OpenJDK 8
目录 通过 apt-get 直接安装 JDK 1. 更新 apt 软件源 2. 检查 JDK 是否已安装 3. 安装OpenJDK 4. 检查 JDK 是否成功安装 5. 设置 JAVA_HOME 环境变量 找到需要设置的 Java 路径 使用文本编辑器打开/etc/environment文件 添加 Java 安装路径 应用更改和验证配置 通过…...
图灵300题-21~40-笔记002
图灵300题 图灵面试题视频:https://www.bilibili.com/video/BV17z421B7rB?spm_id_from333.788.videopod.episodes&vd_sourcebe7914db0accdc2315623a7ad0709b85&p20。 本文是学习笔记,如果需要面试没有时间阅读原博文,可以快速浏览笔…...
蓝桥杯--bfs专题第二个题目(leetcode103二叉树)
文章目录 1.题目概述2.思路分析3.代码分析 1.题目概述 这个题目是关于二叉树的锯齿形的遍历:这个锯齿形是什么意思呢?简单的通俗的解释,就是S型的,例如下面的这个示例里面的二叉树: 第一行从左到右:但是只…...
React 知识回顾(HOC、合成事件、Fiber)
HOC 嗯,用户问的是HOC是什么以及它能用来做什么。我需要先理解HOC的基本概念,然后整理它的用途。根据搜索结果,HOC是React中的高阶组件,用来复用逻辑。网页1提到HOC是一个函数,接收组件返回新组件,属于设计…...
s1: Simple test-time scaling 【论文阅读笔记】
s1: Simple test-time scaling 关于test-time scaling 这个概念其实是相对 train scaling而言的。train scalling 指的是增加训练数据,增加训练flops等等,投入更多资源在train上。test-time scaling,其实现在简化点的理解,就是 …...
基于 Milvus 和 BiomedBERT 的医学文献智能搜索系统
前言 随着医学研究的不断深入,文献数量呈爆炸式增长,如何快速从海量文献中提取关键信息成为一大挑战。最近,我基于 Milvus 向量数据库和 BiomedBERT 嵌入模型,开发了一个智能搜索系统,支持语义搜索和关键词匹配&#…...
ASP.NET Web的 Razor Pages应用,配置热重载,解决.NET Core MVC 页面在更改后不刷新
Razor Pages应用,修改页面查看修改效果,如果没有热重载,改一句话跑一次,这个活就没法干了。 1、VS2022中的NuGet中安装RuntimeCompilation Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation 需要配套你的.net sdk版本&#x…...
MySQL 对text类型字段添加索引
对于 MySQL 中的 text 类型字段,可以通过以下步骤向其添加索引: 创建辅助字段:创建一个辅助字段,将该字段的一部分数据转移到辅助字段中。例如,可以创建一个 varchar 类型的字段来存储 text 字段的前缀。 添加索引&am…...
深入解析SQL2API平台:数据交互革新者
在数字化转型持续深入的当下,企业对数据的高效利用与管理的需求愈发迫切。SQL2API平台应运而生,成为助力企业突破数据交互困境的有力工具,特别是它由麦聪软件基于DaaS(数据即服务)产品创新衍生而来,备受业界…...
@Autowired 和 @Resource 注解的区别
前言 Autowired 和 Resource 是 Spring 中用于依赖注入的注解,但两者在实现机制和使用方式上有显著差异。 主要区别 1.来源不同 Autowired:由 Spring 框架提供(org.springframework.beans.factory.annotation),与 S…...
稳定运行的以ElasticSearch数据库为数据源和目标的ETL性能变差时提高性能方法和步骤
在使用 Elasticsearch 作为数据源和目标的 ETL(Extract, Transform, Load)过程中,性能逐渐变差的原因可能有很多,比如查询效率下降、集群负载过高、资源配置不合理等。 性能的提升通常需要从多个方面入手,尤其是在处理…...
游戏引擎学习第182天
回顾和今天的计划 昨天的进展令人惊喜,原本的调试系统已经被一个新的系统完全替换,新系统不仅能完成原有的所有功能,还能捕获完整的调试信息,包括时间戳等关键数据。这次的替换非常顺利,效果很好。 今天的重点是在此基…...
EJS缓存解决多页面相同闪动问题
基于 EJS 的模板引擎特性及其缓存机制,以下是关于缓存相同模块的详细解答: 一、EJS 缓存机制的核心能力 模板编译缓存 EJS 默认会将编译后的模板函数缓存在内存中,当相同模板文件被多次渲染时,会直接复用已编译的模板函数&#x…...
【MySQL】mysql日志文件
目录 日志文件特征 错误日志(Error log ) 常规查询日志(General query log ) 慢速查询日志(Slow query log ) 审计日志(Audit log ) 二进制日志(Binary log &#…...
【C++】STL性能优化实战
STL性能优化实战 STL (Standard Template Library) 是 C 标准库的核心部分,提供了各种容器、算法和迭代器。虽然 STL 提供了强大的功能,但不恰当的使用可能导致性能问题。下面我将详细介绍 STL 性能优化的实战技巧,并通过具体案例说明。 1.…...
Playwright + MCP:用AI对话重新定义浏览器自动化,效率提升300%!
一、引言:自动化测试的“瓶颈”与MCP的革新 传统自动化测试依赖开发者手动编写脚本,不仅耗时且容易因页面动态变化失效。例如,一个简单的登录流程可能需要开发者手动定位元素、处理等待逻辑,甚至反复调试超时问题。而MCP…...
12-scala样例类(Case Classes)
例类(Case classes)和普通类差不多,只有几点关键差别,接下来的介绍将会涵盖这些差别。样例类非常适合用于不可变的数据。 定义一个样例类 一个最简单的样例类定义由关键字case class,类名,参数列表&#…...