当前位置:首页 > 后端开发 > 正文内容

13.SpringCloudSeata处理分布式业务

邻居的猫1个月前 (12-09)后端开发787

分布式事务(引进)

面试题

你简历上写用微服务boot/cloud做过项目,你不可能只要一个数据库吧?请你谈谈多个数据库之间,你怎样处理分布式事务?

举例:在订单付出成功后,交易中心会调用订单中心的服务把订单状况更新,并调用物流中心的服务告诉产品发货,一同还要调用积分中心的服务为用户添加相应的积分。怎样确保分布式事务一致性,成为了确保订单事务安稳运转的中心诉求之一。

阿里巴巴的Seata-AT方式怎样做到对事务的无侵入?
关于分布式事务,你知道的处理计划有那些?请你谈谈?
  • 2PC(两阶段提交)
  • 3PC(三阶段提交)
  • TCC计划[TCC(Try-Confirm-Cancel)被称为补偿事务),相似2PC的柔性分布式处理计划,2PC改良版]
  • LocalMessage本地音讯表
  • 独立音讯微服务 + RabbitMQ/Kafka组件,结束可靠音讯终究一致性计划
  • 最大尽力告诉计划...

分布式事务问题,怎样发生?先看事务

上述面试问题都指向一个重要问题?

一次事务操作需求跨多个数据源或需求跨多个体系(多个进程)进行长途调用,就会发生分布式事务问题,可是联系型数据库供给的才能是依据单机事务的,一旦遇到分布式事务场景,就需求经过更多其他技能手段来处理问题。

微服务呈现之前

单机单库没有分布式事务的问题。

微服务呈现之后

单体运用被拆分红微服务运用,本来的三个模块,被拆分红三个敌对的运用,别离运用三个独立的数据源,事务操作需求调用三个服务来结束,此刻每个服务自己内部的数据一致性由本地事务来确保,可是大局的数据一致性问题无法确保。

定论

迫切希望供给一种分布式事务结构,处理微服务架构下的分布式事务问题。

1.Seata简介

1.1 是什么

Simple Extensible Autonomous Transaction Architecture(简略可扩展自治事务结构) -- Seata

1.1.1 官网解说

Apache Seata(incubating) 是一款开源的分布式事务处理计划,致力于在微服务架构下供给高性能和简略易用的分布式事务服务。

阿里,现已将其捐献给了Apache基金会。

1.1.2 开展进程

阿里巴巴作为国内最早一批进行运用分布式(微服务化)改造的企业,很早就遇到微服务架构下的分布式事务问题。

2019年1月份蚂蚁金服和阿里巴巴一同开源的分布式事务处理计划:

2014 年,阿里中间件团队发布 TXC(Taobao Transaction Constructor),为集团内运用供给分布式事务服务。

2016 年,TXC 在经过产品化改造后,以 GTS(Global Transaction Service) 的身份登陆阿里云,成为其时业界仅有一款云上分布式事务产品。在阿云里的公有云、专有云处理计划中,开端服务于很多外部客户。

2019 年起,依据 TXC 和 GTS 的技能堆集,阿里中间件团队建议了开源项目 Fescar(Fast & EaSy Commit And Rollback, FESCAR),和社区一同建造这个分布式事务处理计划。

2019 年 fescar(全称fast easy commit and rollback) 被重命名为了seata(simple extensiable autonomous transaction architecture)。TXC、GTS、Fescar 以及 seata 一脉相承,为处理微服务架构下的分布式事务问题交出了一份异乎寻常的答卷。

1.2 功用

Seata是一款开源的分布式事务处理计划,致力于在微服务架构下供给高性能和简略易用的分布式事务服务。

1.3 下载地址

官网

GitHub

1.4 怎样用

Spring中的本地事务@Transactional,大局事务@GlobalTransactional

Seata的分布式事务处理计划

2.Seata作业流程简介(原理)

2.1 分布式事务的办理,便是大局事务id的传递和改变,要让开发者无感知

