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

Redis篇--常见问题篇7--缓存一致性2(分布式事务框架Seata)

1、概述

在传统的单体应用中,事务管理相对简单,通常使用数据库的本地事务(如MySQL的BEGIN和COMMIT)来保证数据的一致性。然而,在微服务架构中,由于每个服务都有自己的数据库,跨服务的事务管理变得复杂。Seata正是为了解决这一问题而设计的,它提供了一种轻量级的分布式事务解决方案,能够在多个微服务之间协调事务,确保数据的一致性。

Seata是阿里巴巴开源的一款分布式事务解决方案,旨在解决微服务架构中的分布式事务问题。它提供了ACID(原子性、一致性、隔离性、持久性)事务的分布式实现,确保在多个微服务之间进行跨服务调用时,事务能够保持一致性和可靠性。

2、Seata的4种工作模式

AT(Automatic Transaction Mode)模式:

AT模式是Seata 默认的分布式事务模式,它基于SQL解析和拦截器机制,自动处理全局事务,无需我们编码,适用于大多数关系型数据库(如MySQL、Oracle、PostgreSQL等)。在AT模式下,Seata会自动记录数据库操作的前后镜像(before image和after image),并在事务提交或回滚时进行数据的一致性检查。开发者不需要编写额外的补偿逻辑,适合大多数场景。也是Seata最常用的一种模式。

TCC(Try-Confirm-Cancel Mode)模式:

TCC模式一般用于适合对性能要求较高的场景。是一种显式的两阶段提交协议,开发者需要为每个业务操作定义三个方法:

  • try:尝试执行业务操作,预留资源。
  • confirm:确认操作,正式提交资源。
  • cancel:取消操作,回滚资源。
    TCC模式适用于复杂的业务场景,尤其是跨多个服务的分布式事务。开发者需要手动编写补偿逻辑,确保事务的一致性。

SAGA(Saga Orchestration Mode)模式:

SAGA模式是一种长事务模式,是基于状态机驱动的分布式事务。适用于涉及多个服务需要长时间运行的业务流程。SAGA模式将整个业务流程拆分为多个子事务,每个子事务都有对应的补偿操作。如果某个子事务失败,SAGA会依次执行前面子事务的补偿操作,确保事务的一致性。
SAGA 模式有两种实现方式:

  • Orchestration(编排模式):由一个中央控制器(Orchestrator)负责协调各个子事务的执行。
  • Choreography(编舞模式):各个子事务通过事件驱动的方式协同工作,没有中央控制器。

XA(X/Open XA Mode)模式:

XA模式是传统的两阶段提交协议,兼容XA规范,广泛应用于传统的关系型数据库系统。Seata支持XA模式,允许开发者使用XA协议来管理分布式事务。XA模式依赖于数据库的XA支持,因此需要数据库和JDBC驱动的支持。适合对一致性要求极高的场景,但性能较低。

3、Seata的核心特性

(1)、支持多种分布式事务模式(AT,TCC,SAGA,XA)。
(2)、轻量级:Seata不依赖于任何特定的中间件或框架,可以与Spring Cloud、Dubbo等微服务框架无缝集成。
(3)、高可用性和扩展性:Seata的事务协调器(TC)和事务管理器(TM)都可以水平扩展,支持集群部署,确保系统的高可用性和可扩展性。
(4)、多语言支持:Seata支持多种编程语言,包括Java、Go、C等,方便不同技术栈的团队使用。
(5)、丰富的生态:Seata提供了与主流数据库、消息队列、缓存等组件的集成,能够满足复杂的业务需求。

4、两阶段提交

XA协议的核心是两阶段提交(Two-Phase Commit,2PC)机制:

(1)、第一阶段(准备阶段):

全局事务协调者向所有参与者发送准备请求,每个参与者执行本地事务并返回确认信息给协调者。如果所有参与者都返回成功,那么协调器进入第二阶段。如果任何一个参与者返回失败,协调者将发送回滚请求。

(2)、第二阶段(提交/回滚阶段):

