主頁 > 軟體設計 > 微服務架構 | 11.1 整合 Seata AT 模式實作分布式事務

微服務架構 | 11.1 整合 Seata AT 模式實作分布式事務

2022-02-10 08:12:24 軟體設計

目錄
  • 前言
  • 1. Seata 基礎知識
    • 1.1 Seata 的 AT 模式
    • 1.2 Seata AT 模式的作業流程
    • 1.3 Seata 服務端的存盤模式
    • 1.4 Seata 與 Spring Cloud 整合說明
    • 1.5 關于事務分組的說明
  • 2. Seata 服務端的安裝
    • 2.1 安裝包安裝 Seata
      • 2.1.1 下載 Seata
    • 2.1.2 修改存盤模式為 db
    • 2.1.3 指明注冊中心與配置中心,上傳 Seata 配置
      • 2.1.4 啟動 Seata 服務器
    • 2.2 原始碼安裝 Seata
      • 2.2.1 拉取代碼
      • 2.2.2 修改組態檔
      • 2.2.3 啟動服務
  • 3. Spring Cloud 集成 Seata 實作分布式事務
    • 3.1 引入 pom.xml 依賴檔案
    • 3.2 修改 bootstrap.yml 組態檔
    • 3.3 注入資料源
    • 3.4 添加 undo_log 表
    • 3.5 使用 @GlobalTransactional 開啟事務
  • 4. Seata AT 模式的實作原理
    • 4.1 兩個階段
    • 4.2 AT 模式第一階段實作原理
    • 4.3 AT 模式第二階段實作原理
      • 4.3.1 事務提交
      • 4.3.2 事務回滾
    • 4.4 關于事務的隔離性保證
      • 4.4.1 寫隔離
      • 4.4.2 讀隔離
  • 最后


前言

參考資料
《Spring Microservices in Action》
《Spring Cloud Alibaba 微服務原理與實戰》
《B站 尚硅谷 SpringCloud 框架開發教程 周陽》
《Seata 中文官網》
《Seata GitHub 官網》
《Seata 官方示例》

Seata 是一款開源的分布式事務解決方案,致力于在微服務架構下提供高性能和簡單易用的分布式事務服務;它提供了 AT、TCC、Saga 和 XA 事務模式,為開發者提供了一站式的分布式事務解決方案;


1. Seata 基礎知識

1.1 Seata 的 AT 模式

  • Seata 的 AT 模式基于 1 個全域 ID 和 3 個組件模型:
    • Transaction ID XID:全域唯一的事務 ID;
    • Transaction Coordinator TC:事務協調器,維護全域事務的運行狀態,負責協調并驅動全域事務的提交或回滾;
    • Transaction Manager TM:控制全域事務的邊界,負責開啟一個全域事務,并最終發起全域提交或全域回滾的決議;
    • Resource Manager RM:控制分支事務,負責分支注冊、狀態匯報,并接收事務協調器的指令,驅動分支(本地)事務的提交和回滾;
  • 為方便理解這里稱 TC 為服務端;
  • 使用 AT 模式時有一個前提,RM 必須是支持本地事務的關系型資料庫;

1.2 Seata AT 模式的作業流程

  • TMTC 申請開啟一個全域事務,全域事務創建成功并生成一個全域唯一的 XID
  • XID 在微服務呼叫鏈路的背景關系中傳播;
  • RMTC 注冊分支事務,將其納入 XID 對應全域事務的管轄;
  • TMTC 發起針對 XID 的全域提交或回滾決議;
  • TC 調度 XID 下管轄的全部分支事務完成提交或回滾請求;

Seata AT 模式的作業流程

1.3 Seata 服務端的存盤模式

  • Seata 服務端的存盤模式有三種:file、db 和 redis:
    • file:默認,單機模式,全域事務會話資訊持久化在本地檔案 ${SEATA_HOME}\bin\sessionStore\root.data 中,性能較高(file 型別不支持注冊中心的動態發現和動態配置功能);
    • db:需要修改配置,高可用模式,Seata 全域事務會話資訊由全域事務、分支事務、全域鎖構成,對應表:globaltablebranchtablelock_table
    • redis:需要修改配置,高可用模式;

1.4 Seata 與 Spring Cloud 整合說明

  • 由于 Spring Cloud 并沒有提供分布式事務處理的標準,所以它不像配置中心那樣插拔式地集成各種主流的解決方案;
  • Spring Cloud Alibaba Seata 本質上還是基于 Spring Boot 自動裝配來集成的,在沒有提供標準化配置的情況下只能根據不同的分布式事務框架進行配置和整合;

1.5 關于事務分組的說明

  • 在 Seata Clien 端的 file.conf 配置中有一個屬性 vgroup_mapping,它表示事務分組映射,是 Seata 的資源邏輯,類似于服務實體,它的主要作用是根據分組來獲取 Seata Serve r的服務實體;
  • 服務分組的作業機制
    • 首先,在應用程式中需要配置事務分組,也就是使用 GlobalTransactionScanner 構造方法中的 txServiceGroup 引數,這個引數有如下幾種賦值方式:
      • 默認情況下,為 ${spring.application.name}-seata-service-group
      • 在 Spring Cloud Alibaba Seata 中,可以使用 spring cloudalibaba.seata.tx-service-group 賦值;
      • 在 Seata-Spring-Boot-Starter 中,可以使用 seata.tx-service-group 賦值;
    • 然后,Seata 客戶端會根據應用程式的 txServiceGroup 去指定位置(file.conf 或者遠程配置中心)查找 service.vgroup_mapping.${txServiceGroup} 對應的配置值,該值代表TC集群(Seata Server)的名稱;
    • 最后,程式會根據集群名稱去配置中心或者 file.conf 中獲得對應的服務串列,也就是 clusterName.grouplist
  • 在客戶端獲取服務器地址并沒有直接采用服務名稱,而是增加了一層事務分組映射到集群的配置,這樣做的好處在于,事務分組可以作為資源的邏輯隔離單位,當某個集群出現故障時,可以把故障縮減到服務級別,實作快速故障轉移,只需要切換對應的分組即可;

事務分組的實作原理


2. Seata 服務端的安裝

Seata 安裝的是 AT 模型中的 TC,為方便理解這里稱為服務端;
Seata 作為一個事務中間件,有很多種部署安裝方式,有安裝包部署、原始碼部署和 Docker 部署,這里介紹前兩種,版本選 1.4.2;

2.1 安裝包安裝 Seata

2.1.1 下載 Seata

  • 進入 Seata 官網下載 binary 二進制檔案安裝包(也可以在官方 GitHub 倉庫里下):http://seata.io/zh-cn/blog/download.html;

下載 Seata

2.1.2 修改存盤模式為 db

  • 修改存盤模式:
    • 修改 ${SEATA_HOME}\conf\file.conf 檔案,store.mode="db",如下圖所示:
      修改存盤模式
  • 修改 MySQL 連接資訊:
    • 修改 ${SEATA_HOME}\conf\file.conf 檔案里的 db 模塊為自己需要連接的 MySQL 地址;
      修改 MySQL 連接資訊
  • 在 MySQL 上新建資料庫和表;
    • SQL 建表陳述句如下:
    • 該 SQL 檔案在原始碼包里的 ${SEATA_HOME}\script/server/db/mysql.sql 檔案;
-- 判斷資料庫存在,存在再洗掉
DROP DATABASE IF EXISTS seata;
	
-- 創建資料庫,判斷不存在,再創建
CREATE DATABASE IF NOT EXISTS seata;

-- 使用資料庫
USE seata;

