如果遇到用户短时间内会触发多次重复的请求,且每次请求都会耗费一定的资源,所以希望,多次重复请求,只处理一个请求,然后返回结果。但是又希望再用户发送请求的时候,尽可能最快的返回结果。不考虑前端,只考虑后端,应该如何做比较好。
我在后端用了缓存,来防止后续的请求进行操作。但是后续的请求,应该是让他们以空结果返回呢(这样会造成用户的得到的结果为空吗?),还是让他们设定一个时间都挂起来停滞,直到第一个的请求处理好反馈回去。
在处理请求前,前面来个队列,根据你当前请求的参数生产一个Hash值,存入队列,每个请求加入队列前,判断是否已存在该请求。
谢谢,方案是可以的,也可以用缓存代替。但是,后续的重复请求在入队列前,判断发现已经存在这个请求,那么这个请求应该怎么处置呢?直接返回给客户端吗?这样的话,客户端会不会多次请求只得到一个空的返回值。
@Shendu.cc: 你后续请求需要执行吗?不需要的直接返回了,需要的就执行。至于空返回值,这就是前端判断的事了, 你只考虑后端的话,不需要考虑这个。
@BUTTERAPPLE: 后续的请求不需要执行,但是返回给前端的值一定是执行过的请求,这样才是正确的数据。
http或者其他常见server通常是并发而不是串行且单工不应答确认;
楼上的不是解决的办法,如果不是前端处理,办法都不太可行。
——服务端无法确认客户端是否收到,收到的是不是正常的结果。再说服务器先收到不一定客户端先收到,那服务器又如何知道。
除非你的通信不是上面的这种方式,是应答确认模式,服务器知道客户端的情况。
那如果,先收到的请求放到缓存中立刻执行,后到的请求由于缓存中已经存在了一样的请求,所以全部挂起,比如挂5分钟。Thread.sleep(300000)。然后再返回空的回去。这样会有问题吗
@Shendu.cc: 你上面的假设有点串行概念。
比如你搞的http根本不是这么回事。即使你的服务是串行,那假设处理过程是1s,1s后的该任务没得了,又来一个一样的要不要处理,不需要的话——凭什么认为第一个处理是ok的,上面说了除非你的通信是有答复的。
除非你的任务是超长的,这种的话通常场景也不会让通信一直等待任务处理完的,通常是服务端收到任务消息,然后返回客户端并去并处理任务。
服务器敢这么动不动挂起,你也不怕work此耗完。
@花飘水流兮: 一个任务处理的时间大概是10秒吧,10秒之内,用户可能会点很多次,第一个任务处理完了,也就是10秒后,用户会跳到另一个界面。因此10秒后不会有任何请求了,10秒之内的多次请求,很显然只有第一次是真正的需要的,后面的请求都是重复的。我应该怎么做。我为的是不让后面的请求去操作,因为要消耗很多资源。
@Shendu.cc: 上面我已经强调多次——“凭什么认为第一个处理是ok的,上面说了除非你的通信是有答复的。” ;你如何确定客户端收到~
事务+状态迁移.
1.业务主表加状态字符串.
2.每一次操作.都是讲业务实体从一个状态迁移到另一个状态
2.在进入业务时:开启事务 ->udpate 业务主表 set状态=2 where id=@id and 状态=1 判断更新条数.条数为1时直接返回:重复操作
这种做个幂等接口不就完了么?前面传过来一个唯一标识作为判断为相同请求的依据,什么你认为用户可能会点很多次这些是不靠谱的。
具体点你加个接口,专门返回唯一标识的,这个接口上你就可以加上你的业务逻辑了,比如针对某个高耗时的操作那么相同用户请求多长时间内接口都返回相同值。
而后要应用端在实际请求高耗时操作接口时带上前面操作返回的标识,你处理的逻辑也容易,判断标识是否存在,判断标识是否处理完毕,然后把你各种东西塞进去就完了。当真正处理完毕后再次用相同标识及用户请求就直接从持久化层返回前面处理完的结果就完了