spring 当并行调用另一个微服务时,我应该使用CoroutineScope(Dispatchers.IO)吗?

yrdbyhpb  于 5个月前  发布在  Spring
关注(0)|答案(1)|浏览(66)

假设我们在控制器中有一个getProducts()方法:

@RestController
@RequestMapping("/products")
class ProductController(
 ...    
){
   suspend fun getProducts(): ProductsDto {
        val productsDtoRs = productService.getProducts()  (1) to get a response
        
        CoroutineScope(Dispatchers.IO).launch {        (2) no need to wait for response  
            subscriptionService.createSubscription()
        }         
        return productsDto 
   }
}

字符串
它对另一个微服务进行两次调用:一次是生成响应,另一次只是一个我们不需要等待的调用,这就是为什么我们并行启动它。
如果在subscriptionService.createSubscription()中没有执行CPU消耗操作,那么在这种情况下是否需要使用Dispatchers.IO线程?这只是对另一个微服务的调用。或者CoroutineScope(Dispatchers.Default).launch就足够了?
第二个问题,第二次调用是否会导致内存泄漏,我是否应该在这里释放资源?

4nkexdtk

4nkexdtk1#

你说没有必要等待createSubscription()。我认为你应该问自己一个不同的问题:如果你不需要等待它。仅仅因为我们不使用调用的结果来创建响应,并不意味着我们不应该等待它。如果createSubscription()失败了呢?忽略失败甚至不通知调用者或者我们应该传播错误是否安全?
当然,在某些情况下,我们实际上喜欢调度异步任务,但同样,这应该是根据应用程序需求的有意识的决定。
在这种情况下是否需要使用Dispatchers.IO线程
假设createSubscription()也是一个挂起函数,并且它被正确地实现,那么我们使用哪个调度器应该没有那么重要。我建议使用Dispatchers.Default。如果它不是一个挂起函数,并且它是阻塞的,那么我们应该使用Dispatchers.IO
第二次调用是否会导致内存泄漏,我是否应该在这里释放资源?
不需要释放任何资源,但是,我们通常会在这里泄漏后台任务。例如,如果由于某种错误,这些任务从未完成,我们不会知道,应用程序将正常工作,直到任务堆积并占用整个内存。跟踪后台任务总是一个好主意-无论是通过它们的调用者还是某种服务。
此外,通常不鼓励像您的示例中那样创建即发即忘的协同程序作用域。您所做的是一种令人费解的方式来表示GlobalScope.launch {}。常见模式是为您的服务创建一个作用域,并使用它来启动其任务。话虽如此,如果服务是在应用程序的整个生命周期内运行的单例,那么它不会发生太大变化。

相关问题