我正在使用Clojure编写Web应用程序的后端,其中包括以下内容:
- http-kit 作为HTTP服务器和客户端(非阻塞)
- monger 作为我的DB驱动程序(阻塞)
- clj-aws-s3 作为S3客户端(阻塞)
我知道像NodeJS和Play Framework上的事件驱动、非阻塞堆栈的性能优势(这个问题帮助了我),以及它如何产生更好的负载能力。因此,我考虑使用core.async使我的后端异步。
我的问题是:通过在阻塞的客户端/驱动程序库上使用core.async,可以重现非阻塞Web堆栈的性能优势吗?
详细说明:
我目前正在做的事情是通常的同步调用:
(defn handle-my-request [req]
(let [data1 (db/findData1)
data2 (db/findData2)
data3 (s3/findData3)
result (make-something-of data1 data2 data3)]
(ring.util.response/response result))
)
我计划做的是将涉及到IO的任何调用都包装在一个
thread
块中,并在一个go
块内进行同步。(defn handle-my-request! [req resp-chan] ;; resp-chan is a core.async channel through which the response must be pushed
(go
(let [data1-ch (thread (db/findData1)) ;; spin of threads to fetch the data (involves IO)
data2-ch (thread (db/findData2))
data3-ch (thread (s3/findData3))
result (make-something-of (<! data1-ch) (<! data2-ch) (<! data3-ch))] ;; synchronize
(->> (ring.util.response/response result)
(>! resp-chan)) ;; send response
)))
这样做有意义吗?
我这样做是因为这是最佳实践,但性能优势对我来说仍然是个谜。我原以为同步堆栈的问题在于它们每个请求使用一个线程。现在看来它们使用的线程数超过了一个。
感谢您的帮助,祝您拥有美好的一天。