程序员过关斩将--重复的请求并不好过滤

为什么要做重复请求的过滤呢?不过滤不行吗?

过滤重复请求很难吗?加一个请求ID不就好了吗?

每个技术难点的话题,肯定是由一个产品需求引发的,俗话说:如果没有产品经理,程序员将不需要听诊器,但是会失业!!

产生背景

重复请求能够对系统造成伤害是架构中很难避免的一个设计问题,一般情况下,读请求很少会造成致命性的故障,主要是系统的写请求,很多时候一个重复写的动作,会是我们程序员加班的缘由。比如:用户使用积分兑换物品,重复的请求会造成用户积分的重复扣减,而作为线上系统,如果日志等辅助打的不好的话,排查原因其实需要很多时间。

一般的产品经理设计系统的时候并不会涉及到这类异常情况,但是一旦出现问题,产品经理就会找到程序员骂娘,多么悲哀的故事,人家付出5分精力设计的系统,我们却要花费10分的精力去编码和维护。

重复的业务请求,有的时候对系统造成的影响很大,所以程序员在设计的时候尤其要注意,产生的原因有很多:

  • 黑客进行了拦截,人为的重放了请求

  • 客户端因为某些原因,用户在很短的时间内重放了请求

  • 一些中间件(比如网关)重放了请求

  • 未知的其他情况

道理很简单,用一张图表达的会更清爽一些

image

抽象出来是不是很简单?但是落地却并非像这张图一样简单!!

从这张图上一眼就可以看到,整个过程的重点难点在于过滤器这个逻辑设计部分,这部分可以和业务代码融合在一起,有的时候也可以相分离,比如:有的网关可以内嵌脚本(比如:lua),就完全可以做到和业务无关,但是通常情况下,落地的代码却和业务息息相关。

客户端处理

客户端处理重复请求是一种可以有效过滤正常请求的手段,为什么这么说呢?当一个用户正常操作的时候,客户端完全可以利用loading的方式或者其他过滤重复手段来达到目的,比如:当用户点击一个按钮的时候,弹出loading窗口方式用户再次操作。

再比如:客户端可以设置一个类似于布隆过滤的数据结构,配合对应的过滤算法也可以达到过滤重复请求的效果。

不过,客户端的任何解决方案也只是治标不治本,毕竟,客户端在整个系统架构中,是最不可靠的终端。

请求标识

重复请求过滤的关键在于过滤器的逻辑设计,目前最常用,落地最多当属使用请求ID的方式。大体流程如下:

  1. 客户端发送请求的时候,会生成随机的请求ID,随着业务参数一起传送到服务端

  2. 服务端会根据传送上来的请求ID做是否重复的判断

服务器的判断逻辑其实有很多落地方案了,比如最常见的利用redis来存储请求ID,以下是伪代码(NetCore):

