2010-12-17 62 views
14

我们有云托管(Rackspace公司云)Ruby和Java应用程序,将互相配合如下:最快可靠的方式应用程式沟通

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

我们感兴趣的是评估两个邮件格式(JSON,Buffer ProtocolsThrift等)以及消息传输信道/技术(插座,消息队列,RPC,REST,SOAP等)

我们的标准:

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

你会推荐什么消息格式和传输方法的组合?为什么?

我已经在这里聚集,我们已经收集了一些复习材料:

+0

你真的想可靠性(从标题)?在你所谈论的消息类中,这意味着消息永远不会丢失(并且可能还会以发送的顺序发送消息),这非常昂贵。当然,这里的可靠性指的是甚至抵制诸如反铲攻击(即网络或电力基础设施的物理破坏)之类的事情。我主要更喜欢及时交付,并使应用程序能够抵抗失败,因为这样更容易... – 2010-12-29 23:28:48

+0

嗨,我们希望合理的良好可靠性,并且不关心按订单交付。我们的系统可以容忍偶尔的故障,但保持故障率非常低很重要。 – jkndrkn 2010-12-30 16:51:25

回答

3

我们决定与BSON走了过来RabbitMQ

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

我们选择RabbitMQ主要是因为我们已经有了它的经验,并且正在将它用于要求高吞吐量和可用性的系统中。如果消息传递确实成为一个瓶颈,我们将首先考虑BERT(我们拒绝它,因为它目前似乎没有Java支持),然后是MessagePack(因为它似乎没有一个大的社区Java开发者使用它),然后到Avro(因为它需要你预先定义你的消息格式而被拒绝),然后Protocol Buffers(由于额外的代码生成步骤和缺乏异构集合而被拒绝),然后Thrift(被拒绝了Protocol Buffers提到的原因)。

我们可能希望使用简单的RPC方案而不是使用消息队列,因为我们的消息传递风格实质上是同步的点对点。

感谢您输入的每一个人!

更新:这里是project.cljcore.clj,说明如何Clojure的地图转换为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)))))
1

我认为协议缓冲区比JSON快很多并且效率更高(上次我检查速度快了40倍,我没有用ruby tho试试它,所以你的里程可能会有所不同)。

+0

比什么快40倍? – jkndrkn 2010-12-17 20:14:09

+0

编辑: ProtoBuffs vs JSON在我的情况下,但它当时并没有使用杰克逊(我想我使用jsonlib),并且从那时起,原型动物java库肯定也有进化。 – mpenet 2010-12-18 15:32:11

+0

网络RTT通常占主导地位,有效负载大小是真正重要的。 Gzipped JSON与协议缓冲区大小相当,所以我认为或者没问题。 – Kevin 2012-07-21 06:05:20

2

我不能从个人的经验说,但我知道,Flightcaster使用JSON消息到他们的后端Clojure的分析引擎链接到前端Rails应用程序,它似乎是为他们工作。这里的文章(似乎接近尾声):

Clojure and Rails - the Secret Sauce Behind FlightCaster

希望这有助于。 --Mike

+0

嗨,迈克。好文章。原来,我的队友们已经非常熟悉这种用例^ _ ^我不确定Ruby/Clojure interop是否有一部分是关键的速度敏感路径。 – jkndrkn 2010-12-20 18:47:53

2

我在这方面没有经验。无论如何,我会发布这个可能有用的猜测。

  • ZeroMQ提供点对点消息传递,包括各种类型的网络拓扑。消息由任意的二进制值组成 - 所以您只需要为您的结构化消息使用二进制序列化格式。

  • BSON,ProtoBuffersBERT提供任意数据结构(数字,字符串,顺序数组,关联数组)的序列化为二进制值。

GitHub发明了快速RCP的BERT; BSON是由MongoDB(或10gen)出于同样的原因发明的;和Google的ProtoBuffers。

+0

谢谢,我们已经在系统中使用了RabbitMQ,并且可能会考虑简单地使用它来代替RPC解决方案进行消息传递。到目前为止,它看起来像我们要去与Apache Thrift,Protocol Buffers,或者MessagePack进行序列化。 Apache Avro是另一种可能性。 – jkndrkn 2010-12-30 16:39:12

+0

如果您已经部署了像RabbitMQ这样的消息总线,那么当您需要消息传递时重新使用它可能是有意义的。否则,ZeroMQ可能是有道理的,因为它可能更易于部署:它是一个用于从应用程序组件中使用的直接消息传递的库,并且不需要部署任何单独的基础架构。我添加了这个评论,以防其他人有相同的问题,但没有部署RabbitMQ。 – yfeldblum 2010-12-30 16:49:01