处理外部服务接口未响应


处理服务未响应异常

队列任务中调用的外部服务接口除了返回 500 错误码之外,有时候可能没有任何响应,要处理这种情况,我们可以在发起请求时主动设置一个超时时间:

假设我们为请求设置了一个 10s 的超时时间,则 10s 之后未响应会抛出 ConnectionException 异常,然后在运行熔断器的时候捕获这个异常:

现在,熔断器会在十次请求失败后开启,直到熔断器关闭之前,都不能再运行这个任务了,在此期间,队列处理器进程可以正常处理其他任务。

隔离超时任务

不过,如果服务未响应的话,则至少需要 10s 才能开启熔断器,在此期间,队列处理器也不能运行任何其他任务。

要阻止这种情况发生,可以限定处理该任务的队列处理器数量,一种方式是指定进程处理的队列:

php artisan queue:work --queues=slow,default  // 开启5个进程
php artisan queue:work --queues=default       // 开启5个进程

这样一来,超时请求服务处理任务位于 slow 队列,在服务未响应的情况下,至多让五个队列处理器进程处于阻塞状态,其他五个可以正常运行。

使用 Redis 限流器

要隔离超时任务,除了使用上述队列处理命令参数外,还可以引入队列限流中间件进行处理,这里我们使用基于漏斗算法的 Redis 限流器实现:

这样一来,同时最多只允许 5 个队列处理器进程处理该任务,如果队列处理器进程总数还是 10 个的话,剩下的 5 个就不会阻塞,转而可以去处理其他队列任务了。


点赞 取消点赞 收藏 取消收藏

<< 上一篇: 通过熔断器处理不稳定的外部服务

>> 下一篇: 基于队列任务中间件重构服务熔断器