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

分布式事务篇-2.4 Spring-Boot整合Seata

文章目录

  • 前言
  • 一、pom jar导入:
  • 二、项目配置:
    • 2.1 配置 说明:
      • 2.1 .1 seata server 端:
      • 2.1 .2 seata client 端:
    • 2.2 开启seata 对于数据源的代理:
    • 2.3 seata-client 的注册中心:
    • 2.4 seata-client 的配置中心:
    • 2.5 去掉手写的数据源代理和feign代理:
  • 三、项目使用:
    • 3.1 AT 模式使用:
    • 3.2 XA 模式使用:
    • 3.3 TCC 模式使用:
  • 四、总结:
  • 五、参考:


前言

在了解了Seata 的工作原理后,如何在springboot 项目中进行整合使用,本文进行阐述。


提示:本文使用 seata 版本 :1.5 ;在整合之前 你需要先要部署seate 的服务

一、pom jar导入:

<?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.7.14</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>spring-seata-storage</artifactId><version>0.0.1-SNAPSHOT</version><name>spring-seata-storage</name><description>spring-seata-storage</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><optional>true</optional><version>3.1.6</version></dependency><!-- mysql --><!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version></dependency><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.21</version><!-- <version>5.1.49</version>--></dependency><!-- https://mvnrepository.com/artifact/net.sf.jsqlparser/jsqlparser --><dependency><groupId>net.sf.jsqlparser</groupId><artifactId>jsqlparser</artifactId><version>0.8.0</version></dependency><dependency><groupId>io.swagger</groupId><artifactId>swagger-annotations</artifactId><version>1.6.2</version></dependency><!-- https://mvnrepository.com/artifact/io.seata/seata-spring-boot-starter --><!-- <dependency><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId><version>1.5.2</version></dependency>--><!--处理 在SpringBoot 2.4.x的版本之后,对于bootstrap.properties/bootstrap.yaml配置文件(我们合起来成为Bootstrap配置文件)的支持,需要导入如下的依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId><version>3.1.6</version></dependency><!-- seata 使用nacos 作为配置中心和 注册中心时 使用  --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId><version>2021.0.5.0</version></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><version>2021.0.5.0</version></dependency><dependency><groupId>com.alibaba.cloud</groupId><!-- 里面已经集成服务间调用X-id的传递,包括FeignClient的重写,如果在之前自定义封装过Feign,注意启动冲突--><artifactId>spring-cloud-starter-alibaba-seata</artifactId><version>2021.0.5.0</version><exclusions><!--去除低版本--><exclusion><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId></exclusion></exclusions></dependency><!-- https://mvnrepository.com/artifact/io.seata/seata-spring-boot-starter --><dependency><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId><version>1.6.1</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><mainClass>com.example.springseata.springseatastorage</mainClass></configuration><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins><resources><resource><directory>src/main/resources</directory><filtering>true</filtering></resource></resources></build></project>

jar 目的:

  • spring-boot-starter-web: 使用 浏览器进行 http 访问;
  • lombok: 生成 get set 等方法,使代码更加简洁;
  • spring-boot-starter-test: 可以进行单元测试;
  • spring-cloud-starter-openfeign: 可以使用feign 接口进行服务间的http 通信;
  • mybatis-plus-boot-starte,mysql-connector-java ,jsqlparser:导入mysql-plus 进行 增删改查;
  • swagger-annotations: 类和方法的说明;
  • spring-cloud-starter-bootstrap :在SpringBoot 2.4.x的版本之后,对于bootstrap.properties/bootstrap.yaml配置文件(我们合起来成为Bootstrap配置文件)的支持;
  • spring-cloud-starter-alibaba-nacos: seata 使用nacos 作为配置中心和 注册中心时 使用;
  • spring-cloud-starter-alibaba-seata: 导入cloud对饮的jar 让其帮助进行 分布式事务xid 的传递;
  • seata-spring-boot-starter : seata 的核销服务jar;

springcloud ,springboot,springcloud-alibaba 版本对应:版本说明

二、项目配置:

2.1 配置 说明:

目的: 了解seat 客户端和服务端的 关系,清楚其配置的含义;

2.1 .1 seata server 端:

  • seata server 的存储模式:
    存储模式指定了Seata Server用于存储事务和元数据的方式,这个只有在seata 服务端才有。Seata Server支持三种存储模式:file、db和Redis。列如 当开始事务时需要生成全局事务id Xid ,在生成后就需要Seata 服务进行存储,所以他是Seata Server的重要组成部分;

  • seata server 的配置中心:
    配置中心的作用:用于配置 Seata Server的相关参数, Seata Server 端在启动的时候也可以配置很多参数,如果把这些参数都放到 Seata Server 中,每次修改度需要连接到Seata Server 的服务器,然后对其配置文件进行修改,如果把这个参数放到 配置中心如config ,zk,nacos 就可以在配置中心进行修改,更加的方便;

  • seata server 的注册中心:
    Seata Server 的注册中心是用于存储和管理 Seata 事务参与者的信息的组件;多个Seata Server 可以成为一个集群,然后注册到zk,eureka,nacos 里,这样方便集群的管理;

