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

使用seata实现分布式事务管理

配置

版本说明:
springCloud Alibaba组件版本关系
我用的是spring cloud Alibaba 2.2.1.RELEASE 、springboot 2.2.1.RELEASE、nacos 2.0.1、seata1.2.0,jdk1.8

seata 主要用于在分布式系统中对数据库进行事务回滚,保证全局事务的一致性。

seata的使用非常简单,主要是在涉及到跨服务调用并且要保证各服务事务的一致性的方法上添加注解@GlobalTransactional即可。重点和难点在seata的配置,因此本篇文章的重点也放在seata的配置上。

特别说明:seata和各组件版本对应关系非常重要,如果引用的seata版本跟springboot,cloud不匹配,会产生各种各样的问题,因此务必引起重视。

一、seata的下载和安装

下载地址:Releases · apache/incubator-seata · GitHub

找到1.2.0版本,拉到Assets部分展开,找到自己需要的安装包并下载。

windows的下载后解压即可。

下面说下docker的安装方式:

#拉取Seata镜像
docker pull seataio/seata-server:1.2.0

#运行镜像
docker run --name seata-server -p 8091:8091 -d  seataio/seata-server:1.2.0

#复制seata的配置文件到主机
docker cp seata-server:/seata-server  /root/seata

#停止删除服务
docker stop seata-server
docker rm seata-server

#重新运行镜像
docker run -d --restart always  --name  seata-server -p 8091:8091  -v /root/seata:/seata-server -e SEATA_IP=192.168.200.131 -e SEATA_PORT=8091 seataio/seata-server:1.2.0

#注意:SEATA_IP、SEATA_PORT 一定要重新指定下,不然用docker自动分配的虚拟ip,服务是访问不到的
 

 以下配置相同,无论是Windows、Linux还是docker,只是配置文件位置不同,下面以Windows为例。

1、修改seata-server-1.2.0\seata\conf\file.conf文件,标红部分是需要修改的,其他部分可忽略或根据个人需要修改。

## transaction log store, only used in seata-server
store {
  ## store mode: file、db
  mode = "db"        #!!!!!!!!!这里改为db

  ## file store property
  file {
    ## store location dir
    dir = "sessionStore"
    # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions
    maxBranchSessionSize = 16384
    # globe session size , if exceeded throws exceptions
    maxGlobalSessionSize = 512
    # file buffer size , if exceeded allocate new buffer
    fileWriteBufferCacheSize = 16384
    # when recover batch read size
    sessionReloadReadSize = 100
    # async, sync
    flushDiskMode = async
  }

  ## database store property
  db {
    ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc.
    datasource = "druid"
    ## mysql/oracle/postgresql/h2/oceanbase etc.
    dbType = "mysql"
    driverClassName = "com.mysql.jdbc.Driver"
    url = "jdbc:mysql://192.168.200.131:3306/seata"    #你的msyql地址
    user = "root"    #用户名
    password = "root"    #密码

    minConn = 5
    maxConn = 30
    globalTable = "global_table"
    branchTable = "branch_table"
    lockTable = "lock_table"
    queryLimit = 100
    maxWait = 5000
  }
}

2、修改seata-server-1.2.0\seata\conf\registry.conf文件

registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  type = "nacos"        #改为nacos

  nacos {
    application = "seata-server"
    serverAddr = "192.168.200.199"        #nacos注册中心地址
    namespace = ""
    cluster = "default"
    username = "nacos"        #nacos用户名
    password = "nacos"        #nacos密码

  }
  eureka {
    serviceUrl = "http://localhost:8761/eureka"
    application = "default"
    weight = "1"
  }
  redis {
    serverAddr = "localhost:6379"
    db = 0
    password = ""
    cluster = "default"
    timeout = 0
  }
  zk {
    cluster = "default"
    serverAddr = "127.0.0.1:2181"
    sessionTimeout = 6000
    connectTimeout = 2000
    username = ""
    password = ""
  }
  consul {
    cluster = "default"
    serverAddr = "127.0.0.1:8500"
  }
  etcd3 {
    cluster = "default"
    serverAddr = "http://localhost:2379"
  }
  sofa {
    serverAddr = "127.0.0.1:9603"
    application = "default"
    region = "DEFAULT_ZONE"
    datacenter = "DefaultDataCenter"
    cluster = "default"
    group = "SEATA_GROUP"
    addressWaitTime = "3000"
  }
  file {
    name = "file.conf"
  }
}

