资损分布式系统并发互斥设计

小明java问道之路 小明java问道之路     2023-03-30     594

关键词:

📫作者简介:小明java问道之路,专注于研究 Java/ Liunx内核/ C++及汇编/计算机底层原理/源码,就职于大型金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的架构设计与演进、系统优化与稳定性建设。

📫 热衷分享,喜欢原创~ 关注我会给你带来一些不一样的认知和成长。

🏆 InfoQ签约作者、CSDN专家博主/后端领域优质创作者/内容合伙人、阿里云专家/签约博主、51CTO专家 🏆

🔥如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主~ 

本文目录

本文导读

一、 资损防控系统设计资损防控规范

二、系统层面的并发互斥控制

1、服务的并发请求控制(进程级)

2、服务内处理的并发请求控制(线程级)

三、常见并发互斥类资损风险

1、无状态迁移变化的控制

2、并发请求处理中,没有考虑到消息与调度场景

3、对内存中资源未做并发控制或并发控制不严格

4、数据脏读问题

5、常见的数据库锁操作问题

四、系统并发互斥设计

1、业务状态比较复杂的场景,使用状态机进行状态控制

2、并发请求的处理

3、数据操作的规范。一锁二判三改

4、多线程操作规范

5、避免死锁

总结


本文导读

并发互斥控制设计在整个分布式系统中,大到业务的并发处理、服务的并发请求,小到数据库表的并发读写、java对象的多线程访问,并发无处不在。因为并发,所以互斥。

一、 资损防控系统设计资损防控规范

从系统架构层面整体来看,支付公司的系统可以抽象为如下结构:

一、对外部商户提供收单服务类的系统

二、连通支付公司与各金融渠道的网关类系统

三、支付公司的内部业务处理系统

四、消息、调度等中间件系统

五、数据库、缓存等存储平台

​从系统架构与业务架构上来讲,各个结构连接的地方最容易出现资损。因此我们将从接口服务层面与系统设计层面对资损进行分析并总结相关规范。

二、系统层面的并发互斥控制

我们所说的系统层面的并发互斥控制,主要包括:

1、服务的并发请求控制(进程级)

服务的并发请求控制,服务的并发请求既包括dubbohttp等同步调用的场景也包括消息、调单等异步调用场景需要一起考虑。

此外,在业务处理中,还存在各种互斥的资金处理的场景与流程,也是我们需要在设计的时候考虑的。

2、服务内处理的并发请求控制(线程级)

服务内处理的并发请求控制,内存中的并发控制。主要是内存中的对象、线程变量等资源共享资源进行并发控制。

内存外的并发控制。主要是指内存外的存储资源,如数据库表的访问等的并发控制。

三、常见并发互斥类资损风险

1、无状态迁移变化的控制

在互斥的业务流程与场景中,业务处理过程中,无状态迁移变化的控制。复杂的场景中未使用状态机。或者状态机状态迁移合法性验证不全面。或者状态机设计不合理,使得状态迁移变化不可靠。

常见的状态机设计问题有:

1状态被执行有多次。如支付成功多次可能导致业务被推进多次。

2、终态还可以继续变化。如代发成功又变更为待支付。

3、互斥状态没有做并发控制。如发货和退款同时发生,同时成功。

4、状态机没有统一控制。

5、多个状态机耦合在一起,状态控制混乱。如交易核心支付状态、交易状态耦合在一起,由于不同的状态控制,导致支付状态成功交易状态失败的问题。

6、状态机的状态迁移被漏处理。

2、并发请求处理中,没有考虑到消息与调度场景

并发请求处理中,没有考虑到消息与调度场景,比如收单服务请求支付核心进行支付处理,同步响应结果和消息通知结果同时到达,未做并发处理,业务被推进了两次(可能申购了两次基金、也可能通知商户发货了两次)。

3、对内存中资源未做并发控制或并发控制不严格

多线程环境下,对内存中资源未做并发控制或并发控制不严格,尤其是对线程变量的使用。

如对共享数据访问不加锁、单例对象进行写操作、线程变量进出不清空等均会导致并发控制问题。

4、数据脏读问题

数据脏读,并根据脏数据做判断。需要注意的是,不仅仅是对数据库中的数据访问存在脏读,分布式缓存中的数据访问也存在脏读。

5、常见的数据库锁操作问题

为了防范脏读脏写、不可重复读等常见的数据库并发问题我们常用锁机制进行处理;不合理的锁使用会导致风险。

常见的问题有:

1、先读后锁而非先锁后读。读的数据不能保证是最新数据,会导致仍然基于脏数据做判断的风险。

2、批量update流水的时候,where条件中没有原有流水的状态,且没有判断更新条数。容易出现不可重复读的问题。

