我们决定与BSON一起而不是RabbitMQ。
我们喜欢BSON对异构集合的支持,并且不需要预先指定消息的格式。我们不介意它具有较差的空间使用特征,并且可能比其他消息格式更差的序列化性能,因为预计应用程序的消息传递部分不会成为瓶颈。它看起来不像一个很好的Clojure接口被编写来让你直接操作BSON对象,但希望这不会成为一个问题。如果我们决定BSON不适合我们,我将修改此条目。
我们之所以选择 RabbitMQ,主要是因为我们已经有了这方面的经验,并且正在一个需要高吞吐量和可用性的系统中使用它。
如果消息传递确实成为瓶颈,我们将首先关注BERT(我们拒绝了它,因为它目前似乎没有Java支持),然后是MessagePack(被拒绝,因为它似乎没有一个大型的Java开发人员社区使用它),然后是Avro(被拒绝,因为它需要你预先定义你的消息格式), 然后是协议缓冲区(由于额外的代码生成步骤和缺乏异构集合而被拒绝),然后是Thrift(由于协议缓冲区提到的原因而被拒绝)。
我们可能希望使用普通的 RPC 方案,而不是使用消息队列,因为我们的消息传递样式本质上是点对点同步的。
谢谢大家的输入!
更新:这是,显示了如何将Clojure映射转换为BSON并返回:project.clj
core.clj
;;;; project.clj
(defproject bson-demo "0.0.1"
:description "BSON Demo"
:dependencies [[org.clojure/clojure "1.2.0"]
[org.clojure/clojure-contrib "1.2.0"]
[org.mongodb/mongo-java-driver "2.1"]]
:dev-dependencies [[swank-clojure "1.3.0-SNAPSHOT"]]
:main core)
;;;; core.clj
(ns core
(:gen-class)
(:import [org.bson BasicBSONObject BSONEncoder BSONDecoder]))
(defonce *encoder* (BSONEncoder.))
(defonce *decoder* (BSONDecoder.))
;; XXX Does not accept keyword arguments. Convert clojure.lang.Keyword in map to java.lang.String first.
(defn map-to-bson [m]
(->> m (BasicBSONObject.) (.encode *encoder*)))
(defn bson-to-map [^BasicBSONObject b]
(->> (.readObject *decoder* b) (.toMap) (into {})))
(defn -main []
(let [m {"foo" "bar"}]
(prn (bson-to-map (map-to-bson m)))))