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

发布于 2024-10-08 07:35:12 字数 2906 浏览 10 评论 0原文

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

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

我们有兴趣评估这两种消息传递格式(JSON、缓冲区协议Thrift等)以及消息传输渠道/技术(套接字、消息队列、RPC、REST、SOAP 等)

我们的标准:

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

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

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

We have cloud-hosted (RackSpace cloud) Ruby and Java apps that will interact as follows:

  1. Ruby app sends a request to Java app. Request consists of map structure containing strings, integers, other maps, and lists (analogous to JSON).
  2. Java app analyzes data and sends reply to Ruby App.

We are interested in evaluating both messaging formats (JSON, Buffer Protocols, Thrift, etc.) as well as message transmission channels/techniques (sockets, message queues, RPC, REST, SOAP, etc.)

Our criteria:

  1. Short round-trip time.
  2. Low round-trip-time standard deviation. (We understand that garbage collection pauses and network usage spikes can affect this value).
  3. High availability.
  4. Scalability (we may want to have multiple instances of Ruby and Java app exchanging point-to-point messages in the future).
  5. Ease of debugging and profiling.
  6. Good documentation and community support.
  7. Bonus points for Clojure support.
  8. Good dynamic language support.

What combination of message format and transmission method would you recommend? Why?

I've gathered here some materials we have already collected for review:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

残疾 2024-10-15 07:35:12

我们决定使用 BSON 而不是 RabbitMQ

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

我们选择 RabbitMQ 主要是因为我们已经有使用它的经验,并且正在需要高吞吐量和可用性的系统中使用它。

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

我们可能想要使用普通的 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)))))

We have decided to go with BSON over RabbitMQ.

We like BSON's support for heterogeneous collections and the lack of the need to specify the format of messages up-front. We don't mind that it has poor space usage characteristics and likely poorer serialization performance than other message formats since the messaging portion of our application is not anticipated to be the bottleneck. It doesn't look like a nice Clojure interface has been written to let you directly manipulate BSON objects, but hopefully that won't be an issue. I will revise this entry if we decide that BSON won't work out for us.

We chose RabbitMQ mainly because we already have experience with it and are using it in a system that demands high throughput and availability.

If messaging does become a bottleneck, we will look first to BERT (we rejected it because it currently does not appear to have Java support), then to MessagePack (rejected because it appears that there isn't a large community of Java developers using it), then to Avro (rejected because it requires you to define your message format up-front), then Protocol Buffers (rejected because of the extra code generation step and lack of heterogeneous collections) and then Thrift (rejected for the reasons mentioned for Protocol Buffers).

We may want to go with a plain RPC scheme rather than using a message queue since our messaging style is essentially synchronous point-to-point.

Thanks for your input everyone!

Update: Here is the project.clj and core.clj that shows how to convert Clojure maps to BSON and back:

;;;; 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)))))
删除→记忆 2024-10-15 07:35:12

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

Clojure 和 Rails - FlightCaster 背后的秘密

希望这有帮助。
- 麦克风

I can't speak from personal experience, but I know that Flightcaster is using JSON messaging to link their back-end clojure analytics engine to a front-end Rails app and it seems to be working for them. Here's the article (appears near the end):

Clojure and Rails - the Secret Sauce Behind FlightCaster

Hope this helps.
--Mike

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

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

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

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

I have no experience in this regard. I will post this possibly-helpful guess anyway.

  • ZeroMQ offers point-to-point messaging, including with various types of network topologies. Messages consist of arbitrary binary values - so you will just need a binary serialization format for your structured messages.

  • BSON, ProtoBuffers, and BERT offer serialization of arbitrary data structures (numbers, strings, sequential arrays, associative arrays) into binary values.

GitHub invented BERT for fast RCP; BSON was invented by MongoDB (or 10gen) for the same reason; and ProtoBuffers likewise by Google.

时常饿 2024-10-15 07:35:12

我相信协议缓冲区会比 JSON 更快、更高效(上次我检查它大约快了 40 倍,但我没有用 ruby​​ 尝试过,所以你的情况可能会有所不同)。

I believe Protocol-buffers would be a lot faster and more efficient than JSON (last time i checked it was around 40 times faster, i didn t try it with ruby tho so your mileage may vary).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文