8

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

 3 years ago
source link: http://developer.51cto.com/art/202102/644147.htm
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

6nuimaR.jpg!mobile

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

本文转载自微信公众号「彤哥读源码」,可以通过以下二维码关注。转载本文请联系彤哥读源码公众号。

reQjauI.png!mobile


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK