【分布式事务】初步探索分布式事务的概率和理论,初识分布式事的解决方案 Seata,TC 服务的部署以及微服务集成 Seata

文章目录

  • 一、分布式服务案例
    • 1.1 分布式服务 demo
    • 1.2 演示分布式事务问题
  • 二、分布式事务的概念和理论
    • 2.1 什么是分布式事务
    • 2.2 CAP 定理
    • 2.3 BASE 理论
    • 2.4 分布式事务模型
  • 三、分布式事务解决方案 —— Seata
    • 3.1 什么是 Seata
    • 3.2 Seata 的架构
    • 3.3 Seata 的四种分布式事务解决方案
  • 四、Seata 服务的部署和集成
    • 4.1 部署 Seata 的 TC 服务
    • 4.2 微服务集成 Seata


一、分布式服务案例

在了解分布式事务之前,让我们通过一个微服务的案例来演示一下分布式事务存在的问题。

1.1 分布式服务 demo

首先,我准备了一个微服务的 demo 项目,这个项目的结构如下:

在这个Spring Cloud 项目中一共有三个服务:account-service 账户服务,order-service 订单服务和 storage-service 库存服务。其中order-service 负责下单业务,在下单时会调用订单服务,创建订单并写入数据库。然后订单服务调用账户服务和库存服务:

  • 账户服务负责扣减用户余额;
  • 库存服务负责扣减商品库存。

这个调用的流程图如下:

目前这三个服务涉及到了三种数据库表,它们的结构如下:

  1. 首先是订单表:

  2. 然后是账户表:

  3. 最后是库存表:

这三个服务的核心业务代码如下:

  1. 首先是 order-service

    @Override
    @Transactional
    public Long create(Order order) {// 创建订单orderMapper.insert(order);try {// 扣用户余额accountClient.deduct(order.getUserId(), order.getMoney());// 扣库存storageClient.deduct(order.getCommodityCode(), order.getCount());} catch (FeignException e) {log.error("下单失败,原因:{}", e.contentUTF8(), e);throw new RuntimeException(e.contentUTF8(), e);}return order.getId();
    }
    
  2. 然后是account-service

    @Override
    @Transactional
    public void deduct(String userId, int money) {log.info("开始扣款");try {accountMapper.deduct(userId, money);} catch (Exception e) {throw new RuntimeException("扣款失败,可能是余额不足!", e);}log.info("扣款成功");
    }
    
  3. 最后是storage-service

    @Transactional
    @Override
    public void deduct(String commodityCode, int count) {log.info("开始扣减库存");try {storageMapper.deduct(commodityCode, count);} catch (Exception e) {throw new RuntimeException("扣减库存失败,可能是库存不足!", e);}log.info("扣减库存成功");
    }
    

可以发现,这三个核心的业务代码都加上了 @Transactional 注解来开启事务,下面就通过 Postman 来演示一下这个过程。

1.2 演示分布式事务问题

在演示之前,先看看数据库中的数据:

  1. order_tbl

  2. account_tbl

  3. storage_tbl

首先是正常状态,即余额和库存都充足的情况:

通过 Postman 发送如下请求,此时指定商品的数量为 2,库存充足:

最终成功执行,然后让我们看一看数据库中的数据变化

  1. order_tbl 中新增了一条订单数据:

  2. account_tbl表中该用户的余额成功扣减 200:

  3. storage_tbl表中该商品的库存数量也成功扣减 2 个:

然后让我们来演示一下当库存不足的情况下,是否会存在问题:

现在设置要扣减的库存为 10,而此时的库存数量为 8,则整个过程应该执行失败:


然后再让我们来看一看数据库中的数据变化:

  1. order_tbl表中没有新增订单:

  2. account_tbl表中却扣减了 200 金额:

  3. storage_tbl表中没有扣减库存:

在上面的微服务中,一个业务跨越多个服务或数据源,每个服务都是一个分支事务,要保证所有分支事务最终状态一致,这样的事务就是分布式事务。