全局事务协调者根据第一阶段的反馈情况,决定提交或回滚全局事务。首先,协调者发送提交或回滚指令给所有参与者,然后参与者按照指令执行相应的操作。
在这里插入图片描述
通过两阶段提交,XA协议保证了分布式事务的原子性和一致性。每个参与者在第一阶段确认准备之后,就无法单独执行本地事务的提交或回滚操作,而是依赖于全局事务协调的指令。
简单说:
第一阶段是所有服务执行各自的事务代码并记录了执行结果。
第二阶段是事务协调者根据所有服务第一阶段的结果决定是否提交全局事务。第一阶段中每一个服务都记录了自身的undo_log日志,在第二阶段中,事务协调者如果发现有一个服务失败了,就会通知所有的服务执行undo_log日志,实现全局回滚。如果全部服务都成功了,那么就直接提交全局事务,结束本次事务处理。不论第二阶段是成功还是失败,TC(事务协调器)都会清理本次全局事务的状态,并释放资源。

5、Seata的架构及原理

(1)、架构

Seata的工作原理基于“三者分离”的架构设计,分别是:

事务协调器(Transaction Coordinator, TC):
  • 负责维护全局事务的状态,协调各个分支事务的提交或回滚。
  • 作为独立的服务部署,通常是一个集群,确保高可用性和容错能力。
事务管理器(Transaction Manager, TM):
  • 负责开启全局事务,并向TC注册全局事务。
  • 当所有分支事务完成后,TM会根据业务逻辑决定是提交还是回滚全局事务。
资源管理器(Resource Manager, RM):
  • 负责管理分支事务,通常是微服务中的数据库连接。
  • RM会将本地事务注册到TC,并在全局事务提交或回滚时执行相应的操作。

架构示例如下:
在这里插入图片描述
简单理解下:
TC就相当于我们部署的Seata服务,用于管理所有的全局事务信息。TM就相当于我们用注解标注的方法,RM内就相当于注解方法内使用的每一个微服务的任务。
当执行到标识全局事务的方法时,TM就会往TC注册全局事务的信息并开启全局事务,同时会通知TC本次全局任务有哪些RM的任务。
之后程序会运行方法中的代码,执行每一个RM任务并记录执行结果。TC会监听这些子任务的结果,如果全部RM都运行成功,全局任务就会通过。如果有一个失败,就会通知所有的RM去回滚服务。

(2)、以AT模式为例,Seata的工作流程如下

第一步:开启全局事务
  • TM向TC发起请求,开启一个新的全局事务,并获取全局事务ID(XID)。
第二步:执行分支事务
  • 在每个微服务中,RM会拦截SQL语句,解析并生成对应的undo_log,用于记录事务的回滚信息。
  • RM将本地事务注册到TC,并将XID传递给下游服务。
第三步:执行全局事务(提交或回滚)
  • 当所有分支事务执行完毕后,TM根据业务逻辑决定是提交还是回滚全局事务。
  • 如果提交,TC会通知所有RM提交本地事务;如果回滚,TC会通知所有RM使用undo_log回滚本地事务。
第四步:清理资源
  • 全局事务提交或回滚后,TC会清理相关的事务状态,释放资源。

6、Seata的优势

- 无侵入性:在AT模式下,Seata可以通过AOP(面向切面编程)自动拦截SQL语句,生成undo_log,而不需要修改业务代码。这使得开发者可以专注于业务逻辑,而不必关心事务的实现细节。
- 高性能:Seata的AT模式基于SQL解析和两阶段提交,避免了传统XA协议的性能瓶颈。它只在必要的时候生成undo_log,减少了对数据库的压力。
- 强一致性:Seata通过两阶段提交协议,确保了分布式事务的强一致性。即使某个分支事务失败,整个全局事务也会回滚,保证数据的一致性。
- 灵活的事务模式:Seata提供了多种事务模式(AT、TCC、SAGA、XA),可以根据不同的业务场景选择最适合的模式。例如,对于简单的CRUD操作,可以使用AT模式;对于复杂的业务流程,可以使用TCC或SAGA模式。

7、Seata的应用场景

- 微服务之间的数据一致性:当多个微服务需要协同完成一个业务操作时,Seata可以确保这些服务之间的数据一致性。例如,订单系统和库存系统之间的扣减库存操作。
- 跨库事务:当同一个微服务需要操作多个数据库时,Seata可以确保这些数据库之间的事务一致性。例如,一个微服务需要操作更新用户库和订单库。
- 异步事务:Seata的SAGA模式支持长事务,适用于需要长时间运行的业务流程。例如,复杂的审批流程或订单处理流程。
- 跨服务的消息队列事务:Seata可以与消息队列(如RocketMQ、Kafka)结合使用,确保消息的发送和接收在一个全局事务中。例如,订单创建成功后,发送一条消息通知库存系统扣减库存。

