电商(强一致性系统)的场景设计
领域拆分:如何合理地拆分系统?
一般来说,强一致性的系统都会牵扯到“锁争抢”等技术点,有较大的性能瓶颈,而电商时常做秒杀活动,这对系统的要求更高。业内在对电商系统做改造时,通常会从三个方面入手:系统拆分、库存争抢优化、系统隔离优化。
业务拆分的方法有很多,最简单便捷的方式是:先从上到下做业务流程梳理,将流程归类聚合;然后从不同的领域聚合中找出交互所需主要实体,根据流程中主要实体之间的数据依赖程度决定是否拆分(从下到上看);把不同的实体和动作拆分成多个模块后,再根据业务流程归类,划分出最终的模块(最终汇总)。这个拆分过程用一句话总结就是:从上往下看流程,从下往上看模块,最后综合考虑流程和模块的产出结果。用这种方式能快速拆出模块范围,拆分出的业务也会十分清晰。
强一致锁:如何解决高并发下的库存争抢问题
由于秒杀场景是库存争抢非常经典的一个应用场景,接下来我会结合秒杀需求,带你看看如何实现高并发下的库存争抢,相信在这一过程中你会对锁有更深入的认识。
锁争抢的错误做法
public class ThreadCounter {private static int count = 0;public static void main(String[] args) throws Exception {Runnable task = new Runnable() {public void run() {for (int i = 0; i < 1000; ++i) {count += 1;}}};Thread t1 = new Thread(task);t1.start();Thread t2 = new Thread(task);t2.start();t1.join();t2.join();cout << "count = " << count << endl;}
}
这段代码,count预期是2000,但是一般都会小于2000。对于这个情况,我们一般都会用到锁或原子操作来保护库存变量:
如果是简单 int 类型数据,可以使用原子操作保证数据准确;
如果是复杂的数据结构或多步操作,可以加锁来保证数据完整性。
不过锁操作是很影响性能的,在讲锁方式之前,我先给你介绍几个相对轻量的方式。
前面我们提到当有大量用户去并行修改一个变量时,只有用锁才能保证修改的正确性,但锁争抢性能很差,那怎么降低锁的粒度、减少锁的争枪呢?
举个例子,当前商品库存有 100 个,我们可以把它放在 10 个 key 中用不同的 Redis 实例保存,每个 key 里面保存 10 个商品库存,当用户下单的时候可以随机找一个 key 进行扣库存操作。如果没库存,就记录好当前 key 再随机找剩下的 9 个 key,直到成功扣除 1 个库存。
除了这种方法以外,我个人更推荐的做法是使用 Redis 的原子操作,因为原子操作的粒度更小,并且是高性能单线程实现,可以做到全局唯一决策。而且很多原子操作的底层实现都是通过硬件实现的,性能很好
redis> decr prod_1475_stock_1
incr、decr 这类操作就是原子的,我们可以根据返回值是否大于 0 来判断是否扣库存成功。但是这里你要注意,如果当前值已经为负数,我们需要考虑一下是否将之前扣除的补偿回来。并且为了减少修改操作,我们可以在扣减之前做一次值检测,整体操作如下:
//读取当前库存,确认是否大于零
//如大于零则继续操作,小于等于拒绝后续
redis> get prod_1475_stock_1
1//开始扣减库存、如返回值大于或等于0那么代表扣减成功,小于0代表当前已经没有库存
//可以看到返回-2,这可以理解成同时两个线程都在操作扣库存,并且都没拿到库存
redis> decr prod_1475_stock_1
-2//扣减失败、补偿多扣的库存
//这里返回0是因为同时两个线程都在做补偿,最终恢复0库存
redis> incr prod_1475_stock
0
这看起来是个不错的保护库存量方案,不过它也有缺点,相信你已经猜到了,这个库存的数值准确性取决于我们的业务是否能够返还恢复之前扣除的值。如果在服务运行过程中,“返还”这个操作被打断,人工修复会很难,因为你不知道当前有多少库存还在路上狂奔,只能等活动结束后所有过程都落地,再来看剩余库存量。
而要想完全保证库存不会丢失,我们习惯性通过事务和回滚来保障。但是外置的库存服务 Redis 不属于数据库的缓存范围,这一切需要通过人工代码去保障,这就要求我们在处理业务的每一处故障时都能处理好库存问题。所以,很多常见秒杀系统的库存在出现故障时是不返还的,并不是不想返还,而是很多意外场景做不到。
令牌库存
具体是使用 Redis 中的 list 保存多张令牌来代表库存,一张令牌就是一个库存,用户抢库存时拿到令牌的用户可以继续支付:
//放入三个库存
redis> lpush prod_1475_stock_queue_1 stock_1
redis> lpush prod_1475_stock_queue_1 stock_2
redis> lpush prod_1475_stock_queue_1 stock_3
//取出一个,超过0.5秒没有返回,那么抢库存失败
redis> brpop prod_1475_stock_queue_1 0.5
在没有库存后,用户只会拿到 nil。当然这个实现方式只是解决抢库存失败后不用再补偿库存的问题,在我们对业务代码异常处理不完善时仍会出现丢库存情况。同时,我们要注意 brpop 可以从 list 队列“右侧”中拿出一个令牌,如果不需要阻塞等待的话,使用 rpop 压测性能会更好一些。
不过,当我们的库存成千上万的时候,可能不太适合使用令牌方式去做,因为我们需要往 list 中推送 1 万个令牌才能正常工作来表示库存。如果有 10 万个库存就需要连续插入 10 万个字符串到 list 当中,入库期间会让 Redis 出现大量卡顿。
多库存秒杀
如果产品侧提出“一个商品可以抢多个库存”这样的要求,也就是一次秒杀多个同种商品(比如一次秒杀两袋大米
这时候你应该发现了,在“一个商品可以抢多个库存”这个场景下,拆分并没有减少锁争抢次数,同时还加大了维护难度。当库存越来越少的时候,抢购越往后性能表现越差,这个设计已经不符合我们设计的初衷
系统隔离:如何应对高并发流量冲击?
我曾经在一家教育培训公司做架构师,在一次续报活动中,我们的系统出现了大规模崩溃。在活动开始有五万左右的学员同时操作,大量请求瞬间冲击我们的服务器,导致服务端有大量请求堆积,最终系统资源耗尽停止响应。我们不得不重启服务,并对接口做了限流,服务才恢复正常。究其原因,我们习惯性地将公用的功能和数据做成了内网服务,这种方式虽然可以提高服务的复用性,但也让我们的服务非常依赖内网服务。当外网受到流量冲击时,内网也会受到放大流量的冲击,过高的流量很容易导致内网服务崩溃,进而最终导致整个网站无法响应。事故后我们经过详细复盘,最终一致认为这次系统大规模崩溃,核心还是在于系统隔离性做得不好,业务极易相互影响。
如果系统隔离性做得好,在受到大流量冲击时,只会影响被冲击的应用服务,即使某个业务因此崩溃,也不会影响到其他业务的正常运转**。这就要求我们的架构要有能力隔离多个应用,并且能够隔离内外网流量,只有如此才能够保证系统的稳定。**
为了提高系统的稳定性,我们决定对系统做隔离改造,具体如下图:
也就是说,每个内、外网服务都会部署在独立的集群内,同时每个项目都拥有自己的网关和数据库。而外网服务和内网必须通过网关才能访问,外网向内网同步数据是用 Kafka 来实现的。
网关隔离和随时熔断
网关隔离和随时熔断在这个改造方案中有两种网关:外网网关和内网网关。每个业务都拥有独立的外网网关(可根据需要调整)来对外网流量做限流。当瞬时流量超过系统承受能力时,网关会让超编的请求排队阻塞一会儿,等服务器 QPS 高峰过后才会放行,这个方式比起直接拒绝客户端请求来说,可以给用户更好的体验。外网调用内网的接口必须通过内网网关。外网请求内网接口时,内网网关会对请求的来源系统和目标接口进行鉴权,注册授权过的外网服务只能访问对其授权过的内网接口,这样可以严格管理系统之间的接口调用.
同时,我们在开发期间要时刻注意,内网网关在流量增大的时候要做熔断,这样可以避免外网服务强依赖内网接口,保证外网服务的独立性,确保内网不受外网流量冲击。并且外网服务要保证内网网关断开后,仍旧能正常独立运转一小时以上。但是你应该也发现了,这样的隔离不能实时调用内网接口,会给研发造成很大的困扰。要知道常见外网业务需要频繁调用内网服务获取基础数据才能正常工作,而且内网、外网同时对同一份数据做决策的话,很容易出现混乱。
减少内网 API 互动
为了防止共享的数据被多个系统同时修改,我们会在活动期间把参与活动的数据和库存做推送,然后自动锁定,这样做可以防止其他业务和后台对数据做修改。若要禁售,则可以通过后台直接调用前台业务接口来操作;活动期间也可以添加新的商品到外网业务中,但只能增不能减。
这样的实现方式既可以保证一段时间内数据决策的唯一性,也可以保证内外网的隔离性.
只有保证数据同步是单向的,才能取消相互锁定操作。我们可以规定所有库存决策由外网业务服务决定,后台对库存操作时必须经过外网业务决策后才能继续操作,这样的方式比锁定数据更加灵活。而外网交易后要向内网同步交易结果,只能通过队列方式推
后台系统推送数据到 Redis 或数据库中,外网服务通过 Kafka 把结果同步到内网,扣减库存需通知外网服务扣减成功后方可同步操作。
外网与内网的区别:
外网是一般是针对用户端,直接对接用户使用,需要做公网解析;
内网一般是公司技术服务节点,不需要公网解析且不对外服务,都是外网服务上做单独解析才能访问内网服务,访问内网会比公网获取数据速度更快,减少了一层解析。
一般大点的公司都会做外网和内网隔离,以保障服务安全和稳定。
分布式事务:多服务的2PC、TCC都是怎么实现的?
目前业界流行微服务,DDD 领域驱动设计也随之流行起来。DDD 是一种拆分微服务的方法,它从业务流程的视角从上往下拆分领域,通过聚合根关联多个领域,将多个流程聚合在一起,形成独立的服务。相比由数据表结构设计出的微服务,DDD 这种方式更加合理,但也加大了分布式事务的实现难度。
在传统的分布式事务实现方式中,我们普遍会将一个完整的事务放在一个独立的项目中统一维护,并在一个数据库中统一处理所有的操作。这样在出现问题时,直接一起回滚,即可保证数据的互斥和统一性。**不过,这种方式的服务复用性和隔离性较差,很多核心业务为了事务的一致性只能聚合在一起。**为了保证一致性,事务在执行期间会互斥锁定大量的数据,导致服务整体性能存在瓶颈。
好在目前业内有很多实现分布式事务的方式,比如 2PC、3PC、TCC 等,但究竟用哪种比较合适呢?这是我们需要重点关注的。
XA 协议
XA 协议是一个很流行的分布式事务协议,可以很好地支撑我们实现分布式事务,比如常见的 2PC、3PC 等。而理解了 XA 协议,对我们深入了解分布式事务的本质很有帮助。
支持 XA 协议的数据库可以在客户端断开的情况下,将执行好的业务结果暂存起来,直到另外一个进程确认才会最终提交或回滚事务,这样就能轻松实现多个数据库的事务一致性。
在 XA 协议里有三个主要的角色:
应用(AP):应用是具体的业务逻辑代码实现,业务逻辑通过请求事务协调器开启全局事务,在事务协调器注册多个子事务后,业务代码会依次给所有参与事务的子业务下发请求。待所有子业务提交成功后,业务代码根据返回情况告诉事务协调器各个子事务的执行情况,由事务协调器决策子事务是提交还是回滚(有些实现是事务协调器发请求给子服务)。
事务协调器(TM):用于创建主事务,同时协调各个子事务。事务协调器会根据各个子事务的执行情况,决策这些子事务最终是提交执行结果,还是回滚执行结果。此外,事务协调器很多时候还会自动帮我们提交事务;
资源管理器(RM):是一种支持事务或 XA 协议的数据资源,比如 MySQL、Redis 等。
另外,XA 还对分布式事务规定了两个阶段:Prepare 阶段和 Commit 阶段。
在 Prepare 阶段,事务协调器会通过 xid(事务唯一标识,由业务或事务协调器生成)协调多个资源管理器执行子事务,所有子事务执行成功后会向事务协调器汇报。这时的子事务执行成功是指事务内 SQL 执行成功,并没有执行事务的最终 commit(提交),所有子事务是提交还是回滚,需要等事务协调器做最终决策。接着分布式事务进入 Commit 阶段:当事务协调器收到所有资源管理器成功执行子事务的消息后,会记录事务执行成功,并对子事务做真正提交。如果 Prepare 阶段有子事务失败,或者事务协调器在一段时间内没有收到所有子事务执行成功的消息,就会通知所有资源管理器对子事务执行回滚的操作。
我们以购物场景为例,在购物的整个事务流程中,需要协调的服务有三个:用户钱包、商品库存和用户购物订单,它们的数据都放在私有的数据库中。
按照业务流程,用户在购买商品时,系统需要执行扣库存、生成购物订单和扣除用户账户余额的操作 。其中,“扣库存”和“扣除用户账户余额”是为了保证数据的准确和一致性,所以扣减过程中,要在事务操作期间锁定互斥的其他线程操作保证一致性,然后通过 2PC 方式,对三个服务实现事务协调。
2PC 事务不仅容易理解,实现起来也简单。不过它最大的缺点是在 Prepare 阶段,很多操作的数据需要先做行锁定,才能保证数据的一致性。并且应用和每个子事务的过程需要阻塞,等整个事务全部完成才能释放资源,这就导致资源锁定时间比较长,并发也不高,常有大量事务排队。除此之外,在一些特殊情况下,2PC 会丢数据,比如在 Commit 阶段,如果事务协调器的提交操作被打断了,XA 事务就会遗留在 MySQL 中。而且你应该已经发现了,2PC 的整体设计是没有超时机制的,如果长时间不提交遗留在 MySQL 中的 XA 子事务,就会导致数据库长期被锁表。
3PC 简述。与 2PC 相比,3PC 主要多了事务超时、多次重复尝试,以及提交 check 的功能。但因为确认步骤过多,很多业务的互斥排队时间会很长,所以 3PC 的事务失败率要比 2PC 高很多。为了减少 3PC 因资源锁定等待超时导致的重复工作,3PC 做了预操作,整体流程分成三个阶段:CanCommit 阶段:为了减少因等待锁定数据导致的超时情况,提高事务成功率,事务协调器会发送消息确认资源管理器的资源锁定情况,以及所有子事务的数据库锁定数据的情况。PreCommit 阶段:执行 2PC 的 Prepare 阶段;DoCommit 阶段:执行 2PC 的 Commit 阶段。总体来说,3PC 步骤过多,过程比较复杂,整体执行也更加缓慢,所以在分布式生产环境中很少用到它,这里我就不再过多展开了。
TCC 是 Try-Confirm-Cancel 的缩写,从流程上来看,它比 2PC 多了一个阶段,也就是将 Prepare 阶段又拆分成了两个阶段:Try 阶段和 Confirm 阶段。TCC 可以不使用 XA,只使用普通事务就能实现分布式事务。
首先在 Try 阶段,**业务代码会预留业务所需的全部资源,**比如冻结用户账户 100 元、提前扣除一个商品库存、提前创建一个没有开始交易的订单等,这样可以减少各个子事务锁定的数据量。业务拿到这些资源后,后续两个阶段操作就可以无锁进行了。
在 Confirm 阶段,业务确认所需的资源都拿到后,子事务会并行执行这些业务。执行时可以不做任何锁互斥,也无需检查,直接执行 Try 阶段准备的所有资源就行。请注意,协议要求所有操作都是幂等的,以支持失败重试,因为在一些特殊情况下,比如资源锁争抢超时、网络不稳定等,操作要尝试执行多次才会成功。
最后在 Cancel 阶段:如果子事务在 Try 阶段或 Confirm 阶段多次执行重试后仍旧失败,TM 就会执行 Cancel 阶段的代码,并释放 Try 预留的资源,同时回滚 Confirm 期间的内容。注意,Cancel 阶段的代码也要做幂等,以支持多次执行
最后,我们总结一下 TCC 事务的优点:并发能力高,且无长期资源锁定;当然,它的缺点也很明显:只适合短事务,不适合多阶段的事务;相关事务逻辑要求幂等;存在执行过程被打断时,容易丢失数据的情况。
目前,市面上有很多优秀的中间件,比如 DTM、Seata,它们对分布式事务协调做了很多的优化,比如过程中如果出现打断情况,它们能够自动重试
相关文章:
电商(强一致性系统)的场景设计
领域拆分:如何合理地拆分系统? 一般来说,强一致性的系统都会牵扯到“锁争抢”等技术点,有较大的性能瓶颈,而电商时常做秒杀活动,这对系统的要求更高。业内在对电商系统做改造时,通常会从三个方面…...
算法与数据结构(一)
一、时间复杂度 一个操作如果和样本的数据量没有关系,每次都是固定时间内完成的操作,叫做常数操作。 时间复杂度为一个算法流程中,常数操作数量的一个指标。常用O(读作big O)来表示。具体来说,这个算法流程中,发生了多…...
【Python】元组如何创建?
嗨害大家好鸭!我是小熊猫~ Python 元组 Python 的元组与列表类似, 不同之处在于元组的元素不能修改。 元组使用小括号,列表使用方括号。 元组创建很简单,只需要在括号中添加元素, 并使用逗号隔开即可。 如下实例…...
qt操作文件以及字符串转换
//从文件加载英文属性与中文属性对照表QFile file(":/propertyname.txt");if (file.open(QFile::ReadOnly)) {//QTextStream方法读取速度至少快百分之30#if 0while(!file.atEnd()) {QString line file.readLine();appendName(line);}#elseQTextStream in(&file)…...
数组中只出现一次的两个数字(异或法思路)
题目简介 一个数组中只有2个数字只有一个,其他数字都有两个。找出这两个数字。a, b 用HashMap记录就不说了。 这里记录一下用异或的方式解决。 由于异或特性为自己异或自己为0。a^a 0;所以可以异或数组中的所有数字得出 a^b 的结果,其他相同的都消掉…...
python支持的操作系统有哪些
支持python开发环境的系统有Linux、OSX和windows,以及所有主要的操作系统中。 Linux,Linux系统是为编程而设计的,因此在大多数Linux计算机中,都默认安装了Python。编写和维护Linux的人认为会使用这种系统进行编程。要在Linux中运…...
S3C2440开发环境搭建
拿出了之前的S3C2440开发板,然后把移植uboot、移植内核、制作根文件系统、设备树编写驱动等几项再做一遍,这篇文章先记录下环境搭建过程,以及先把现成的uboot、内核、根文件系统下载进去,看看开发板还能不能用,先熟悉一…...
软件测试之测试用例
测试用例 1. 测试用例定义 测试用例又叫做test case,是为某个特殊目标而编制的一组测试输入、执行条件以及预期结果,以便测试某个程序路径或核实是否满足某个特定需求。 2. 编写测试用例的原因 2.1 理清思路,避免遗漏 如果测试的项目大而复杂&#…...
null和undefined的区别有哪些?
null和undefined的区别有哪些?相同点不同点undefinednull总结相同点 1.null和undefined都是js的基本数据类型 2.undefined和null都是假值(falsy),都能作为条件进行判断,所以在绝大多数情况下两者在使用上没有区别 if(undefined)…...
【强烈建议收藏:计算机网络面试专题:HTTP协议、HTTP请求报文和响应报文、HTTP请求报文常用字段、HTTP请求方法、HTTP响应码】
一.知识回顾 之前我们一起学习了HTTP1.0、HTTP1.1、HTTP2.0协议之前的区别、以及URL地址栏中输入网址到页面展示的全过程&&DNS域名解析的过程、HTTP协议基本概念以及通信过程、HTTPS基本概念、SSL加密原理、通信过程、中间人攻击问题、HTTP协议和HTTPS协议区别。接下来…...
关于Java中的静态块讲解
文章目录类的加载特性与时机类加载的特性类加载的时机static的三个常用地方什么是静态块?特点写法静态块 static怎么用?类的加载特性与时机 在介绍static之前可以先看看类的相关 类加载的特性 在JVM的生命周期里,每个类只会被加载一次。 类加载的原则…...
ledcode【用队列实现栈】
目录 题目描述: 解析题目 代码解析 1.封装一个队列 1.2封装带两个队列的结构体 1.3封装指向队列的结构体 1.4入栈函数实现 1.5出栈函数实现 1.6取栈顶数据 1.7判空函数实现 题目描述: 解析题目 这个题我是用c语言写的,所以队列的pu…...
【基础算法】双指针----字符串删减
🌹作者:云小逸 📝个人主页:云小逸的主页 📝Github:云小逸的Github 🤟motto:要敢于一个人默默的面对自己,强大自己才是核心。不要等到什么都没有了,才下定决心去做。种一颗树,最好的时间是十年前…...
Billu靶场黑盒盲打——思路和详解
一、信息收集 1、探测内网主机IP可以使用各种扫描工具比如nmap,我这里用的是自己编写的。 nmap -n 192.168.12.0/24 #扫描IP,发现目标主机 2、先不着急,先收集一波它的端口(无果) nmap -n 192.168.12.136 -p 1-10000…...
【2363. 合并相似的物品】
来源:力扣(LeetCode) 描述: 给你两个二维整数数组 items1 和 items2 ,表示两个物品集合。每个数组 items 有以下特质: items[i] [valuei, weighti] 其中 valuei 表示第 i 件物品的 价值 ,we…...
【C++提高编程】C++全栈体系(二十四)
C提高编程 第三章 STL - 常用容器 九、map/ multimap容器 1. map基本概念 简介: map中所有元素都是pairpair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)所有元素都会根…...
c++11 标准模板(STL)(std::unordered_set)(十一)
定义于头文件 <unordered_set> template< class Key, class Hash std::hash<Key>, class KeyEqual std::equal_to<Key>, class Allocator std::allocator<Key> > class unordered_set;(1)(C11 起)namespace pmr { templ…...
AI/CV大厂笔试LeetCode高频考题之基础核心知识点
AI/CV互联网大厂笔试LeetCode高频考题之基础核心知识点算法复习1、二叉树的遍历2、回溯算法3、二分搜索4、滑动窗口算法题5、经典动态规划6、动态规划答疑篇6.1、总结一下如何找到动态规划的状态转移关系7、编辑距离8、戳气球问题9、最长公共子序列 Longest Common Subsequence…...
华为OD机试题,用 Java 解【静态扫描最优成本】问题
最近更新的博客 华为OD机试题,用 Java 解【停车场车辆统计】问题华为OD机试题,用 Java 解【字符串变换最小字符串】问题华为OD机试题,用 Java 解【计算最大乘积】问题华为OD机试题,用 Java 解【DNA 序列】问题华为OD机试 - 组成最大数(Java) | 机试题算法思路 【2023】使…...
常见无线技术方案介绍
无线技术 无线网络大体有两种:WAN(广域网)、PAN(个人区域网)。 对于LoRa,NB-IoT,2G / 3G / 4G等无线技术,通常传输距离超过1 km,因此它们主要用于广域网(WA…...
收获满满的2022年
收到csdn官方的证书,感谢官方的认可!...
react的生命周期
目录 一、初始化阶段 constructor() static getDerivedStateFromProps() componentWillMount() / UNSAFE_componentWillMount() render(): componentDidMount() 二、运行阶段 componentWillUpdate() / UNSAFE_componentWillUpdate() render() getSnapsh…...
scanpy 单细胞分析API接口使用案例
参考:https://zhuanlan.zhihu.com/p/537206999 https://scanpy.readthedocs.io/en/stable/api.html scanpy python包主要分四个模块: 1)read 读写模块、 https://scanpy.readthedocs.io/en/stable/api.html#reading 2)pp Prepr…...
【Vue3 第二十一章】Teleport组件传送
一、基本使用场景 有时我们可能会遇到这样的场景:一个组件模板的一部分在逻辑上从属于该组件,但从整个应用视图的角度来看,它在 DOM 中应该被渲染在整个 Vue 应用外部的其他地方。 这类场景最常见的例子就是全屏的模态框。理想情况下&#…...
在 Windows Subsystem for Linux (WSL2) 的 Ubuntu 系统上配置 Vulkan 开发环境
在 Windows Subsystem for Linux (WSL2) 的 Ubuntu 系统上配置 Vulkan 开发环境Vulkan Tutorial https://vulkan-tutorial.com/ Development environment - Linux https://vulkan-tutorial.com/Development_environment 1. Vulkan - Cross platform 3D Graphics https://www…...
放苹果HJ61
入门题目 把m个同样的苹果放在n个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?注意:如果有7个苹果和3个盘子,(5,1,1)和(1,5&#…...
Windows下,OPC UA移植,open62541移植
OPC通信标准的核心是互通性 (Interoperability) 和标准化 (Standardization) 问题。传统的OPC技术在控制级别很好地解决了硬件设备间的互通性问题,在企业层面的通信标准化是同样需要的。OPC UA之前的访问规范都是基于微软的COM/DCOM技术, 这会给新增层面的通信带来不可根除的…...
【Tomcat与Servlet篇1】认识Tomcat与Maven
目录 一、什么是Tomcat 二、Tomcat的几个重要目录 conf文件编辑 Server.xml logs文件 Webapps目录 三、如何使用Tomcat 但是,如果出现了点击之后进行闪退的情况,那又是怎么回事呢? 原因1:环境变量没有配置 原因2&#…...
C++类和对象:拷贝构造函数和运算符重载
目录 一. 拷贝构造函数 1.1 什么是拷贝构造函数 1.2 编译器默认生成的拷贝构造函数 1.3 拷贝构造函数特性总结 二. 运算符重载 2.1 运算符重载概述 2.2 比较运算符重载(> > < <) 2.2.1 >运算符的重载 2.2.2 运算符的重载 2.…...
【IntelliJ IDEA】idea plugins搜索不出来,如何找到插件的解决方案
一、背景描述安装好IDEA后,想下载一些插件来使用,因为IDEA非常方便的一点就是插件使用非常的方便,但是经常会发现进入到插件市场无法搜索到插件的情况,这个时候就有点烦人了。那么怎么解决这个问题呢?以下会把我能想到…...
怎样做一个微信小程序/谷歌优化的网络公司
core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump. (linux中如果内存越界会收到SIGSEGV信号,然后就会core dump) 在程序运行的过程中,有的时候我们会遇到Segment fa…...
上海专业网站建设价格低/西安网站seo服务
先概括一下飞流有四个特点。 第一,释放用户,减少用户开发成本,所以说这个系统是不需要用户编程,只需要登录个网页,点点配置一下,然后等下,数据就出来了。这是很重要的一个点,也是我们…...
公司制作网站怎么做的/郑州网络营销推广机构
Closing期末结算【02年结流程】 (2016-11-02 23:05:51) 转载▼ 标签: 年结 ajab f.07 f.16 2kes 分类: FI财务会计【原创】 (加作者微信索取无水印PDF完整版) 在会计年度结束时需要将总账科目、供应商&客户、固定资产价值的年末余额结转…...
查询网站日流量/产品推广方案模板
1.选择器 2.样式属性 3.布局 4.浏览器原理 以妓会友,评赞走起 转载于:https://www.cnblogs.com/lgyong/p/8617044.html...
六安哪家做网站好/推广费用一般多少钱
知乎视频www.zhihu.com在 Windows10 系统中,有这五个小秘密,你可能还不太知道。001. 任务栏的宽度是可以随意改变的。对于有的人来说,无意中会发现电脑突然任务栏变宽,不知道该怎么办。其实你只需要在任务栏上单击右键ÿ…...
怎样注册免费网站/成都百度业务员电话
锁2—预备知识Java的AQS ****************** 如有侵权请提示删除 ******************* 1、概念: 所谓AQS,指的是AbstractQueuedSynchronizer,它提供了一种实现阻塞锁和一系列依赖FIFO等待队列的同步器的框架,ReentrantLock、Sema…...