但是,上面的微服务上没有实现分布式事务,而只有分支事务,站在分支事务的角度上来看:

  • 订单服务虽然下单成功,但是因为调用库存服务,库存服务因为库存不足调用失败回滚了,因此订单服务作为外部事务也会回滚。
  • 账户服务在执行的时候没有问题,因此执行成功了。
  • 库存服务因为库存不足,业务失败因此回滚了。

因此,要想保证整个业务的流程都能够正常执行,那么就需要采用分布式事务,即要么所有的分支事务都执行成功,要么都执行失败。

二、分布式事务的概念和理论

2.1 什么是分布式事务

分布式事务是指在分布式系统中,多个独立的事务操作需要协同工作以维护数据的一致性和完整性。在传统的单机事务中,ACID(原子性、一致性、隔离性、持久性)属性可以轻松满足,但在分布式系统中,由于涉及多个数据存储节点,实现分布式事务变得更加复杂。

关键问题包括如何协调各个参与者的事务、如何处理网络分区和节点故障、如何保证全局数据一致性等。因此,分布式事务需要特殊的技术和协议来管理和维护数据一致性,以确保分布式系统的正确运行。

2.2 CAP 定理

CAP 定理是分布式系统理论中的一个重要概念,由计算机科学家 Eric Brewer 提出。CAP 定理指出,一个分布式系统的设计不能同时满足以下三个属性:

  • 一致性(Consistency):所有节点看到的数据是一致的,即在任何时刻,系统中的所有节点都能看到相同的数据。

  • 可用性(Availability):系统在任何时刻都能处理读写请求,即系统保持可用状态,不会出现服务不可用的情况。

  • 分区容忍性(Partition Tolerance):系统能够在网络分区或节点故障的情况下继续工作,即系统能够容忍部分节点无法通信或故障。

CAP 定理指出,在分布式系统中,最多只能满足其中的两个属性,而必须牺牲其中一个。这意味着在面对网络分区或故障时,要么保证一致性和可用性,但失去了分区容忍性;要么保证一致性和分区容忍性,但失去了可用性。这对分布式系统的设计和架构提出了重要挑战。

例如:ES 集群出现分区时,故障节点会被剔除集群,数据分片会重新分配到其它节点,保证数据一致。因此是低可用性,高一致性,属于CP 模式。

2.3 BASE 理论

BASE 理论是对 CAP 定理的一种思考和解决方案,它的名称是对以下三个核心概念的缩写:

1. Basically Available(基本可用性): 这意味着分布式系统在出现故障时仍然能够保持基本的可用性。即使部分组件故障或数据出现不一致,系统仍然可以提供有限的服务,不会变得完全不可用。这允许系统在面临问题时继续对外提供核心功能,确保用户体验。

2. Soft State(软状态): BASE 理论承认在一定时间内,分布式系统的数据可以处于不一致的中间状态。这是因为各个节点在进行数据同步或处理时可能存在延迟、不同步的情况,导致数据不完全一致。允许出现软状态意味着系统可以容忍一段时间内的数据不一致,但要求最终达到一致状态。

3. Eventually Consistent(最终一致性): 最终一致性是 BASE 理论的核心概念,它强调虽然分布式系统不能保证强一致性,但最终所有节点的数据将达到一致状态。系统会采取一系列措施来保证数据最终一致,例如定期数据同步、修复数据不一致等。这种方法可以在面临一致性挑战的同时,保持分布式系统的可用性和性能。

BASE 理论的思想在分布式系统中得到了广泛应用,特别是对于大规模、高可用性的系统。它提供了一种权衡可用性和一致性的方法,允许根据具体需求和应用场景来选择适当的数据一致性模型(如最终一致性),以满足不同业务的要求。这使得分布式系统更具弹性、可伸缩性和容错性,同时在最终实现数据一致性。

因此分布式事务最大的问题是各个子事务的一致性问题,因此可以借鉴 CAP 定理和 BASE 理论:

  • AP模式:各子事务分别执行和提交,允许出现结果不一致,然后采用弥补措施恢复数据即可,实现最终一致。

  • CP模式:各个子事务执行后互相等待,同时提交,同时回滚,达成强一致。但事务等待过程中,处于弱可用状态。