8、Seata使用示例

(1)、安装,配置及使用

主要包括以下几个步骤:
第一步:下载

  • 你可以从Seata官方GitHub下载最新的Seata Server。
    目录如:
    在这里插入图片描述
    第二步:配置Seata Server
    • 编辑conf/file.conf文件,配置Seata Server的存储方式(如文件存储、数据库存储等)。
    • 编辑registry.conf文件,配置Seata的注册中心(如Nacos、Eureka、Zookeeper等)。

第三步:启动服务
在bin目录下有启动脚本,解压后启动seata-server.sh或seata-server.bat。
在这里插入图片描述
第四步:配置客户端:

  • 在微服务中引入Seata的依赖项(如seata-spring-boot-starter),并在application.yml中配置Seata的相关参数,如事务模式、Seata Server地址等。

第五步:编写业务代码:

  • 在业务代码中使用@GlobalTransactional注解来开启全局事务。Seata会自动拦截SQL语句,生成undo_log,并协调各个分支事务的提交或回滚。

(2)、四种模式代码示例

AT模式(Automatic Transaction Mode)

概述:
AT模式是Seata默认的分布式事务模式,它基于SQL解析和拦截器机制,自动处理全局事务。在AT模式下,Seata会自动记录数据库操作的前后镜像(before image和after image),并在事务提交或回滚时进行数据的一致性检查。开发者不需要编写额外的补偿逻辑,适合大多数场景。

适用场景:

  • 适用于标准的SQL操作,如INSERT、UPDATE、DELETE。
  • 不需要手动编写补偿逻辑,适合对事务一致性要求较高的场景。

代码示例

import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class OrderService {@Autowiredprivate OrderRepository orderRepository;@Autowiredprivate AccountService accountService;// 创建订单并扣减账户余额@GlobalTransactional(name = "create-order", rollbackFor = Exception.class)public void createOrder(Long userId, Double amount) {try {// 1. 扣减账户余额accountService.decreaseBalance(userId, amount);// 2. 创建订单Order order = new Order();order.setUserId(userId);order.setAmount(amount);order.setStatus("CREATED");orderRepository.save(order);// 3. 模拟异常(用于测试回滚)// if (true) throw new RuntimeException("Simulated error");System.out.println("Order created successfully.");} catch (Exception e) {System.err.println("Error creating order: " + e.getMessage());throw e;  // 抛出异常以触发事务回滚}}
}

解释:

  • @GlobalTransactional:标记该方法为全局事务,确保所有参与的方法(如:扣减账户余额和创建订单)都在同一个事务中执行。
  • 自动处理:Seata会自动记录SQL操作的前后镜像,并在事务提交或回滚时进行数据的一致性检查。
  • 无需补偿逻辑:开发者不需要编写额外的补偿逻辑,Seata会自动处理事务的提交和回滚。
TCC模式(Try-Confirm-Cancel Mode)

概述
TCC模式是一种显式的两阶段提交协议,开发者需要为每个业务操作定义三个方法:

  • try:尝试执行业务操作,预留资源。
  • confirm:确认操作,正式提交资源。
  • cancel:取消操作,回滚资源。
    TCC模式适用于复杂的业务场景,尤其是跨多个服务的分布式事务。开发者需要手动编写补偿逻辑,确保事务的一致性。

适用场景

  • 适用于复杂的业务场景,尤其是跨多个服务的分布式事务。
  • 需要手动编写补偿逻辑,适合对性能和灵活性有较高要求的场景。

代码示例