2.2 Seata对分布式事务的协谐和操控便是1 + 3

2.2.1 1个XID

XID是大局事务的仅有标识,它能够在服务的调用链路中传递,绑定到服务的事务上下文中。

2.2.2 官网版3个概念

2.2.3 周阳教师对Seata术语的解说

TC(Tansaction Coordinator):事务和谐器

便是Seata组件,担任保护大局事务和分支事务的状况,驱动大局事务提交或回滚。

TM(Transaction Manager):事务办理器

标示大局@GlobalTransactional发动进口的微服务模块(接口),它是大局事务的建议者,担任界说大局事务的规模,并依据TC保护的大局事务和分支事务状况,做出开端事务、提交事务、回滚事务的抉择。

RM(Resource Manager):资源办理器

便是联系型数据库自身,能够时多个RM,担任办理分支事务上的资源,向TC注册分支事务,报告分支事务状况,驱动分支事务的提交或回滚。

留意,Seata的不同方式,运用的存储,运转中发生的的大局事务数据的介质不同,有的是文件,有的是联系型数据库的表,并且运用联系型数据库作为存储介质时,所支撑的联系型数据库也不同,详细见官网数据源支撑,这也是运用Seata作为分布式处理计划的约束之一。

2.3 分布式事务的履行流程-小总结

三个组件相互协作,TC以Seata 服务器(Server)方式独立布置,TM和RM则是以Seata Client的方式集成在微服务中运转,

A typical lifecycle of Seata managed distributed transaction:

  1. TM asks TC to begin a new global transaction. TC generates an XID representing the global transaction.
  2. XID is propagated through microservices' invoke chain.
  3. RM registers local transaction as a branch of the corresponding global transaction of XID to TC.
  4. TM asks TC for committing or rollbacking the corresponding global transaction of XID.
  5. TC drives all branch transactions under the corresponding global transaction of XID to finish branch committing or rollbacking.

1.TM 向 TC 恳求敞开一个大局事务,大局事务创立成功并生成一个大局仅有的 XID;

2.XID 在微服务调用链路的上下文中传达;

3.RM 向 TC 注册分支事务,将其归入 XID 对应大局事务的统辖;

4.TM 向 TC 建议针对 XID 的大局提交或回滚抉择;

5.TC 调度XID 下统辖的悉数分支事务结束提交或回滚恳求。

2.4 Seata的事务方式

AT方式


周阳教师,本次课程,只介绍了AT方式。理由是,日常作业,企业调研和本次课时组织约束。

3.Seata-Server2.0.0装置

3.1 下载

见本文1.3 下载地址

3.2 Seata参数官网参阅

https://seata.apache.org/zh-cn/docs/user/configurations

3.3 Seata新手布置攻略

Seata分TC,TM和RM三个人物,TC(Server)端为独自服务端布置,TM和RM(Client端)由事务体系集成。

官网新手布置攻略

3.4 MySQL8.0数据库建库 + 建表

3.4.1 树立TC运用的库
create database seata;

use seata;
3.4.2 在上一步seata库里建表

建表sql地址

--
-- Licensed to the Apache Software Foundation (ASF) under one or more
-- contributor license agreements.  See the NOTICE file distributed with
-- this work for additional information regarding copyright ownership.
-- The ASF licenses this file to You under the Apache License, Version 2.0
-- (the "License"); you may not use this file except in compliance with
-- the License.  You may obtain a copy of the License at
--
--     http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--

-- -------------------------------- 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_status_gmt_modified` (`status` , `gmt_modified`),
    KEY `idx_transaction_id` (`transaction_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

-- 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 = utf8mb4;