3、SQL语句中使用updatesetselect完成数据的更新,有可能导致update锁机制不生效。

4、锁没有顺序且未设置超时等退出机制(如SQL中未加nowait)导致死锁。

四、系统并发互斥设计

1、业务状态比较复杂的场景,使用状态机进行状态控制

业务状态比较复杂的场景,使用状态机进行状态控制,状态机是针对业务状态比较复杂的场景下,并发互斥控制比较常见的设计模式。如统一订单交易平台均使用状态机来进行业务状态的管理。

状态机设计过程中需遵循如下规范:

1、由于业务状态的迁移,可能由同步服务请求、异步消息、后台调度、用户操作、运营操作等多种情形触发。在此情况下,需要保证状态机统一进行控制,不能设计多个状态迁移变更模块。更不能设计多个状态机进行对不同情形做状态迁移。

2、要设计终态,且保证终态不能被继续迁移。如一笔交易订单的超时关闭就是终态,在设计上就要避免其不能再次迁移为待支付。

3、要保证状态迁移和业务处理的一致性。

4、设计中,针对状态迁移的处理,需要对所有可能的状态做判断。极端情况下可以判断所有的状态。

5、由于业务状态比较复杂,为防止状态机状态设计腐化,与状态机实现代码表现不一致。状态机不能只根据文字描述进行开发,要先设计或更新状态迁移表或状态迁移图;可以明确表达出入口状态(初始状态)、终态、状态跃迁路径。

6、不能用同一个状态字段表达多种状态迁移。简单的业务处理,可能不使用状态机进行状态迁移的并发控制。但仍然需要使用统一模块进行状态控制、并考虑多种情况下的并发请求做好业务的并发与互斥处理。

2、并发请求的处理

并发请求的处理,针对分布式环境下的并发请求的处理多是基于数据库或分布式缓存等资源等进行并发访问控制。

常见的并发访问控制模型主要有如下几种:

1、基于资源的并发控制(悲观)。

这是比较经典的并发控制模型,使用较多,如账务系统中的记账操作就使用该模型控制用户账户余额的并发更改。

2、基于资源的并发控制(乐观)

 由于是在第4点更新领域对象的时候检查并发,其实整个过程中并没有锁定任何对象和记录。所以采用该机制的时候,系统应该要容许不可重复读问题的出现。

3、基于分布式锁服务的并发控制分布式锁可以借助分布式缓存实现。

3、数据操作的规范。一锁二判三改

1、一定要保证先锁后读,避免脏读。数据库可以使用selectforupdate这种模型进行加锁。

2、提交的时候要判断更新的数据的状态是否符合要求,避免不可重复读。要在SQL的where条件中增加原有流水的状态,且检查了update方法返回的记录条数是否满足预期。如果是状态机的状态进行update的时候,要基于状态迁移来写where条件中的前置状态值,wherestatus=xx或者wherestatusin(xxyy)。update的结果,影响行数0、1N的时候处理逻辑均需要实现。

3、不要使用updatesetselect完成数据的更新有可能导致update锁机制不生效。

4、多线程操作规范

多线程操作规范需要遵循常规的java并发操作规范,保证操作的原子性。代码开发的指导原则应该是:尽可能的避免在多线程间共享数据、共享操作;如果要共享数据,需要对共享数据加锁;尽可能的使用spring提供的单例框架配置单例的bean;不要对单例的bean进行写操作;业务代码开发过程中,尽可能的避免使用线程变量使用线程变量的时候,一定要在出入口进行清空。...。。

5、避免死锁

无论是数据库还是分布式锁服务或者jvm内部的锁,在可能发生死锁的场景,加锁的时候需要通过加锁排序和设置超时时间等方式避免死锁。

总结

并发互斥控制设计在整个分布式系统中,大到业务的并发处理、服务的并发请求,小到数据库表的并发读写、java对象的多线程访问,并发无处不在。因为并发,所以互斥。

资损业务产品分析资损防控规范

...点赞、收藏三连支持👍一下博主~ 本文目录前言一、资损防控系统设计资损防控规范二、常见业务产品分析资损风险三、常见业务产品分析资损防控点四、业务参数调整资损风险1、常见的业务参数调整资损风险2、常见业务... 查看详情

分布式系统互斥性与幂等性问题的分析与解决

...在不断演进。传统的集中式系统已经逐渐无法满足要求,分布式系统被使用在更多的场景中。分布式系统由独立的服务器通过网络松散耦合组成。在这个系统中每个服务器都是一台独立的主机,服务器之间 查看详情

高并发大访问量架构设计演进之路归纳总结

...进之路归纳总结第01:大型架构的演进之路第02(上):分布式缓存第02(下):分布式缓存第03:分布式消息队列第04:分布式数据存储第05:分布式服务框架第06:高性能系统架构第07:高可用系统架构第08:系统的安全架构第09... 查看详情