config {
  # file、nacos 、apollo、zk、consul、etcd3
  type = "nacos"        #!!!!!!!!!改为nacos

  nacos {
    serverAddr = "192.168.200.199"        #!!!!!!!!!配置中心地址
    namespace = "" #配置所在的命名空间,不配置就是public
    group = "SEATA_GROUP"
    username = "nacos"        #!!!!!!!!!用户名
    password = "nacos"        #!!!!!!!!!密码
  }
  consul {
    serverAddr = "127.0.0.1:8500"
  }
  apollo {
    appId = "seata-server"
    apolloMeta = "http://192.168.1.204:8801"
    namespace = "application"
  }
  zk {
    serverAddr = "127.0.0.1:2181"
    sessionTimeout = 6000
    connectTimeout = 2000
    username = ""
    password = ""
  }
  etcd3 {
    serverAddr = "http://localhost:2379"
  }
  file {
    name = "file.conf"
  }
}

 3、首先启动Nacos服务,然后再启动Seata,查看nacos服务注册中心是否注册上了Seata

双击上图圈中的bat文件,如果一切正常,将会看到started的提示,如果双击后闪退,可采用cmd的方式打开,即可看到启动失败的原因。比如jdk版本和seata版本不对应也会导致闪退。我的jdk最初是17,跟seata不对应,后面提示信息后,调整为jdk8就可正常启动了。说句题外话,jdk17安装后无需进行环境变量配置,并且会将本机的jre设置为最新的版本17。

nacos查看seata是否注册进来:

默认在public的命名空间下,端口号是8091。

二、搭建Seata运行环境

1、在mysql数据库中创建名为seata的库,并创建以下3张数据表

-- -------------------------------- The script used when storeMode is 'db' --------------------------------
-- the table to store GlobalSession data
CREATE TABLE IF NOT EXISTS `global_table`
(`xid`                       VARCHAR(128) NOT NULL,`transaction_id`            BIGINT,`status`                    TINYINT      NOT NULL,`application_id`            VARCHAR(32),`transaction_service_group` VARCHAR(32),`transaction_name`          VARCHAR(128),`timeout`                   INT,`begin_time`                BIGINT,`application_data`          VARCHAR(2000),`gmt_create`                DATETIME,`gmt_modified`              DATETIME,PRIMARY KEY (`xid`),KEY `idx_gmt_modified_status` (`gmt_modified`, `status`),KEY `idx_transaction_id` (`transaction_id`)
) ENGINE = InnoDBDEFAULT CHARSET = utf8;-- the table to store BranchSession data
CREATE TABLE IF NOT EXISTS `branch_table`
(`branch_id`         BIGINT       NOT NULL,`xid`               VARCHAR(128) NOT NULL,`transaction_id`    BIGINT,`resource_group_id` VARCHAR(32),`resource_id`       VARCHAR(256),`branch_type`       VARCHAR(8),`status`            TINYINT,`client_id`         VARCHAR(64),`application_data`  VARCHAR(2000),`gmt_create`        DATETIME(6),`gmt_modified`      DATETIME(6),PRIMARY KEY (`branch_id`),KEY `idx_xid` (`xid`)
) ENGINE = InnoDBDEFAULT CHARSET = utf8;-- the table to store lock data
CREATE TABLE IF NOT EXISTS `lock_table`
(`row_key`        VARCHAR(128) NOT NULL,`xid`            VARCHAR(96),`transaction_id` BIGINT,`branch_id`      BIGINT       NOT NULL,`resource_id`    VARCHAR(256),`table_name`     VARCHAR(32),`pk`             VARCHAR(36),`gmt_create`     DATETIME,`gmt_modified`   DATETIME,PRIMARY KEY (`row_key`),KEY `idx_branch_id` (`branch_id`)
) ENGINE = InnoDBDEFAULT CHARSET = utf8;

 2、要在参与全局事务的每个数据库中都加入undo_log这张表

