【问题标题】:Idiomatic Way Handle and Concat Multiple HTTP Requests In Clojure?在 Clojure 中处理和连接多个 HTTP 请求的惯用方式?
【发布时间】:2021-05-07 06:44:10
【问题描述】:

我正在开发一个程序,该程序需要多次调用各种微服务,可能对这些结果进行一些处理,然后返回这些处理的组合。

一个非常基本的示例可能如下所示:

(def urls ["http://localhost:8080" "http://localhost:8080"])

(defn handle-http-request [url]
  (let [request (http-kit/get url)]
    (do-some-processing (:body @request))))

(defn home-page
  [request]
  (let [response (pmap handle-http-request urls)]
    (ring-resp/response {:buildings (first response) :characters (second response)})))

在这种情况下,我使用pmap 来处理并行运行我的所有请求,然后将它们作为发出请求的 UI 可以处理的 JSON 返回。在真实环境中会有更多的 URL,每个 URL 获取不同的数据。

我的问题是这是否是处理这个问题的合适方法?我看过一些 core.async,并将其视为处理此问题的一种可能方法,但担心它可能会矫枉过正?我的第二个问题是处理错误,看起来 core.async 可能能够更优雅地处理远程超时的问题。我的这个假设是对的,还是在这种情况下使用pmap 好吗?

最后,关于如何处理这样的微服务架构,是否有任何公认的模式或阅读资料?我认为我的问题相对具体,但我觉得服务器向许多其他人发出请求并编译这些结果的想法并不是什么新鲜事。

【问题讨论】:

  • 我不会为此使用core.async。使用pmap 或为每个请求创建future。您能否更具体地说明您希望输出的内容?为什么?
  • @AlanThompson 在这种情况下,输出可能是一个映射,然后将其制成 JSON 字符串。我的情况是,整个过程是由一些 UI 请求数据启动的,这是一种返回数据的简单方法,以便 UI 可以做它需要做的事情。

标签: api http clojure microservices


【解决方案1】:

HTTP-Kit documentation 提供了一个使用期货的例子:

合并的并发请求,同步处理结果

(let [urls ["http://server.com/api/1" "http://server.com/api/2" "http://server.com/api/3"]
      ;; send the request concurrently (asynchronously)
      futures (doall (map http/get urls))]
  (doseq [resp futures]
    ;; wait for server response synchronously
    (println (-> @resp :opts :url) " status: " (:status @resp))
    )

然而,这通常还不够。确保配置超时 一旦超时,您就有了升级策略。越多 您将要访问的其他服务,此任务变得越复杂。 也许看看像这样的图书馆 Resilience4JClj,那个 提供可配置的方式来处理重试、缓存、超时……

注意:pmap 最适合 CPU 密集型任务。或如文档所述:

仅适用于 f 的时间占主导地位的计算密集型函数 协调开销。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-24
    • 2014-01-03
    • 2012-12-08
    • 1970-01-01
    • 2021-02-26
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多