ja17-大型电商分布式系统应用实践+性能优化+分布式应用架构+负载均衡+高并发设计+持久化存储视频教程

JA17-大型电商分布式系统应用实践+性能优化+分布式应用架构+负载均衡+高并发设计+持久化存储视频教程新年伊始,学习要趁早,点滴记录,学习就是进步!不要到处找了,抓紧提升自己。对于学习有困难不知道如何提升自己可以... 查看详情

redis实现分布式锁

1、使用背景几乎每个互联网公司中都使用了分布式部署,分布式服务下,就会遇到对同一个资源的并发访问的技术难题,如秒杀、下单减库存等场景。这些场景有一个共同特点就是访问量激增,虽然在系统设计时... 查看详情

分布式系统设计

一、分布式系统基础设施简介1、分布式协作及配置管理系统ZooKeeper2、分布式缓存系统   分布式缓存主要用于高并发环境下,减轻数据库的压力,提高系统的响应速度和并发吞吐。当大量的读、写请求涌向数据库时,... 查看详情

高并发系统设计

...通用设计方法横向扩展:组合多台性能机器组成一个分布式集群来共同抵御并发流量的冲击纵向扩展:不断提升CPU性能缓存:磁盘寻道ms级,CPU指令和内存寻址在纳秒级,异步架构分层什么是分层架构整体系统... 查看详情

互联网三高设计之高并发

一、什么是​高并发​高并发(HighConcurrency)是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计保证系统能够同时并行处理很多请求。高并发相关常用的一些指标有响应时间(ResponseTime),吞吐量(Thr... 查看详情

分布式架构“高并发”--详解

...高并发    高并发(HighConcurrency)是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计保证系统能够同时并行处理很多请求。    高并发相关常用的一些指标有   &nb... 查看详情

分布式锁那点事

    为什么要使用分布式锁  为了保证一个方法在高并发情况下的同一时间只能被同一个线程执行,在传统单体应用单机部署的情况下,可以使用Java并发处理相关的API(如ReentrantLcok或synchronized)进行互斥控制。但是,随着... 查看详情

高并发解决思路

...2、机器多了也扛不住了?服务拆分,把集中式部署改成分布式部署。(提升QPS)3、分布式了还是扛不住?先做降级,再做限流。(保证系统可用性)4、数据库扛不住了?上分布式缓存。(降低RT)5、缓存上了之后,数据还是扛... 查看详情

高并发系统的设计及秒杀实践

...采用了各种各样技术,前端静态资源压缩整合、使用CDN、分布式SOA架构、缓存、数据库加索引、读写分离等等。这些技术是高并发系统所必须的,但是今天先不细说,而先谈谈在这些架构既定的情况下,一些高并发业务/接口实... 查看详情

dubbo框架----探索-大型系统架构设计(图解)

...  3.高可用  4.面向服务架构(Dubbo框架使用)  5.分布式缓存(redis分布式缓存)  6.分布式全文检索(solr分分布式全文检索)  7.分布式数据库集群(mycat集群mysql数据库) dubbo 简介 系统架构 redis集群&... 查看详情

redis分布式锁

分布式锁的应用场景在传统单机部署的情况下,可以使用Java并发处理相关的API(如synchronized)进行互斥控制。但是在分布式系统后,由于分布式系统多线程、多进程并且分布在不同机器上,这将使原单机并发控制锁策略失效,A服... 查看详情

互联网架构“高并发”

...e/1048632一、什么是高并发高并发(HighConcurrency)是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计保证系统能够同时并行处理很多请求。高并发相关常用的一些指标有响应时间(ResponseTime),吞吐量(... 查看详情

20165223《信息安全系统设计基础》第八周学习总结

...的方式:进程、线程、I/O多路复用2.掌握线程控制及相关系统调用3.掌握线程同步互斥及相关系统调用二、学习内容教材第12章《并发编程》实验楼教程1.并发程序并发程序:使用应用级并发的应用程序。现代操作系统提供了三种... 查看详情

一文带你领略并发编程的内功心法

...务,线程可以以不同的方式进行通信和协作。并发模型和分布式系统很相似并发模型其实和分布式系统模型非常相似,在并发模型中是​​线程​​​彼此进行通信,而在分布式系统模型中是​​进程​​彼此进行通信。然而本... 查看详情

java架构师,微服务架构设计,并发编程,java8新特性,p2p金融项目,高并发,分布式

微服务架构设计微服务       软件架构是一个包含各种组织的系统组织,这些组件包括Web服务器,应用服务器,数据库,存储,通讯层),它们彼此或和环境存在关系。系统架构的目标是解决利益相关者的关注点... 查看详情