import com.alibaba.fastjson.JSONObject;
import io.seata.rm.tcc.api.BusinessActionContext;
import io.seata.rm.tcc.api.BusinessActionContextParameter;
import io.seata.rm.tcc.api.LocalTCC;
import io.seata.rm.tcc.api.TwoPhaseBusinessAction;@LocalTCC
public class AccountService {// Try 阶段:尝试扣减账户余额
// 通常在try阶段通过使用二阶段提交注解,指定提交的方法和回滚的方法,如下:@TwoPhaseBusinessAction(name = "decreaseBalance", commitMethod = "confirmDecreaseBalance", rollbackMethod = "cancelDecreaseBalance")public boolean tryDecreaseBalance(@BusinessActionContextParameter(paramName = "userId") Long userId,@BusinessActionContextParameter(paramName = "amount") Double amount) {// 检查账户余额是否足够if (checkBalance(userId, amount)) {// 预留资源(例如,冻结金额)freezeBalance(userId, amount);return true;}return false;}// Confirm 阶段:正式扣减账户余额public boolean confirmDecreaseBalance(BusinessActionContext actionContext) {// 从上下文中获取参数JSONObject params = actionContext.getActionContext();Long userId = params.getLong("userId");Double amount = params.getDouble("amount");// 正式扣减余额decreaseBalance(userId, amount);return true;}/ / Cancel 阶段:取消扣减账户余额public boolean cancelDecreaseBalance(BusinessActionContext actionContext) {// 从上下文中获取参数JSONObject params = actionContext.getActionContext();Long userId = params.getLong("userId");Double amount = params.getDouble("amount");// 取消预留的资源(例如,解冻金额)unfreezeBalance(userId, amount);return true;}// 辅助方法private boolean checkBalance(Long userId, Double amount) {// 检查账户余额是否足够return true;  // 简化示例}private void freezeBalance(Long userId, Double amount) {// 冻结余额System.out.println("Freezing balance for user " + userId + " with amount " + amount);}private void decreaseBalance(Long userId, Double amount) {// 扣减余额System.out.println("Decreasing balance for user " + userId + " with amount " + amount);}private void unfreezeBalance(Long userId, Double amount) {// 解冻余额System.out.println("Unfreezing balance for user " + userId + " with amount " + amount);}
}

解释:

  • @LocalTCC:标记该类为 TCC 模式的本地事务参与者。
  • @TwoPhaseBusinessAction:定义TCC模式的三步操作:try、confirm和cancel。
  • 手动编写补偿逻辑:开发者需要为每个业务操作编写try、confirm和cancel方法,确保事务的一致性。
  • 资源预留:try阶段只预留资源,不真正修改数据;confirm阶段正式提交资源;cancel阶段回滚资源。
SAGA模式(Saga Orchestration Mode)

概述
SAGA模式是一种长事务模式,适用于涉及多个服务的复杂业务流程。SAGA模式将整个业务流程拆分为多个子事务,每个子事务都有对应的补偿操作。如果某个子事务失败,SAGA会依次执行前面子事务的补偿操作,确保事务的一致性。

SAGA 模式有两种实现方式:

  • Orchestration(编排模式):由一个中央控制器(Orchestrator)负责协调各个子事务的执行。
  • Choreography(编舞模式):各个子事务通过事件驱动的方式协同工作,没有中央控制器。

适用场景

  • 适用于涉及多个服务的复杂业务流程。
  • 适合长事务场景,允许部分子事务成功后继续执行后续操作。
  • 适合对最终一致性要求较高的场景。

代码示例:(Orchestration模式)

import io.seata.saga.statelang.domain.StateMachineInstance;
import io.seata.saga.statelang.domain.StateMachineStatus;
import io.seata.saga.statelang.service.StateMachineEngine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class SagaOrderService {@Autowiredprivate StateMachineEngine stateMachineEngine;// 创建订单并扣减账户余额public void createOrder(Long userId, Double amount) {// 定义SAGA流程的状态机IDString stateMachineId = "orderStateMachine";// 创建状态机实例StateMachineInstance instance = new StateMachineInstance();instance.setStateMachineId(stateMachineId);instance.setBizKey("order_" + System.currentTimeMillis());// 设置输入参数instance.setInputData(new JSONObject().fluentPut("userId", userId).fluentPut("amount", amount));// 启动SAGA流程StateMachineStatus status = stateMachineEngine.start(instance);if (status == StateMachineStatus.EXECUTED) {System.out.println("SAGA流程执行成功。");} else {System.err.println("SAGA流程执行失败。");}}
}

解释

  • StateMachineEngine:SAGA模式的状态机引擎,负责协调各个子事务的执行。
  • StateMachineInstance:表示SAGA流程的一个实例,包含状态机ID、业务键和输入参数。
  • start():启动SAGA流程,执行一系列子事务。
  • 补偿机制:如果某个子事务失败,SAGA会自动执行前面子事务的补偿操作,确保事务的一致性。
XA模式(X/Open XA Mode)

概述
XA模式是传统的两阶段提交协议,广泛应用于传统的关系型数据库系统。Seata支持XA模式,允许开发者使用XA协议来管理分布式事务。XA模式依赖于数据库的XA支持,因此需要数据库和JDBC驱动的支持。

