Clojure(Java)和Ruby应用程序通信的最快可靠方式
我们有云托管(RackSpace cloud)Ruby和Java应用程序,它们将按如下方式交互:Clojure(Java)和Ruby应用程序通信的最快可靠方式,java,ruby,clojure,messaging,network-protocols,Java,Ruby,Clojure,Messaging,Network Protocols,我们有云托管(RackSpace cloud)Ruby和Java应用程序,它们将按如下方式交互: Ruby应用程序向Java应用程序发送请求。请求由包含字符串、整数、其他映射和列表(类似于JSON)的映射结构组成 Java应用程序分析数据并向Ruby应用程序发送回复 我们对评估两种消息格式(JSON等)以及消息传输通道/技术(套接字、消息队列、RPC、REST、SOAP等)感兴趣 我们的标准: 往返时间短 低往返时间标准差。(我们知道垃圾收集暂停和网络使用高峰会影响此值) 高可用性 可伸缩性(我
--迈克我在这方面没有经验。我将张贴这可能有帮助的猜测无论如何
- 提供点对点消息传递,包括各种类型的网络拓扑。消息由任意二进制值组成,因此您只需要为结构化消息使用二进制序列化格式
- ,并将任意数据结构(数字、字符串、顺序数组、关联数组)序列化为二进制值
GitHub发明了用于快速RCP的BERT;BSON是由MongoDB(或10gen)出于同样的原因发明的;谷歌也同样如此。我们决定继续 我们喜欢BSON对异构集合的支持,并且不需要预先指定消息的格式。我们不介意它的空间使用特性较差,并且可能比其他消息格式的序列化性能较差,因为我们的应用程序的消息传递部分预计不会成为瓶颈。它看起来不像是一个很好的Clojure接口,可以让您直接操作BSON对象,但希望这不会成为一个问题。如果我们决定BSON不适合我们,我将修改此条目 我们选择RabbitMQ主要是因为我们已经有了使用它的经验,并且正在要求高吞吐量和可用性的系统中使用它 如果消息传递确实成为一个瓶颈,我们将首先关注BERT(我们拒绝了它,因为它目前似乎没有Java支持),然后关注MessagePack(拒绝了,因为似乎没有大量Java开发人员使用它),然后关注Avro(拒绝了,因为它要求您预先定义消息格式),然后是协议缓冲区(由于额外的代码生成步骤和缺乏异构集合而被拒绝),然后是Thrift(由于提到的协议缓冲区原因而被拒绝) 我们可能希望使用普通RPC方案,而不是使用消息队列,因为我们的消息传递风格本质上是同步的点对点 谢谢大家的意见 更新:这里是
项目.clj
和核心.clj
,展示了如何将Clojure映射转换为BSON和BSON:
;;;; 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)))))
;;;; project.clj
(defproject bson演示“0.0.1”
:说明“BSON演示”
:依赖项[[org.clojure/clojure“1.2.0”]
[org.clojure/clojure-contrib“1.2.0”]
[org.mongodb/mongo-java-driver“2.1”]]
:开发依赖项[[swank clojure“1.3.0-SNAPSHOT”]]
:主磁芯)
;;;; core.clj
(ns核心
(:gen类)
(:导入[org.bson basicbonobject bsonecoder BSONDecoder]))
(defonce*编码器*(BSONECODER.))
(defonce*解码器*(BSONDecoder.))
;; XXX不接受关键字参数。首先将映射中的clojure.lang.Keyword转换为java.lang.String。
(定义映射到bson[m]
(>>m(基本对象)(.encode*encoder*))
(定义为映射[^BasicBonObject b]
(>>(.readObject*解码器*b)(.toMap)(到{})))
(defn-main[]
(让[m{“foo”“bar}]
(prn(bson to map(map to bson m‘‘‘‘)’)编辑:protobuff vs JSON在我的例子中,但它当时没有使用Jackson(我想我使用的是jsonlib),protobuff java lib从那时起一定也在发展。网络RTT通常会占主导地位,负载大小才是真正重要的。Gzip JSON在大小上与协议缓冲区相当,所以我认为两者都可以。好文章。事实证明,我的队友已经非常熟悉该用例了^ ^我不确定这里描述的Ruby/Clojure互操作是否是关键速度敏感路径的一部分。你真的想要可靠性(从标题上看)?在您所讨论的消息传递类别的上下文中,这意味着消息永远不会丢失(也可能是按照发送顺序发送),这是非常昂贵的。当然,这里的可靠性指的是抵抗反铲攻击(即网络或电力基础设施的物理破坏)。我更喜欢及时交付,让应用程序更具抵抗力