前端的批量接口如何快速响应?有没有通用解决方案?

昨日回顾

昨天我们讨论了服务间是否应该提供批量接口的问题,很多同学留言讨论,非常好,一起讨论一起进步。

其中,留言最多的一种观点是说可以提供,但是要限制条数,比如每次最多传1000条数据过来。

说句实话,我们的项目很多也是这么做的。

不过我还是坚持我的观点,最好就不要提供批量接口。

因为随着数据量的不断增大,势必导致存储架构升级。

我们以商品查询为例,数据量变大,肯定是要上Redis的吧,以前批量接口可能直接一个数据库in就解决了,现在你是先走缓存还是不走呢?走的话要改代码,不走的话性能肯定不高。数据量再继续增大,分库分表了,批量接口怎么处理?上Elasticsearch了,怎么处理?

这里,我们举例是说的批量查询,如果换成批量操作呢?每次存储架构升级可能都要改这块的代码,而且还有另外一个操蛋的问题,比如你们规定服务间调用超时最大是1秒钟,超过1秒就有熔断逻辑,那么,你要不要单独为这个批量接口配置超时?

所以,批量接口极其容易形成瓶颈,需要花费巨大的代价去维护这个代码,还是不提供比较好。

当然,如果你们的数据量在可以预见的未来都不会增长到那么大,提供一个批量接口也不是不可以,视情况自行决定哈。(数据量都没有,还不赶紧跑路😂)

今日话题

好了,关于昨天的问题先唠这么多,今天,我们看另外一个问题:对前端提供的批量接口,后端如何快速响应?有没有通用的解决方案呢?

场景

首先,我们分析一下这个场景。

这里说的批量接口,肯定不是查询哈,而是批量操作类的接口,比如批量导入,批量发货,批量删除,批量流转,批量修改某种状态,等等,有很多,不过做2C系统的可能比较少见,一般2B的系统会有非常多这种批量的接口,往往他们也是系统中的顽固,需要投入很多精力不断打磨不断优化。

一般解决方案

好了,场景我们清楚了,那么,怎么解决这类难题呢?

一般地,我们提供一个批量接口,前端传一堆id过来,或者数据过来,后端慢慢处理,处理完了再给前端返回,因为是2B的系统,用户也愿意等待。

但是,这里其实有很多问题,最典型的就是超时问题,超时这个问题说简单也简单,说复杂也复杂,以我们的系统为例,我们部署到华为云上面,可能会有这么几个超时的地方:

1、华为云的防火墙有超时;
2、华为云ELB有超时;
3、前端nginx有超时;
4、前端代码里写死了超时;
5、后端网关有超时;
6、后端服务有超时;
7、远程调用有超时;

所以,你看,一个超时问题能把你折磨死,而且,这种问题非常难排查,当然,你躺完一次这个坑之后后面可能会好很多。(所以,我为什么知道这么多地方可能有问题呢😂)

超时只是一个典型的问题,并不是全部,再说一个情形,以批量发货为例,晚上,很多商家都喜欢批量发货,比如一次1000条,这么多商家的请求呢,一不小心就会出现很多打到同一台机器上面去了,然后大家都在搞批量,都要申请大量的内存,都在搞内存,内存扛不住呀,然后就OOM了,这是典型的请求倾斜的问题,所以,怎么设置你的负载均衡策略呢?目前,并没有很好的解决方案。

通用解决方案

基于以上这些可能会出现的问题,我一直在思考,能不能提供一种通用解决方案呢?

其实是有的,但是,要改原型。

比如,批量发货,本来状态只有未发货、已发货、发货失败,能不能加一个“发货中”呢?

别小看这个发货中的威力,真的很强大。

后端接收到批量发货这个请求,先检查数据的正确性,然后把数据库这些单据的状态改成发货中,接着把这些数据一个一个的丢到消息队列中,就可以返回了,前端查询的时候就显示发货中,旁边放一个刷新按钮。此时,用户完全去干别的事,比如去建商品,等会回来再看有没有发货完成或者发货失败的。

最后,有一组消费者不断的从消息队列中消费数据,调用物流服务发货等等。

经过这么一折腾,本来前端要hang死几分钟的请求几秒钟就返回了,用户体验上去了,也不用去搞超时、请求倾斜等问题了,解放了生产力,可以多划水了。

而且,这还是一个可以无限横向扩展的架构,随着用户量的不断增大,理论上来说,只要堆机器就可以了。

好了,关于前端批量接口的处理就到这里了。

写在最后

最后,我想问,你们系统中是怎么处理前端批量接口的呢?

欢迎留言讨论。

posted @ 2021-02-02 10:02  彤哥读源码  阅读(1654)  评论(0编辑  收藏  举报