2.1 .2 seata client 端:

  • seata client 的配置中心:
    同seata-sever 端相同,客户端在启动的时候也可以进行参数的配置,所以可以在客户端我们也可以 将参数放到 config ,zk,nacos 进行配置;

  • seata client 的注册中心:
    seata 客户端的注册中心,用于服务端的发现,一个重要的信息就是,可以将seata 客户端和seata 服务端 注册到相同的地方,已nacos 为例:服务端和客户端 注册到相同命名空间,相同分组,相同应用,此时客户端会动态的发现 seata 服务的地址,此时不需要在显示的设置 seata 服务断的地址;
    Seata 客户端在启动时会从 Nacos 服务获取 service.vgroupMapping.your-service-group 定义的服务群组实例,这需要和 Seata 服务端的配置保持一致。以下三个参数需要和 Seata 服务端保持一致:application:, group, namespace

2.2 开启seata 对于数据源的代理:

目的:让 seata 接管数据源,然后才能协调各个微服务的本地事务;

seata:enabled: true # spring 自动装配enable-auto-data-source-proxy: true # 开启数据源自动代理transport:enable-client-batch-send-request: true #客户端事务消息请求是否批量合并发送,默认true,false单条发送tx-service-group: my_tx_group # 事务分组application-id: storageservice:vgroup-mapping:my_tx_group: default
#    grouplist:
#      default: localhost:8091
  • tx-service-group 定义事务分组,可以自定义,多个微服务只有在同一个事务分组中,分布式事务才能生效,也就是多个微服务改参数要保持一致;
  • application-id 该服务事务id ,同一分组下的 的微服务 需要进行不同的定义;
  • servicevgroup-mapping 定义改事务分组 连接的seata 服务端 集群的名称,改名称需要和seata server 定义的集群名称保持一致;
    在这里插入图片描述
  • grouplist 中 default 为集群的名称,后面的为集群seata-server 端的地址,注意 这中连接模式只在 seata 客户端为 file 模式下生效; 其他方式如nacos ,需要配置使得 seata-server 和seata-client 都注册在相同命名空间,相同分组,相同application 下,这样seata-client 就可以动态的发现seata-server 的实例地址;

2.3 seata-client 的注册中心:

目的: 了解本地springboot 服务如何连接到 seata server 端

客户端和服务端 seata 都是默认已file 作为注册中心:

  • file
    seata-server 服务端 注册中心使用的file 本地模式,则seata 客户端 也需要使用file注册模式:
    此时需要配置 seata.service.grouplist.default=127.0.0.1:8091 用于客户端连接 seata 服务端;

  • nacos
    seata-server 服务端 注册中心使用的nacos,则seata 客户端 也需要使用nacos注册模式:

 seata-server 服务端 注册中心使用的nacos,则seata 客户端 也需要使用nacos注册模式:
seata:enabled: true # spring 自动装配enable-auto-data-source-proxy: true # 开启数据源自动代理transport:enable-client-batch-send-request: true #客户端事务消息请求是否批量合并发送,默认true,false单条发送tx-service-group: my_tx_groupapplication-id: storageservice:vgroup-mapping:my_tx_group: default
#    grouplist:
#      default: localhost:8091registry:#    type: filetype: nacosnacos:application: seata-serverserver-addr: localhost:8848group: SEATA_GROUPnamespace: 7f2765bc-d8c1-4b49-b706-8c292d2ffac9username: nacospassword: nacos

注意 application,server-addr,group,namespace,username,password 客户端和服务端报纸一致;

2.4 seata-client 的配置中心:

目的: 了解本地springboot 如何对seata 进行参数配置

客户端和服务端 seata 都是默认已file 作为配置中心,他们的只是用作参数的配置使用,所以他们各自是独立的;

  • file
    seata 客户端的默认配置;
  • nacos
    使用nacos 作为配置中心 :
seata:enabled: true # spring 自动装配enable-auto-data-source-proxy: true # 开启数据源自动代理transport:enable-client-batch-send-request: true #客户端事务消息请求是否批量合并发送,默认true,false单条发送tx-service-group: my_tx_groupapplication-id: storageservice:vgroup-mapping:my_tx_group: default
#    grouplist:
#      default: localhost:8091config:type: nacos
#    type: filenacos:server-addr: localhost:8848namespace: c0befc56-f31b-4de6-929b-6f75604992d1
#      namespace: 7f2765bc-d8c1-4b49-b706-8c292d2ffac9group: DEFAULT_GROUPusername: nacospassword: nacos##if use MSE Nacos with auth, mutex with username/password attribute#access-key: ""#secret-key: ""data-id: seata.properties