public class Para
{public string ReqId{get ;set ;}  //其他业务参数
}public bool IsExsit(Para p)
{//利用redis来判断当前的key是否存在bool isExsit=redisMethond(p.ReqId);//如果存在,则说明是重复请求,如果不存在说明不是重复请求,并且添加到redisif(!isExsit){AddRedis(p.ReqId);}return isExsit;}

一般网上的文章都到此为止了,这种方案有没有问题呢?答案:有

问题1

正常的客户端重复请求,一般情况下真的会根据我们写的代码过滤掉重复请求,为什么说一般情况呢?那是因为分布式的原因,极限情况下也会导致重复的请求到业务处理端,比如以下情况:

  1. 请求被路由到了A服务器,A服务器会去请求Redis,判断是否有相同的请求ID存在,如果是第一次请求,Redis会返回不存在

  2. 同样的时间,客户端或者黑客重放了同样的请求,这个请求被路由到了B服务器,B服务器同样会请求Redis来判断是否存在,这个时候由于A服务器还没回写Redis,所以B服务器得到的结果也是不存在该请求

  3. 这样就导致了业务端收到了两次同样的请求,会导致业务不可预期的结果

可见,一个小小重复过滤请求,可能还需要分布式锁的出场才可以

问题2

即便请求中加了唯一的请求ID,但是这个ID并没有安全保证,或者说,这个ID是可以篡改的。当黑客拦截到请求,随便改一下请求ID,在重放就搞定你了。所以,加的请求ID,还需要一个安全机制来保证安全,不然这个参数其实意义不大。

业务签名

由于单纯添加请求ID,并不能解决问题,所以我们需要一种保证请求ID的机制,目前来看,普遍的落地方案是根据业务参数生成摘要,也就是所谓的加签操作。加签操作可以有效的防止参数被篡改。如果你做过微信相关的开发,你会发现和微信服务器的交互也是基于加签操作的。而生成的签名可以作为请求ID,以下是伪代码:

    //客户端生成签名string sigh=MD5($"参数1=值1&参数2=值2&time=当前时间戳")

以上只是例子,虽然MD5算法有产生重复数据的可能性,但是对于当前这个业务场景来说足够了。细心的同学会发现,参数当中加了一个时间戳的参数,这个是我故意加的,这个时间戳在这个场景下会出现问题,什么问题呢?

时间戳问题

当前的请求场景是要过滤重复的请求,什么样的请求算是重复请求呢?关键是这个定义要明确,我看了很多重复过滤请求的文章,重复请求这个概念其实定义的不好,这个是和具体业务场景相关的。举个栗子:当用户一秒内重复点击某个按钮算是重复请求,那10秒内重复点击呢?用户一秒之内对同一个商品下单算重复请求,那10秒内呢?

这个定义就涉及到了上面所说的时间戳参数的问题,时间戳是否要参与生成签名,要根据具体的业务场景来定义,不过,我还是要建议,请求的参数中带上时间戳,无论它参不参与签名,至于为什么这么做,当时间长了你就知道了

写在最后

过滤重复请求这个需求,并没有像想象中那么容易,并非只要加上一个请求ID就完事了,它涉及到安全以及分布式的问题,在某些场景下(比如:秒杀)还会涉及到性能以及高可用等非功能性问题,所以那些说:只需要一个请求ID就能过滤的同学,请不要再误导别人了,技术是神圣不可侵犯的。

还是那句话:具体的业务影响到具体的代码实现,脱离业务讲架构其实就是耍流氓

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/303551.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET团队送给.NET开发人员的云原生学习资源

企业正在迅速采用云的功能来满足用户需求,提高应用程序的可伸缩性和可用性。要完全拥抱云并优化节约成本,就需要在设计应用程序时考虑到云的环境,也就是要用云原生的应用开发方法。这意味着不仅要更改应用程序的构建方式,还要更改…

深夜,学妹说她想做Python数据分析师

大家好,我是大鹏,目前是一名数据分析师。上周末晚上,我的学妹突然约我出来喝咖啡。想起学妹在学校就一直说想转行,最近在网上捣鼓自学数据分析软件有一小段时间了。我想她不是为了叙旧。果然来到咖啡店,她一屁股坐下来…

在真实工作中的编程是怎么样的,与学校里有什么不同?

学校里每门编程语言课程都是上一点上不完的,实验课写的代码最长一两百行。 而在真实的工作环境中,程序员写代码是怎么样的?每天要啪啪啪手敲成千上万行代码嘛?和在学校学习时写代码有什么异同呢?/*说说我的经验*/刚进公…

聊一聊Docker与时区

前言 当我们把应用部署到容器里面之后,基本都会要和时间/时区打交道!!大部分的应用,多多少少都会有获取当前时间的操作,试想一下应用拿到的时间不对,那么业务极有可能会乱套,造成严重的损失。时…

百度竟然不是中国的

2019独角兽企业重金招聘Python工程师标准>>> 身份之谜—百度是中国公司吗? 虽然,Baidu在美国上市使用了“中国的Google”这么一个概念,说真的,我知道的Baidu和Google最大的共同点也许就是他们都是美资公司。Baidu公司…

tortoisegit图标消失_安装TortoiseGit 状态图标不能正常显示

如果你安装 TortoiseSVN 之后,功能使用正常,但是文件夹或文件左上角就是不显示图标,那么你可能1. 64bit 系统上装了 32bit 的 TortoiseSVN解决方法是,再安装 64bit 的 TortoiseSVN,两者可并行运行2. Windows Explorer …

好用的验证框架FluentValidation(上)

把数据错误扼杀在早期,那就是在数据的入口处,一般数据都是打包成一个实体的方式进传递,FluentValidation就以实体类为单位进行属性验证的集合。Install-Package FluentValidation下面看一个例子吧。实体类:public class Person {p…

10G 职场晋升/IT干货/生活技能/理财秘籍 【全套】学习资料免费送!

你的同龄人正在抛弃你,大学毕业后五年,你就会发现,同龄人之间的差距已经是云泥之别。当年一起追剧,一起逃课,一起吹牛的同学,有人已经年薪百万,有人还在抢两块钱的红包。有人去过许多国家&#…

iNeuOS工业互联平台,发布消息管理、子用户权限管理、元件移动事件、联动控制、油表饼状图和建筑类设备驱动,v3.4版本...

目 录1. 概述... 22. 平台演示... 23. 消息管理... 24. 子用户权限管理... 35. 元件移动事件... 36. 联动控制... 47. 增加油表和饼图... 58. 增加住建部DL/T645和智能液位计协议驱动1. 概述发布iNeuOS 3.4版本,主…

程序猿看段子,越看越心碎!

程序员整天面对代码,压力一定很大吧~小编表示应该时不时也给你们来点段子,增加一下生活的乐趣,让你们看到希望的曙光...今天整理的10个段子,你们绝对喜欢。看看就知道啦!【一直有人问我,程序员应该看什么书…

mysql写入监控_zabbix 自定义key 监控mysql增删查改

vim /etc/zabbix/zabbix_agentd.d/mysql.conf##zabbix_agentd.d在这个文件夹下的.conf,都会被agent读取,我们这里新建的一个配置文件方便使用,这样就不需要去动主配置文件了UserParameterecho[*],echo "$1"#要传递参数要带[*],且ke…

自制H3C交换机CONSOLE线

单位有一台H3C S3600交换机,手痒痒的想进入玩一下。 从网上查得,连接CONSOLE接口用的是串口,只不过用RJ45水晶头插入而已。 山高路远,囊中羞涩,刚好手头上有一个文曲星的连接线,串口的。 凭自己半桶水的电子…

5月份Github上最热门的数据科学和机器学习项目

GitHub最近以数十亿美元的交易被微软收购。GitHub一直是开发人员之间协作的终极平台,我们已经看到数据科学和机器学习社区同样非常需要它,因此,我们希望GitHub能在微软的保护下继续发展下去。在本月排行中,上榜的项目有英特尔开源…

Blazor 中如何下载文件到浏览器

Blazor 中如何下载文件到浏览器目录一、前言二、方法一(导航跳转)三、方法二(下载后传出)(一) 使用 RestSharp 下载(二) 使用 BlazorDownloadFile 传出独立观察员 2021 年 3 月 28 日一、前言最近想给之前文章《下载中转加速器 VP…

荐书 | 5本数学科普让你不再“畏惧”数学,感受数学的内在美

最近,小木了解了许多关于数学的书籍,简直打开了小木数学新世界的大门。出版社寄了一些样书给小木,经过斟酌对比之后,推荐以下5本数学科普书给大家。01《数学简史》[中] 蔡天新 43.50提到数学,很多人的第一反应就是复杂…

ASP.NET Core依赖注入初识与思考

一、前言在上一篇中,我们讲述了什么是控制反转(IoC)以及通过哪些方式实现的。这其中,我们明白了,「控制反转(IoC)」 是一种软件设计的模式,指导我们设计出更优良,更具有松耦合的程序&#xff0c…

memcached mysql缓存_memcached做数据库缓存

最近研究memcache小有成果,把经验分享出来。白话:很早就听说memcache了,一直没搞懂,后来又看到redis很火,可以用来做缓存,研究了半天也没搞懂咋个做缓存,后来也不纠结了,继续学习python,当对pyt…

掌握Python爬虫基础,仅需1小时!

随着互联网的发展,google、百度等搜索引擎让我们获取信息愈加方便。但需求总会不断涌现,纯粹地借助百度等收集信息是远远不够的,因此编写爬虫爬取信息的重要性就越发凸显。比如有人为了炒股,专门爬取了多种股票信息;也…

我看ITIL在中国(六):如何建立有中国特色的IT运维管理平台【二】

在开始筹划建设有“中国特色的IT运维管理平台”之前,先来看看我们目前面临的情况: 随着信息化建设的不断深入,各种企业的核心业务都逐步地迁移到IT平台上来,对IT管理的要求也越来越高,IT需要管理,向IT管理要…

史上首次!世界杯使用视频裁判

2018年6月16日18时,法国队在喀山中央球场迎来了他们本届世界杯的首场比赛,对手是澳大利亚队。比赛进行到第56分钟,格列兹曼接到队友的直塞球,单刀杀入禁区,澳大利亚后卫里斯登铲球,但并没有碰到皮球&#x…