适用场景

  • 适用于传统的企业级应用,尤其是已经使用XA协议的系统。
  • 适合对事务一致性要求极高的场景,但性能相对较低。

代码示例
XA是比较传统的方式,功能实现的话和AT模式相似,通常还是建议使用AT模式,更加简单和方便。

import io.seata.rm.datasource.DataSourceProxy;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;@Configuration
@EnableTransactionManagement
public class XAConfig {@Autowiredprivate DataSource dataSource;// 配置XA模式的数据源代理@Beanpublic DataSource xaDataSource() {return new DataSourceProxy(dataSource);}// 配置事务管理器@Beanpublic PlatformTransactionManager transactionManager() {return new DataSourceTransactionManager(xaDataSource());}
}// 使用 XA 模式的业务逻辑
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class OrderService {@Autowiredprivate OrderRepository orderRepository;@Autowiredprivate AccountService accountService;// 创建订单并扣减账户余额@Transactionalpublic void createOrder(Long userId, Double amount) {try {// 1. 扣减账户余额accountService.decreaseBalance(userId, amount);// 2. 创建订单Order order = new Order();order.setUserId(userId);order.setAmount(amount);order.setStatus("CREATED");orderRepository.save(order);// 3. 模拟异常(用于测试回滚)// if (true) throw new RuntimeException("Simulated error");System.out.println("Order created successfully.");} catch (Exception e) {System.err.println("Error creating order: " + e.getMessage());throw e;  // 抛出异常以触发事务回滚}}
}

解释

  • DataSourceProxy:Seata提供的数据源代理,用于包装原有的数据源,使其支持XA协议。
  • @Transactional:标记该方法为事务性方法,确保所有操作都在同一个事务中执行。
  • 依赖XA支持:XA模式依赖于数据库和JDBC驱动的支持,因此需要确保使用的数据库和驱动程序支持XA协议。

(3)、四种模式的区别

在这里插入图片描述

9、Seata实现缓存一致性

上面四种工作模式的介绍中,其实比较常用的也就是AT模式和TCC模式。
我们在回头看下缓存一致性的问题,想要想实现Redis和Mysql的分布式事务。AT模式显然不合适,AT模式通常是通过undo_log实现回滚,也就是每个任务都是数据库任务才行。
TCC模式刚好能实现,通过TCC模式,可以自定义实现回滚方法,可以保证Redis和mysql的一致性,但方法千万不能写错了啊。
代码示例:
Service调用层类