本文测试时虽然在 nacos 中创建了seata.properties 的配置文件但是其 配置的参数没有起作用;
在这里插入图片描述
会提示无法找到service.vgroupMapping.my_tx_group(my_tx_group 为定义的分组名称)的集群,通过创建 service.vgroupMapping.my_tx_group 配置文件 并且定义default 得以解决,目前没有找到其它解决办法;
在这里插入图片描述

2.5 去掉手写的数据源代理和feign代理:

  • seata DataSourceProxy 的代理:因为在其配置文件中已经开启了自动代理

seata:enabled: true # spring 自动装配enable-auto-data-source-proxy: true # 开启数据源自动代理
所以需要去重 手动加入的代理,防止冲突,导致 事务失效

在这里插入图片描述

  • feign 接口的代理:
    因为引入的spring-cloud-starter-alibaba-seata 已经对feign 进行了xid 的处理
<dependency><groupId>com.alibaba.cloud</groupId><!-- 里面已经集成服务间调用X-id的传递,包括FeignClient的重写,如果在之前自定义封装过Feign,注意启动冲突--><artifactId>spring-cloud-starter-alibaba-seata</artifactId><version>2021.0.5.0</version><exclusions><!--去除低版本--><exclusion><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId></exclusion></exclusions>
</dependency>

所以可以去除 手动增加的对于feign 接口xid 的特殊处理防止冲突:
在这里插入图片描述

三、项目使用:

3.1 AT 模式使用:

seata 客户端的事务模式默认使用AT 模式;通过以下两个步骤配置就可使用:

  • 在每个 数据库中增加undo_log 表,用于AT 模式事务日志记录使用:
CREATE TABLE `undo_log` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`branch_id` bigint(20) NOT NULL,`xid` varchar(100) NOT NULL,`context` varchar(128) NOT NULL,`rollback_info` longblob NOT NULL,`log_status` int(11) NOT NULL,`log_created` datetime NOT NULL,`log_modified` datetime NOT NULL,`ext` varchar(100) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
  • 在不同服务中都完成seata 的集群 ,然后在对应的业务实现中增加@GlobalTransactional(rollbackFor =
    Exception.class) 注解:
    在这里插入图片描述

3.2 XA 模式使用:

  • mysql 开启XA协议:
SHOW VARIABLES LIKE 'innodb_support_xa';

在这里插入图片描述
如果没有开通,则打开 MySQL 配置文件 my.cnf 或 my.ini。在文件中找到 [mysqld] 部分,并在该部分下添加以下行:

[mysqld]
innodb_support_xa = 1

保存配置文件并重启 MySQL 服务;

  • 显示设置 模式为XA 模式,代码层面无需变动;
 seata.data-source-proxy-mode=XA

3.3 TCC 模式使用:

根据两阶段行为模式的不同,我们将分支事务划分为 Automatic (Branch) Transaction Mode 和 TCC (Branch) Transaction Mode.

AT 模式(参考链接 TBD)基于 支持本地 ACID 事务 的 关系型数据库:

一阶段 prepare 行为:在本地事务中,一并提交业务数据更新和相应回滚日志记录。
二阶段 commit 行为:马上成功结束,自动 异步批量清理回滚日志。
二阶段 rollback 行为:通过回滚日志,自动 生成补偿操作,完成数据回滚。
相应的,TCC 模式,不依赖于底层数据资源的事务支持:

一阶段 prepare 行为:调用 自定义 的 prepare 逻辑。
二阶段 commit 行为:调用 自定义 的 commit 逻辑。
二阶段 rollback 行为:调用 自定义 的 rollback 逻辑。
所谓 TCC 模式,是指支持把 自定义 的分支事务纳入到全局事务的管理中。

  • tcc 事务记录表:tcc_fence_log
