前言
现在稍具规模的网站和大型应用都不再是单机模式,而是分布式应用,基于多机的集群构建的应用,这样服务能力就可以基本实现横向扩容(scale out),不会像单机模式下的纵向扩容(scale up)会受到单机服务能力上限的限制。另外,随着“微服务”概念的火爆,很多应用在构建之初就已经走在了分布式的路线上了,所以就目前行业的发展来看,基于分布式的应用会越来越普遍,甚至变成常态。加上docker这些容器技术的出现,应用分布式化的工具也越来越成熟。
分布式的复杂性
众所周知,构建分布式应用所面临的复杂度远远超出集中式的单一应用,导致复杂性的因素有很多,在此只提其中一点:网络的不可靠性。在单一进程内部,对一个函数的调用,结果只有两种——成功和失败,失败的情况下,调用者可以决定做一些事情弥补。但是在跨进程的调用中,对一个远程(也可以在同一个节点上)进程上运行的函数调用除了会得到成功和失败,还会有第三种的情况——超时,这个现象被称为分布式的三态。这也是困扰分布式应用构建的最核心因素之一,很多分布式应用的复杂度之所以上升这么多也是因为三态之中的超时引起的。
简单看看超时给我们带来的困扰,进程A调用进程B上的函数f,对于成功和失败的结果,相信和单机下一样,进程A都可以进行很好地的处理,因为结果是很明确的。如果进程A调用f之后,在允许的等待最大时间内没有返回结果,就是调用超时了,此时进程A能做什么?其实进程A什么都做不了,因为超时是一个不明确的结果——成功和失败都有可能。详细解释下可能的情况:
- 成功的情况:进程A把数据通过网络传输到进程B上,f执行成功,通 网络返回执行结果给进程A,可是网络不太好,传输失败了,进程A并 未在指定时间内收到结果,认为超时了。
- 失败的情况:情况和成功的情况差不多,只是f执行失败了,但是结 果依然传输失败,进程A也认为执行超时了。
- 未执行的情况:进程A的数据发送到进程B所在的节点过程中网络失败 了,或者发送到了进程B所在的机器上,但是进程B没有消费掉在TCP 网络层的数据等等
由此可见,进程A对于超时确实无能为力,有太多的可能存在的情况了。但是分布式协作过程中又必须解决这个问题,不然分布式应用是没意义的,这种情况下,一般会采用让进程A尝试重试——即重复发起之前的调用。但是这样也可能会带来问题,因为超时的那次调用可能已经成功了,再次以同样的参数调用f会不会带来额外的问题?这就引出本文的主角——幂等性。
幂等性
幂等性本来是一个数学概念,在计算机方面用来表示对同一个过程应用相同的参数多次和应用一次产生的效果是一样,这样的过程即被称为满足幂等性。
有了这个概念之后,假如之前的f是满足幂等性的,那么是不是意味着进程A在调用f超时之后,可以继续重复调用f多次?这样最起码进程A可以在超时情况下做一些促进事情正向发展的努力。所以这种方式是分布式节点间常用的方式,那么如何保证幂等呢?
如何实现幂等性
在考虑实现幂等之前,先看看有哪些操作是天然幂等的,以SQL为例。update tab1 set col1 = 1 where id = 2这样的更新语句,无论执行多少次结果都是不受影响的,所以是幂等的。update tab1 set col1 = col1 + 1 where id = 2这样的更新语句会随着每次更新不断变化,所以不是幂等的。所以在考虑之前,先识别出幂等和非幂等操作。
业务系统实现幂等的通用方式:一般是排重表校验,在业务操作所在的库建一张小表,名称暂时搞成dup_forbidden,核心字段就一个biz_id,并且在这个字段上建立一个unique index,其他字段可以根据业务需求来扩充。那么原来的业务f实现幂等的伪代码如下:
begin transaction;
count = insert ignore dup_forbidden (...biz_id...) value(...biz_id...)
if(count >0){
f(biz_id)
}
commit;
可以认为这是一套业务系统实现幂等的模板做法,通过insert ignore返回值来判断是否已经执行过了,但是针对不同的情况可能还有变化。使用事务的目的是为了保证f和dup_forbidden的操作同时成功和失败。本质上来看,dup_forbidden表就是通过unique index来屏蔽对f的多次调用,事实上很多业务已经存在dup_forbidden表的功能。
考虑如下场景:在一个面向交易的分布式应用中,支付子系统完成了支付功能,支付子系统通知订单子系统,通知的方式无非是调用订单子系统的一个函数f而已,只是调用的方式分为同步和异步。无论是同步还是异步,f都可能存在超时,所以为了支持重试,f必须是幂等的。f会首先根据传入的订单号来查找订单,检查订单状态。如果是已经支付,就会直接返回成功。如果是待支付状态,那么会尝试锁定(悲观锁和乐观锁)订单,修改状态,指定其他操作,其中锁定只是为了防止并发操作。伪代码实现如下:
begin transaction;
count = update deal_tab set status = paid where id = xx_id and status = unpaid
if(count >0){
f(xx_id)
}
commit;
从这个例子可以看出deal_tab订单表本身已经可以作为dup_forbidden表的作用了,所以insert防重操作变成update来实现,当然这个是乐观锁的版本。悲观锁的版本如下:
begin transaction;
deal =select*from deal_tab where id = xx_id for update
if(deal.status == paid){
returntrue;
}elseif(deal.status = unpaid){
f(xx_id)
}
commit;
当然基于悲观锁的做法对于高并发的系统是不建议的,毕竟长时间锁定记录会降低系统的TPS。
当然,所有这些方案都是基于业务存在唯一的业务编号来设计实现的,可能会存在完全没有业务编号的吗?答案是it depends。即使没有完全唯一的编号,我们也可以人为生成编号,比如调用方负责生成调用编号,同一个调用编号发起的多次调用都被视为一次调用,既可以作为唯一键来排重。事实上,这种情况确实比较少!
总结
业务系统实现幂等性的方式基本确定。系统关键接口的幂等性为以后系统的长期发展,特别是往分布式方向发展打下了很好的根基,可以大大简化分布式应用的构建复杂度。
相关推荐
这是一个用Python编写的日历拼图求解程序,主要用来解决以下问题:给定8块不规则形状的拼图,在一个7x7的网格中拼出所有可能的日期组合。程序需要确保每次拼图都恰好留出两个空格,分别代表月份(1-12)和日期(1-31,根据月份不同天数不同)。 程序的核心算法采用深度优先搜索(DFS),通过不断尝试不同的拼图放置位置、旋转角度和翻转方式来寻找所有可能的解。为了提高运行效率,程序使用了多进程并行计算,同时利用NumPy进行矩阵运算,大大提升了计算速度。 此外,程序还包含了一些实用的功能,比如解的查重、结果保存、进度日志等。它不仅能找出所有可能的日期组合,还会将结果以易读的格式保存到文件中。对于想要研究组合优化问题或者对拼图游戏感兴趣的同学来说,这是一个不错的参考示例。
库存报表1113
法律事务_
百分点:2024年4月食品餐饮行业舆情分析报告.pdf
进程间通信.pptx
ISO协议和SAE协议对应关系.docx
基于uniapp校园帮外卖跑腿快递代拿平台设计【可发布到小程序和HTML5】毕业源码案例设计Uniapp_Campus_Help_Delivery基于uniapp校园帮外卖跑腿快递代拿平台设计【可发布到小程序和HTML5】毕业源码案例设计开发软件 Eclipse或者Idea + HbuilderX + Mysql + Redis开发技术uni-app 是一个使用vue的语法+微信小程序的标签和API的跨平台接口框架,开发者编写一套代码,可编译到iOS、Android、H5、小程序等多个平台,几乎覆盖所有流量端端接口符合java语言的Springboot技术开发后台登录地址http://localhost:8888/gp/login管理员账号密码 admin/123456用户账号密码ys4/123456骑手账号密码pt4/123456功能介绍系统共有3个身份用户、跑腿员和管理员,其中用户和跑腿员在移动端实现,管理员在web端登录管理,在移动端可以注册成为用户或者跑腿人员。用户登录后可以发布订单的订单,订单分类有很多外卖订单、购物订单、快递订单
测绘工程_
配电网自动化技术—配电网馈线监控终端.pptx
内容概要:本文探讨了通过微调预训练语言模型(LMs)来构建更好的语言智能体的方法。研究提出了一个新的方法——FireAct,它利用从多个任务和提示方法生成的任务解决轨迹数据对小型模型进行微调,提高了模型在自然问答任务中的表现、鲁棒性和泛化能力。实验表明,通过这种多元化的学习支持,语言智能体能够更好地应对噪声环境、跨任务泛化,并提高效率和性能。 适合人群:对语言模型微调及应用感兴趣的学术研究人员和工程技术人员。 使用场景及目标:本文的研究旨在推动语言智能体的发展,特别是提升它们在多任务场景下的推理能力和行动效果。主要应用场景包括基于文本的知识检索、复杂问题解答和工具交互等。 其他说明:作者详细展示了不同数据规模、提示方式以及模型大小对微调效果的影响,为未来进一步探索提供了有益的指导。同时,文章强调了多方法和多任务混合微调的重要性和潜力,为进一步优化语言智能体指明了方向。
教学教务系统原型设计
wygdove 本科毕业设计一个集成医疗传感器,室内传感器,及调用外部环境数据的综合平台。主要对应一个人的身体健康检测,人的周围环境,以及外界大环境,以人为主体的智能医疗系统。
非常好的python学习资料包含笔记+源代码+教程100%好用.zip
洗衣店全球市场报告:2023年洗衣机零售额高达934亿元,潜力无限 在快节奏的现代生活中,衣物清洁与保养成为了人们日常不可或缺的需求之一。洗衣店,作为这一需求的直接响应者,正悄然经历着一场前所未有的变革。在这片充满机遇的海域中,如何精准把握市场脉搏,有效利用技术创新提升服务品质,成为了众多洗衣店企业亟需解答的关键问题。本文将深入探讨洗衣店市场的现状、趋势及咨询服务的重要性,为您揭示这片蓝海的无限潜力。 市场概况 近年来,洗衣店市场展现出强劲的增长势头。据QYR最新调研,2023年洗衣机全渠道零售量达到4005万台,零售额高达934亿元,这一数据不仅反映了家庭洗涤需求的持续扩大,也间接映射出洗衣店作为专业洗涤服务提供商的市场潜力。随着生活水平的提高和消费观念的转变,消费者对衣物清洁的品质要求日益提升,传统的家庭洗涤方式已难以满足高端面料和特殊衣物的保养需求,这为洗衣店行业提供了广阔的发展空间。预计未来几年,受智能洗涤设备、自助洗衣柜、线上预约平台等新兴业务模式的推动,洗衣店市场将保持年均10%以上的增长率,市场规模持续扩大。 技术创新与趋势 技术创新是推动洗衣店行业转型升级的核心动力。智
3690-机械设计制造及其自动化
DCP-7090/7095D/7190DN/7195DW DCP-B7500D/B7520DW/B7530DN/B7535DW DCP-L2510D/L2511D/L2512D/L2530DW DCP-L2531DW/L2532DW/L2535D/L2535DW DCP-L2536D/L2537DW/L2550DN/L2550DW DCP-L2551DN/L2551DW/L2552DN HL-L2390DW/L2395DW MFC-7390/7490D/7890DN/7895DW MFC-B7700D/B7715DW/B7720DN MFC-L2690DW/L2710DN/L2710DW/L2712DN MFC-L2712DW/L2713DW/L2715D/L2715DW MFC-L2716D/L2716DW/L2717DW MFC-L2730DW/L2732DW/L2750DW/L2750DWXL
faster rcnn算法pytorch版本,按requirements.txt文件配置即可。
信息化教学基本理论省公共课一等奖全国赛课获奖课件.pptx
内容概要:本文档主要介绍了Westport Channel(简称WPC)与Logan Beach(简称LGB)两个硬件设备的DPLL固件更新方法,以及I2C驱动器的具体编程指南。文章从WPC和LGB的针脚布局开始,逐步讲解了连接设置方式、固件升级步骤和可能出现的问题及其解决办法,最后还附带了Microchip DPLL固件升级工具的安装指导和操作截图。 适用人群:适用于需要进行网络接口卡固件维护的技术人员、IT管理员或有一定电子技术背景的研发工程师。 使用场景及目标:为确保通信系统的稳定性和安全性,对网络适配器的关键部件如数字锁相环路(DPLL)实施正确的固件升级是必要的。文档详细指导用户完成这一过程,避免错误导致的设备故障。 其他说明:本文档为Intel公司的内部资料,涉及多项技术细节,仅供授权用户查阅。阅读前请确保已准备好相关软硬件环境并严格按照指引执行。对于复杂情况,可咨询Intel技术支持获取帮助。