2010-12-17 9 views
14

Mamy chmurze gospodarzem (Rackspace Chmura) Ruby i Java aplikacje, które oddziałują w sposób następujący:Najszybsza niezawodny sposób na Clojure (Java) i Ruby aplikacje do komunikowania

  1. Ruby aplikacja wysyła żądanie do aplikacji Java. Żądanie składa się ze struktury mapy zawierającej ciągi, liczby całkowite, inne mapy i listy (analogiczne do JSON).
  2. Aplikacja Java analizuje dane i wysyła odpowiedź do aplikacji Ruby.

Jesteśmy zainteresowani w ocenie oba formaty wiadomości (JSON, Buffer Protocols, Thrift, itd.), Jak również kanałów transmisji wiadomości/technik (rurkowe, kolejki komunikatów, RPC, REST, SOAP, etc.)

Nasze kryteria:

  1. Krótki czas podróży w obie strony.
  2. Niskie odchylenie standardowe w czasie krótkiego cyklu. (Rozumiemy, że wstrzymanie zbierania śmieci i wzrost wykorzystania sieci może wpłynąć na tę wartość).
  3. Wysoka dostępność.
  4. Skalowalność (możemy chcieć mieć wiele instancji aplikacji Ruby i Java wymieniających wiadomości typu punkt-punkt w przyszłości).
  5. Łatwość debugowania i profilowania.
  6. Dobra dokumentacja i wsparcie społeczności.
  7. Punkty premiowe za wsparcie Clojure.
  8. Dobra obsługa dynamicznego języka.

Jaką kombinację formatu wiadomości i metody transmisji poleciłbyś? Czemu?

Mam tu pewne materiały zebrane już zebrane na test:

+0

Naprawdę chcesz niezawodność (z tytułu)? W kontekście klasy wiadomości, o której mówisz, oznacza to, że wiadomości nigdy się nie gubią (i być może również, że są dostarczane w kolejności, w jakiej zostały wysłane), co jest * bardzo * drogie. Oczywiście niezawodność odnosi się tutaj do odporności na takie rzeczy, jak atak z wykorzystaniem broni koparkowej (np. Fizyczne zniszczenie sieci lub infrastruktury energetycznej). Najczęściej wolę mieć terminową dostawę i sprawić, że aplikacje będą odporne na awarie, ponieważ jest to o wiele łatwiejsze ... –

+0

Witaj, chcemy rozsądnie dobrej niezawodności i nie dbają o dostawę w kolejności. Nasz system może tolerować okazjonalne awarie, chociaż utrzymanie wskaźnika awarii jest bardzo niskie. – jkndrkn

Odpowiedz

3

Zdecydowaliśmy się przejść z BSON przez RabbitMQ.

Lubimy wsparcie BSON dla heterogenicznych kolekcji i brak potrzeby określania formatu komunikatów z góry.Nie przeszkadza nam to, że ma słabą charakterystykę użytkowania przestrzeni i prawdopodobnie gorszą wydajność serializacji niż inne formaty wiadomości, ponieważ część komunikacyjna naszej aplikacji nie jest wąskim gardłem. Wygląda na to, że ładny interfejs Clojure nie został napisany, aby pozwolić ci bezpośrednio manipulować obiektami BSON, ale mam nadzieję, że to nie będzie problem. Zrewiduję ten wpis, jeśli zdecydujemy, że BSON nie zadziała dla nas.

Wybraliśmy RabbitMQ głównie dlatego, że mamy już z tym doświadczenie i używamy go w systemie, który wymaga dużej przepustowości i dostępności.

Jeśli komunikat stanie się wąskim gardłem, najpierw zajrzymy do BERT (odrzuciliśmy go, ponieważ obecnie nie obsługuje Java), następnie do MessagePack (odrzucono, ponieważ wydaje się, że nie ma dużej społeczności Programiści Java używający go), następnie do Avro (odrzucony, ponieważ wymaga to zdefiniowania formatu wiadomości z góry), następnie bufory protokołów (odrzucone z powodu dodatkowego etapu generowania kodu i braku heterogenicznych zbiorów), a następnie oszczędzanie (odrzucone dla wymienione powody dla buforów protokołu).