-- for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE IF NOT EXISTS `undo_log`
(`id`            BIGINT(20)   NOT NULL AUTO_INCREMENT COMMENT 'increment id',`branch_id`     BIGINT(20)   NOT NULL COMMENT 'branch transaction id',`xid`           VARCHAR(100) NOT NULL COMMENT 'global transaction id',`context`       VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',`rollback_info` LONGBLOB     NOT NULL COMMENT 'rollback info',`log_status`    INT(11)      NOT NULL COMMENT '0:normal status,1:defense status',`log_created`   DATETIME     NOT NULL COMMENT 'create datetime',`log_modified`  DATETIME     NOT NULL COMMENT 'modify datetime',PRIMARY KEY (`id`),UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDBAUTO_INCREMENT = 1DEFAULT CHARSET = utf8 COMMENT ='AT transaction mode undo table';

 3、从官方github仓库拿到参考配置做修改 incubator-seata/script/client/spring at develop · apache/incubator-seata · GitHub
加到你项目的application.yml中,红色部分需修改为自己的应用名。

seata:
  enabled: true
  application-id: shopping-mall
  tx-service-group: my_test_tx_group
  enable-auto-data-source-proxy: true
  config:
    type: nacos
    nacos:
      namespace:
      serverAddr: 127.0.0.1:8848
      group: SEATA_GROUP
      userName: "nacos"
      password: "nacos"
  registry:
    type: nacos
    nacos:
      application: seata-server
      server-addr: 127.0.0.1:8848
      namespace:
      userName: "nacos"
      password: "nacos"

 

 4、由于Seata1.2.0支持从Nacos读取配置,所以我们还需要一个bootstrap.yml读取配置信息

#Nacos同springcloud-config-样, 在项目初始化时,要保证先从配置中心进行配置拉取,拉取配置之后,才能保证项目的正常启动。
#springboot中配置文件的加载是存在优先级顺序的,bootstrap优先级高于application

#当前服务端口号
server:
  port: 2002

spring:
  application:
    name: seata-storage-service #当前服务名称
  main:
    allow-bean-definition-overriding: true
  cloud:
    loadbalancer:
      retry:
        enabled: false
    nacos:
      discovery:
        server-addr: 192.168.200.199 #通过虚拟IP访问Nginx主服务器,然后反向代理到其中一台nacos注册中心
      config:
        server-addr: 192.168.200.199 #通过虚拟IP访问Nginx主服务器,然后反向代理到其中一台nacos配置中心

#设置feign客户端超时时间(OpenFeign默认支持ribbon)
ribbon:
  ReadTimeout: 5000 #指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
  connectTimeout: 5000  #指的是建立连接后从服务器读取到可用资源所用的时间
 

 在需要用到seata的服务添加上依赖

  <!--SpringCloudAlibaba的seata分布式事务管理-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-seata</artifactId>
            <version>2.2.0.RELEASE</version>
             <!--需要排除掉自带的seata-spring-boot-starter,否则无法启动,并提示jar冲突-->
                ​​​<exclusions>
                <exclusion>
                    <groupId>io.seata</groupId>
                    <artifactId>seata-spring-boot-starter</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--指定与安装的seata版本一致,重要!-->
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-spring-boot-starter</artifactId>
            <version>1.2.0</version>
        </dependency>

jar引用这里还需要注意,如果只引入下面的依赖,将不能实现事务回滚,seata 1.2版本需要引用spring-cloud-starter-alibaba-seata依赖。这个依赖里才有xid传递的功能。 seata-spring-boot-starter依赖并没有xid传递的功能。spring-cloud-alibaba-seata需要和seata-spring-boot-starter一起引入并注意它们的版本对应关系,并在此之前引入nacos注册和配置中心的依赖。

        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-spring-boot-starter</artifactId>
            <version>1.2.0</version>
        </dependency>

 6、将Seata项目克隆或下载到本地 GitHub - apache/incubator-seata: :fire: Seata is an easy-to-use, high-performance, open source distributed transaction solution.

 重点是下面红色标记的文件:

下载到本地后进入\seata\script\config-center目录修改config.txt为以下内容:

service.vgroupMapping.my_test_tx_group=default
store.mode=db
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.jdbc.Driver
store.db.url=jdbc:mysql://192.168.200.131:3306/seata?useUnicode=true   
store.db.user=root
store.db.password=root

store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000

 

 运行仓库中提供的nacos脚本,将以上信息提交到nacos控制台,如果有需要更改,可直接通过控制台更改。如果电脑中安装有git,双击后在弹出的窗口中选择使用git运行sh命令,就会看到seata的配置同步到nacos配置中心。

 注意:如果你的nacos地址不是本机,需要修改脚本nacos-config.sh,他是默认使用本机nacos的,修改地方如下

 

 导入完成后,在nacos配置中心,即可看到导入的配置文件,都归到SEATA_GROUP组下,足足有7页之多

三、测试事务是否成功

经过以上配置,就可以验证seata是否生效了

    @GlobalTransactional@Transactional@Overridepublic SubmitOrderResponseVo submitOrder(OrderSubmitVo orderSubmitVo) {System.out.println("seata分布式事务id:"+RootContext.getXID());//用于在同一线程共享数据,减少方法传参confirmVoThreadLocal.set(orderSubmitVo);SubmitOrderResponseVo responseVo=new SubmitOrderResponseVo();responseVo.setCode(0);MemberRespVo memberRespVo = LoginUserInterceptor.localUser.get();String redisOrderKey=OrderConstants.USER_TOKEN_PREFIX + memberRespVo.getId();String redisToken = stringredisTemplate.opsForValue().get(redisOrderKey);//验证提交的令牌与后台令牌是否一致//验证的逻辑【验证令牌和删除令牌要保证原子性】String orderToken = orderSubmitVo.getOrderToken();// 使用lua脚本解锁,保证原子性 0 验证失败 1 验证并删除成功String script = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";//原子验证令牌,若成功则删除令牌,保证订单提交的幂等性Long result = stringredisTemplate.execute(new DefaultRedisScript<Long>(script, Long.class), Arrays.asList(redisOrderKey), orderToken);if(result==0L){//验证失败,直接返回responseVo.setCode(1);return responseVo;}else {//令牌验证成功,执行创建订单等业务流程OrderCreateTo order = createOrder();//验价//1.后台计算的价格BigDecimal payPrice = order.getOrder().getPayAmount();//2.前端提交的价格BigDecimal payPrice1 = orderSubmitVo.getPayPrice();//不用比较相等,只需前端和后台价格相差的绝对值小于0.01元即1分,即视为相等if(Math.abs(payPrice.subtract(payPrice1).doubleValue())<0.01){//3、创建订单saveOrder(order);//订单创建成功后立即锁定库存,防止缺货WareSkuLockVo lockVo=new WareSkuLockVo();lockVo.setOrderSn(order.getOrder().getOrderSn());List<OrderItemVo> orderItemVos = order.getOrderItems().stream().map(item -> {OrderItemVo orderItemVo = new OrderItemVo();orderItemVo.setSkuId(item.getSkuId());orderItemVo.setTitle(item.getSkuName());orderItemVo.setCount(item.getSkuQuantity());return orderItemVo;}).collect(Collectors.toList());lockVo.setLocks(orderItemVos);//4、远程锁库存R r = wmsFeignService.lockStock(lockVo);if(r.getCode()==0){//锁定库存成功responseVo.setOrder(order.getOrder());int i=10/0;return responseVo;}else{//锁定库存失败throw new NoStockException(1L);// responseVo.setCode(3);// return responseVo;}}else{//价格不相等返回2responseVo.setCode(2);return responseVo;}}}

上面的代码中,我在订单服务中保存订单的方法中添加了@GlobalTransactional注解,该服务远程调用了库存服务的wmsFeignService.lockStock(lockVo)的方法,实现当订单创建成功扣减库存,为了模拟发生异常实现全局事务回滚,在扣减库存处添加了以下代码:

int i=10/0;

 当前在订单服务,由于我们添加了@Transactional注解,异常发生时触发订单服务数据回滚,而库存服务属于远程调用的服务,数据在另一个数据库中,此时实现库存服务事务回滚依靠的就是seata了,通过引入@GlobalTransactional来实现。来看控制台,实现了库存服务的数据回滚。

这里还有一个地方需要注意,只需要在当前服务的方法上添加@GlobalTransactional注解,远程调用的库存服务无需添加该注解,只需要添加@Transactional即可。

seata回滚成功后会将业务数据恢复到方法调用前的样子,同时seata数据库中的global_table等表格中的数据也会清除,如果想查看seata操作数据的流程,可在业务方法上添加断点调试,就可看到中途的数据演变,下面是global_table在方法执行时seata插入的一条数据:

注意:上面的seata使用的是AT模式保证全局事务的一致性,在高并发情景下可能并不适用。

 本文参考自:Seata1.2.0安装配置Nacos注册配置中心,以及实际运行案例_seata 1.2.0-CSDN博客

向原博主表示感谢!

相关文章:

使用seata实现分布式事务管理

配置 版本说明&#xff1a;springCloud Alibaba组件版本关系 我用的是spring cloud Alibaba 2.2.1.RELEASE 、springboot 2.2.1.RELEASE、nacos 2.0.1、seata1.2.0,jdk1.8 seata 主要用于在分布式系统中对数据库进行事务回滚&#xff0c;保证全局事务的一致性。 seata的使用…...

【机器学习】深度学习(DNN)

文章目录 1. 神经网络结构2. 训练步骤3. 反向传播4. 为什么深&#xff0c;而不是宽&#xff08;模块化&#xff09;5. 初始化参数能否全为0&#xff1f; 1. 神经网络结构 输入层隐藏层&#xff1a;用于特征转换输出层&#xff1a;用于分类技巧&#xff1a;将网络中的参数写成矩…...

C++ 设计模式:门面模式(Facade Pattern)

链接&#xff1a;C 设计模式 链接&#xff1a;C 设计模式 - 代理模式 链接&#xff1a;C 设计模式 - 中介者 链接&#xff1a;C 设计模式 - 适配器 门面模式&#xff08;Facade Pattern&#xff09;是一种结构型设计模式&#xff0c;它为子系统中的一组接口提供一个一致&#…...

自动化测试之Pytest框架(万字详解)

Pytest测试框架 一、前言二、安装2.1 命令行安装2.2 验证安装 三、pytest设计测试用例注意点3.1 命名规范3.2 断言清晰3.3 fixture3.4 参数化设置3.5 测试隔离3.6 异常处理3.7 跳过或者预期失败3.8 mocking3.9 标记测试 四、以案例初入pytest4.1 第一个pytest测试4.2 多个测试分…...

YOLOv10-1.1部分代码阅读笔记-conv.py

conv.py ultralytics\nn\modules\conv.py 目录 conv.py 1.所需的库和模块 2.def autopad(k, pNone, d1): 3.class Conv(nn.Module): 4.class Conv2(Conv): 5.class LightConv(nn.Module): 6.class DWConv(Conv): 7.class DWConvTranspose2d(nn.ConvTranspose2d)…...

大模型-Ollama使用相关的笔记

大模型-Ollama使用相关的笔记 解决Ollama外网访问问题&#xff08;配置ollama跨域访问&#xff09;Postman请求样例 解决Ollama外网访问问题&#xff08;配置ollama跨域访问&#xff09; 安装Ollama完毕后&#xff0c; /etc/systemd/system/ollama.service进行如下修改&#…...

【机器学习】概述

文章目录 1. 机器学习三步骤2. 机器学习图谱2.1 任务类型 (Task)2.2 模型选择 (Methods)2.3 学习场景 (Scenario) 1. 机器学习三步骤 定义一个模型 (Define a set of function) 选择一组合适的函数来表示模型。 评估模型好坏 (Goodness of function) 找到一个损失函数&#xf…...

什么是网络安全(Cybersecurity)?

不同组织机构对网络安全&#xff08;Cybersecurity或Cyber Security&#xff09;的定义不尽相同。从目标上来说&#xff0c;网络安全主要用于保护网络、计算机、移动设备、应用程序及数据等资产免受网络攻击&#xff0c;避免造成数据泄露、业务中断等安全问题。 网络钓鱼、勒索…...

3_TCP/IP连接三次握手与断开四次挥手

TCP/IP 通信是网络通信的基础协议&#xff0c;分为以下主要步骤&#xff1a; 1、建立连接&#xff08;三次握手&#xff09; 目的&#xff1a;保证双方建立可靠的通信连接。 过程&#xff1a; 1>客户端发送 SYN&#xff1a;客户端向服务器发送一个 SYN&#xff08;同步&…...

基于单片机的电梯模拟控制系统

摘要: 文章主要针对基于单片机的电梯模拟控制系统进行研究,指出基于单片机的电梯模拟控制系统应用优点,并在此基础上介绍单片机控制技术,分析单片机在电梯模拟控制系统中的具体应用。 关键词: 单片机;电梯;模拟控制系统 1 基于单片机的电梯模拟控制系统应用优点概述 1…...

区块链安全常见的攻击——ERC777 重入漏洞 (ERC777 Reentrancy Vulnerability)【5】

区块链安全常见的攻击分析——ERC777 重入漏洞 ERC777 Reentrancy Vulnerability【5】 区块链安全常见的攻击合约和简单复现&#xff0c;附带详细分析——ERC777 重入漏洞 (ERC777 Reentrancy Vulnerability)【5】1.1 漏洞合约1.2 漏洞分析1.3 攻击分析1.4 攻击合约1.5 hardhat…...

MusicFree - 免费播放全网歌曲!无广告开源网络音乐聚合播放器 (安卓电脑版)

大家平常听歌可能都会在 QQ 音乐、网易云音乐、酷狗、喜马拉雅等不同平台来回切换&#xff0c;体验其实很烦。曾经推荐过不少“聚合”音乐应用&#xff0c;比如 洛雪音乐助手、Listen1 等等。 最近又有一个新选择了&#xff01;MusicFree 是一款免费开源清爽无广告的音乐播放器…...

html+css+js网页设计 美食 美拾9个页面

htmlcssjs网页设计 美食 美拾9个页面 网页作品代码简单&#xff0c;可使用任意HTML辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 1&#xff0…...

RustDesk内置ID服务器,Key教程

RustDesk内置ID服务器&#xff0c;Key教程 首先需要准备一个域名&#xff0c;并将其指定到你的 rustdesk 服务器 ip 地址上&#xff0c;这里编译采用的是Github Actions &#xff0c;说白了是就workflows&#xff0c;可以创建一些自动化的工作流程&#xff0c;例如代码的检查&a…...

Python学生管理系统(MySQL)

上篇文章介绍的Python学生管理系统GUI有不少同学觉得不错来找博主要源码&#xff0c;也有同学提到老师要增加数据库管理数据的功能&#xff0c;本篇文章就来介绍下python操作数据库&#xff0c;同时也对上次分享的学生管理系统进行了改进了&#xff0c;增加了数据库&#xff0c…...

Spring Boot 学习笔记

学习代码第一步&#xff1a;如何写 Hello world &#xff1f; 1、新建项目 新建一个 Maven Java 工程&#xff0c;在 pom.xml 文件中添加 Spring Boot Maven 依赖&#xff1a; <parent><groupId>org.springframework.boot</groupId><artifactId>spri…...

UML统一建模语言测试题汇总

2-UML概念模型测试 (单选题, 1.0 分) UML中的关系不包括&#xff08;&#xff09;。 A. 抽象 B. 实现 C. 依赖 D. 关联 我的答案:A正确答案: A 知识点&#xff1a; UML的构成 1.0分 (单选题, 1.0 分) 下列事物不属于UML结构事物的是&#xff08;&#xff09;。 A. 组件 B.…...

【微服务】SpringBoot 自定义消息转换器使用详解

目录 一、前言 二、SpringBoot 内容协商介绍 2.1 什么是内容协商 2.2 内容协商机制深入理解 2.2.1 内容协商产生的场景 2.3 内容协商实现的常用方式 2.3.1 前置准备 2.3.2 通过HTTP请求头 2.3.2.1 操作示例 2.3.3 通过请求参数 三、SpringBoot 消息转换器介绍 3.1 H…...

数据结构(哈希表(中)纯概念版)

前言 哈希表&#xff08;Hash Table&#xff09;是计算机科学中的一个基础而重要的数据结构&#xff0c;它广泛评估各种算法和系统中&#xff0c;尤其是在需要快速查找、插入和删除操作的场景中。由于其O( 1)的平均时间复杂度&#xff0c;存储表在性能要求较高的应用中表现得非…...

Node.js 工具:在 Windows 11 中配置 Node.js 的详细步骤

一、概述 记录时间 [2024-12-25] 本文讲述如何在 Windows 11 中进行 Node.js 工具的安装和配置。 以下是详细的步骤和说明。 二、安装 Node.js 1. 官网下载 通过官网&#xff0c;下载 Node.js&#xff0c;上面有好几种下载方式&#xff0c;文中下载的是 zip 压缩包。 如图&…...

工作流并行网关退回思路

问题描述 在设计工作流时遇到并行的流程&#xff0c;会出现并行流程的退回&#xff0c;这里记录下想到的解决思路&#xff0c;后续问题会记录在这里。 流程图 这里是一个简单的流程图&#xff1a; 并行退回思路 若是正常流程退回&#xff0c;流程是&#xff1a; 获取回退…...

C#数学相关开发性能优化方法

本文Github地址&#xff1a;CSharp-MathOptimization.md 华为公司的C语言编程规范在开头就强调了&#xff1a; 一般情况下&#xff0c;代码的可阅读性高于性能&#xff0c;只有确定性能是瓶颈时&#xff0c;才应该主动优化。 本文讲述的方法没有经过大项目和大公司的检验&…...

vulnhub jangow靶机

1.扫描靶机IP arp-scan -l如果扫不到靶机的话根据以下配置 启动时点击第二个 按回车 继续选择第二个 按e进入编辑 删除"recovery nomodeset" 在末尾添加"quiet splash rw init/bin/bash" Ctrlx 启动进入如下界面 passwd修改root密码 重启电脑登录root修…...

配置搜索无人机

升级ubuntu内核 https://www.bilibili.com/video/BV11X4y1h7qN/?spm_id_from333.337.search-card.all.click 进入四个内核文件并安装 sudo dpkg -i *.deb安装ROS&#xff0c;PX4&#xff0c;XTDrone&#xff0c;QGC https://blog.csdn.net/qq_45493236/article/details/13…...

2-6-1-1 QNX编程入门之进程和线程(四)

阅读前言 本文以QNX系统官方的文档英文原版资料“Getting Started with QNX Neutrino: A Guide for Realtime Programmers”为参考&#xff0c;翻译和逐句校对后&#xff0c;对在QNX操作系统下进行应用程序开发及进行资源管理器编写开发等方面&#xff0c;进行了深度整理&…...

Vue开发环境搭建上篇:安装NVM和NPM(cpnm、pnpm)

文章目录 引言I 安装NVM1.1 Windows系统安装NVM,实现Node.js多版本管理1.2 配置下载镜像1.3 NVM常用操作命令II NPM永久使用淘宝源安装 cnpm安装pnpm【推荐】see also: vscode常用插件引言 淘宝镜像:http://npm.taobao.org 和 http://registry.npm.taobao.org 已在 2022.06.3…...

2.微服务灰度发布落地实践(agent实现)

文章目录 前言java agent的介绍基础实现agent端 http服务实现agent端api接口 前言 据上一篇&#xff0c;设计方案的分析&#xff0c;综合考虑&#xff0c;最终决定,客户端采用agent方案实现&#xff0c;具本原因不再赘述&#xff0c; 感觉兴趣的小伙伴可以回头了解一下.该篇主…...

网络安全专业术语

网络安全专有名词详解 1.肉鸡 被黑客操控的终端设备&#xff08;电脑、服务器、移动设备等等&#xff09;&#xff0c;黑客可以随心所欲的操作这些终端设备而不会被发觉。 2.木马 表面上伪装成正常的程序&#xff0c;但是当这些程序运行时候就会获取整个系统的控制权限&#…...

SpringMVC核心、两种视图解析方法、过滤器拦截器 “ / “ 的意义

SpringMVC的执行流程 1. Spring MVC 的视图解析机制 Spring MVC 的核心职责之一是将数据绑定到视图并呈现给用户。它通过 视图解析器&#xff08;View Resolver&#xff09; 来将逻辑视图名称解析为具体的视图文件&#xff08;如 HTML、JSP&#xff09;。 核心流程 Controlle…...

ubuntu快速入门

1.进入某个文件夹 cd workspace/2.tab自动补全 3.列出当前文件夹所有文件 ls列出所有文件包括隐藏文件 ls -a 4.创建文件夹 mkdir linuxLearn 5.创建文件 gedit command.sh在commmand.sh键入 echo hello echo hi? echo how are you? PS:touch hello.txt(也可以创建新…...

HarmonyOS NEXT应用开发实战:一分钟写一个网络接口,JsonFormat插件推荐

在开发鸿蒙操作系统应用时&#xff0c;网络接口的实现往往是一个繁琐且重复的过程。为了提高开发效率&#xff0c;坚果派(nutpi.net)特别推出了一个非常实用的插件——JsonFormat。这款插件的主要功能是将JSON格式的数据直接转换为arkts的结构定义&#xff0c;让我们在编写接口…...

光谱相机与普通相机的区别

一、成像目的 普通相机&#xff1a;主要目的是记录物体的外观形态&#xff0c;生成人眼可见的、直观的二维图像&#xff0c;重点在于还原物体的形状、颜色和纹理等视觉特征&#xff0c;以供人们进行观赏、记录场景或人物等用途。例如&#xff0c;拍摄旅游风景照片、人物肖像等…...

贝叶斯神经网络(Bayesian Neural Network)

最近在研究贝叶斯神经网络,一些概念一直搞不清楚,这里整理一下相关内容,方便以后查阅。 贝叶斯神经网络(Bayesian Neural Network) 贝叶斯神经网络(Bayesian Neural Network)1. BNN 的核心思想2. BNN 的优化目标3. BNN 的结构与特点4. BNN 的训练过程5. BNN 的优缺点6. …...

使用FFmpeg进行拉流和推流操作

FFmpeg是一款强大的多媒体处理工具&#xff0c;可以用于视频的录制、转换、推流和拉流等操作。下面将详细介绍如何使用FFmpeg进行拉流和推流操作。 1. FFmpeg推流操作 推流是将本地的音视频流推送到流媒体服务器上&#xff0c;例如主播将本地电脑上的画面推流到直播平台的流媒…...

flutter插件开发-ios

flutter插件开发是一个重要的技能&#xff0c;拓展flutter与原生的通信&#xff0c;将一些公用的东西封装&#xff0c;给不同的项目使用。 阅读前置&#xff1a; flutter基本通道调用 objective-c基础语法 ios项目基础知识 目录 1、创建一个插件项目2、项目结构3、编写原生代码…...

【代码随想录|完全背包问题】

518.零钱兑换|| 题目链接&#xff1a;518. 零钱兑换 II - 力扣&#xff08;LeetCode&#xff09; 这里求的是组合数&#xff0c;就是不强调元素排列的顺序&#xff0c;211和121是同一个数那种&#xff0c;要先遍历物品&#xff0c;这样的话我算出来的每个值才是按顺序121&…...

xss csrf怎么预防?

一、XSS&#xff08;跨站脚本攻击&#xff09;预防 XSS 是指攻击者向目标网站注入恶意脚本&#xff0c;从而在用户浏览器中执行。 1. 输入过滤 清理用户输入&#xff1a; 拦截或清理HTML特殊字符&#xff08;如 <, >, , ", &&#xff09;。使用安全库&#x…...

黑神话悟空游戏鼠标光标使用教程与下载

效果图&#xff1a; 鼠标光标特点 这套鼠标光标的设计灵感来源于《黑神话&#xff1a;悟空》游戏中的角色和元素&#xff0c;具有以下特点&#xff1a; • 主题鲜明&#xff1a;光标设计紧扣游戏主题&#xff0c;采用了游戏中的元素&#xff0c;让玩家在使用电脑时也能感受到…...

<数据集>芝麻作物和杂草识别数据集<目标检测>

数据集下载链接 &#xff1c;数据集&#xff1e;芝麻作物和杂草识别数据集&#xff1c;目标检测&#xff1e;https://download.csdn.net/download/qq_53332949/90181548数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;1300张 标注数量(xml文件个数)&#xff1a;130…...

实测数据处理(CS算法处理:可斜视)——SAR成像算法系列(十一)

系列文章目录 《SAR学习笔记-SAR成像算法系列&#xff08;一&#xff09;》 《线性调频变标算法&#xff08;CSA&#xff09;-SAR成像算法系列&#xff08;四&#xff09;》 文章目录 前言 一、算法流程 1.1、回波信号生成 1.2、CS处理 1.3、距离脉压 1.4、方位脉压 1.5…...

【强化学习入门笔记】 2.4 时序差分算法

本系列为学习赵世钰老师的《强化学习的数学原理》所作的学习笔记. 本节我们将介绍强化学习中的蒙特卡洛方法. 2.4.1 Robbins-Monro算法 Robbins-Monro算法是一种随机近似方法&#xff0c;通过迭代的方式求解非线性方程。 假设我们要求解: g ( w ) 0 g(w)0 g(w)0, 但是我们…...

Scrapy数据解析+保存数据

Scrapy数据解析保存数据 目录 1.数据解析 2.基于item存放数据并提交给管道 3.用txt文件来保存数据 今天我们需要爬取B站数据并保存到txt文件里面。 我们先打开B站, 然后点击热门, 进去之后再点击排行榜: 我们打开F12后, 可以看到, 我们想要的请求, 轻而易举的就可以拿到(…...

Redis--缓存穿透、击穿、雪崩以及预热问题(面试高频问题!)

缓存穿透、击穿、雪崩以及预热问题 如何解决缓存穿透&#xff1f;方案一&#xff1a;缓存空对象方案二&#xff1a;布隆过滤器什么是布隆过滤器&#xff1f;优缺点 方案三&#xff1a;接口限流 如何解决缓存击穿问题&#xff1f;方案一&#xff1a;分布式锁方案一改进成双重判定…...

【Python高级353】python实现多线程版本的TCP服务器

前面学了了套接字编程、tcp服务端客户端开发、面向对象版的服务端客户端、带有端口复用的服务端。 这里使用多线程开发多任务版的服务端 多任务版本的TCP服务器 来一个客户&#xff0c;就为其创建一个线程 import socket import threadingclass WebServer:# 3、定义一个__ini…...

【Pandas】pandas Series to_period

Pandas2.2 Series Conversion 方法描述Series.astype用于将Series对象的数据类型转换为指定类型的方法Series.convert_dtypes用于将 Series 对象的数据类型智能地转换为最佳可能的数据类型的方法Series.infer_objects用于尝试推断 Series 中对象&#xff08;object&#xff0…...

深度学习领域车辆识别与跟踪

深度学习中车辆识别是一个广泛应用的领域&#xff0c;它涵盖了从车辆检测到车型识别的多个方面。以下是对深度学习中车辆识别与车辆相关内容的详细探讨&#xff1a; 一、车辆检测 车辆检测是车辆识别中的基础任务&#xff0c;其目标是在图像或视频中准确地定位出车辆的位置。…...

数学建模 绘图 图表 可视化(2)

文章目录 前言柱形图条形图克利夫兰点图系列坡度图南丁格尔玫瑰图径向柱图极坐标图词云图总结参考资料 前言 承接上期 数学建模 绘图 图表 可视化&#xff08;1&#xff09;的总体描述&#xff0c;这期我们继续跟随《Python 数据可视化之美 专业图表绘制指南》步伐来学习其中l…...

vue源码分析(十)—— 生命周期

文章目录 前言一、关键方法 callHook二、详细的钩子函数说明1.beforeCreate和create2.beforeMount & mounted注意点组件&#xff08;非根组件&#xff09;的渲染节点&#xff08;1&#xff09;invokeInsertHook函数&#xff08;2&#xff09;insert方法&#xff08;3&#…...

[创业之路-222]:波士顿矩阵与GE矩阵在业务组合选中作用、优缺点比较

目录 一、波士顿矩阵 1、基本原理 2、各象限产品的定义及战略对策 3、应用 4、优点与局限性 二、技术成熟度模型与产品生命周期模型的配对 1、技术成熟度模型 2、产品生命周期模型 3、技术成熟度模型与产品生命周期模型的配对 三、产品生命周期与产品类型的对应关系 …...

# 【超全面了解鸿蒙生命周期】-生命周期补充

【超全面了解鸿蒙生命周期】-生命周期补充 鸿蒙所有的生命周期函数梳理 文章目录 【超全面了解鸿蒙生命周期】-生命周期补充前言一、AbilityStage的生命周期二、ExtensionAbility卡片生命周期三、Web组件常用生命周期 前言 本文是继之前写的生命周期函数梳理的进一步补充&…...