分布式事务理论基础
今天啊,本片博客我们一起来学习一下微服务中的一个重点和难点知识:分布式事务。
我们会基于Seata 这个框架来学习。
1、分布式事务问题
事务,我们应该比较了解,我们知道所有的事务,都必须要满足ACID的原则。也就是
在我们以前所学习的单体架构当中的这个服务直接访问一个数据库,业务比较简单。基于数据库本身的特性,就已经能够实现ACID了。
但是,我们现在要研究的是微服务。微服务的业务往往比较复杂,可能一个业务啊,就会跨越多个服务,而每个服务又会有自己的数据库。
这个时候你再靠数据库本身的特性,还能保证整个业务的ACID吗?这可就不一定了。
我们来看一个例子啊。
比方说我这里有一个微服务,它里边啊包含三个服务啊,有订单有账户和库存。
现在,我们有一个用户下单的业务,用户下单时,我希望订单服务去创建订单,并且写入数据库。
然后,他再去调用账户服务和库存服务,账户服务呢,去扣减用户的余额,而库存服务呢,则去扣减商品库存。
那你可以看到这个业务里边就包含了三个不同的微服务的调用,而每个微服务都有自己独立的数据库,也就是独立的事务。
那我们最终希望的肯定是我这个下单业务一旦执行,每一个是不是都要成功?当然,如果你失败,是不是大家都失败?
1.1 演示分布式事务问题
结果是这样一个的结果,但是能不能达到这样一个效果?我们来验证一下。
微服务结构如下:
其中:
seata-demo:父工程,负责管理项目依赖
- account-service:账户服务,负责管理用户的资金账户。提供扣减余额的接口
- storage-service:库存服务,负责管理商品库存。提供扣减库存的接口
- order-service:订单服务,负责管理订单。创建订单时,需要调用account-service和storage-service
我们先来看一下这个order(订单服务)。看下它里边的业务逻辑啊,在controller里边啊我们可以看到一个创建订单的接口。
在controller当中呢,它就调了service,所以我们进去入service方法。
在这个service方法当中 ,我们可以看到它先去创建订单,把这个订单数据直接写到数据库当中。
那创建完订单了就去调用accountClient (扣用户余额)和storageClient(扣库存)完成扣余额和扣库存。
accountClient 和 storageClient 是通过 Feign调用的。
这是这三张表的数据。
业务逻辑就是这样的了,我们接下来使用Postman去做一下测试。
我们发送请求。
返回了500,我们看一下数据库。
发现用户余额少了200。
订单并没有创建
库存也没有减少。
这个时候事务的状态是一致的吗?不是吧?
那为什么会这样子呢?
那在刚才的业务当中,我们的订单服务去创建了订单。
然后去调用账务服务和库存服务,完成余额扣减和库存扣减。
其中,订单和账务服务啊,都执行成功了。
而库存服务在执行的时候却因为库存不足而报错了。
那按照理论上讲,这里一报错,前边是不是都应该跟着回滚啊?但是我们所看到的结果是库存服务失败了,账户的余额该扣还是扣了?为什么呢?
第一,我们的每一个服务都是独立的。
那现在库存服务你抛了异常。
账户服务它知不知道?它是不知道的呀!
那我都不知道你抛异常了,我去回滚什么呢?
第二,每一个服务是独立的,所以他们的事务呢,也是独立的。
那现在我订单服务和账务服务,我执行完业务以后,我事务结束了,我是不是直接就提交了呀?
现在你让我回滚,我怎么回滚?我事都办完了,提交了,就撤销不了了。
所以最终就没有达成事务状态的一致,那么这个时候啊,就出现了分布式事务的问题了!
1.2 什么是分布式事务
那我们总结一下什么是分布式事务。
在分布式系统下一个业务,它跨越了多个服务和数据源。每一个服务都可以认为是一个分支事务,而我们要保证的是所有分支事务最终状态一致。
要么大家都成功,要么大家都失败。那么这样的一种事务就是分布式事务了。
那为什么分布式事务出现了问题?
就是因为各个服务之间,或者说各个分支事务之间互相是感知不到的,大家各提交各的,那将来呀,就无法去回滚,就导致状态无法一致。
2、理论基础
接下来我们就进入分布式事务理论基础的学习。
解决分布式事务问题,需要一些分布式系统的基础知识作为理论指导。
2.1 CAP定理
CAP定理是1998年啊,加州大学的计算机科学家Eric Brewer 提出的,那它说分布式系统里边往往有三个指标。
分别是:
- Consistency(一致性)
- Availability(可用性)
- Partition tolerance (分区容错性)
那艾瑞克说呢,这三个指标啊,分布式系统它不可能同时满足。
你像这三个圆,不就是分别三个特性吗?
但是你看这三个圆不会出现三个同时重叠啊,最多就是两两重叠。
那么这个结论就叫CAP定理了。那为什么会出现这样一个情况呢?
我们必须得先弄清楚啊,一致性,可用性和分区容错性代表的含义才能理解这个其中含义。
2.1.1.一致性
那我们先来看一下其中的第一个,一致性。
一致性是说用户在访问分布式系统中的任意节点时得到的数据必须是一致的。比方说我现在有两个结点。
那第一个结点上面有一个数据叫data值是v0,第二个结点上也是如此。那它们其实就形成了一个什么呢?主从。
现在用户去访问这两个节点啊,不管访问的是谁,拿到结果是不是都一样的?
但是呢,现在如果我对node 1节点的数据发生了修改。
这个时候两个节点数据是不是就不一样了?
那为了满足一致性,你要做什么?
你是不是一定要把node 01的数据同步给node 02啊?
一旦两者的数据同步完成,数据是不是再次一致了?所以呢,作为一个分布式系统。
在做数据备份的时候,你一定要及时的去完成数据同步,这样才能满足一致性。
2.1.2.可用性
第二个概念可用性。
它说用户在访问集群中的任意健康节点的时候啊,必须得到响应,而不是超时或者拒绝。
比方说我现在这个集群里就有三个节点啊。
正常情况下用户访问任何一个是不是都没问题。
现在啊,这三个节点没有出现宕机的情况。但是不知道什么原因啊,比如说这个node3,它的请求就会被阻塞或者拒绝了。
那所有请求进来根本就无法访问了。这个时候node3不就不可用了。所以可用性是指这个节点能不能被正常的访问。
2.1.3 分区容错
第三个概念 :分区容错。
分区是指因为网络的故障或者其他原因导致分布式系统中的部分节点与其他节点失去了连接,形成独立分区。
比方说还是这三个节点啊node 123。
然后用户呢,可以访问其中任意一个。
但是因为网络出现了故障,机器没有挂,然后node 3与node 1和node 2之间断开了连接。
node 1,node 2,正常访问啊,它们之间是能够感知到对方的,但node 3感知不到了。所以呢,此时整个集群就会被划分成两个区了。
那node1和node2它们俩是一个区,node3自己是一个分区。
这个时候如果有用户向node 02写入了一个新的数据。
那node 02是可以把数据同步给node 01的。
但是那么node 3上面有没有同步?
显然没有,因为他们感知不到了,怎么去做同步?
那这两个分区数据就不一致了。
那分区容错是什么意思呢?
容错就是不管集群有没有出现分区啊,整个系统也要持续对外提供服务。
2.1.4.矛盾
那也就是说,尽管你这儿分区了,那用户该访问是不是还要访问呢?
但是如果我现在去访问node1,我拿到的结果和访问node3拿到结果一样吗?不一样。
所以出现了数据不一致的情况,没有满足一致性。那如果我一定要满足一致性。
我应该怎么办?那我是不是可以这么做?
我让node 3它等待node 2这个网络的恢复和数据的同步。
在恢复之前。所有来访问我的请求,我都阻塞在这里,说你们等等我这数据还没好。
可不可以?
那如果这么做,我是不是就能够满足数据的一致性了?但是你的node3明明是一个健康的节点,结果进来的请求你都卡在这里,不让人家访问了。
那node3不就变成不可用了吗?所以它就不满足可用性了。
所以你现在就会发现当网络出现分区时,可用性和一致性是不是没有办法同时满足?但是呢,这个分区它又是不可避免的。
为什么这么说呢?
只要你是一个分布式系统,你的节点之间是不是一定是通过网络连接的?而你只要是通过网络连接的,你有没有办法保证网络100%永远是健康的?
这不可能吧?
所以我们可以认为凡是分布式系统分区一定会出现,既然分区一定会出现。
而你整个集群,又必须要对外提供服务,那也就认为.
Partition tolerance (分区容错性)一 定要实现,那么这个时候Consistency(一致性)和 Availability(可用性)之间,你是不是要做出抉择了?你要么Consistency,要么Availability。没有办法同时满足啊,
这也就是CAP 定理的一个原因了。
2.2 BASE理论
我们已经学习了CAP 的定理,我们知道在分布式系统下,因为分区不可避免,所以你不得不在一致性和可用性之间做出一个选择,但是这两个特性啊,其实都非常的重要,我一个都不想放弃,那我该怎么办呢?
好那么 BASE 理论正好可以解决这个问题.
BASE 理论它是对CAP 的一种解决的思路。其实呢,主要包含了三个思想:
- Basically Available (基本可用):分布式系统在出现故障时,允许损失部分可用性,即保证核心可用。
- **Soft State(软状态):**在一定时间内,允许出现中间状态,比如临时的不一致状态。
- Eventually Consistent(最终一致性):虽然无法保证强一致性,但是在软状态结束后,最终达到数据一致。
其实BASE理论正是对CAP里边,这种Consistency(一致性)和 Availability(可用性)的矛盾去做一种调和和选择。
那在CAP里边你要达到了一致性,你就要牺牲可用性,但是在BASE 里我们如果达到了强的一致性,你是要牺牲可用性,但不是不可用,而是部分可用性的一个牺牲或者临时的不可用。
2.3.解决分布式事务的思路
说了这么多的思想,它能不能去解决我们分布式事务的问题呢?
其实是可以的。那我们分布式事务里边出现了什么问题呢?
分布式事务当中往往包含n个子事务,每个事务各自执行和提交。结果呢,有些成功,有些失败了,这个时候大家的状态不一致。
而我们希望的就是这个分布式事务里边的每个子事务,大家最终状态一定要一致,要么都成功,要么都失败。
那我们基于base理论怎么样去解决这分布式事务呢?
第一种解决方案其实就是基于AP的模式。
AP模式:各子事务分别执行和提交,允许出现结果不一致,然后采用弥补措施恢复数据即可,实现最终一致。
也就是满足可用性,牺牲一定的一致性。比如说我们各个子事务,将来我们执行的时候分别去执行和提交,那有些成功有些失败了,那这叫什么?
这叫状态不一致。
也就是说你处于一个什么?
软状态了。
临时的不一致状态,没关系,为什么呢?执行完了以后我们各个子事务可以通个气。
互相看一看哎,你成功了吗?哦,我成功了呃,你成功了吗?哎,这么一对比发现有人失败了怎么办?
这个时候别着急啊,我们采取一个弥补的措施去恢复数据啊,那有的说已经提交了,没法恢复了呀,那我们可以做反向的操作呀,比如说你之前新增了一个对不对?
那我接下来我把它删了不就完了吗?
这样不就把数据又恢复到原来的状态了,那这样不就实现了最终一致了吗?
所以这种模式啊,其实就是一种AP的一种思想了,
那反过来呢,我可不可以达成强一致呢?哎,也是可以的。
CP模式:各个子事务执行后互相等待,同时提交,同时回滚,达成强一致。但事务等待过程中,处于弱可用状态。
之前是各个子事务啊,是分别执行和提交,你一上来全部执行完了,那么没法回滚,对不对?
但现在呢,我各个子事务执行完,别提交,互相等待,大家彼此看一看啊诶,我这执行完了,你执行完了没有?这样直到什么我们全部都执行完都没问题。
那我们同时提交或者中间有人失败了,那我们同时回滚,那么这样是不是就能达成强一致了?没有中间状态对不对?
只不过在这个过程中啊,你的各个子事务是不是要互相等待啊?等待彼此的执行嘛,所以在这个过程当中,你的服务其实是处于一个弱可用状态。
因为你会锁定资源啊,导致无法访问嘛。
你看我们是不是就基于base的这种理论来实现了分布式事务的一种解决的一个思想了?
后面我们解决分布式事务都会基于这样一个思想去做,但是无论你是CP还是AP,这里边有一个共同点那就是各个子事务将来要做一个互相的通信,去辨别对方的执行状态。
那么各个子事务之间怎么去通信呢?
所以呢,它就需要有一个协调者来帮助分布式事务中的各个子事务进行一个通信啊感知。对方的或者彼此的状态,那我们就举个例子啊,就以我们之前的那个下单为例。
用户下单调用订单服务,然后去调用账务服务和库存服务。那这个地方呢?我们就需要有一个事务的协调者了,然后每一个微服务都跟事务的协调者啊,保持一个联系。
业务来了以后啊,大家各自执行。如果你现在要做强一致,那好第三服务执行的时候不要提交啊。执行下单扣款服务,执行扣款库存服务,执行库存。
但是执行完了以后,结果发现库存失败了。
怎么知道的?他们要把自己的执行结果是不是告知这个协调者?然后这协调者一看有人失败了再通知他们将来去做这个回滚。
那这样大家是不是就能保持一致了?所以呢,这个事务的协调者啊,就起到了一个非常关键的作用了,那么在整个过程当中啊,我们参与分布式事务当中的每一个子系统的事务,我们称之为叫分支事务。
而整个分支事务称之为叫全局事务,所以事务协调者其实就是来去协调各个分支事务的状态的,让他们达成一致。
相关文章:
分布式事务理论基础
今天啊,本片博客我们一起来学习一下微服务中的一个重点和难点知识:分布式事务。 我们会基于Seata 这个框架来学习。 1、分布式事务问题 事务,我们应该比较了解,我们知道所有的事务,都必须要满足ACID的原则。也就是 …...
线性代数强化第三章
目录 一,关于A伴随,A逆与初等矩阵 二,分块矩阵 三,矩阵方程 一,关于A伴随,A逆与初等矩阵 如何证明行列式的值不能是0; 此秩为1. 法一: 法二: 不用看是列变换还是行变…...
搭建自己的私有 开源LoRaWAN 网络服务器(The ThingsStack)---之配置
介绍 这是使用 Docker 在您自己的硬件上安装 Things Stack Enterprise 或开源代码以运行您自己的私有 LoRaWAN 网络服务器的指南。 运行 The Things Stack 的方法有多种。 Things Stack 开源和企业发行版旨在在您自己的硬件上运行,本指南也对此进行了介绍。 对于具有高吞吐量的…...
多维时序 | MATLAB实现SCNGO-CNN-Attention多变量时间序列预测
多维时序 | MATLAB实现SCNGO-CNN-Attention多变量时间序列预测 目录 多维时序 | MATLAB实现SCNGO-CNN-Attention多变量时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.SCNGO-CNN-Attention超前24步多变量回归预测算法。 程序平台:无Attention适…...
clickhouse的删除和更新
clickhouse不擅长更新和删除操作,更新操作很重,更新是重新创建一个分区,更新完后,太混之前的 ClickHouse提供了DELETE和UPDATE的能力,这类操作被称为Mutation查询,它可以看作ALTER语句的变种。虽然Mutation…...
微前端 - qiankun
qiankun 是一个基于 single-spa 的微前端实现库,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。 本文主要记录下如何接入 qiankun 微前端。主应用使用 vue2,子应用使用 vue3、react。 一、主应用 主应用不限技术栈,只需要提…...
前端编辑页面修改后和原始数据比较差异
在软件研发过程中,会遇到很多编辑页面,有时编辑页面和新增页面长的基本上一样,甚至就是一套页面供新增和编辑共用。编辑页面的场景比较多,例如: 场景一、字段比较多,但实际只修改了几个字段,如…...
docker第一次作业
docker第一次作业 1.安装docker服务,配置镜像加速器 yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo sed -i sdownload.docker.commirrors.aliy…...
Springboot3.0.0+集成SpringDoc并配置knife4j的UI
环境:JDK17,Springboot3,springdoc2,knife4j 4 Springdoc本身也是集成了Swagger3,而knife4j美化了Swagger3的UI Knife4j官网: 快速开始 | Knife4j Springdoc官网 OpenAPI 3 Library for spring-boot 1.pom配置 由于此knife4j内依赖了S…...
电脑运行缓慢?4个方法,加速电脑运行!
“我电脑才用了没多久哎!怎么突然就变得运行很缓慢了呢?有什么方法可以加速电脑运行速度吗?真的很需要,看看我吧!” 电脑的运行速度快会让用户在使用电脑时感觉愉悦,而电脑运行缓慢可能会影响我们的工作效率…...
3.Docker 搭建 MySQL8.0
1、docker仓库搜索mysql docker search mysql2、docker仓库拉取mysql8.0 docker pull mysql:8.0 备注: docker pull mysql //默认拉取最新版本3、查看本地仓库镜像是否下载成功 docker images mysql:8.04、安装运行mysql8.0容器 docker run -p 3306:3306 --name…...
Mybatis的SqlSource SqlNode BoundSql
学习链接 MyBatis SqlSource解析 【Mybatis】Mybatis源码之SqlSource#getBoundSql获取预编译SQL Mybatis中SqlSource解析流程详解 Mybatis TypeHandler解析 图解 Mybatis的SqlSource&SqlNode - processon DynamicSqlSource public class DynamicSqlSource implement…...
html动态爱心代码【二】(附源码)
目录 前言 效果演示 内容修改 完整代码 总结 前言 七夕马上就要到了,为了帮助大家高效表白,下面再给大家带来了实用的HTML浪漫表白代码(附源码)背景音乐,可用于520,情人节,生日,表白等场景,…...
【Rust】Rust学习 第十六章无畏并发
安全且高效的处理并发编程是 Rust 的另一个主要目标。并发编程(Concurrent programming),代表程序的不同部分相互独立的执行,而 并行编程(parallel programming)代表程序不同部分于同时执行,这两…...
系统报错mfc100u.dll丢失的解决方法(完美解决dll问题)
系统文件mfc100u.dll丢失和出错,极有可能是盗号木马、流氓软件等恶意程序所导致,其感染相关文件并加载起来,一旦杀毒软件删除被感染的文件,就会导致相关组件缺失,游戏等常用软件运行不起来,且提示“无法启动…...
docker compose的用法
目录 一、Docker-Compose介绍 1.1 Docker-Compose的概述 1.2 Docker-Compose 用来实现Docker容器快速编排 1.3 Docker-compose模板文件简介 二、YAML简介 2.1 YAML的概述 2.2 YAML的基本语法规则 2.3 YAML支持的数据架构 三、配置内部常用字段 四、Docker-compose 常…...
Linux: 使用 ssh 连接其他服务器
通过ifconfig 查看要连接的服务器地址: ubuntuubuntu1804-0172:/media/sangfor/vdc$ ssh ubuntu192.168.11.49 输入要连接的服务器密码: ubuntua192.168.1149 s password: 连接服务器成功:...
[.NET/WPF] CommunityToolkit.Mvvm 异步指令
我们在开发中, 经常会有这样的需求: 点击按钮后, 进行一些耗时的工作工作进行时, 按钮不可再次被点击工作进行时, 会显示进度条, 或者 “加载中” 的动画 RelayCommand CommunityToolkit.Mvvm 中的 RelayCommand 除了支持最简单的同步方法, 还支持以 Task 作为返回值的异步方…...
热烈祝贺汇隆成功入选航天系统采购供应商库
经过航天系统采购平台的严审,浙江汇隆晶片技术有限公司成功入选中国航天系统采购供应商库。航天系统采购平台是航天系统内企业采购专用平台,服务航天全球范围千亿采购需求,目前,已有华为、三一重工、格力电器、科大讯飞等企业、机…...
2019年3月全国计算机等级考试真题(C语言二级)
2019年3月全国计算机等级考试真题(C语言二级) 第1题 负责数据库中查询操作的数据库语言是 A. 数据定义语言 B. 数据管理语言 C. 数据操纵语言 D. 数据控制语言 正确答案:C 第2题 有关系如下图所示,其违反了哪一类完整性约束 …...
MySQL 游标
文章目录 1.游标是什么2.MySQL 游标3.定义游标4.打开游标5.提取数据6.关闭游标参考文献 1.游标是什么 游标(Cursor)是一种用于处理查询结果集的数据库对象,它允许开发者按照特定的顺序逐行遍历查询结果集中的数据。游标通常用于在数据库中执…...
ElasticSearch 7.4学习记录(DSL语法)
上文和大家一起初次了解了很多ES相关的基础知识,本文的内容将会是实际企业中所需要的吗,也是我们需要熟练应用的内容。 面对ES,我们最多使用的就是查询,当我负责这个业务时,现不需要我去考虑如何创建索引,添…...
全志orangepi-zero2驱动编写2,控制电平高低
使用驱动编写控制高低电平 可看我前俩篇文章: 【1】全志orangepi-zeor2驱动编写 【2】驱动函数框架详解 检索芯片手册关键信息 知道GPIO基地址 知道PC偏移地址 知道想要控制的端口的信息 知道数据位如何操作 代码实操 驱动代码 #include <linux/fs.h&…...
软考高级系统架构设计师系列之:论文典型试题写作要点和写作素材总结系列文章四
软考高级系统架构设计师系列之:论文典型试题写作要点和写作素材总结系列文章四 一、论软件的静态演化和动态演化及其应用1.论文题目2.写作要点和写作素材二、论大规模分布式系统缓存设计策略1.论文题目2.写作要点和写作素材三、论基于REST服务的Web应用系统设计1.论文题目2.写…...
06.利用Redis实现点赞功能
学习目标: 提示:学习如何利用Redisson实现点赞功能 学习产出: 解决方案: 点赞后的用户记录在Redis的set数据类型中 1. 准备pom环境 <dependency><groupId>org.springframework.boot</groupId><artifactI…...
【React】生命周期和钩子函数
概念 组件从被创建到挂载到页面中运行,再到组件不用时卸载的过程。 只有类组件才有生命周期。 分为三个阶段: 挂载阶段更新阶段销毁阶段 三个阶段 挂载阶段 钩子函数 - constructor 创建阶段触发 作用:创建数据 之前定义状态是简写&…...
无涯教程-TensorFlow - 优化器
Optimizers是扩展类,其中包括用于训练特定模型的附加信息,Optimizers类使用给定的参数初始化,用于提高速度和性能,以训练特定模型。 TensorFlow的基本Optimizers是- tf.train.Optimizer 此类在tensorflow/python/training/opti…...
基于AQS+双向链表实现队列先进先出
学习AQS写的一个模拟案例 package com.tom.xiangyun.ch04_aqs;import com.tom.tuling.UnsafeFactory; import sun.misc.Unsafe;import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReentrantLock;/*** 使用双向链表实现队列** author 钟棋…...
无涯教程-Perl - time函数
描述 此函数返回自纪元以来的秒数(对于大多数系统,是1970年1月1日UTC,00:00:00;对于Mac OS,是1904年1月1日,00:00:00)。适用于gmtime和本地时间。 语法 以下是此函数的简单语法- time返回值 此函数返回自纪元后数秒的整数。 例 以下是显示其基本用法的示例代…...
CUDA Bug<三>当__global__函数出现里面所有输出的数组都随机赋值了
问题具体描述: eg. __global__ void Updata_HomJm(float* H,float *HJm,float* fr,float *gr,float* ur,float* urgrJm,float*wpd,float *w, float *wJm,int n) { int idx blockIdx.x*blockDim.x threadIdx.x;float t 0.0;//H*zpint idx_Ai idx*n;for (int j…...
银川怎么做网站/拉新推广一手接单平台
眼下我们项目是基于AngularJS和ionic框架开发的Hybrid App。支持android phone/pad, iPhone,iPad四个平台版本号。以及微信版。由于使用的技术有点新,所以做了这个内部的新人上手指引,对于想学习HTML5Hybrid App开发的同学也有參考价值。 合格…...
做试管婴儿的网站/百度指数移动版app
源码获取:博客首页 "资源" 里下载! 一、项目简述 功能: 前台: * 用户模块 * 分类模块 * 商品模块 * 购物车模块 * 订单模块 后台: * 管理员模块 * 分类管理模块 * 商品管理模块 * 订单模块…...
西宁网站开发/seo效果最好的是
之前一直对于integration的xml配置感到很无力,首先不知道可以用什么 节点名,然后又不知道节点内部的参数的作用。这两个问题一问出来会很模糊,看官方文档当然是你可以的,但是如果你忘记了或者不知道xml中命名空间 别名的声明和sch…...
营销导向网站建设/宁波优化seo软件公司
1、安装过程请点击移步 postcss-pxtorem官网解释点击进入 2、这里只修改了1中的如下部分 postCssPxToRem({// rootValue: 37.5, // 设计图最大宽度除以10 //比如750的宽就写成75 我这边是1125的宽rootValue ({ file }) {// 如果是 Vant 的样式就按照 37.5 处理转换// 如果…...
什么大的网站是帝国cms做的/搜索引擎营销案例分析题
语法:wait 解析:wait语句是一种不可综合的电平触发事件控制语句,有如下两种形式: 用法1: wait(条件表达式) 语句/语句块; 【举例】 wait(evt_flag 1b1) begin uvm_hdl_release("test_top.dut.block1.a&quo…...
清河县网站建设/打开百度一下
需要给表单的 class 添加值 $(#id).addClass(required); 给表单的 class 移除值 $(#id).removeClass(required);...