ktor 服务器 - 何时移动到另一个协程上下文

Posted

技术标签:

【中文标题】ktor 服务器 - 何时移动到另一个协程上下文【英文标题】:ktor server - when to move to another coroutine context 【发布时间】:2021-06-19 05:32:33 【问题描述】:

这可能是关于协程的一般问题,但在我的 ktor 服务器(netty 引擎,默认配置)应用程序中,我对数据库和 api 端点执行了多个异步调用,并希望确保我有效地使用协程。我的问题如下:

    是否有工具或方法可以确定我的代码是否有效地使用协程,或者我是否只需要使用 curl 向我的端点发送垃圾邮件并测量将进程移动到另一个上下文的性能,例如compute? 我不想开始将任务/作业移动到另一个上下文“以防万一”,但我是否应该将我的Route.route() 中的默认协程上下文处理为类似于 android 主线程并对其执行最少的工作?

这是我正在使用的代码的粗略示例:


fun Route.route() 
    get("/") 
        call.respondText(getRemoteText())
    


suspend fun getRemoteText() : String? 
   return suspendCoroutine  cont ->
        val document = 3rdPartyLibrary.get()
            if (success) 
                cont.resume(data)
             else 
                cont.resume(null)
            
        


【问题讨论】:

您的getRemoteText 看起来不正确,因为它似乎使用了阻塞调用3cdPartLibrary.get()。这已经证明您没有有效地使用协程。 这就是为什么我将阻塞操作包装在 suspendCoroutine... 这没有任何作用,您无法使用 Kotlin 协程取消阻止调用。您应该使用可以适应可暂停功能的异步 API。如果你保留阻塞调用,协程只能给你一些附带的好处,比如更方便地将阻塞调用提交到线程池。但是,该方法不涉及suspendCoroutine,而是涉及withContext(IO) 【参考方案1】:
    您可以使用 Apache Jmeter 之类的东西,但编写脚本并使用 curl 向服务器发送垃圾邮件对我来说似乎也是一个不错的选择 协程在context/thread 切换时非常有效,而使用Dispatchers.DefaultDispatchers.IO 你会得到一个线程池。有一些关于此的文档,但我认为您绝对可以利用这些调度程序进行繁重的操作

【讨论】:

【参考方案2】:
    用于测试端点的工具很少。 jmeter不错,还有wrk、wrk2、siege等命令行工具。 当然是上下文切换成本。除非您设置了选项shareWorkGroup,否则路由中的协程可以安全地运行阻塞操作。但是,通常最好使用单独的线程池,因为您可以控制它的大小(最大线程数),以免数据库停机。

【讨论】:

以上是关于ktor 服务器 - 何时移动到另一个协程上下文的主要内容,如果未能解决你的问题,请参考以下文章

在 ktor 请求处理程序中启动协程

如何确保清除 ktor websocket 客户端创建的所有 Kotlin 协程?

协程学习笔记

Kotlin Multiplatform Mobile:Ktor - 如何在 Kotlin Native(iOS)中取消活动协程(网络请求、后台工作)?

多任务实现-协程

python async - 休眠多个协程的效率