Самый быстрый и надежный способ взаимодействия приложений Clojure (Java) и Ruby - PullRequest
14 голосов
/ 17 декабря 2010

У нас есть облачные (RackSpace cloud) приложения на Ruby и Java, которые будут взаимодействовать следующим образом:

  1. Приложение Ruby отправляет запрос в приложение Java. Запрос состоит из структуры карты, содержащей строки, целые числа, другие карты и списки (аналог JSON).
  2. Приложение Java анализирует данные и отправляет ответ в приложение Ruby.

Мы заинтересованы в оценке обоих форматов обмена сообщениями (JSON, Буферные протоколы , Экономия и т. Д.), А также каналов / методов передачи сообщений (сокеты, очереди сообщений, RPC, ОТДЫХ, МЫЛО и пр.)

Наши критерии:

  1. Короткое время в оба конца.
  2. Низкое стандартное отклонение в обоих направлениях. (Мы понимаем, что паузы сборки мусора и пики использования сети могут повлиять на это значение).
  3. Высокая доступность.
  4. Масштабируемость (в будущем может потребоваться, чтобы несколько приложений Ruby и Java обменивались сообщениями точка-точка).
  5. Простота отладки и профилирования.
  6. Хорошая документация и поддержка сообщества.
  7. Бонусные баллы за поддержку Clojure.
  8. Хорошая поддержка динамического языка.

Какую комбинацию формата сообщения и способа передачи вы бы порекомендовали? Почему?

Я собрал здесь некоторые материалы, которые мы уже собрали для обзора:

Ответы [ 4 ]

3 голосов
/ 05 января 2011

Мы решили пойти с BSON более RabbitMQ .

Нам нравится поддержка BSON для разнородных коллекций и отсутствие необходимости предварительно указывать формат сообщений.Мы не возражаем против того, что он имеет плохие характеристики использования пространства и, вероятно, более низкую производительность сериализации, чем другие форматы сообщений, поскольку не предполагается, что узкая часть нашего приложения для обмена сообщениями является узким местом.Не похоже, что был написан хороший интерфейс Clojure, чтобы позволить вам напрямую манипулировать объектами BSON, но, надеюсь, это не будет проблемой.Я пересмотрю эту запись, если мы решим, что BSON не сработает для нас.

Мы выбрали RabbitMQ главным образом потому, что уже имеем опыт работы с ним и используем его в системе, требующей высокой пропускной способности и доступности.

Если обмен сообщениями становится узким местом, мы сначала обратимся к BERT (мы отказались от него, потому что в настоящее время он не поддерживает Java), а затем к MessagePack (отклонено, поскольку кажется, что сообщество не слишком большое).разработчиков Java, использующих его), затем Avro (отклонено, поскольку требуется предварительно определить формат сообщения), затем буфер протокола (отклонено из-за дополнительного этапа генерации кода и отсутствия разнородных коллекций), а затем Thrift (отклонено дляпричины, упомянутые для буферов протокола).

Возможно, мы захотим использовать простую схему RPC, а не использовать очередь сообщений, поскольку наш стиль обмена сообщениями по существу синхронен «точка-точка».

Спасибоза ваш вклад всем!

Обновление: вотproject.clj и core.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)))))
2 голосов
/ 17 декабря 2010

Я не могу говорить по личному опыту, но я знаю, что Flightcaster использует обмен сообщениями JSON для связи своего внутреннего механизма аналитики clojure с внешним приложением Rails, и, похоже, он работает на них. Вот статья (появляется в конце):

Clojure и Rails - секретный соус для FlightCaster

Надеюсь, это поможет. --Mike

2 голосов
/ 30 декабря 2010

У меня нет опыта в этом отношении. В любом случае, я опубликую это, возможно, полезное предположение.

  • ZeroMQ предлагает обмен сообщениями точка-точка, в том числе с различными типами сетевых топологий. Сообщения состоят из произвольных двоичных значений, поэтому для структурированных сообщений вам просто потребуется двоичный формат сериализации.

  • BSON , ProtoBuffers и BERT предлагают сериализацию произвольных структур данных (чисел, строк, последовательных массивов, ассоциативных массивов) в двоичные значения .

GitHub изобрел BERT для быстрого RCP; BSON был изобретен MongoDB (или 10gen) по той же причине; и ProtoBuffers также от Google.

1 голос
/ 17 декабря 2010

Я полагаю, что буферы протокола будут намного быстрее и эффективнее, чем JSON (в прошлый раз я проверял, что он примерно в 40 раз быстрее, я не пробовал это с ruby, поэтому ваш пробег может отличаться).

...