当前位置: 首页 > 知识库问答 >
问题:

Clojure http kit get请求在多个异步调用上卡住

万俟华辉
2023-03-14

我创建了一个小示例来突出问题:

(->> (range 0 4)
     (mapv (fn [i]
             (http/get "http://http-kit.org/"
                       (fn [res]
                         (info "first callback")
                         (let [res2 @(http/get "http://http-kit.org/")]
                           (info "second callback ")))))))

打印4s第一次回拨消息时卡住了。

如果我将范围更改为0。。3它可以工作,同步版本也可以工作。

更新:

(info)是一个taoensso.timbre日志库

共有2个答案

曹新觉
2023-03-14

这看起来像是由于http kit客户端线程池在回调函数完成之前不会释放线程而导致的问题。因此,它最终会耗尽线程。

因此,我开始思考如何使回调函数更快,并提出了以下解决方案:

我为超文本传输协议-kit客户端创建了异步包装器函数,在回调中使用clojure.core.async/chan快速地将结果放入通道,然后等待结果并执行重回调:

(defn async-http-get
  [url opts callback]
  (let [channel (chan)]
    (http/get url opts #(go (>! channel %)))
    (go (callback (<! channel)))
    nil))

所以现在使用async-超文本传输协议-get而不是超文本传输协议/get为我解决了这个问题。

(->> (range 0 4)
     (mapv (fn [i]
             (async-http-get "http://http-kit.org/"
                       (fn [res]
                         (info "first callback")
                         (let [res2 @(http/get "http://http-kit.org/")]
                           (info "second callback ")))))))
方献
2023-03-14

我目前的假设是,通过耗尽线程池,您会陷入死锁:

  1. 你创建一个线程每外部超文本传输协议/get
  2. 如果您创建的请求少于线程池中的可用线程,则有空间为至少一个内部超文本传输协议/get(这将需要一个新线程)提供服务
    1. 或者如果您的第一个请求在您用尽线程池之前完成

    您可以使用peekhttp/default pool检查线程池http工具包的状态。在那里,您可以看到如下内容:

    #object[java.util.concurrent.ThreadPoolExecutor 0x5a99e5c "java.util.concurrent.ThreadPoolExecutor@5a99e5c[Running, pool size = 8, active threads = 0, queued tasks = 0, completed tasks = 24]"]
    

    当你没有陷入僵局的时候。或

    #object[java.util.concurrent.ThreadPoolExecutor 0x5a99e5c "java.util.concurrent.ThreadPoolExecutor@5a99e5c[Running, pool size = 8, active threads = 8, queued tasks = 8, completed tasks = 28]"]
    

    当你这么做的时候。

    我已经在我的机器中测试过了(显示8为(.可用性处理器(运行时/getRuntime))),我得到了上面的结果。当我运行超过8个请求时,我陷入了僵局。

    当做

 类似资料:
  • 问题内容: 首先,让我解释一下上下文: 我必须创建一个客户端,该客户端将发送许多HTTP请求以下载图像。这些请求必须是异步的,因为一旦完成图像,它将被添加到队列中,然后打印到屏幕上。由于图像可能很大且响应分块,因此我的处理程序必须将其聚合到缓冲区中。 因此,我遵循Netty示例代码(HTTP勺示例)。 目前,我有三个静态映射,用于为每个通道存储通道ID和缓冲区/块布尔值/我的最终对象。 在那之后,

  • 我调用了多个ajax调用,但代码只在所有ajax调用执行之后才到达API。 JavaScript: AppFactory API 链接工作很好,但我需要运行两个独立,我真的想知道发生了什么。 谢谢!!!

  • 但是,如下所示的调用序列使用相同的TCP连接。 我还没有对此进行调试,但OkHttp似乎迫使我们首先在主线程上发出阻塞HTTP请求,以获得TCP连接上下文,然后与其他线程共享该上下文?或者,我是不是漏掉了什么?

  • 本文向大家介绍angularjs 处理多个异步请求方法汇总,包括了angularjs 处理多个异步请求方法汇总的使用技巧和注意事项,需要的朋友参考一下 在实际业务中经常需要等待几个请求完成后再进行下一步操作。但angularjs中$http不支持同步的请求。 解决方法一: 解决方法二: then中的方法会按顺序执行。 解决方法三: $q.all方法第一个参数可以是数组(对象)。在第一参数中内容都执

  • 我正在开发一个移动应用程序,现在我正在进行身份验证。在我访问我的主页之前,我需要访问我构建的API上的各种endpoint,然后才能向用户显示数据。 在Postman中测试时,所有endpoint都返回了正确的数据,但是当我在应用程序中使用它时,我在第二次异步调用中得到了一个值。 我确信这与这些呼叫的顺序有关,所以我只是在寻找一些帮助,如何在开始另一个呼叫之前正确地等待一个呼叫完成。

  • 我使用相同的输入Json在REST API上提交多个POST提交。这意味着多用户(例如:10000)使用相同的Json提交相同的POST来测量POST请求的性能,但是我需要使用GET方法捕获每次提交的完成结果,并且仍然测量GET的性能。这是一个如下的异步过程。 提交后 因此,我需要创建一个jmeter测试计划,该计划可以处理多用户提交的异步POST,并等待它们被处理,最后捕获每次提交的完成情况。我