import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class OrderService {@Autowiredprivate OrderTcc orderTcc;@GlobalTransactional(name = "create-order", rollbackFor = Exception.class)public void createOrder(Long userId, Long productId, int quantity) {// 调用 TCC 模式的 Try 接口orderTcc.tryCreateOrder(userId, productId, quantity);}
}

实现类

import com.alibaba.ttl.TransmittableThreadLocal;
import io.seata.rm.tcc.api.BusinessActionContext;
import io.seata.rm.tcc.api.BusinessActionContextParameter;
import io.seata.rm.tcc.api.LocalTCC;
import io.seata.rm.tcc.api.TwoPhaseBusinessAction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
@LocalTCC     // TCC模式
public class OrderTcc {@Autowiredprivate OrderRepository orderRepository;  // MySQL 订单表的操作@Autowiredprivate RedisTemplate<String, Object> redisTemplate;  // Redis 操作// Try 接口:预留资源@TwoPhaseBusinessAction(name = "create-order")public boolean tryCreateOrder(@BusinessActionContextParameter("userId") Long userId,@BusinessActionContextParameter("productId") Long productId,@BusinessActionContextParameter("quantity") int quantity) {// 1. 在 MySQL 中插入订单(预留资源)Order order = new Order();order.setUserId(userId);order.setProductId(productId);order.setQuantity(quantity);order.setStatus("PENDING");  // 订单状态为待确认orderRepository.save(order);// 2. 在 Redis 中设置临时键,表示库存已预留String tempKey = "temp:stock:" + productId;redisTemplate.opsForValue().set(tempKey, quantity, 60, TimeUnit.SECONDS);  // 设置 60 秒过期时间return true;}// Confirm 接口:确认提交public boolean commit(BusinessActionContext actionContext) {// 1. 获取订单 IDLong orderId = (Long) actionContext.getActionContext("orderId");// 2. 更新 MySQL 中的订单状态为已完成orderRepository.updateStatusById(orderId, "COMPLETED");// 3. 在 Redis 中设置正式的库存缓存Long productId = (Long) actionContext.getActionContext("productId");int quantity = (int) actionContext.getActionContext("quantity");redisTemplate.opsForValue().set("stock:" + productId, quantity);// 4. 删除临时键redisTemplate.delete("temp:stock:" + productId);return true;}// Cancel 接口:回滚资源public boolean rollback(BusinessActionContext actionContext) {// 1. 获取订单 IDLong orderId = (Long) actionContext.getActionContext("orderId");// 2. 回滚 MySQL 中的订单orderRepository.deleteById(orderId);// 3. 删除 Redis 中的临时键Long productId = (Long) actionContext.getActionContext("productId");redisTemplate.delete("temp:stock:" + productId);return true;}
}

相关文章:

Redis篇--常见问题篇7--缓存一致性2(分布式事务框架Seata)

1、概述 在传统的单体应用中&#xff0c;事务管理相对简单&#xff0c;通常使用数据库的本地事务&#xff08;如MySQL的BEGIN和COMMIT&#xff09;来保证数据的一致性。然而&#xff0c;在微服务架构中&#xff0c;由于每个服务都有自己的数据库&#xff0c;跨服务的事务管理变…...

Docker Compose 安装 Harbor

我使用的系统是rocky Linux 9 1. 准备环境 确保你的系统已经安装了以下工具&#xff1a; DockerDocker ComposeOpenSSL&#xff08;用于生成证书&#xff09;#如果不需要通过https连接的可以不设置 1.1 安装 Docker 如果尚未安装 Docker&#xff0c;可以参考以下命令安装&…...

使用docker compose安装gitlab

使用docker compose安装gitlab GitLab简介设置GITLAB_HOME路径创建docker挂载目录获取可用的GitLab版本编写docker-compose.yml文件启动docker基础配置GITLAB_OMNIBUS_CONFIG修改配置 中文设置数据库配置系统邮箱配置 GitLab简介 ‌GitLab是一个基于Git的开源项目&#xff0c;…...

大模型日报 2024-12-18

大模型日报 2024-12-18 大模型资讯 标题&#xff1a; 3B模型长思考后击败70B&#xff01;HuggingFace逆向出o1背后技术细节并开源 摘要&#xff1a;这篇文章探讨了小模型在经过长时间思考后&#xff0c;如何在性能上超越更大规模模型的现象。HuggingFace通过逆向工程和开源技术…...

Linux安装mysql5.7

一、下载mysql5.7 ​ 首先我们需要去下载linux版本的mysql-5.7.24的安装包。 1.可以去官方网站链接: https://downloads.mysql.com/archives/community/ ,下载mysql-5.7.24-linux-glibc2.12-x86_64.tar压缩包。 2.在线下载&#xff0c;使用wget命令&#xff0c;直接从官网下载…...

【容器】k8s学习笔记原理详解(十万字超详细)

Pod详解 Pod介绍 Pod结构 每个Pod中都可以包含一个或者多个容器&#xff0c;这些容器可以分为两类&#xff1a; 用户程序所在的容器&#xff0c;数量可多可少Pause容器&#xff0c;这是每个Pod都会有的一个根容器&#xff0c;它的作用有两个&#xff1a; 可以以它为依据&am…...

.NET重点

B/S C/S B/S&#xff1a; 浏览器端&#xff1a;JavaScript&#xff0c;HTML&#xff0c;CSS 服务器端&#xff1a;ASP&#xff08;.NET&#xff09;PHP/JSP 优势&#xff1a;维护方便&#xff0c;易于升级和扩展 劣势&#xff1a;服务器负担沉重 C/S java/.NET/VC系列 …...

SMMU软件指南SMMU编程之虚拟机结构和缓存

安全之安全(security)博客目录导读 目录 一、虚拟机结构(VMS) 二、缓存 一、虚拟机结构(VMS) 虚拟机结构(VMS)是SMMU中的概念,是一个由STE.VMSPtr字段指向的结构,包含每个虚拟机的配置设置。在相同安全状态下具有相同虚拟机ID(VMID)的多个STE必须指向相同的VMS。…...

Go 语言并发实战:利用协程处理多个接口进行数据融合

高效地处理多个数据源并将其整合为有意义的结果是开发中一项重要的任务。Go 语言&#xff0c;以其强大的并发特性&#xff0c;为我们提供了优雅而高效的解决方案。那么我们探讨一下如何利用 Go 语言的协程&#xff0c;同时调用多个接口获取数据&#xff0c;并将这些数据无缝地合…...

Redis Hash Tag 知识详解

一、Redis Hash Tag概述 Redis Hash Tag是Redis集群环境里用于控制数据分片的关键机制。在Redis集群中&#xff0c;数据依据键的哈希值来确定分片存储位置。Hash Tag能让用户指定键的特定部分作为哈希计算核心部分&#xff0c;进而使相关键存储于同一节点&#xff0c;这对处理…...

在 Ubuntu 上安装 Muduo 网络库的详细指南

在 Ubuntu 上安装 Muduo 网络库的详细指南 首先一份好的安装教程是非常重要的 C muduo网络库知识分享01 - Linux平台下muduo网络库源码编译安装-CSDN博客 像这篇文章就和shit一样&#xff0c;安装到2%一定会卡住&#xff0c;如果你不幸用了这个那真是遭老罪了 环境&#xf…...

Golang Gin Redis+Mysql 同步查询更新删除操作(我的小GO笔记)

我的需求是在处理几百上千万数据时避免缓存穿透以及缓存击穿情况出现&#xff0c;并且确保数据库和redis同步&#xff0c;为了方便我查询数据操作加了一些条件精准查询和模糊查询以及全字段模糊查询、分页、排序一些小玩意&#xff0c;redis存储是hash表key值也就是数据ID&…...

nodejs搭配express网站开发后端接口设计需要注意事项

nodejs搭配express网站开发后端接口设计需要注意事项&#xff01;为了回避一些常见的误区&#xff0c;今天和大家汇总一下&#xff0c;最近我遇到的一些错误信息&#xff0c;虽然都是小问题&#xff0c;但是还是需要分享一下&#xff0c;以免大家再次犯错。 1&#xff1a;第一个…...

mysql 基于chunk机制是如何支持运行期间,动态调整buffer pool大小的

mysql 基于chunk机制是如何支持运行期间&#xff0c;动态调整buffer pool大小的 MySQL 的 InnoDB 存储引擎确实支持在运行期间动态调整缓冲池&#xff08;buffer pool&#xff09;的大小&#xff0c;但其机制与自定义缓存系统有所不同。InnoDB 通过内部优化和配置参数来实现这…...

智能客户服务:AI与大数据的革新力量

在当今信息技术日新月异的时代&#xff0c;大数据和人工智能&#xff08;AI&#xff09;正逐步成为推动各行各业变革的重要力量。尤其是在客户服务领域&#xff0c;大数据与AI的深度融合正引领着客服系统的全面革新。 一、大数据与AI在智能客服系统中的应用 智能客服系统是一种…...

Python日常使用的自动化脚本

Python日常使用的自动化脚本 LinkDescriptionsort_files根据文件扩展名将目录中的文件组织到子目录中remove_empty_folders删除所有空的文件夹rename_files批量重命名目录中的文件scrape_data从网站上抓取数据download_images从网站批量下载图片count_words统计指定文件中的单…...

代理模式(JDK,CGLIB动态代理,AOP切面编程)

代理模式是一种结构型设计模式&#xff0c;它通过一个代理对象作为中间层来控制对目标对象的访问&#xff0c;从而增强或扩展目标对象的功能&#xff0c;同时保持客户端对目标对象的使用方式一致。 代理模式在Java中的应用,例如 1.统一异常处理 2.Mybatis使用代理 3.Spring…...

【Leetcode 热题 100】236. 二叉树的最近公共祖先

问题背景 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 最近公共祖先的定义为&#xff1a;对于有根树 T T T 的两个节点 p p p、 q q q&#xff0c;最近公共祖先表示为一个节点 x x x&#xff0c;满足 x x x 是 p p p、 q q q 的祖先且 x x x 的深度尽可能大…...

Go框架比较:goframe、beego、iris和gin

由于工作需要&#xff0c;这些年来也接触了不少的开发框架&#xff0c;Golang的开发框架比较多&#xff0c;不过基本都是Web"框架"为主。这里稍微打了个引号&#xff0c;因为大部分"框架"从设计和功能定位上来讲&#xff0c;充其量都只能算是一个组件&…...

Kafka Streams 在监控场景的应用与实践

作者&#xff1a;来自 vivo 互联网服务器团队- Pang Haiyun 介绍 Kafka Streams 的原理架构&#xff0c;常见配置以及在监控场景的应用。 一、背景 在当今大数据时代&#xff0c;实时数据处理变得越来越重要&#xff0c;而监控数据的实时性和可靠性是监控能力建设最重要的一环…...

数据结构 -- 二叉树

目录 1、二叉树概念及结构 1.1、概念 1.2、特殊的二叉树 1.3、二叉树的性质 1.4、二叉树的存储结构 1.4.1、顺序存储 -- 看截图&#xff1a;二叉树的顺序存储 1.4.2、链式存储 -- 非完全二叉树用这种方式存储 2、二叉树的遍历 2.1、前序、中序以及后序遍历2.2、层序遍…...

redis数据转移

可能有时候因为硬件的原因我们我们需要更换服务器&#xff0c;如果更换服务器的话&#xff0c;那我们redis的数据该怎样转移呢&#xff0c;按照一下步骤即可完成redis数据的转移 1.进入redis客户端 2.使用 bgsave命令进行数据的备份&#xff0c;此命令完成后会在你的redis安装目…...

Ubuntu Netlink 套接字使用介绍

Netlink 套接字 是 Linux 特有的一种 IPC&#xff08;进程间通信&#xff09;机制&#xff0c;用于用户态进程和内核模块之间的通信。它可以用来完成路由管理、设备通知、网络状态更新等任务。 1. Netlink 的基本工作原理 Netlink 是一种双向通信机制。Netlink 消息分为请求和…...

spring boot密码加密方式

1. BCrypt 原理 BCrypt是一种专为密码哈希设计的算法&#xff0c;它被广泛认为是安全的选择之一。它不仅是一个单向函数&#xff08;即只能加密不能解密&#xff09;&#xff0c;而且还内置了盐&#xff08;salt&#xff09;生成机制来防止彩虹表攻击。BCrypt的一个重要特点是…...

springboot根据租户id动态指定数据源

代码地址 码云地址springboot根据租户id动态指定数据源: springboot根据租户id指定动态数据源,结合mybatismysql多数源下的事务管理 创建3个数据库和对应的表 sql脚本在下图位置 代码的执行顺序 先设置主数据库的数据源配置目标数据源和默认数据源有了主库的数据源&#xff…...

使用C语言编写UDP循环接收并打印消息的程序

使用C语言编写UDP循环接收并打印消息的程序 前提条件程序概述伪代码C语言实现编译和运行C改进之自由设定端口注意事项在本文中,我们将展示如何使用C语言编写一个简单的UDP服务器程序,该程序将循环接收来自指定端口的UDP消息,并将接收到的消息打印到控制台。我们将使用POSIX套…...

【AI】✈️问答页面搭建-内网穿透公网可访问!

目录 &#x1f44b;前言 &#x1f440;一、后端改动 &#x1f331;二、内网穿透 &#x1f49e;️三、前端改动 &#x1f379;四、测试 &#x1f4eb;五、章末 &#x1f44b;前言 小伙伴们大家好&#xff0c;上次本地搭建了一个简单的 ai 页面&#xff0c;实现流式输出问答…...

计算机毕业设计原创定制(免费送源码):NodeJS+MVVM+MySQL 樱花在线视频网站

目 录 摘要 1 1 绪论 1 1.1研究背景 1 1.2系统设计思想 1 1.3B/S体系工作原理 1 1.4node.js主要功能 2 1.5论文结构与章节安排 3 2 樱花在线视频网站分析 4 2.1 可行性分析 4 2.2 系统流程分析 4 2.2.1数据增加流程 5 2.3.2数据修改流程 5 2.3.3数据删除流程 5 …...

ECharts热力图-笛卡尔坐标系上的热力图,附视频讲解与代码下载

引言&#xff1a; 热力图&#xff08;Heatmap&#xff09;是一种数据可视化技术&#xff0c;它通过颜色的深浅变化来表示数据在不同区域的分布密集程度。在二维平面上&#xff0c;热力图将数据值映射为颜色&#xff0c;通常颜色越深表示数据值越大&#xff0c;颜色越浅表示数…...

【Lua热更新】下篇

上篇链接&#xff1a;【Lua热更新】上篇 文章目录 三、xLua热更新&#x1f4d6;1.概述&#x1f4da;︎2.导入xLua框架&#x1f516;3. C#调用Lua3.1Lua解析器3.2Lua文件夹的重定向3.3Lua解析器管理器3.4全局变量获取3.5全局函数获取3.6映射到List和Dictionary3.7映射到类3.8映…...