CREATE TABLE `tcc_fence_log` (`xid` varchar(128) NOT NULL COMMENT 'global id',`branch_id` bigint(20) NOT NULL COMMENT 'branch id',`action_name` varchar(64) NOT NULL COMMENT 'action name',`status` tinyint(4) NOT NULL COMMENT 'status(tried:1;committed:2;rollbacked:3;suspended:4)',`gmt_create` datetime(3) NOT NULL COMMENT 'create time',`gmt_modified` datetime(3) NOT NULL COMMENT 'update time',PRIMARY KEY (`xid`,`branch_id`),KEY `idx_gmt_modified` (`gmt_modified`),KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  • 订单服务 java demo:
    IOrderService:
public interface IOrderService extends IService<Order> {Boolean orderCreate(OrderReqDto reqDto);
}

实现类:

@Override
@GlobalTransactional(rollbackFor = Exception.class)public Boolean orderCreate(OrderReqDto reqDto) {log.error("Seata全局事务id=================>{}", RootContext.getXID());// stock服务未报错,order服务报错try {// 扣减库存-通过fegin 接口进行调用storageFeignApi.tccSumGoodNum(reqDto.getByGoods());} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e);}// 订单创建Order order = new Order();order.setAccountId("123").setMoney(reqDto.getOrderMoney());this.save(order);return true;}

controller:

@ResponseBody@PostMapping("/tcc/sure")public Boolean orderCreate(@RequestBody OrderReqDto reqDto) throws SQLException {return orderService.orderCreate(reqDto);}
  • 库存服务 java demo:
    controller:
 @ResponseBody@PostMapping(value = "/tcc/sumGoodNum")public boolean tccSumGoodNum(@RequestBody List<GoodDto> param){return  tccStorageService.deduct(param);}

ITccStorageService:

package com.example.springseatastorage.service;import com.example.springseatastorage.controller.dto.GoodDto;
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 java.util.List;@LocalTCC
public interface ITccStorageService {/*** 减库存* useTCCFence=true 为开启防悬挂* @param param*/@TwoPhaseBusinessAction(name = "deduct", commitMethod = "busCommit", rollbackMethod = "busRollback", useTCCFence = true)boolean deduct(@BusinessActionContextParameter(paramName = "param")  List<GoodDto>param);/*** 提交事务** @param actionContext* @return*/boolean busCommit(BusinessActionContext actionContext);/*** 回滚事务** @param actionContext* @return*/boolean busRollback(BusinessActionContext actionContext);
}

ITccStorageServicempl:

package com.example.springseatastorage.service.impl;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.springseatastorage.controller.dto.GoodDto;
import com.example.springseatastorage.entity.Storage;
import com.example.springseatastorage.service.IStorageService;
import com.example.springseatastorage.service.ITccStorageService;
import io.seata.core.context.RootContext;
import io.seata.rm.tcc.api.BusinessActionContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;@Slf4j
@Service
public class ITccStorageServicempl implements ITccStorageService {@Autowiredprivate IStorageService storageService;@Override@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)public boolean deduct(List<GoodDto> param) {log.error("Seata全局事务id=================>{}", RootContext.getXID());Map<String, Integer> good = param.stream().collect(Collectors.toMap(GoodDto::getGoodId, GoodDto::getBuyNum));LambdaQueryWrapper<Storage> wrapper = new LambdaQueryWrapper<>();wrapper.in(Storage::getGoodId, param.stream().map(e -> e.getGoodId()).collect(Collectors.toList()));List<Storage> storages = storageService.list(wrapper);storages.stream().forEach(e -> {e.setGoodNum(e.getGoodNum() - good.get(e.getGoodId()));});storageService.updateBatchById(storages);return true;}@Overridepublic boolean busCommit(BusinessActionContext actionContext) {log.info("busCommit xid = " + actionContext.getXid() + "提交成功");return true;}@Overridepublic boolean busRollback(BusinessActionContext actionContext) {// 编写对应的业务数据进行回滚List<GoodDto> param = actionContext.getActionContext("param", List.class);
//        int count = actionContext.getActionContext("count", Integer.class);
//        LambdaQueryChainWrapper<Stock> eq = lambdaQuery().eq(Stock::getCommodityCode, commodityCode);
//        Long count1 = eq.one().getCount();
//        // 扣了多少数,需要重新添加回去
//        lambdaUpdate().set(Stock::getCount, count + count1)
//                .eq(Stock::getCommodityCode, commodityCode)
//                .update();log.info("busRollback xid = " + actionContext.getXid() + "回滚成功");return true;}
}

四、总结:

本文通过springboot 项目整合seata 然后 通过 AT,XA,TCC 事务模式,模拟实现分布式事务。

五、参考:

1 Seata新手部署指南;
2 版本说明;
3 Seata 事务模式;

相关文章:

分布式事务篇-2.4 Spring-Boot整合Seata

文章目录 前言一、pom jar导入:二、项目配置&#xff1a;2.1 配置 说明&#xff1a;2.1 .1 seata server 端:2.1 .2 seata client 端: 2.2 开启seata 对于数据源的代理:2.3 seata-client 的注册中心&#xff1a;2.4 seata-client 的配置中心&#xff1a;2.5 去掉手写的数据源代…...

718. 最长重复子数组

718. 最长重复子数组 原题链接&#xff1a;完成情况&#xff1a;题解&#xff1a;方法一&#xff1a;动态规划方法二&#xff1a;滑动窗口方法三&#xff1a;二分查找 哈希 原题链接&#xff1a; 718. 最长重复子数组 https://leetcode.cn/problems/maximum-length-of-repe…...

Mysql join加多条件与where的区别

最近在项目中遇到一个问题&#xff0c;感觉有点意思&#xff0c;在解决问题及查阅了相关资料后&#xff0c;打算写篇文章给朋友们分享一下。 问题现象&#xff1a; 问题是很常见的空指针问题&#xff0c;后端查询数据库数据&#xff0c;遍历进行相关业务处理时报空指针。通过…...

div滚动条自动滚动到底部

<div id"center"></div>// 滚动条到最底部scrollToBottom(){var box document.getElementById(center);this.$nextTick(() > {box.scrollTop box.scrollHeight})},...

【深度学习】实验02 鸢尾花数据集分析

文章目录 鸢尾花数据集分析决策树K-means 鸢尾花数据集分析 决策树 # 导入机器学习相关库 from sklearn import datasets from sklearn import treeimport matplotlib.pyplot as plt import numpy as np# Iris数据集是常用的分类实验数据集&#xff0c; # 由Fisher, 1936收集…...

AI大模型潮水中,医疗数字化加速「求解」

蝴蝶挥动翅膀&#xff0c;医疗行业每个角落开始连锁反应&#xff0c;曾经被忽视的问题也愈发明显。但与之对应的是&#xff0c;对数字化和AI大模型的价值认可&#xff0c;在中国医疗赛道也正在加速来临。 作者|斗斗 编辑|皮爷 出品|产业家 重庆市某地方人民医院&#xf…...

【安卓】自定义View实现画板涂鸦等功能

一、实现效果 二、代码 1、MainActivity.class package com.lsl.mydrawingboarddemo;import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.ContextCompat;import android.os.Bundle; import android.os.Handler; import android.view.View; impo…...

面试题. 搜索旋转数组

搜索旋转数组。给定一个排序后的数组&#xff0c;包含n个整数&#xff0c;但这个数组已被旋转过很多次了&#xff0c;次数不详。请编写代码找出数组中的某个元素&#xff0c;假设数组元素原先是按升序排列的。若有多个相同元素&#xff0c;返回索引值最小的一个。 示例1: 输入…...

前端需要理解的数据治理与异常监控知识

1 数据治理 前端数据治理的重要指标是准确性和数据&#xff0c;一个数据对象包括数据值和其他元数据。 2 数据上报方式 2.1 Image 通过将采集的数据拼接在图片请求的后面&#xff0c;向服务端请求一个 1*1 px 大小的图片&#xff08;gif&#xff09;实现的&#xff0c;设置…...

ip_vs 原理解析 (四)hook 后的开始 一

文章目录 ip_vs hook 后NF_INET_LOCAL_IN 本章重点&#xff1a; k8s 如何利用 ip_vs 实现源 IP 会话亲和性。 ip_vs hook 后 NF_INET_LOCAL_IN 根据优先级依次是 ip_vs_reply4&#xff0c;ip_vs_remote_request4 ip_vs_reply4| -- ip_vs_out| -- skb_to_full_sk(skb&#xf…...

【论文解读】基于图的自监督学习联合嵌入预测架构

一、简要介绍 本文演示了一种学习高度语义的图像表示的方法&#xff0c;而不依赖于手工制作的数据增强。论文介绍了基于图像的联合嵌入预测架构&#xff08;I-JEPA&#xff09;&#xff0c;这是一种用于从图像中进行自监督学习的非生成性方法。I-JEPA背后的idea很简单&#xff…...

C++ 容器

string 1. 构造 string s1(); // 1 string s2("hello"); // hello string s3(3, k); // kkk string s4("hellohello", 2, 4); // lloh2. 赋值 string s1 "hellohello"; // hellohello string s2.assign(s1); // he…...

【PHP】PHP文件操作详解

PHP是一种广泛使用的服务器端脚本语言&#xff0c;用于开发Web应用程序。在PHP中&#xff0c;文件操作是一项重要的功能&#xff0c;包括文件的读取、写入、删除和其他操作。本文将详细介绍PHP文件操作的各个方面&#xff0c;并通过示例代码进行说明。 一、文件读取 要读取一…...

硬核旗舰南卡OE CC开放式耳机发布,重新定义百元开放式耳机新标杆!

​随着现在健康意识的不断提高&#xff0c;人们对于日常用品的要求越来越高&#xff0c;在耳机市场中&#xff0c;健康因素也逐渐成为消费者所考虑的因素之一&#xff0c;入耳式耳机因为会引发中耳炎、耳膜炎等疾病&#xff0c;正在逐渐被开放式蓝牙耳机所取代&#xff0c;南卡…...

785. 判断二分图

785. 判断二分图 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a; 原题链接&#xff1a; 785. 判断二分图 https://leetcode.cn/problems/is-graph-bipartite/description/ 完成情况&#xff1a; 解题思路&#xff1a; 题目解释&#x…...

限时 180 天,微软为 RHEL 9 和 Ubuntu 22.04 推出 SQL Server 2022 预览评估版

导读近日消息&#xff0c;微软公司今天发布新闻稿&#xff0c;宣布面向 Red Hat Enterprise Linux&#xff08;RHEL&#xff09;9 和 Ubuntu 22.04 两大发行版&#xff0c;以预览模式推出 SQL Server 2022 评估版。 近日消息&#xff0c;微软公司今天发布新闻稿&#xff0c;宣布…...

一款ccm的功率因素校正控制器ncp1654

产品概述&#xff1a; NCP1654是用于连续传导模式的控制器&#xff08;CCM&#xff09;功率因数校正升压预转换器。它控制固定频率模式下的电源开关导通时间&#xff08;PWM&#xff09;并且取决于瞬时线圈电流。 该电路封装在SO8封装中&#xff0c;最大限度地减少了外部组件&a…...

4.若依框架上传文件

1.服务端代码-控制器 /*** 上传文件*/PostMapping("/upload")Operation(summary "上传")public AjaxResult uploadFile(MultipartFile file) throws Exception {try {// 上传文件路径String filePath RuoYiConfig.getUploadPath();// 上传并返回新文件名…...

Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are required

项目场景&#xff1a; 最近因为公司业务需要在搭一个新架构&#xff0c;用的springboot3和jdk17,在整合mybatis多数据源的时候报错 &#xff08;引用的mybatisplus 和 mybatisplusjion的是最新的包-2023-08-26&#xff09; Error creating bean with name ‘XXXServiceImpl’:…...

idea的debug断点的使用

添加断点&#xff08;目前不知道如何添加断点&#xff0c;就给AutoConfigurationImportSelector的每个方法都加上断点&#xff09;&#xff1a; 然后将StockApplication启动类以debug方式运行&#xff0c;然后程序就会停在119行 点击上边的step over让程序往下运行一行&#x…...

【UE】蓝图通信——事件分发器

目标 比如我现在希望点击控件蓝图A中的按钮后&#xff0c;蓝图B能够马上做出响应 实现步骤 1. 这里控件蓝图A叫“UI_按钮”&#xff0c;我在该蓝图中创建了一个名为“btnIsClicked”的事件分发器 当按钮被点击时&#xff0c;就会调用“btnIsClicked” 2. 蓝图B这里叫做“BP_…...

Python爬虫分布式架构问题汇总

在使用Python爬虫分布式架构中可能出现以下的问题&#xff0c;我们针对这些问题&#xff0c;列出相应解决方案&#xff1a; 1、任务重复执行 在分布式环境下&#xff0c;多个爬虫节点同时从消息队列中获取任务&#xff0c;可能导致任务重复执行的问题。 解决方案&#xff1a;…...

AIGC人工智能涉及三十六职业,看看有没有你的职业(一)

文章目录 一只弹吉他的熊猫 神奇的企鹅 功夫熊猫 视觉光影下的女子 闪光灯效 局部柔光 生物光 LOGO设计 制作儿童绘本故事 换脸艺术 打造专属动漫头像 包装设计之美 建筑设计 如何转高清图 生成3D质感图标 生成微信表情包 探索美食摄影的奇妙之旅 蛋糕创意设…...

万界星空科技/免费MES系统/免费质量检测系统

质量管理也是万界星空科技免费MES中的一个重要组成部分&#xff0c;旨在帮助制造企业实现全面的质量管理。该系统涵盖了供应商来料、生产过程、质量检验、数据分析等各个环节&#xff0c;为企业提供了一站式的质量管理解决方案。 1. 实时质量监控 质量管理能够实时监控生产过程…...

解决IndexError: index 0 is out of bounds for axis 1 with size 0

标题 引言问题背景解决思路如何防止总结参考资料 博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的博客&#x1f466;&#x1f3fb; 《java 面试题大全》 &#x1f369;惟余辈才疏学浅&#xff0c;临摹之作或有不妥之处&#xff0c;还请读者海涵指正。☕&#x1f36d;…...

Java中hashTable的基本介绍,细节讨论,使用注意事项,常用方法和底层的扩容机制

Hashtable 是 Java 标准库中提供的一个古老的散列表&#xff08;Hash Table&#xff09;实现&#xff0c;用于存储键值对。它是线程安全的&#xff0c;基于哈希表的数据结构。然而&#xff0c;由于其线程安全性引入的同步机制&#xff0c;使得在多线程环境下性能相对较低。在现…...

redis -实战记录

redis -实战记录 一、安装二、使用 一、安装 centos - docker安装redisWindows10安装redis(图文教程&#xff09; 二、使用 node-red进行读写redis...

Mysql知识梳理

Mysql知识梳理 索引索引分类索引未命中的原因性能调优命令Explain回表 mysql性能优化事务四大特性事务隔离级别设置事务隔离级别 存储引擎聚簇索引和非聚簇索引聚簇索引非聚簇索引 最左前缀结合原则全文索引 索引 索引分类 mysql有普通索引、空间索引、主键索引、唯一索引、组…...

文生图模型之Stable Diffusion

原始文章地址 autoencoder CLIP text encoder tokenizer最大长度为77&#xff08;CLIP训练时所采用的设置&#xff09;&#xff0c;当输入text的tokens数量超过77后&#xff0c;将进行截断&#xff0c;如果不足则进行paddings&#xff0c;这样将保证无论输入任何长度的文本&…...

Java List循环安全删除元素

Java List循环安全删除元素的几种方式如下&#xff1a; 使用迭代器&#xff08;Iterator&#xff09;&#xff1a;通过调用List的iterator()方法获取List的迭代器&#xff0c;然后使用迭代器的remove()方法删除元素。这种方式可以避免在遍历过程中修改List导致的并发修改异常&…...

2023年03月 C/C++(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题:和数 给定一个正整数序列,判断其中有多少个数,等于数列中其他两个数的和。 比如,对于数列1 2 3 4, 这个问题的答案就是2, 因为3 = 2 + 1, 4 = 1 + 3。 时间限制:10000 内存限制:65536 输入 共两行,第一行是数列中数的个数n ( 1 <= n <= 100),第二行是由n个…...

bert-base-chinese 判断上下句

利用BERT等模型来实现语义分割。BERT等模型在预训练的时候采用了NSP&#xff08;next sentence prediction&#xff09;的训练任务&#xff0c;因此BERT完全可以判断两个句子&#xff08;段落&#xff09;是否具有语义衔接关系。这里我们可以设置相似度阈值 MERGE_RATIO &#…...

vue3+vue-cli使用mockjs

1.下载mockjs包 npm i mockjs -D 2.main.js中全局引入 // mock模拟后端数据 import /mock/index.js 3.axios下baseUrl注释掉&#xff0c;让其不走本地代理 // 使用mock数据的话&#xff0c;将这一项注释即可 // axios.defaults.baseURL process.env.VUE_APP_BASE_API; 4.s…...

Android 全局监听软键盘弹起隐藏 动态修改布局并适配无限循环的问题

思路&#xff1a; 要在 Android 应用中全局检测软键盘的弹起&#xff0c;您可以使用 ViewTreeObserver.OnGlobalLayoutListener 监听器来监听布局树的变化。当软键盘弹起或隐藏时&#xff0c;布局树会发生变化&#xff0c;因此您可以在监听器中捕获这些变化。 以下是一个示例…...

第 k 小整数

题目描述 现有 n 个正整数&#xff0c;要求出这 n 个正整数中的第 k 个最小整数&#xff08;相同大小的整数只计算一次&#xff09;。 输入格式 第一行为 n 和 k; 第二行开始为 n 个正整数的值&#xff0c;整数间用空格隔开。 输出格式 第kk个最小整数的值&#xff1b;若无…...

LeetCode 1448. 统计二叉树中好节点的数目:DFS

【LetMeFly】1448.统计二叉树中好节点的数目 力扣题目链接&#xff1a;https://leetcode.cn/problems/count-good-nodes-in-binary-tree/ 给你一棵根为 root 的二叉树&#xff0c;请你返回二叉树中好节点的数目。 「好节点」X 定义为&#xff1a;从根到该节点 X 所经过的节点…...

AR室内导航技术之技术说明与效果展示

随着科技的飞速发展&#xff0c;我们周围的环境正在经历着一场数字化的革命。其中&#xff0c;AR室内导航技术以其独特的魅力&#xff0c;为我们打开了一扇通往全新数字化世界的大门。本文将为您详细介绍这一技术的实现原理、工具应用以及成品展示&#xff0c;带您领略AR室内导…...

06-Numpy基础-线性代数

线性代数&#xff08;如矩阵乘法、矩阵分解、行列式以及其他方阵数学等&#xff09;是任何数组库的重要组成部分。 NumPy提供了一个用于矩阵乘法的dot函数&#xff08;既是一个数组方法也是numpy命名空间中的一个函数&#xff09; x.dot(y)等价于np.dot(x, y) 符&#xff08;…...

SpringBootWeb 登录认证

登录认证&#xff0c;那什么是认证呢&#xff1f; 所谓认证指的就是根据用户名和密码校验用户身份的这个过程&#xff0c;认证成功之后&#xff0c;我们才可以访问系统当中的信息&#xff0c;否则就拒绝访问。 在前面的案例中&#xff0c;我们已经实现了部门管理、员工管理的…...

【JVM 内存结构丨栈】

栈 -- 虚拟机栈 简介定义压栈出栈局部变量表操作数栈方法调用特点作用 本地方法栈&#xff08;C栈&#xff09;定义栈帧变化作用对比 主页传送门&#xff1a;&#x1f4c0; 传送 简介 栈是用于执行线程的内存区域&#xff0c;它包括局部变量和操作数栈。 Java 虚拟机栈会为每…...

LeetCode 138.复制带随机指针的链表

文章目录 &#x1f4a1;题目分析&#x1f4a1;解题思路&#x1f6a9;步骤一&#xff1a;拷贝节点插入到原节点的后面&#x1f369;步骤一代码 &#x1f6a9;步骤二&#xff1a;控制拷贝节点的random进行连接&#x1f369;步骤二代码 &#x1f6a9;步骤三&#xff1a;拷贝节点解…...

基于SSM的小说网站的设计与实现(论文+源码)_kaic

目 录 1 绪论................................................................................................... 1 1.1 项目背景................................................................................................................ 1 1.2 发展历程..…...

【Python】代理池针对ip拦截破解

代理池是一种常见的反反爬虫技术&#xff0c;通过维护一组可用的代理服务器&#xff0c;来在被反爬虫限制的情况下&#xff0c;实现数据的爬取。但是&#xff0c;代理池本身也面临着被目标网站针对ip进行拦截的风险。 本文将详细介绍代理池针对ip拦截破解的方法&#xff0c;包含…...

P1065 [NOIP2006 提高组] 作业调度方案

[NOIP2006 提高组] 作业调度方案 题目描述 我们现在要利用 m m m 台机器加工 n n n 个工件&#xff0c;每个工件都有 m m m 道工序&#xff0c;每道工序都在不同的指定的机器上完成。每个工件的每道工序都有指定的加工时间。 每个工件的每个工序称为一个操作&#xff0c;…...

设计模式三原则

1.1单一职责原则 C 面向对象三大特性之一的封装指的就是将单一事物抽象出来组合成一个类&#xff0c;所以我们在设计类的时候每个类中处理的是单一事物而不是某些事物的集合。 设计模式中所谓的单一职责原则&#xff0c;就是对一个类而言&#xff0c;应该仅有一个引起它变化的原…...

dll载入时发生的事情

dll是什么 DLL 是一个包含可由多个程序同时使用的代码和数据的库。 对于 Windows 操作系统&#xff0c;操作系统的大部分功能都由 DLL 提供。 另外&#xff0c;当您在这些 Windows 操作系统之一上运行某一程序时&#xff0c;该程序的很多功能可能是由 DLL 提供的。 例如&…...

k8s-ingress-context deadline exceeded

报错&#xff1a; rancher-rke-01:~/rke # helm install rancher rancher-latest/rancher --namespace cattle-system --set hostnamewww.rancher.local Error: INSTALLATION FAILED: Internal error occurred: failed calling webhook "validate.nginx.ingress.kube…...

css盒模型

盒模型的组成&#xff1a; content&#xff0c;padding&#xff0c;border&#xff0c;margin 盒模型的分类&#xff1a; 内容盒模型(标准盒模型) — 盒子的宽widthpaddingborder 边框盒模型 — 盒子的宽width 参考 盒模型【CSS面试题】_哔哩哔哩_bilibili...

cuda11.1和cuDNN v8.8.1的安装目录问题

cuda的不同版本文件路径是不一致的&#xff0c;在cuda10.1中&#xff0c;配置cudnn的文件路径是&#xff1a; sudo cp cuda/include/cudnn.h /usr/local/cuda-10.1/include/ sudo cp -P cuda/lib64/libcudnn* /usr/local/cuda-10.1/lib64/但是在cuda11.1中&#xff0c;文件路径…...

微信小程序scroll-view的触发机制

一、scroll-view 可滚动视图区域。使用竖向滚动时&#xff0c;需要给scroll-view一个固定高度&#xff0c;通过 WXSS 设置 height。组件属性的长度单位默认为px&#xff0c;2.4.0起支持传入单位(rpx/px)。 两个属性是作为上拉加载下拉刷新触发事件 scroll-view属性bindrefresh…...