Możemy chcieć pójść prostym schematem RPC zamiast używać kolejki komunikatów, ponieważ nasz styl przesyłania wiadomości jest zasadniczo synchroniczny punkt-punkt.

Dzięki za wkład każdy!

Aktualizacja: Oto project.clj i core.clj, który pokazuje w jaki sposób przekonwertować mapy Clojure do BSON i tył:

;;;; 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

Wierzę, że bufory protokołów byłyby dużo szybsze i bardziej wydajne niż JSON (ostatnio sprawdzałem, że było około 40 razy szybciej, nie próbowałem tego z rubinem, aby twój przebieg był różny).

+0

40 razy szybciej niż co? – jkndrkn

+0

edytowane: ProtoBuffs vs JSON w moim przypadku, ale nie używałem wtedy Jacksona (myślę, że użyłem jsonlib) i od tego czasu ewolucja java lib protobuff też musiała ewoluować. – mpenet

+0

Sieć RTT zwykle dominuje, a wielkość ładunku jest tym, co naprawdę ważne. Gzipped JSON ma rozmiar podobny do buforów protokołu, więc myślę, że albo jest w porządku. – Kevin

2

Nie mogę mówić z osobistych doświadczeń, ale wiem, że Flightcaster korzysta z przesyłania komunikatów JSON, aby połączyć swój mechanizm analityki kliknięć w back-end z aplikacją Railsową front-end i wydaje się, że działa dla nich. Oto artykuł (pojawia się pod koniec):

Clojure and Rails - the Secret Sauce Behind FlightCaster

Nadzieja to pomaga. - Mike

+0

Cześć Mike. Niezły artykuł. Okazuje się, że moi koledzy z drużyny są już bardzo zaznajomieni z tym przypadkiem użycia^_^Nie jestem pewien, czy opisany przez niego interwał Ruby/Clojure jest częścią krytycznej, zależnej od prędkości ścieżki. – jkndrkn

2

Nie mam żadnego doświadczenia w tym zakresie. W każdym razie opublikuję to prawdopodobnie pomocne podpowiedź.

  • ZeroMQ oferuje wiadomości point-to-point, włącznie z różnymi typami topologii sieci. Wiadomości składają się z arbitralnych wartości binarnych - więc potrzebujesz tylko formatu serializacji binarnej dla wiadomości strukturalnych.

  • BSON, ProtoBuffers i BERT oferta serializacji dowolnych struktur danych (numerów sekwencyjnych, smyczki, tablice, tablice asocjacyjne) do wartości binarnych.

GitHub wynalazł BERT dla szybkiego RCP; BSON został wynaleziony przez MongoDB (lub 10gen) z tego samego powodu; i ProtoBuffers również przez Google.

+0

Dzięki, że już używamy RabbitMQ w systemie i możemy rozważyć użycie tego zamiast rozwiązania RPC do przesyłania wiadomości. Do tej pory wygląda na to, że zastosujemy Apache Thrift, Protocol Buffers lub być może MessagePack do serializacji. Apache Avro to kolejna możliwość. – jkndrkn

+0

Jeśli masz już zainstalowaną magistralę komunikatów, taką jak RabbitMQ, może być przydatne ponowne jej użycie, gdy potrzebujesz wiadomości. W przeciwnym razie ZeroMQ może mieć sens, ponieważ może być łatwiejsze do wdrożenia: jest to biblioteka bezpośredniego przesyłania wiadomości, z której korzystasz w ramach składników aplikacji i nie wymaga wdrażania żadnej oddzielnej infrastruktury. Dodaję ten komentarz w przypadku, gdy ktoś inny ma to samo pytanie, ale nie ma wdrożonego RabbitMQ. – yfeldblum

Powiązane problemy