2.4 分布式事务模型

要解决分布式事务的问题,各个子系统之间必须能够感知彼此的事务状态,以确保状态一致性。为实现这一目标,通常需要引入一个事务协调者,它的职责是协调每个事务的参与者(子系统内的事务)。这些子系统内的事务通常被称为分支事务,而涉及多个分支事务的全局事务需要协调者来确保一致性。

以上述微服务为例,引入一个事务协调者后的架构如下:

分布式事务架构

在这种架构中,事务协调者负责协调每个分支事务的执行。当某一分支事务(例如库存服务)由于库存不足而导致业务失败时,事务协调者可以通知所有分支事务进行回滚,以确保所有事务状态的一致性。

分布式事务模型的关键点包括:

  • 事务协调者(Coordinator): 负责协调全局事务的执行和状态管理。它监控每个分支事务的执行情况,并根据需要发出提交或回滚命令。

  • 分支事务(Branch Transaction): 每个子系统内部的事务,负责执行具体的业务操作。分支事务会根据协调者的指示执行提交或回滚操作。

  • 全局事务(Global Transaction): 涉及多个子系统内的一组分支事务,全局事务由协调者协调管理,以确保所有分支事务的状态一致性。

引入事务协调者后,分布式系统可以更好地处理各个子系统之间的事务一致性问题,保证全局事务的正确执行。这种模型有助于应对网络故障、部分事务失败等情况,以确保分布式系统的数据一致性和完整性。

三、分布式事务解决方案 —— Seata

3.1 什么是 Seata

Seata(前身为Fescar)是一个分布式事务解决方案,最早由蚂蚁金服和阿里巴巴共同开源于2019年1月。Seata 的目标是提供高性能、简单易用的分布式事务服务,旨在为用户提供一站式的分布式解决方案。

Seata的主要功能和特点包括:

  • 分布式事务协调: Seata充当分布式事务的协调者,负责管理和协调多个分支事务,以确保它们的一致性和完整性。

  • 高性能: Seata通过优化事务日志存储和协调算法,提供高性能的分布式事务处理能力。

  • 简单易用: Seata提供了简单的API和配置方式,使开发人员能够轻松地集成和使用分布式事务功能。

  • 支持多种存储后端: Seata支持多种存储后端,包括MySQL、Oracle、PostgreSQL等,以满足不同环境的需求。

  • 分布式事务模式: Seata支持两阶段提交(2PC)和补偿模式,可以根据业务需求选择合适的事务模式。

  • 跨框架和跨语言: Seata可以与各种编程语言和框架集成,包括Java、Spring Cloud、Dubbo等,以及Node.js、Python等非Java语言。

