API接口调用(接口响应时间过长,业务方调用超时的解决方法)

大雄 5000 2022-06-14


问题场景

后台计算逻辑复杂,或者计算数据量比较大,导致接口响应时间特别长,短则几十秒,长则几分钟。从而导致前端请求接口超时。

解决方法

将原来的接口分拆为两个接口,两个接口异步操作。

两个接口的功能和使用方法如下:

接口一:业务方直接调用的接口,该接口返回数据中包含一个回调接口的url,该回调接口就是接口二。

接口响应示例








{
   "code": 1,
   "message": "任务已开始执行,但是未执行完成。",
   "body": {
       "callback_url": "HTTP://test.com/callback?task_id=3421"
   }
}

接口二:业务方调用完接口一后,从接口一返回数据中,拿到回调接口的url,然后轮询请求该接口,获取最终的处理结果。

因为无法确定接口二什么时候可以处理完数据,所以接口二的响应结果需要包含一个判断后台是否执行完成的状态字段。

接口响应示例








{
    "code": 1, # 0:任务还在执行中,1:任务执行完成,2:任务执行失败
   "message": "任务执行完成。",
   "body": {
       "result": "XXXXXXXXXXXXXX"
   }
}

遇到的问题

写这种接口的时候,如果使用单线程,调用接口后,必定会导致最终的数据出来之前,不会有任何数据返回,这时候我们可以采用多线程或者多进程的方式来解决这个问题。


下面回顾一下什么是线程和进程。

线程定义

线程是进程的基本执行单元,一个进程的所有任务都在线程中执行

进程要想执行任务,必须得有线程,进程至少要有一条线程

程序启动会默认开启一条线程,这条线程被称为主线程或 UI 线程
进程定义

进程是指在系统中正在运行的一个应用程序

每个进程之间是独立的,每个进程均运行在其专用的且受保护的内存
进程与线程的区别

地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。

资源拥有:同一进程内的线程共享本进程的资源如内存、I/O、cpu等,但是进程之间的资源是独立的。

一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。

进程切换时,消耗的资源大,效率高。所以涉及到频繁的切换时,使用线程要好于进程。同样如果要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程

执行过程:每个独立的进程有一个程序运行的入口、顺序执行序列和程序入口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

线程是处理器调度的基本单位,但是进程不是。


上面对进程和线程的描述比较“专业”,下面我们通过一个比喻来区分一下线程和进程的区别。


假设你经营着一家物业管理公司。最初,业务量很小,事事都需要你亲力亲为。给老张家修完暖气管道,立马再去老李家换电灯泡——这叫单线程,所有的工作都得顺序执行。

后来业务拓展了,你雇佣了几个工人,这样,你的物业公司就可以同时为多户人家提供服务了——这叫多线程,你是主线程。工人们使用的工具,是物业管理公司提供的,这些工具由大家共享,并不专属于某一个人——这叫多线程资源共享。

工人们在工作中都需要管钳,可是管钳只有一把——这叫冲突。解决冲突的办法有很多,比如排队等候、等同事用完后的微信通知等——这叫线程同步。

你给工人布置任务——这叫创建线程。之后你还得要告诉他,可以开始了,不然他会一直停在那儿不动——这叫启动线程(start)。

如果某个工人(线程)的工作非常重要,你(主线程)也许会亲自监工一段时间,如果不指定时间,则表示你会一直监工到该项工作完成——这叫线程参与(join)。

业务不忙的时候,你就在办公室喝喝茶。下班时间一到,你群发微信,所有的工人不管手头的工作是否完成,都立马撂下工具,跟你走人。因此如果有必要,你得避免不要在工人正忙着的时候发下班的通知——这叫线程守护属性设置和管理(daemon)。再后来,你的公司规模扩大了,同时为很多生活社区服务,你在每个生活社区设置了分公司,分公司由分公司经理管理,运营机制和你的总公司几乎一模一样——这叫多进程,总公司叫主进程,分公司叫子进程。

总公司和分公司,以及各个分公司之间,工具都是独立的,不能借用、混用——这叫进程间不能共享资源。各个分公司之间可以通过专线电话联系——这叫管道。各个分公司之间还可以通过公司公告栏交换信息——这叫进程间共享内存。另外,各个分公司之间还有各种协同手段,以便完成更大规模的作业——这叫进程间同步。分公司可以跟着总公司一起下班,也可以把当天的工作全部做完之后再下班——这叫守护进程设置。

总结

接口响应过长的时候,我们可以将接口分拆为两个异步操作的接口,异步操作可以采用多进程非阻塞的方式。

将耗时的后台计算放到子进程中,然后先通过主进程返回给业务方接口二的url链接,然后业务方通过轮询第二个接口最终获得执行结果。



版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Go语言之父带你重新认识字符串、字节、rune和字符(golang字符串)
下一篇:黑客入侵 linux 系统常用手段,有你不知道的没?
相关文章

 发表评论

评论列表

2023-06-06 15:35:57

线程和进程描述的很清晰,通俗易懂!