-- 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),
    `status`         TINYINT      NOT NULL DEFAULT '0' COMMENT '0:locked ,1:rollbacking',
    `gmt_create`     DATETIME,
    `gmt_modified`   DATETIME,
    PRIMARY KEY (`row_key`),
    KEY `idx_status` (`status`),
    KEY `idx_branch_id` (`branch_id`),
    KEY `idx_xid` (`xid`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

CREATE TABLE IF NOT EXISTS `distributed_lock`
(
    `lock_key`       CHAR(20) NOT NULL,
    `lock_value`     VARCHAR(20) NOT NULL,
    `expire`         BIGINT,
    primary key (`lock_key`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('AsyncCommitting', ' ', 0);
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryCommitting', ' ', 0);
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryRollbacking', ' ', 0);
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('TxTimeoutCheck', ' ', 0);


CREATE TABLE IF NOT EXISTS `vgroup_table`
(
    `vGroup`    VARCHAR(255),
    `namespace` VARCHAR(255),
    `cluster`   VARCHAR(255),
  UNIQUE KEY `idx_vgroup_namespace_cluster` (`vGroup`,`namespace`,`cluster`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

3.5 更改装备

修正seata-server-2.0.0\conf\application.yml装备文件,记住先备份(避免需求回退到原有的装备)

#  Copyright 1999-2019 Seata.io Group.
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#  http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
server:
  port: 7091

spring:
  application:
    name: seata-server

logging:
  config: classpath:logback-spring.xml
  file:
    path: ${log.home:${user.home}/logs/seata}
  extend:
    logstash-appender:
      destination: 127.0.0.1:4560
    kafka-appender:
      bootstrap-servers: 127.0.0.1:9092
      topic: logback_to_logstash
 
console:
  user:
    username: seata
    password: seata

seata:
  config:
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      namespace:
      group: SEATA_GROUP #后续自己在nacos里边新建,不想新建SEATA_GROUP,就写DEFAULT_GROUP
      username: nacos
      password: nacos
  registry:
    type: nacos
    nacos:
      application: seata-server
      server-addr: 127.0.0.1:8848
      group: SEATA_GROUP #后续自己在nacos里边新建,不想新建SEATA_GROUP,就写DEFAULT_GROUP
      namespace:
      cluster: default
      username: nacos
      password: nacos    

  store:
    mode: db
    db:
      datasource: druid
      db-type: mysql
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/seata?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
      user: root
      password: 123456
      min-conn: 10
      max-conn: 100
      global-table: global_table
      branch-table: branch_table
      lock-table: lock_table
      distributed-lock-table: distributed_lock
      query-limit: 1000
      max-wait: 5000


  #  server:
  #    service-port: 8091 #If not configured, the default is '${server.port} + 1000'
  security:
    secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
    tokenValidityInMilliseconds: 1800000
    ignore:
      urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.jpeg,/**/*.ico,/api/v1/auth/login,/metadata/v1/**

3.6 发动Nacos2.2.3端口号8848

startup.cmd -m standalone

指令运转成功后拜访http://localhost:8848/nacos

3.7 发动seata-server-2.0.0

进入seata软件目录\bin,发动略

进入seata前端界面,http://localhost:7091

进入Nacos,服务列表,会有seata-server服务。

4.Seata事例实战-数据库和表预备

订单 + 库存 + 账户3个事务数据库MySQL预备。

以下演示都需求先发动Nacos后发动Seata,确保两个都OK。

4.1 分布式事务本事例事务阐明

这儿咱们创立三个服务,一个订单服务,一个库存服务,一个账户服务。**

当用户下单时,会在订单服务中创立一个订单,然后经过长途调用库存服务来扣减下单产品的库存,

再经过长途调用账户服务来扣减用户账户里边的余额,

终究在订单服务中修正订单状况为已结束。该操作跨过三个数据库,有两次长途调用,很明显会有分布式事务问题。

4.2 创立3个事务数据库DATABASE

seata_order:存储订单的数据库;

seata_storage:存储库存的数据库;

seata_account:存储账户信息的数据库;

CREATE DATABASE seata_order;

CREATE DATABASE seata_storage;

CREATE DATABASE seata_account;

4.3 依照上述3库别离树立对应的undo_log回滚日志表

由于AT方式,是需求将分布式事务中,修正前后的数据,做一个快照,保存到数据库中,假如大局事务失利,分支(本地)事务需求回滚,便利修正本地事务现已提交的数据。所以,需求在单个微服务对应的数据库中,树立回滚日志表。成功的话,只要把记载的这条数据删去即可。大局事务成功或失利,没必要保存此事务中的暂时数据。

4.3.1 undo_log表

https://github.com/apache/incubator-seata/blob/2.x/script/client/at/db/mysql.sql

CREATE TABLE IF NOT EXISTS `undo_log`
(
    `branch_id`     BIGINT       NOT NULL COMMENT 'branch transaction id',
    `xid`           VARCHAR(128) 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(6)  NOT NULL COMMENT 'create datetime',
    `log_modified`  DATETIME(6)  NOT NULL COMMENT 'modify datetime',
    UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';
ALTER TABLE `undo_log` ADD INDEX `ix_log_created` (`log_created`);

留意,在当时笔记中,是以AT方式的mysql数据源,所以挑选的建表句子都是mysql版别的。不同数据源见GitHub或Seata官网。

4.4 依照上述库别离树立对应事务表和undo_log表

#订单库
CREATE DATABASE seata_order;
USE seata_order;
CREATE TABLE t_order(

`id` BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`user_id` BIGINT(11) DEFAULT NULL COMMENT '用户id',
`product_id` BIGINT(11)DEFAULT NULL COMMENT '产品id',
`count` INT(11) DEFAULT NULL COMMENT '数量',
`money` DECIMAL(11,0) DEFAULT NULL COMMENT '金额',
`status` INT(1) DEFAULT NULL COMMENT '订单状况: 0:创立中; 1:已结束'
)ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;


-- 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`
(
    `branch_id`     BIGINT       NOT NULL COMMENT 'branch transaction id',
    `xid`           VARCHAR(128) 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(6)  NOT NULL COMMENT 'create datetime',
    `log_modified`  DATETIME(6)  NOT NULL COMMENT 'modify datetime',
    UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';
ALTER TABLE `undo_log` ADD INDEX `ix_log_created` (`log_created`);

#账号库
CREATE DATABASE seata_account;
USE seata_account;

CREATE TABLE t_account(
`id` BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'id',
`user_id` BIGINT(11) DEFAULT NULL COMMENT '用户id',
`total` DECIMAL(10,0) DEFAULT NULL COMMENT '总额度',
`used` DECIMAL(10,0) DEFAULT NULL COMMENT '已用账户余额',
`residue` DECIMAL(10,0) DEFAULT '0' COMMENT '剩下可用额度'
)ENGINE=INNODB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
#刺进一条假数据
INSERT INTO t_account(`id`,`user_id`,`total`,`used`,`residue`)VALUES('1','1','1000','0','1000');


-- 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`
(
    `branch_id`     BIGINT       NOT NULL COMMENT 'branch transaction id',
    `xid`           VARCHAR(128) 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(6)  NOT NULL COMMENT 'create datetime',
    `log_modified`  DATETIME(6)  NOT NULL COMMENT 'modify datetime',
    UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';
ALTER TABLE `undo_log` ADD INDEX `ix_log_created` (`log_created`);

#库存库
CREATE DATABASE seata_storage;
USE seata_storage;

CREATE TABLE t_storage(
`id` BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`product_id` BIGINT(11) DEFAULT NULL COMMENT '产品id',
`total` INT(11) DEFAULT NULL COMMENT '总库存',
`used` INT(11) DEFAULT NULL COMMENT '已用库存',
`residue` INT(11) DEFAULT NULL COMMENT '剩下库存'
)ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
#刺进一条假数据
INSERT INTO t_storage(`id`,`product_id`,`total`,`used`,`residue`)VALUES('1','1','100','0','100');

-- 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`
(
    `branch_id`     BIGINT       NOT NULL COMMENT 'branch transaction id',
    `xid`           VARCHAR(128) 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(6)  NOT NULL COMMENT 'create datetime',
    `log_modified`  DATETIME(6)  NOT NULL COMMENT 'modify datetime',
    UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';
ALTER TABLE `undo_log` ADD INDEX `ix_log_created` (`log_created`);

4.5 终究作用

在MySQL8.0中有seata库,seata_order库,seata_storage库,seata_account库,其中有对应的表,表信息略,见上sql句子。

5.Seata事例实战-微服务编码落地结束

事例需求:下订单 -> 减库存 -> 扣余额 -> 改(订单)状况

5.1 运用插件生成根底类

运用最开端的generator模块,和之前生成t_pay表的根底类相同。

5.1.1 config.properties
#t_pay表包名
package.name=com.atguigu.cloud

# mysql8.0
jdbc.driverClass = com.mysql.cj.jdbc.Driver
jdbc.url= jdbc:mysql://localhost:3306/db2024?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
jdbc.user = root
jdbc.password =123456

# seata_order
#jdbc.driverClass = com.mysql.cj.jdbc.Driver
#jdbc.url = jdbc:mysql://localhost:3306/seata_order?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
#jdbc.user = root
#jdbc.password =123456

# seata_storage
#jdbc

扫描二维码推送至手机访问。

版权声明:本文由51Blog发布,如需转载请注明出处。

本文链接:https://www.51blog.vip/?id=170

分享给朋友:

“13.SpringCloudSeata处理分布式业务” 的相关文章

FPGA对EEPROM驱动操控(I2C协议)

FPGA对EEPROM驱动操控(I2C协议)

本文摘要:本文首要对I2C协议的通讯形式和AT24C16-EEPROM芯片时序操控进行剖析和了解,规划了一个i2c通讯计划。人为按下写操作按键后,FPGA(Altera EP4CE10)对EEPROM指定地址写入字节数据,并接后按下读操作按键,读取该地址上的一个字节数据在数码管低两位显现出来。其间包...

r语言sort,璇玑AI

在R语言中,`sort` 函数用于对向量、矩阵或数据框的行或列进行排序。以下是关于 `sort` 函数的一些基本用法:1. 对向量进行排序: `sort` 对向量 `x` 进行升序排序。 `sort` 对向量 `x` 进行降序排序。2. 对矩阵或数据框进行排序: `sort` 对矩...

go 热更新,使用Nacos实现配置文件实时更新

go 热更新,使用Nacos实现配置文件实时更新

1. 使用轻量级容器:将Go应用程序部署在轻量级的容器中,如Docker。通过替换容器中的镜像,可以实现快速的应用更新,而无需重启容器。2. 使用Sidecar容器:在Kubernetes等容器编排系统中,可以为应用程序添加一个Sidecar容器,专门用于管理应用程序的更新。Sidecar容器可以监...

宏碁蜂鸟swift3,时尚外观与强大性能的完美结合

宏碁蜂鸟swift3,时尚外观与强大性能的完美结合

宏碁蜂鸟Swift 3是一款定位大众化的轻薄笔记本电脑,以下是其主要特点和配置:1. 显示屏: 采用2K分辨率的3:2显示屏,拥有100%sRGB的高色域,显示效果出色。 屏幕实测色域容积为97.3%sRGB,色域覆盖为96.7%sRGB,平均 E为1.2,最大 E为2.81。2. 处理...

java拼接字符串, 字符串拼接的背景知识

在Java中,拼接字符串有多种方法,以下是几种常见的方式:1. 使用 ` ` 运算符:这是最简单的方法,可以直接使用 ` ` 来拼接字符串。例如:```javaString str1 = Hello, ;String str2 = World!;String result = str1 str2...

php架构, 系统架构概述

php架构, 系统架构概述

2. 三层架构:三层架构是将应用程序分为表现层、业务逻辑层和数据访问层。表现层负责与用户交互,业务逻辑层处理应用程序的核心功能,数据访问层负责与数据库交互。3. 依赖注入(DI):依赖注入是一种设计模式,它允许在运行时动态地将依赖项注入到对象中。这有助于减少代码耦合,提高代码的可测试性和可维护性。4...