-- 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(128),
    `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.1.3 指明注冊中心與配置中心,上傳 Seata 配置

  • 注冊中心:
    • 修改 ${SEATA_HOME}\conf\registry.conf 檔案里的 registry.type,以及下面的注冊中心地址資訊;
      修改注冊中心
  • 配置中心:
    • 也是在這個檔案里,往下翻,如下圖:
      修改配置中心
    • 將 Seata 客戶端和服務端的配置資訊上傳到 Nacos 服務器:
      • Seata 客戶端和服務端的配置資訊保存在 ${SEATA_HOME}/script/config-center/config.txt 檔案里,該檔案只在原始碼包里有,筆者是原始碼安裝 Seata 時做的這步;
      • ${SEATA_HOME}\script\config-center\nacos 目錄下執行以下 nacos-config.sh 腳本即可;
      • 上傳完后可見下圖:

Seata 配置上傳進 Nacos 配置中心

2.1.4 啟動 Seata 服務器

  • 先啟動 Nacos,再執行 ${SEATA_HOME}\bin\seata-server.bat 檔案;

  • 啟動成功后能在 Nacos 服務器里能看見 Seata 服務;

在 Nacos 服務器里能看見 Seata 服務

2.2 原始碼安裝 Seata

2.2.1 拉取代碼

  • 訪問地址:https://github.com/seata/seata;
  • 派生后拉取代碼;

Seata GitHub

2.2.2 修改組態檔

  • 原始碼的組態檔在 seata-server 模塊下的 resource 資源檔案里,有 file.conf 和 registry.conf 檔案;
  • 跟 2.1 安裝包安裝一樣修改即可;

2.2.3 啟動服務

  • 先啟動 Nacos 服務器;
  • 執行 mvm install 將專案安裝到本地;
  • 然后執行 seata-server 模塊的 Server.run() 方法即可;

Seata 原始碼啟動成功

  • 同樣,在 Nacos 服務器里能看見 Seata 服務;

在 Nacos 服務器里能看見 Seata 服務


3. Spring Cloud 集成 Seata 實作分布式事務

  • 配置示例參考官方提供的:https://github.com/seata/seata-samples/blob/master/doc/quick-integration-with-spring-cloud.md

3.1 引入 pom.xml 依賴檔案

  • 需要給四個服務都引入以下依賴:
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

3.2 修改 bootstrap.yml 組態檔

  • Seata 在 1.0 后支持將 ${SEATA_HOME}/script/client/conf 目錄下的兩個組態檔 file.conf 和 registry.conf 寫進 .yml 格式檔案里了(1.0 版本前不支持);

  • .yml 格式的組態檔在 ${SEATA_HOME}script/client/spring 目錄下;

  • 需要修改 seata.tx-service-groupseata.service.vgroup-mapping 一致,配置中心、注冊中心等;

  • 另一種配置方法:

    • 除此之外,還可以將 file.conf 和 registry.conf 兩個檔案添加進 resource 目錄下;

3.3 注入資料源

  • Seata 通過代理資料源的方式實作分支事務;MyBatis 和 JPA 都需要注入 io.seata.rm.datasource.DataSourceProxy, 不同的是,MyBatis 還需要額外注入 org.apache.ibatis.session.SqlSessionFactory

  • MyBatis:

@Configuration
public class DataSourceProxyConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        return new DruidDataSource();
    }

    @Bean
    public DataSourceProxy dataSourceProxy(DataSource dataSource) {
        return new DataSourceProxy(dataSource);
    }

    @Bean
    public SqlSessionFactory sqlSessionFactoryBean(DataSourceProxy dataSourceProxy) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSourceProxy);
        return sqlSessionFactoryBean.getObject();
    }
}

3.4 添加 undo_log 表

  • 在業務相關的資料庫中添加 undo_log 表,用于保存需要回滾的資料;
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 = 1
  DEFAULT CHARSET = utf8

3.5 使用 @GlobalTransactional 開啟事務

  • 在業務的發起方的方法上使用 @GlobalTransactional 開啟全域事務,Seata 會將事務的 xid 通過攔截器添加到呼叫其他服務的請求中,實作分布式事務;

4. Seata AT 模式的實作原理

4.1 兩個階段

  • AT 模式是基于 XA 事務模型演進而來的,所以它的整體機制也是一個改進版的兩階段提交協議;
    • 第一階段:業務資料和回滾日志記錄在同一個本地事務中提交,釋放本地鎖和連接資源;
    • 第二階段:提交異步化,非常快速地完成,回滾通過第一階段的回滾日志進行反向補償;

4.2 AT 模式第一階段實作原理

  • 在業務流程中執行庫存扣減操作的資料庫操作時,Seata 會基于資料源代理對原執行的 SQL 進行決議(Seata 在 0.9.0 版本之后支持自動代理);

  • 然后將業務資料在更新前后保存到 undo_log 日志表中,利用本地事務的 ACID 特性,把業務資料的更新和回滾日志寫入同一個本地事務中進行提交;
    AT 模式第一階段執行流程

    • 提交前,向TC注冊分支事務:申請 tbl_repo 表中主鍵值等于 1 的記錄的全域鎖;
    • 本地事務提交:業務資料的更新和前面步驟中生成的 UNDO_LOG 一并提交;
    • 將本地事務提交的結果上報給TC
  • AT 模式和 XA 最大的不同點:分支的本地事務可以在第一階段提交完成后馬上釋放本地事務鎖定的資源;AT 模式降低了鎖的范圍,從而提升了分布式事務的處理效率;

4.3 AT 模式第二階段實作原理

  • TC 接收到所有事務分支的事務狀態匯報之后,決定對全域事務進行提交或者回滾;

4.3.1 事務提交

  • 如果決定是全域提交,說明此時所有分支事務已經完成了提交,只需要清理 UNDO_LOG 日志即可,這也是和 XA 最大的不同點;
    事務提交執行流程
    • 分支事務收到 TC 的提交請求后把請求放入一個異步任務佇列中,并馬上回傳提交成功的結果給 TC;
    • 從異步佇列中執行分支,提交請求,批量洗掉相應 UNDO_LOG 日志;

4.3.2 事務回滾

  • 整個全域事務鏈中,任何一個事務分支執行失敗,全域事務都會進入事務回滾流程;
  • 也就是根據 UNDO_LOG 中記錄的資料鏡像進行補償;
    事務回滾執行流程
    • 通過 XID 和 branch ID 查找到相應的 UNDO_LOG 記錄;
    • 資料校驗:拿 UNDO_LOG 中的 afterImage 鏡像資料與當前業務表中的資料進行比較,如果不同,說明資料被當前全域事務之外的動作做了修改,那么事務將不會回滾;
    • 如果 afterImage 中的資料和當前業務表中對應的資料相同,則根據 UNDO_LOG中的 beforelmage 鏡像資料和業務 SQL 的相關資訊生成回滾陳述句并執行;
    • 提交本地事務,并把本地事務的執行結果(即分支事務回滾的結果)上報給 TC;

4.4 關于事務的隔離性保證

  • 在 AT 模式中,當多個全域事務操作同一張表時,它的事務隔離性保證是基于全域鎖來實作的;

4.4.1 寫隔離

  • 一階段本地事務提交前,需要確保先拿到全域鎖

  • 拿不到全域鎖 ,不能提交本地事務,

  • 全域鎖的嘗試被限制在一定范圍內,超出范圍將放棄,并回滾本地事務,釋放本地鎖;

  • 舉例:

    • tx1 一階段拿到全域鎖,tx2 等待;
      tx1 拿到全域鎖,tx2 等待
    • tx1 二階段全域提交,釋放全域鎖,tx2 拿到全域鎖提交本地事務;
      tx1 二階段全域提交,釋放全域鎖
    • 如果 tx1 的二階段全域回滾,則 tx1 需要重新獲取該資料的本地鎖,進行反向補償的更新操作,實作分支的回滾;
      • 此時,如果 tx2 仍在等待該資料的全域鎖,同時持有本地鎖,則 tx1 的分支回滾會失敗;
      • 分支的回滾會一直重試,直到 tx2 的全域鎖等鎖超時,放棄全域鎖并回滾本地事務釋放本地鎖,tx1 的分支回滾最終成功;
  • 因為整個程序全域鎖在 tx1 結束前一直是被 tx1 持有的,所以不會發生臟寫的問題;

4.4.2 讀隔離

  • 在資料庫本地事務隔離級別讀已提交(Read Committed) 或以上的基礎上,Seata(AT 模式)的默認全域隔離級別是讀未提交(Read Uncommitted) ;
    • 在該隔離級別,所有事務都可以看到其他未提交事務的執行結果,產生臟讀,這在最終一致性事務模型中是允許存在的,并且在大部分分布式事務場景中都可以接受臟讀
    • 如果應用在特定場景下,必需要求全域的讀已提交 ,目前 Seata 的方式是通過 SELECT FOR UPDATE 陳述句的代理;
      讀已提交執行流程
    • SELECT FOR UPDATE 陳述句的執行會申請全域鎖 ,如果全域鎖被其他事務持有,則釋放本地鎖(回滾 SELECT FOR UPDATE 陳述句的本地執行)并重試;
    • 這個程序中,查詢是被 block 住的,直到全域鎖拿到,即讀取的相關資料是已提交的,才回傳;


最后

新人制作,如有錯誤,歡迎指出,感激不盡!
歡迎關注公眾號,會分享一些更日常的東西!
如需轉載,請標注出處!

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/423594.html

標籤:架構設計

上一篇:微服務架構 | 11. 分布式事務

下一篇:Mysql資料庫 | 基于Docker搭建Mysql-8.0以上版本主從實體實戰

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more