Domanda

Uno dei nostri prodotti implementa la seguente struttura di servizi web unidirezionale:

Server <--------------------- Middleware <---------------- Client
        SOAP over JMS (queue)              SOAP over HTTP

In questo modello, i client inviano messaggi SOAP su HTTP al nostro middleware (Progress SonicMQ). I messaggi vengono inseriti nelle code JMS da SonicMQ e il nostro server li recupera da lì. Tuttavia, come puoi vedere, il server non invia una risposta al client (JMS asincrono).

Vorremmo implementare un canale di risposta a questo modello. La soluzione spesso suggerita è quella di creare una risposta temporanea alla coda (al volo) nel middleware, consentendo al server di inviare una risposta a quella coda. Quindi, il client può recuperare la risposta e la replyTo-queue viene chiusa. Sembra abbastanza conveniente, ma sfortunatamente i nostri clienti operano su HTTP semplice e non su JMS, quindi i loro clienti non possono facilmente impostare la risposta alle code.

Un approccio per ottenere un canale di risposta in tale modello SOAP HTTP / JMS ibrido sarebbe quello di configurare il middleware per aprire la risposta. Per accodare ad ogni ricezione SOAP riuscita, aggiungere la risposta Informazioni di coda e mittente al messaggio SOAP e spingere il messaggio alla coda, dove verrà recuperato dal server. Dopo aver ricevuto ed elaborato il messaggio, il server potrebbe inviare una risposta alla risposta indicata In coda nel middleware. Infine, il middleware invierebbe la risposta (SOAP) su HTTP al client originale utilizzando i dati del messaggio SOAP (i dati che sono stati inseriti lì nelle procedure del middleware quando la richiesta è stata ricevuta per la prima volta).

Sebbene possibilmente possibile, sembra un po 'confuso. Quindi la domanda è: qualche modo più pulito di raggiungere tale modello di richiesta / risposta sul nostro caso? L'estremità del server è stata implementata in Java.

La soluzione:

Progresso SonicMQ supporta " Content Reply Send " HTTP Acceptor, che consente di inviare facilmente una risposta JMS. L'accettore Invia risposta contenuto funziona nel modo seguente:

  • Accettatore riceve il messaggio HTTP inviato da un client
  • Acceptor crea una coda JMS temporanea
  • Acceptor crea un messaggio JMS, contenente il corpo HTTP, e aggiunge l'identificazione della coda temporanea al messaggio JMS appena creato
  • Acceptor inserisce il messaggio JMS nella sua coda di destinazione (non nella coda temporanea)
  • Accettatore inizia a utilizzare la coda di risposta temporanea
  • Quando il client recupera il messaggio dalla coda di destinazione originale, contiene l'identificazione della coda di risposta impostata
  • Il client consuma il messaggio
  • Il client invia la risposta alla coda di risposta
  • Accettatore riceve il messaggio dalla coda
  • Accettatore invia un messaggio come HTTP al client che originariamente ha inviato il messaggio HTTP

Se il consumatore (" server " nel nostro caso) fallisce e non invia la risposta causando il timeout, il HTTP Acceptor di Sonic invia un messaggio HTTP al client indicando il timeout. Questa è una funzionalità molto standard in SonicMQ. Suppongo che esista anche in altri prodotti.

Ciò consente di utilizzare SOAP standard su JMS (vedere la risposta di skaffman) tra " server " end evita qualsiasi programmazione personalizzata nel middleware.

Vedo ancora alcuni problemi nel modello JMS, ma questo è sicuramente un miglioramento.

Aggiornamento 2009-11-05:

Dopo aver studiato ancora di più questo problema, si scopre il mio sospetto contro HTTP < - > middleware < - > JMS è stato rilevante.

Ci sono alcuni problemi critici in questo modello. Il modello sincrono-asincrono con middleware semplicemente non è conveniente. O hanno entrambe le estremità implementare la connessione JMS (che dovrebbe oscillare) o andare con HTTP in entrambe le estremità. Mescolarli provoca solo mal di testa. Di questi due, SOAP-over-HTTP è più semplice e supportato meglio di SOAP-over-JMS.

Ancora una volta: se stai progettando questo tipo di sistema ... NON.

È stato utile?

Soluzione

Non credo che la tua soluzione suggerita sia l'hacking, penso che sia la soluzione giusta. Si dispone del livello client-medio con un protocollo sincrono e quindi del livello server intermedio utilizzando un livello asincrono, a cui è necessario aggiungere un percorso di risposta per soddisfare la semantica sincrona. Ecco a cosa serve il middleware. Ricorda che JMS fornisce supporto esplicito per le code di risposta temporanee, non dovrai assolutamente rovinare il payload.

Una possibilità più a sinistra è la leva sul fatto che SOAP 1.2 è stato progettato pensando a JMS, e quindi è possibile utilizzare il livello di servizio Web tra middleware e livello server che fa SOAP-over-JMS. Ciò significa che è possibile mantenere SOAP end-to-end, con il middleware che modifica solo il trasporto.

L'unico stack di servizi Web che conosco che supporta il trasporto JMS è Spring Web Servizi , in cui il processo e lo sviluppo sono documentato qui . Ciò ti darebbe anche la possibilità di trasferire il tuo livello SOAP su Spring-WS, che prende a calci in culo :)

Altri suggerimenti

Perché non aggiungere un collegamento a una pagina che consenta agli utenti di verificare quando una risposta è pronta, come un ID tracker Fed Ex? Dai ai tuoi utenti l'ID tracker quando inviano la richiesta.

Questo si adatterebbe al linguaggio di richiesta / risposta HTTP e i tuoi utenti saprebbero comunque che la richiesta è " attiva e dimentica " ;.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top