Clojure(Java)和Ruby应用程序通信的最快可靠方式

我们有云托管(RackSpace云)Ruby和Java应用程序,它们将按如下方式进行交互:

  1. Ruby 应用程序向 Java 应用程序发送请求。请求由包含字符串、整数、其他映射和列表(类似于 JSON)的映射结构组成。
  2. Java应用程序分析数据并向Ruby应用程序发送回复。

我们感兴趣的是评估消息传递格式(JSON,缓冲区协议节俭等)以及消息传输通道/技术(套接字,消息队列,RPC,REST,SOAP等)。

我们的标准:

  1. 往返时间短。
  2. 往返时间标准偏差低。(我们知道垃圾回收暂停和网络使用高峰会影响此值)。
  3. 高可用性。
  4. 可扩展性(我们可能希望将来有多个Ruby和Java应用程序实例交换点对点消息)。
  5. 易于调试和分析。
  6. 良好的文档和社区支持。
  7. Clojure支持的奖励积分。
  8. 良好的动态语言支持。

您建议使用哪种组合消息格式和传输方法?为什么?

我在这里收集了一些我们已经收集以供审查的材料:


答案 1

我们决定与BSON一起而不是RabbitMQ

我们喜欢BSON对异构集合的支持,并且不需要预先指定消息的格式。我们不介意它具有较差的空间使用特征,并且可能比其他消息格式更差的序列化性能,因为预计应用程序的消息传递部分不会成为瓶颈。它看起来不像一个很好的Clojure接口被编写来让你直接操作BSON对象,但希望这不会成为一个问题。如果我们决定BSON不适合我们,我将修改此条目。

我们之所以选择 RabbitMQ,主要是因为我们已经有了这方面的经验,并且正在一个需要高吞吐量和可用性的系统中使用它。

如果消息传递确实成为瓶颈,我们将首先关注BERT(我们拒绝了它,因为它目前似乎没有Java支持),然后是MessagePack(被拒绝,因为它似乎没有一个大型的Java开发人员社区使用它),然后是Avro(被拒绝,因为它需要你预先定义你的消息格式), 然后是协议缓冲区(由于额外的代码生成步骤和缺乏异构集合而被拒绝),然后是Thrift(由于协议缓冲区提到的原因而被拒绝)。

我们可能希望使用普通的 RPC 方案,而不是使用消息队列,因为我们的消息传递样式本质上是点对点同步的。

谢谢大家的输入!

更新:这是,显示了如何将Clojure映射转换为BSON并返回:project.cljcore.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)))))

答案 2

我无法从个人经验中说话,但我知道Flightcaster正在使用JSON消息传递将他们的后端clojure分析引擎链接到前端Rails应用程序,它似乎正在为他们工作。这是文章(出现在结尾附近):

Clojure and Rails - FlightCaster背后的秘密酱汁

希望这有帮助。--迈克


推荐