Jednym z naszych produktów realizuje następujące jednokierunkową strukturę serwis internetowy:Request-odpowiedź dla hybrydowego SOAP przez HTTP/JMS nad middleware
Server <--------------------- Middleware <---------------- Client
SOAP over JMS (queue) SOAP over HTTP
W tym modelu klienci wysyłają komunikatów SOAP przez HTTP do naszego middleware (Progress SonicMQ). Wiadomości są przekazywane do kolejek JMS przez SonicMQ, a nasz serwer pobiera je stamtąd. Jednak, jak widać, serwer nie wysyła odpowiedzi do klienta (asynchroniczny JMS).
Chcielibyśmy zaimplementować kanał odpowiedzi do tego modelu. Często proponowanym rozwiązaniem jest utworzenie tymczasowej kolejki odpowiedzi (w locie) w oprogramowaniu pośredniczącym, dzięki czemu serwer może wysłać odpowiedź do tej kolejki. Następnie klient może pobrać odpowiedź, a kolejka replyTo jest zamknięta. Brzmi to dość wygodnie, ale niestety nasi klienci działają na zwykłym HTTP, a nie na JMS, więc ich klienci nie mogą łatwo ustawić kolejek replyTo.
Jednym ze sposobów uzyskania kanału odpowiedzi w takim modelu hybrydowego protokołu HTTP/JMS SOAP byłoby skonfigurowanie oprogramowania pośredniego tak, aby otwierało kolejkę replyTo przy każdym pomyślnym odbiorze SOAP, dodawało informacje o kolejce odpowiedzi i nadawcy do komunikatu SOAP i pchało wiadomość do kolejki, gdzie zostanie pobrana przez serwer. Po otrzymaniu i przetworzeniu komunikatu serwer może wysłać odpowiedź do wskazanej kolejki replyTo w oprogramowaniu pośredniczącym. Na koniec oprogramowanie pośredniczące wyśle odpowiedź (SOAP) za pośrednictwem protokołu HTTP z powrotem do pierwotnego klienta, korzystając z danych z komunikatu SOAP (danych, które zostały tam wstawione w procedurach oprogramowania pośredniego po otrzymaniu żądania po raz pierwszy).
Choć jest to możliwe, brzmi to trochę hacky. Tak więc pytanie brzmi: czy istnieją bardziej czyste sposoby osiągnięcia takiego modelu żądanie/odpowiedź w naszej sprawie? Koniec serwera został zaimplementowany w Javie.
Rozwiązanie:
Progress SonicMQ obsługuje "Content Odpowiedz Wyślij" Akceptanta HTTP, który pozwala w łatwy sposób wysłać JMS odpowiadanie. Treść Odpowiedz Wyślij prace akceptora w następujący sposób:
- Akceptant otrzymuje wiadomość HTTP klient wysłana
- akceptanta tworzy tymczasowy JMS kolejki
- akceptanta buduje się komunikat JMS, zawierająca ciało HTTP i dodaje identyfikację tymczasowego kolejce do nowo utworzonej wiadomości JMS
- akceptanta popycha komunikat JMS do swojej kolejki docelowej (nie kolejce tymczasowy)
- akceptanta rozpoczyna spożywanie tymczasowy zwrotny kolejce
- Gdy klient pobiera wiadomość z oryginalnym kolejki docelowej, to zawiera zestaw zwrotny kolejce IDENTYFIKACJA
- klient zużywa wiadomość
- Klient wysyła odpowiedź na post-warkocz
- Akceptant otrzymuje wiadomość z kolejki
- Akceptant wysyła wiadomość jako HTTP do klienta, który pierwotnie wysłał komunikat HTTP
Should konsument („serwer” w naszym przypadku) nie uda i nie wysłać odpowiedź powodując limit czasu, HTTP akceptor Sonic wysyła komunikat HTTP do klienta ze wskazaniem timeo ut. Jest to bardzo standardowa funkcja w SonicMQ. Przypuszczam, że istnieje również w innych produktach.
Umożliwia to używanie standardowego protokołu SOAP przez JMS (patrz odpowiedź skaffmana) na końcu "serwera", unikając jakiegokolwiek programowania niestandardowego w oprogramowaniu pośredniczącym.
Mimo to nadal widzę pewne problemy w modelu JMS, ale jest to zdecydowanie poprawa.
Aktualizacja 2009-11-05:
Po zbadaniu tego problemu nawet więcej, okazuje się, moje podejrzenia przeciwko HTTP < -> middleware < -> JMS jest istotne.
W tym modelu występuje kilka poważnych problemów. Synchroniczny model asynchroniczny z oprogramowaniem pośredniczącym po prostu nie jest wygodny. Albo oba końce implementują połączenie JMS (które powinno działać), albo idą z HTTP na obu końcach. Mieszanie ich powoduje tylko bóle głowy. Z tych dwóch, SOAP-over-HTTP jest prostszy i lepiej obsługiwany niż SOAP-over-JMS.
Jeszcze raz: jeśli projektujesz ten rodzaj systemu ... NIE.
Natywna obsługa SOAP przez JMS brzmi nieźle. Nie wiedziałem, że to istnieje. Oprócz Spring wydaje się, że implementacja Metro JAX-WS obsługuje również SOAP przez JMS. Przypuszczam, że któryś z nich pozwala na konfigurację JMS fabryki i kolejki konfiguracji niestandardowej? Zastanawiam się nad tym, ponieważ musimy ustawić kilka właściwości specyficznych dla SonicMQ. Ponadto, SonicMQ domyślnie wysyła odpowiedź OK/fault, więc muszę to zmienić w oprogramowaniu pośredniczącym. Jednak myślę, że to powinno być łatwe. Wygląda na to, że muszę się trochę nauczyć ... –
Wygląda na to, że masz do wykonania interesującą inżynierię :) Zgaduję, że Spring-WS używa Spring's JMS support, co jest całkiem niezłe i powinno pozwolić ci na dostosowywanie rzeczy tak, jak potrzebujesz. – skaffman