如何控制方法的调用Timeout超时,并主动中断调用请求

网站建设3年前发布
44 0 0

在我们实际开发过程中,我们经常遇到一些场景:,1、如果调用方法超过1秒,就应该停止调用,不要一直阻塞下去,防止把本身的服务资源搞挂。,2、在不可预知可能出现死锁/死循环的代码,要加上时间的阀值,避免阻塞。,很多开源框架都会有超时响应的设置;如果是我们自己开发的服务,怎么能做到这点呢?,在jdk中有个future类,里面有获取等待超时的方法。,本文不重点介绍future方法,可自行网补。,Google开源的Guava工具包,还是比较强大的;里面即包含了超时的控制。里面有个。,TimeLimiter 是个接口,下面有两个子类。,
,FakeTimeLimiter, 常用于debug时,限制时间超时调试。,
,SimpleTimeLimiter 常用于正式方法中,调用方法超时,即抛出异常。,这个类有2种方式实现超时的控制,代理模式和回调模式。,Guava采用的是JDK动态代理实现的AOP拦截,所以代理类必须实现一个接口。可以达到对类中所有的方法进行超时控制。,定义了一个学生服务接口;,实现了根据id获取姓名,以及获取爱好;,获取姓名方法需耗时3秒;获取爱好方法需耗时10秒。,上面是调用代码,核心代码如下:,利用SimpleTimeLimiter新建了代理对象studentServiceProxy,并传递了6秒的超时设置。,我们只要在调用方法的时候,捕获TimeoutException异常即可。,执行结果如下:,20230306012158935579224d13af534f067103f62c06abed024f831,上面的结果,获取爱好方法超过了6秒就中断了,并抛出了异常。,我们发现配置了超时时间6秒后,StudentServiceProxy代理对象的所有方法都是6秒超时。,我们发现上面的代码需要在调用方实现SimpleTimeLimiter的配置,感觉耦合度高了点。我们可以把代码改造一下。,这样的改造就非常好了,调用方不需要关心具体的超时实现,直接调用即可。,上面的代理模式是针对类的,回调模式是可以针对某段代码的。,上面代码中,定义Callable使用业务代码。执行结果如下,2023030601224029777cd93850579fe8755228b334e1e67bbe89902,SimpleTimeLimiter是可以自定义线程池的,20230306012159623355c945f001c06fd1458de581245171d5bb420,执行结果如下:,20230306012120c9ab36200816a83baa018761da24c22e80f7c5773,SimpleTimeLimiter对象本质上也是使用了JDK中的Future对象实现了Timeout。,源码如下:,20230306012120c60b307580e1a52e18e754086a873cb74c6b52536,被Guava封装了一下,使用起来特别方便。小伙伴可自行尝试。

© 版权声明

相关文章