Come è possibile utilizzare efficacemente i servizi Web in un ambiente aziendale se non è possibile utilizzare le transazioni?


14

Il posto in cui sto lavorando sta cercando di stabilire alcune regole di base, e il dibattito che stiamo avendo ora è biblioteche locali vs servizi web per il riutilizzo del codice. I servizi Web sembrano essere la scelta popolare nella maggior parte delle aziende, ed è ciò a cui la maggior parte degli sviluppatori qui si appoggia.

Non riesco proprio a vedere come è possibile utilizzare efficacemente i servizi Web per qualsiasi lavoro serio. Come posso eseguire in modo sicuro più chiamate di servizio se non riesco a utilizzare una transazione?

Diciamo che ho un lavoro cron che attira clienti dal nostro database che soddisfano una certa condizione di cui devono essere informati. Vengono inviati un fax, un'e-mail e viene creato un ticket per tracciare il problema internamente. Si tratta di 3 diverse chiamate di servizio che potrebbero verificarsi per ciascun cliente in un ciclo for.

Se si verifica un errore ovunque, è possibile che, ad esempio, un fax e un'e-mail vengano inviati al cliente, ma non viene creato un biglietto. O peggio, questo cron job potrebbe contenere un bug che causa ogni volta che fallisce nello stesso punto e invia ripetutamente e-mail allo stesso cliente. Se le biblioteche fossero tutte locali, tutto potrebbe essere racchiuso in una transazione, e nulla di tutto ciò accadrebbe. Ma stiamo usando i servizi web in questo esempio.

Si noti che i metodi di posta elettronica e fax in realtà inseriscono i dati in tabelle delle code supportate dal database, che a loro volta sono gestite da un processo cron cron separato. Pertanto, se necessario, le chiamate ai metodi di servizio "Invia e-mail" e "Invia fax" potrebbero essere annullate senza effetti collaterali.

Un'opzione è quella di inserire l'intero blocco di codice nel servizio Web stesso, in modo che il servizio Web stesso chiamerebbe i metodi di creazione di e-mail, fax e ticket in una transazione. Ma poi stiamo creando un metodo di servizio web solo per l'uso di una transazione; non vi è alcun motivo valido per cui avremmo effettivamente bisogno di chiamare questo metodo da qualsiasi luogo tranne questo script cron.

Come gestiresti generalmente questo metodo?


Per fornire una risposta completa, avrei bisogno di ulteriori informazioni. Ci sono molte cose da considerare quando si passa a un'architettura basata sui servizi. Ad esempio, hai un ambiente eterogeneo (lingue e piattaforme diverse) o omogeneo (lingua e piattaforma singola). È in atto un sistema di bus di servizio? In caso contrario, prevedi di implementarne uno? Come prevedi di accedere ai tuoi servizi (Intranet a singola posizione, wan multi-posizione, client distribuito che colpisce un API di servizio pubblico). Esistono numerose variabili che influiscono su una soluzione "ottimale".
Michael Brown,

@MikeBrown: i servizi sarebbero tutti scritti in una lingua, ma consumati da più piattaforme. Nessuna idea sull'implementazione di un EBS, non abbiamo nemmeno avviato alcun tipo di servizio, quindi tutto è possibile. I servizi sarebbero principalmente consumati internamente sulla nostra rete locale, ma ce ne sarebbero alcuni che dovrebbero essere rivolti al pubblico per le applicazioni mobili.
Ryeguy,

"Se le biblioteche fossero tutte locali, tutto potrebbe essere racchiuso in una transazione e nulla di tutto ciò accadrebbe". Falso. L'errore potrebbe verificarsi dopo l'invio dell'email ma prima dell'aggiornamento finale del database. Una transazione non impedisce retroattivamente l'e-mail o il fax.
S. Lott

@ S.Lott: Sì, perché le chiamate al servizio di posta elettronica e fax in realtà le stanno semplicemente inserendo in una coda, che vengono recapitate da un processo diverso. Se la transazione che ho descritto sopra fosse avvenuta, l'inserimento della coda verrebbe interrotto.
Ryeguy,

1
@ryeguy: aggiorna la domanda. Si prega di non aggiungere commenti alla domanda. Questa è una parte importante della tua architettura. Si prega di rivelarlo nella domanda.
S. Lott

Risposte:


5

