关于timeout参数
clj-http.client的请求(如GET/POST/PUT/DELTE/OPTION等)均支持超时参数配置,各超时参数的含义如下:
:connection-timeout 5000 ;; 与服务建立连接的超时时间
:socket-timeout 5000 ;; 两个数据包之间的最长等待时间
:connection-request-timeout 5000 ;; 从ConnectionManager获取连接的最长超时时间
:conn-request-timeout 5000 ;; 同connection-request-timeout,已不建议使用
:conn-timeout 5000 ;; 同connection-timeout,已不建议使用
可见我们通常只使用前三个参数即可。
参数值设为0时,表示不限制对应的超时时间;设为负数时表示使用系统默认超时时间。
由于系统默认超时时间通常长达几分钟或更长,对于大多数应用可能太长。建议使用clj-http.client发送HTTP请求时都带上以上参数,避免程序假死。
若使用连接池,则应该通过连接池创建函数来配置超时。连接池函数clj-http.client/with-connection-pool
和clj-http.client/with-async-connection-pool
的文档已经有比较详细的说明了,这里就不作赘述了。
重试策略:retry-handler
即使已经配置好以上的超时参数,你可能还会发现http请求卡住,这很可能是因为IO异常导致请求被不停重试。
可以通过设置:retry-handler
传入IO异常处理函数,定制重试策略。其中的try-count
即为已经重试的次数,此函数返回false
即停止重试HTTP请求。
例子
下面是下载图片的一个完整示例:
(require '[clj-http.client :as client])
(require '[clojure.java.io :as io])
(def client-opts {:socket-timeout 5000
:connection-timeout 5000
:connection-request-timeout 5000
:retry-handler (fn [ex try-count http-context]
(t/warn "ignore" ex)
false)})
(let [url "https://pics4.baidu.com/feed/9f2f070828381f305d89a4783526e20c6f06f07f.jpeg?token=7b7cac935fe474bbf2bdfccc3395d5ca&s=DB300FC0C407CAEC2638E5750300D032"
{:keys [body status]} (client/get url client-opts)]
(when (= 200 status)
(io/copy body "a.jpg")))