使用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 = InnoDB
  DEFAULT 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 = InnoDB
  DEFAULT 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 = InnoDB
  DEFAULT 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 = InnoDB
  AUTO_INCREMENT = 1
  DEFAULT 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
    @Override
    public 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{
                //价格不相等返回2
                responseVo.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博客

向原博主表示感谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/945126.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

前端node.js

一.什么是node.js 官网解释:Node.js 是一个开源的、跨平台的 JavaScript 运行时环境。 二.初步使用node.js 需要区分开的是node.js和javascript互通的只有console和定时器两个API. 三.Buffer Buffer 是一个类似于数组的对象&#xff0c;用于表示固定长度的字节序列。 Buffer…

LoRA微调系列笔记

系列文章目录 第一章&#xff1a;LoRA微调系列笔记 第二章&#xff1a;Llama系列关键知识总结 第三章&#xff1a;LLaVA模型讲解与总结 文章目录 系列文章目录LoRA&#xff1a;Low-Rank Adaptation of Large Language Models目的&#xff1a;依据&#xff1a;优势&#xff1a;…

khadas edge2安装ubuntu22.04与ubuntu20.04 docker镜像

khadas edge2安装ubuntu22.04与ubuntu20.04 docker镜像 一、资源准备1.1 镜像文件1.2 刷机工具1.3 ubuntu20.04 docker镜像&#xff08;具备demon无人机所需各种驱动&#xff09; 二、开始刷机&#xff08;安装ubuntu22.04系统&#xff09;2.1 进入刷机状态2.2 刷机 三、docker…

PhPMyadmin-cms漏洞复现

一.通过日志文件拿Shell 打开靶场连接数据库 来到sql中输入 show global variables like %general%; set global general_logon; //⽇志保存状态开启&#xff1b; set global general_log_file D:/phpstudy/phpstudy_pro/WWW/123.php //修改日志保存位置 show global varia…

FPGA流水线考虑因素

流水线考虑因素 另一种提升性能的方法是对拥有多个逻辑级数的长数据路径进行重新组织&#xff0c;并将其分配在多个时钟周期上。这种方法 以时延和流水线开销逻辑管理为代价&#xff0c;来达到加快时钟周期和提高数据吞吐量的目的。 由于 FPGA 器件带有大量的寄存器&#x…

语言模型的革命:大型概念模型(LCM)的崛起

在人工智能领域&#xff0c;Meta最近推出的一项重大突破正在引起研究人员和开发者的广泛关注&#xff1a;大型概念模型&#xff08;Large Concept Models&#xff0c;简称LCM&#xff09;。这一创新彻底改变了我们对语言模型的理解&#xff0c;并为未来AI技术的进展指明了新的方…

郴州年夜饭大数据分析:Python爬虫的美味之旅

在春节这个阖家团圆的日子里&#xff0c;年夜饭无疑是最具仪式感的一餐。郴州&#xff0c;这座美食之城&#xff0c;其年夜饭的餐桌上自然少不了那些让人垂涎三尺的地道美食。作为一名热爱美食的程序员&#xff0c;我决定用Python爬虫技术&#xff0c;为大家揭秘郴州年夜饭的必…

STM32-笔记17-PWM波型

一、介绍 PWM波形&#xff08;Pulse Width Modulation&#xff0c;脉冲宽度调制波形&#xff09;是一种占空比可变的脉冲波形。这种调制方式通过改变脉冲的宽度来控制电路中的信号强度和频率。具体来说&#xff0c;PWM波形中的高电平持续时间和低电平持续时间可以根据需要进行调…

HTML——16.相对路径

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title></head><body><a href"../../fj1/fj2/c.html" target"_blank">链接到c</a><!--相对路径&#xff1a;-->…

【学生管理系统】整合JWT(完)

目录 5. 整合JWT 5.1 生成Token 5.2 携带Token 5.2.1 保存token 5.2.2 携带token 5.3 校验Token 5.4 获得Token 5. 整合JWT 5.1 生成Token 用户登录成功后&#xff0c;通过工具类&#xff0c;将用户信息转换成token 步骤&#xff1a; 拷贝工具类&#xff0c;及其Prop…

java计算机毕设课设—商品供应管理系统(附源码、文章、相关截图、部署视频)

这是什么系统&#xff1f; 资源获取方式再最下方 java计算机毕设课设—商品供应管理系统(附源码、文章、相关截图、部署视频) 项目名称&#xff1a; 基于Java的商品供应管理系统 一、项目介绍 项目背景&#xff1a; 在现代商业活动中&#xff0c;商品供应管理是企业运营的…

ipad如何直连主机(Moonlight Sunshine)

Windows 被连接主机&#xff08;Windows&#xff09; 要使用的话需要固定ip&#xff0c;不然ip会换来换去&#xff0c;固定ip方法本人博客有记载Github下载Sunshine Sunshine下载地址除了安装路径需要改一下&#xff0c;其他一路点安装完成后会打开Sunshine的Web UI&#xff…

B站推荐模型数据流的一致性架构

01 背景 推荐系统的模型&#xff0c;通过学习用户历史行为来达到个性化精准推荐的目的&#xff0c;因此模型训练依赖的样本数据&#xff0c;需要包括用户特征、服务端推荐的视频特征&#xff0c;以及用户在推荐视频上是否有一系列的消费行为。 推荐模型数据流&#xff0c;即为…

快速掌握Haproxy原理架构

文章目录 一、原理架构二、无负载均衡三、四层负载均衡的工作流程四、七层负载均衡工作流程五、基础属性mode 属性retries 属性maxconn 属性clitimeout 属性servtimeout 属性states uri 属性 一、原理架构 四层tcp代理&#xff1a;Haproxy仅在客户端和服务器之间双向转发流量&…

Pytest基础01: 入门demo脚本

目录 1 Pytest接口测试 1.1 最简单版hello world 1.2 pytest.ini 2 pytest兼容unittest 3 封装pytest执行入口 1 Pytest接口测试 Pyest是一个可以用于接口测试的强大框架&#xff0c;开源社区也有非常多的pytest插件。 按江湖传统&#xff0c;学习一个新语言或者新框架&…

《HelloGitHub》第 105 期

兴趣是最好的老师&#xff0c;HelloGitHub 让你对编程感兴趣&#xff01; 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等&#xff0c;涵盖多种编程语言 Python、…

Linux day 1129

家人们今天继续学习Linux&#xff0c;ok话不多说一起去看看吧 三.Linux常用命令 3.1 Linux命令体验 3.1.1 常用命令演示 在这一部分中&#xff0c;我们主要介绍几个常用的命令&#xff0c;让大家快速感 受以下 Linux 指令的操作方式。主要包含以下几个指令&#xff1a; ls命…

python爬虫爬抖音小店商品数据+数据可视化

爬虫代码 爬虫代码是我调用的数据接口&#xff0c;可能会过一段时间用不了&#xff0c;欢迎大家留言评论&#xff0c;我会不定时更新 import requests import time cookies {token: 5549EB98B15E411DA0BD05935C0F225F,tfstk: g1vopsc0sQ5SwD8TyEWSTmONZ3cA2u6CReedJ9QEgZ7byz…

hadoop搭建

前言 一般企业中不会使用master slave01 slave02来命名 vmware创建虚拟机 打开vmware软件&#xff0c;新建虚拟机 典型 稍后安装系统 选择centos7 虚拟机名称和安放位置自行选择&#xff08;最小化安装消耗空间较少&#xff09; 默认磁盘大小即可 自定义硬件 选择centos7的i…

基于深度学习(HyperLPR3框架)的中文车牌识别系统-python程序开发测试

本篇内容为python开发&#xff0c;通过一个python程序&#xff0c;测试搭建的开发环境&#xff0c;读入一张带有车牌号的图片&#xff0c;成功识别出车牌号。 1、通过PyCharm新建一个工程&#xff0c;如&#xff1a;PlateRecognition&#xff0c;配置虚拟环境。 2、在工程中新…