Quello che stai descrivendo è in effetti una transazione distribuita che implementa il commit in due fasi . Alcune piattaforme di messaggistica aziendale includono gestori di transazioni per supportare quel tipo di cose, ma i prodotti concreti dipendono dalla piattaforma / dal linguaggio. Non ho esperienza concreta con tali strumenti, ma spero che questi suggerimenti siano di aiuto.


3

È interessante il fatto che, mentre sto partecipando a questo particolare Q&A, c'è un thread simile sui servizi che supportano più piattaforme sulla mailing list DDD / CQRS a cui sto partecipando. Posso reiterare alcuni dei miei consigli qui.

Un'opzione per supportare le transazioni in un ambiente eterogeneo consiste nell'utilizzare un meccanismo di trasporto che supporta le transazioni ed è supportato su tutte le piattaforme da cui verrà utilizzato. Il protocollo AMQP ( Advanced Message Queue Protocol ) supporta le transazioni e esiste un'API nativa per quasi tutte le lingue comunemente utilizzate oggi. RabbitMQ è un server che implementa AMQP ed è stato testato nel settore come una soluzione affidabile.

Sfruttare un sistema basato su RabbitMQ ti mette sulla strada per avere un ESB completo nel caso tu abbia bisogno di svilupparti. Pubblica messaggi su un canale e ti iscrivi a una coda. Ciò che diventa veramente potente è quello tra il canale e la coda, puoi eseguire molte cose interessanti. Un canale può alimentare più code (pub / sub), una coda può essere alimentata da più canali, è possibile instradare i messaggi a diverse code in base al contenuto, ecc. Ecc.

Stavo solo leggendo delle alternative alle transazioni (che si presentano con spese generali e trasformano un'operazione asincrona in un'operazione di blocco). RabbitMQ supporta la cosiddetta conferma dell'editore . Fondamentalmente ti permette di registrare un callback per un metodo pubblicato per gestire una transazione fallita. Nel tuo caso potrebbe annullare le richieste e-mail / fax ed eliminare il biglietto.

Ovviamente la tana del coniglio (scusate il gioco di parole) va ancora più in profondità da lì. È possibile utilizzare Rabbit per eseguire orchestrazioni complesse con servizi Web interni ed esterni.

Per i tuoi servizi web rivolti al pubblico, diventa semplicissimo. Il tuo servizio (sia esso SOAP, REST o JSON) pubblica semplicemente un messaggio nella coda di servizio appropriata e lascia che il tuo sistema interno lo gestisca da lì.

Sono inoltre disponibili funzionalità per la creazione di un messaggio di richiesta / risposta per quegli scenari in cui si prevedono rapidamente informazioni.


2

Le parole chiave che stai cercando sono "coreografia del servizio web".

Dai un'occhiata all'articolo di Wikipedia a riguardo.


A volte chiamato anche "orchestrazione".
S. Lott,

1

Il modo in cui l'ho gestito in un'app di servizi che ho scritto è stato quello di creare un wrapper per gestire le transazioni necessarie. Nel mio caso, la richiesta dell'utente, effettuata dal sito Web, dall'app desktop o dal servizio Windows, ha dovuto interrogare un servizio Web e, in base al risultato e alle opzioni dell'utente, ha dovuto aggiornare un DB locale e, facoltativamente, uno remoto tramite un servizio web. Quindi ha dovuto generare un rapporto da restituire immediatamente, via e-mail e / o fax. Avevo il controllo del DB locale, della generazione di e-mail e di report, ma nessuno sui servizi Web o sul server fax.

La creazione di un wrapper ha permesso un migliore controllo delle transazioni e una gestione degli errori. Ha inoltre consentito una migliore sicurezza controllando l'accesso ai servizi di rete interna da fonti esterne. In generale, vedo la necessità di transazioni e gestione del servizio come un motivo valido per creare un wrapper appropriato per una singola soluzione purché il codice venga riutilizzato correttamente (nessuna codifica cut-n-paste).


1

Non riesco proprio a vedere come è possibile utilizzare efficacemente i servizi Web per qualsiasi lavoro serio. Come posso eseguire in modo sicuro più chiamate di servizio se non riesco a utilizzare una transazione?

Non puoi.

La domanda che dovresti porre è: come implementare le transazioni con il framework del servizio Web X? In questo momento, stai solo supponendo che sia impossibile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.