Seata 的官方网站(http://seata.io/)提供了详细的文档、博客和源码分析,为用户提供了丰富的资源和支持,帮助开发人员更好地理解和使用分布式事务解决方案。Seata 的开源性质使得它成为解决分布式事务挑战的重要工具之一,广泛应用于云原生和微服务架构中。

3.2 Seata 的架构

Seata 的架构涉及三个重要的角色,它们分别是:

  • TC (Transaction Coordinator) - 事务协调者: TC 是 Seata 中的核心组件,负责维护全局事务和分支事务的状态,协调全局事务的提交或回滚。TC通过全局事务的唯一标识来管理多个分支事务,确保它们的状态一致性,并根据协调结果决定是提交还是回滚全局事务。

  • TM (Transaction Manager) - 事务管理器: TM 定义了全局事务的范围,它负责启动全局事务、提交或回滚全局事务。TM 与 TC 进行通信,以协调全局事务的状态和最终结果。TM可以是应用程序的一部分,用于启动和管理分布式事务。

  • RM (Resource Manager) - 资源管理器: RM 管理分支事务处理的资源,包括数据库、消息队列、缓存等。RM 与 TC 进行通信以注册分支事务、报告分支事务的状态,并根据 TC 的指示来驱动分支事务的提交或回滚。RM 负责协调资源的一致性,以确保全局事务的一致性。

这三个角色的架构图如下:

这三个角色共同协作,构成了 Seata 的分布式事务管理架构。TC 作为协调者负责全局事务的管理,TM 负责事务的启动和控制,RM 负责资源的管理和一致性保障。通过这种分布式事务管理架构,Seata能够有效地管理分布式事务的状态和保证一致性,为分布式系统提供可靠的事务支持。

3.3 Seata 的四种分布式事务解决方案

Seata 提供了四种不同的分布式事务解决方案,以满足不同业务场景的需求。这些解决方案分别是:

  1. XA 模式(eXtended Architecture): XA模式是一种强一致性分阶段事务模式,它允许分布式事务在多个资源管理器(例如数据库)之间进行协调。在XA模式中,事务协调者(TC)协调多个RM(Resource Manager)来确保事务的一致性。虽然XA模式提供了强一致性,但通常会牺牲一定的可用性,并且需要支持XA协议的资源管理器。XA模式不需要业务侵入。

  2. TCC 模式(Try-Confirm-Cancel): TCC模式是一种最终一致性的分阶段事务模式,它要求业务代码显式地定义“尝试”、“确认”和“取消”三个阶段的操作。TCC模式通过在每个参与者(分支事务)上执行这些操作来实现最终一致性。虽然TCC模式具有一定的业务侵入,但它提供了更灵活的事务控制和适应性。

  3. AT 模式(Automatic Transaction): AT模式是一种最终一致性的分阶段事务模式,它无需业务代码显式地定义阶段操作,而是通过自动代理来管理分支事务。AT模式是Seata的默认模式,它提供了最终一致性的分布式事务解决方案,并且无需业务侵入。AT模式适用于大多数业务场景。

  4. SAGA 模式: SAGA模式是一种长事务模式,它将分布式事务分解成多个连续的步骤,每个步骤都是一个本地事务。SAGA模式适用于需要跨多个微服务的长时间事务。虽然SAGA模式具有业务侵入,但它提供了更高级别的事务控制和业务流程管理。

这四种分布式事务解决方案使 Seata 能够适应不同的应用场景,从强一致性到最终一致性,从无业务侵入到有业务侵入,满足了多样化的分布式事务需求。根据具体的业务要求和架构设计,开发人员可以选择适当的 Seata 模式来实现分布式事务管理。

四、Seata 服务的部署和集成

4.1 部署 Seata 的 TC 服务

  1. 首先我们要下载 seata-server (TC 服务)压缩包,下载地址:http://seata.io/zh-cn/blog/download.html。这里我选择的版本是 1.4.2

  2. 将这个压缩包解压到非中文目录下,其目录结构如下:

  3. 修改conf目录下的registry.conf文件,这里我们选择将 seata-server 服务注册到 Nacos 中:

    registry {# 注册中心类型:file 、nacos 、eureka、redis、zk、consul、etcd3、sofatype = "nacos"nacos {application = "seata-tc-server"serverAddr = "127.0.0.1:8848"group = "DEFAULT_GROUP"namespace = ""cluster = "CD"username = "nacos"password = "nacos"}
    }config {# file、nacos 、apollo、zk、consul、etcd3type = "nacos"nacos {serverAddr = "127.0.0.1:8848"namespace = ""group = "SEATA_GROUP"username = "nacos"password = "nacos"dataId = "seataServer.properties"}
    }
    
  4. 在 Nacos 中添加seataServer.properties配置文件。为了让 TC 服务的集群可以共享配置,所以选择了 Nacos 作为统一配置中心。因此服务端配置文件 seataServer.properties 文件需要添加到 Nacos 中。文件内容如下:

    # 数据存储方式,db代表数据库
    store.mode=db
    store.db.datasource=druid
    store.db.dbType=mysql
    store.db.driverClassName=com.mysql.jdbc.Driver
    store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&rewriteBatchedStatements=true
    store.db.user=root
    store.db.password=passwd
    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
    # 事务、日志等配置
    server.recovery.committingRetryPeriod=1000
    server.recovery.asynCommittingRetryPeriod=1000
    server.recovery.rollbackingRetryPeriod=1000
    server.recovery.timeoutRetryPeriod=1000
    server.maxCommitRetryTimeout=-1
    server.maxRollbackRetryTimeout=-1
    server.rollbackRetryTimeoutUnlockEnable=false
    server.undo.logSaveDays=7
    server.undo.logDeletePeriod=86400000# 客户端与服务端传输方式
    transport.serialization=seata
    transport.compressor=none
    # 关闭metrics功能,提高性能
    metrics.enabled=false
    metrics.registryType=compact
    metrics.exporterList=prometheus
    metrics.exporterPrometheusPort=9898
    
  5. 创建数据库表
    TC 服务在管理分布式事务时,需要记录事务相关数据到数据库中,需要提前创建好这些表。因此新建一个名为 seata 的数据库,然后创建一张分支事务表和一张全局事务表。这些表主要记录全局事务、分支事务、全局锁信息:

    
    SET NAMES utf8mb4;
    SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
    -- 分支事务表
    -- ----------------------------
    DROP TABLE IF EXISTS `branch_table`;
    CREATE TABLE `branch_table`  (`branch_id` bigint(20) NOT NULL,`xid` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`transaction_id` bigint(20) NULL DEFAULT NULL,`resource_group_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`resource_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`branch_type` varchar(8) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`status` tinyint(4) NULL DEFAULT NULL,`client_id` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`application_data` varchar(2000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`gmt_create` datetime(6) NULL DEFAULT NULL,`gmt_modified` datetime(6) NULL DEFAULT NULL,PRIMARY KEY (`branch_id`) USING BTREE,INDEX `idx_xid`(`xid`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;-- ----------------------------
    -- 全局事务表
    -- ----------------------------
    DROP TABLE IF EXISTS `global_table`;
    CREATE TABLE `global_table`  (`xid` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`transaction_id` bigint(20) NULL DEFAULT NULL,`status` tinyint(4) NOT NULL,`application_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`transaction_service_group` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`transaction_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`timeout` int(11) NULL DEFAULT NULL,`begin_time` bigint(20) NULL DEFAULT NULL,`application_data` varchar(2000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`gmt_create` datetime NULL DEFAULT NULL,`gmt_modified` datetime NULL DEFAULT NULL,PRIMARY KEY (`xid`) USING BTREE,INDEX `idx_gmt_modified_status`(`gmt_modified`, `status`) USING BTREE,INDEX `idx_transaction_id`(`transaction_id`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;SET FOREIGN_KEY_CHECKS = 1;
    
  6. 启动 TC 服务,进入 seata-serverbin 目录,运行其中的 seata-server.bat 即可:

    启动成功后,可以发现 seata-server默认的端口号是 8091, 并且此时也应该注册到 Nacos 注册中心了。打开浏览器,访问 nacos 的控制台,然后进入服务列表页面,可以看到 seata-tc-server 的信息:

4.2 微服务集成 Seata

  1. 首先,我们需要在微服务中引入 seata 依赖:

    <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId>
    </dependency>
    <dependency><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId><version>1.4.2</version>
    </dependency>
    

    注意,引入的依赖版本要和 seata-server 版本匹配。

  2. 修改配置文件,需要修改所有微服务的application.yml文件,添加下面的配置:

    seata:registry: # TC 服务注册中心的配置,微服务根据这些信息去注册中心获取 tc 服务地址# 参考 tc 服务的 registry.conf 中的配置type: nacosnacos: # tcserver-addr: 127.0.0.1:8848namespace: ""group: DEFAULT_GROUPapplication: seata-tc-server # tc服务在nacos中的服务名称tx-service-group: seata-demo # 事务组,根据这个获取 tc 服务的cluster名称service:vgroup-mapping: # 事务组与TC服务cluster的映射关系seata-demo: CD
    

    注意,Seata 客户端获取 TC 服务的集群名称 cluster 是通过 tx-service-groupvgroup-mapping 的映射来获取的,即以 tx-service-group 为 key ,以 vgroup-mapping 为 value:

  3. 完成了上面的所有配置之后,重启这三个微服务,就可以在 seata-server 的控制台中看到如下的日志:


通过这些日志可以发现,seata-server 成功为微服务注册了资源管理器和事务管理器了。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AIGPT重大升级,界面重新设计,功能更加饱满,用户体验升级

AIGPT AIGPT是一款功能强大的人工智能技术处理软件&#xff0c;不但拥有其他模型处理文本认知的能力还有AI绘画模型、拥有自身的插件库。 我们都知道使用ChatGPT是需要账号以及使用魔法的&#xff0c;实现其中的某一项对我们一般的初学者来说都是一次巨大的挑战&#xff0c;但…

Fourier分析导论——第4章——Fourier级数的一些应用(E.M. Stein R. Shakarchi)

第 4 章 傅里叶级数的一些应用 Fourier series and analogous expansions intervene very naturally in the general theory of curves and surfaces. In effect, this theory, conceived from the point of view of analysis, deals obviously with the study of arbitra…

三款软件录制电脑屏幕视频

在这个视频信息快速发展的新时代&#xff0c;寻找好用的可以录制电脑屏幕视频的软件变得极其重要&#xff0c;因为制作视频已成为我们生活工作中不可或缺的一部分。 这些好用的录屏软件允许你录制摄像头、特定窗口、部分区域或整个桌面&#xff0c;同时还可对录制中的视频进行…

前沿技术:人工智能的未来之路

&#x1f38a;专栏【人工智能】 &#x1f33a;每日一句&#xff1a;天空黑暗到一定程度&#xff0c;星辰就会熠熠生辉&#xff01; ⭐欢迎并且感谢大家指出我的问题 文章目录 一、引言 二、人工智能的未来发展 三、人工智能发展面临的挑战 四、结论 一、引言 随着科技的不…

开源项目管理工具Helper的安装及汉化

什么是 Helper &#xff1f; Helper 是基于 Laravel 和 Filament 的开源项目管理工具。 官方提供了在线演示&#xff1a;https://project-helper.net 安装 在群晖上以 Docker 方式安装。 数据库理论上是可以使用群晖自带的 MariaDB 的&#xff0c;但老苏为了省事&#xff0c…

千兆光模块和万兆光模块的发展前景与市场分析

随着互联网技术的不断发展&#xff0c;千兆光模块和万兆光模块作为网络传输的核心部件&#xff0c;在数据传输领域已得到广泛的应用。本文将从发展历程、市场前景和应用案例三个方面详细分析千兆光模块和万兆光模块的优势和未来发展前景。 一、千兆光模块和万兆光模块的发展历…

WPF中的Binding的常见知识点与技巧

完全来源于十月的寒流&#xff0c;感谢大佬讲解 在XAML中&#xff0c;可以绑定到许多不同类型的数据源和属性。以下是一些可以绑定的常见数据源和属性&#xff1a; 属性&#xff1a;可以绑定到对象的属性&#xff0c;例如控件的Text、Visibility、IsEnabled等属性。 集合&am…

【网络】五中IO模型介绍 + 多路转接中select和poll服务器的简单编写

高级IO 前言正式开始前面的IO函数简单过一遍什么叫做低效的IO钓鱼的例子同步IO和异步IO五种IO模型阻塞IO非阻塞IO信号驱动多路转接异步IO 小结 代码演示非阻塞IO多路转接select介绍简易select服务器timeout 为 nullptrtimeout 为 {0, 0}timeout 为 {5, 0}调用accept select编写…

第二证券:消费电子概念活跃,博硕科技“20cm”涨停,天龙股份斩获10连板

消费电子概念7日盘中再度拉升&#xff0c;到发稿&#xff0c;博硕科技“20cm”涨停&#xff0c;光大同创、波长光电涨超10%&#xff0c;易德龙、向阳科技、得润电子、天龙股份、同兴达等涨停。 博硕科技强势涨停&#xff0c;公司昨日在接受安排调研时表明&#xff0c;公司从上…

前端框架Vue学习 ——(四)Axios

文章目录 Axios 介绍Axios 入门Vue项目中使用 Axios Axios 介绍 介绍: Axios 对原生的 Ajax 进行了封装&#xff0c;简化书写&#xff0c;快速开发。&#xff08;异步请求&#xff09; 官网: https://www.axios-http.cn/ 官网介绍&#xff1a;Axios 是一个基于 promise 网络请…

数据结构和算法是人工智能的基石

文章目录 1. 引言2. 主要内容3. 联合推荐4. 购买方式5. 总结 1. 引言 数据结构和算法是计算机科学的基石&#xff0c;是计算机的灵魂&#xff0c; 要想成为计算机专业人员&#xff0c;学习和掌握算法是十分必要的。不懂数据结构和算法的人不可能写出效率更高的代码。计算机科学…

php实现钉钉机器人推送消息和图片内容(完整版)

先来看下实现效果: 代码如下: function send_dingtalk_markdown($webhook , $title , $message "", $atMobiles [], $atUserIds []) {$data ["msgtype" > "markdown","markdown" > ["title" > $title,&quo…

Luckysheet 实现excel多人在线协同编辑

前言 前些天看到Luckysheet支持协同编辑Excel&#xff0c;正符合我们协同项目的一部分&#xff0c;故而想进一步完善协同文章&#xff0c;但是遇到了一下困难&#xff0c;特此做声明哈&#xff0c;若侵权&#xff0c;请联系我删除文章&#xff01; 若侵犯版权、个人隐私&#x…

五、计算机网络

&#xff08;一&#xff09;OSI/RM 七层模型 七层模型是计算机网络的基石&#xff0c;整个计算机网络是构建与七层模型之上的。 在数据链路层&#xff0c;数据开始以帧为单位&#xff0c;网卡的 MAC 地址就是数据帧的地址&#xff0c;数据的传输开始有地址了。 局域网是工作…

目标检测中的评价指标

目标检测中的评价指标 将检测目标分为正样本和负样本。 真阳性&#xff08;true positives , TP&#xff09; : 正样本被正确识别为正样本。 假阳性&#xff08;false positives, FP&#xff09;: 负样本被错误识别为正样本。 假阴性&#xff08;false negatives, FN&#…

Floor报错注入理论及实战

rand()函数&#xff1a;随机返回0-1之间的小数 floor()函数&#xff1a;小数向下取证书。向上取整数ceiling() concat_ws函数&#xff1a;将括号内数据用第一个字段连接起来 group by子句&#xff1a;分组语句&#xff0c;常用语结合统计函数&#xff0c;根据一个或多个列&a…

word统计全部字符数。

问题描述&#xff1a;在投稿SCI论文时&#xff0c;有时会要求提交一个highlight文档&#xff0c;要求不超过85个字符。 具体如下&#xff1a;maximum 85 characters per bullet point including spaces 这里的字符不单单包括字母和汉字&#xff0c;还包括标点和空格键。那么如…

5G及其后的5G非地面网络:趋势和研究挑战-HARQ部分

NTN组件纳入5G架构第一步 在NTN SI中定义了一组架构选项。就NT部分而言&#xff0c;已确定了两大类&#xff1a;星载&#xff08;即基于卫星的通信平台&#xff09;和机载&#xff08;即HAPS&#xff09;设备 并行管理HARQ最大进程数 NHARQRTT(NTX−1)2μ NTX&#xff1a;传输…

【Vue】vant2使用van-tree-select实现【全选、反选、搜索】,自定义组件,拿去即用。2.0版本保姆级教程

系列文章目录 这是原篇教程&#xff0c;本篇为升级版&#xff0c;旧版已废弃。对你们不友好。 【Vue】vue2移动端 &#xff0c;vant2使用van-tree-select分类选择实现【全选】和【取消全选】、【搜索过滤当前children】&#xff0c;只影响当前显示children&#xff0c;并且去重…

破解密码 LLM(代码LLM如何从 RNN 发展到 Transformer)

舒巴姆阿加瓦尔 一、说明 近年来&#xff0c;随着 Transformer 的引入&#xff0c;语言模型发生了显着的演变&#xff0c;它彻底改变了我们执行日常任务的方式&#xff0c;例如编写电子邮件、创建文档、搜索网络甚至编码方式。随着研究人员在代码智能任务中应用大型语言模型&am…