Clojure Hystrix 异常,因为太多的 http 请求
Clojure Hystrix exceptions because of too many http requests
我需要构建一个需要发出大量外部 http 请求的系统,并且我必须使用 Netflix 的 Hystrix 来创建回退和重新路由异常。现在,我有一个非常简单的设置:
(hystrix/defcommand fetch-request
{:hystrix/group-key "c0"
:hystrix/command-key "URLFetch"
:hystrix/fallback-fn (fn [url]
{:status 419
:headers {}
:body "failed"})}
[url]
@(http/get url))
(defn test3 []
(let [n 4000
m (range 0 n)
p (partition 300 m)]
(doseq [t p]
(thread
(doseq [x t]
(let [res (fetch-request "http://localhost:3000/comments")]
(match (:status res)
200 (prn x)
:else (prn nil)))
)))
))
当我执行 test3
时,我不断得到 nil
。如果我减少 n
的值,我会得到 200
的状态(这是我需要的)。此外,如果我直接在 test3
函数上使用 http/get
而不是 fetch-request
命令,它可以正常工作(即使 n 的值高于 7000)。
注意:我使用分区+线程的原因是并行化 http 请求。如果您知道在 clojure 中尽可能快地执行大量 http 请求的更好方法,那就太棒了。
更新:
我玩过各种配置。他们中的大多数人没有产生不同的结果。大多数请求仍未执行,因此立即触发回退。我尝试禁用 circuitBreaker(我不想这样做,这就是我使用 hystrix 的原因)以查看它是否做了任何事情——它确实做了。 80% 的请求通过。
(hystrix/defcommand fetch-request
{:hystrix/group-key "ct0"
:hystrix/command-key "URLFetch"
:hystrix/init-fn
(fn [_ ^com.netflix.hystrix.HystrixCommand$Setter setter]
(.andCommandPropertiesDefaults
setter
^com.netflix.hystrix.HystrixCommandProperties$Setter
(.withCircuitBreakerEnabled
(HystrixCommandProperties/Setter)
false)
; ^com.netflix.hystrix.HystrixCommandProperties$Setter
; (.withExecutionTimeoutInMilliseconds
; (HystrixCommandProperties/Setter)
; 1000))
; (.andCommandPropertiesDefaults
; setter
; (.withExecutionIsolationStrategy
; (HystrixCommandProperties/Setter)
; com.netflix.hystrix.HystrixCommandProperties$ExecutionIsolationStrategy/THREAD)
))
:hystrix/fallback-fn
(fn fetch-req-fallback [url]
{:status 419
:headers {}
:body "failed"})}
[url]
@(http/get url))
更新 2:
删除 thread
块可以解决问题。但是,我确实需要跨多个线程执行这些请求,所以它不一定能解决我的问题。
已修复。我不得不修改线程池属性。
(hystrix/defcommand fetch-request
{:hystrix/group-key "ct0"
:hystrix/command-key "URLFetch"
:hystrix/thread-pool-key "URLThread"
:hystrix/init-fn
(fn [_ ^com.netflix.hystrix.HystrixCommand$Setter setter]
(.andThreadPoolPropertiesDefaults
setter
(doto (HystrixThreadPoolProperties/Setter)
(.withMaxQueueSize 10)
(.withQueueSizeRejectionThreshold 10)))
(.andCommandPropertiesDefaults
setter
(doto (HystrixCommandProperties/Setter)
(.withExecutionIsolationStrategy
com.netflix.hystrix.HystrixCommandProperties$ExecutionIsolationStrategy/THREAD)
(.withExecutionTimeoutInMilliseconds
1500))))
:hystrix/fallback-fn
(fn fetch-req-fallback [url]
{:status 419
:headers {}
:body "failed"})}
[url]
@(http/get url))
我需要构建一个需要发出大量外部 http 请求的系统,并且我必须使用 Netflix 的 Hystrix 来创建回退和重新路由异常。现在,我有一个非常简单的设置:
(hystrix/defcommand fetch-request
{:hystrix/group-key "c0"
:hystrix/command-key "URLFetch"
:hystrix/fallback-fn (fn [url]
{:status 419
:headers {}
:body "failed"})}
[url]
@(http/get url))
(defn test3 []
(let [n 4000
m (range 0 n)
p (partition 300 m)]
(doseq [t p]
(thread
(doseq [x t]
(let [res (fetch-request "http://localhost:3000/comments")]
(match (:status res)
200 (prn x)
:else (prn nil)))
)))
))
当我执行 test3
时,我不断得到 nil
。如果我减少 n
的值,我会得到 200
的状态(这是我需要的)。此外,如果我直接在 test3
函数上使用 http/get
而不是 fetch-request
命令,它可以正常工作(即使 n 的值高于 7000)。
注意:我使用分区+线程的原因是并行化 http 请求。如果您知道在 clojure 中尽可能快地执行大量 http 请求的更好方法,那就太棒了。
更新:
我玩过各种配置。他们中的大多数人没有产生不同的结果。大多数请求仍未执行,因此立即触发回退。我尝试禁用 circuitBreaker(我不想这样做,这就是我使用 hystrix 的原因)以查看它是否做了任何事情——它确实做了。 80% 的请求通过。
(hystrix/defcommand fetch-request
{:hystrix/group-key "ct0"
:hystrix/command-key "URLFetch"
:hystrix/init-fn
(fn [_ ^com.netflix.hystrix.HystrixCommand$Setter setter]
(.andCommandPropertiesDefaults
setter
^com.netflix.hystrix.HystrixCommandProperties$Setter
(.withCircuitBreakerEnabled
(HystrixCommandProperties/Setter)
false)
; ^com.netflix.hystrix.HystrixCommandProperties$Setter
; (.withExecutionTimeoutInMilliseconds
; (HystrixCommandProperties/Setter)
; 1000))
; (.andCommandPropertiesDefaults
; setter
; (.withExecutionIsolationStrategy
; (HystrixCommandProperties/Setter)
; com.netflix.hystrix.HystrixCommandProperties$ExecutionIsolationStrategy/THREAD)
))
:hystrix/fallback-fn
(fn fetch-req-fallback [url]
{:status 419
:headers {}
:body "failed"})}
[url]
@(http/get url))
更新 2:
删除 thread
块可以解决问题。但是,我确实需要跨多个线程执行这些请求,所以它不一定能解决我的问题。
已修复。我不得不修改线程池属性。
(hystrix/defcommand fetch-request
{:hystrix/group-key "ct0"
:hystrix/command-key "URLFetch"
:hystrix/thread-pool-key "URLThread"
:hystrix/init-fn
(fn [_ ^com.netflix.hystrix.HystrixCommand$Setter setter]
(.andThreadPoolPropertiesDefaults
setter
(doto (HystrixThreadPoolProperties/Setter)
(.withMaxQueueSize 10)
(.withQueueSizeRejectionThreshold 10)))
(.andCommandPropertiesDefaults
setter
(doto (HystrixCommandProperties/Setter)
(.withExecutionIsolationStrategy
com.netflix.hystrix.HystrixCommandProperties$ExecutionIsolationStrategy/THREAD)
(.withExecutionTimeoutInMilliseconds
1500))))
:hystrix/fallback-fn
(fn fetch-req-fallback [url]
{:status 419
:headers {}
:body "failed"})}
[url]
@(http/get url))