Linea guida: Gestione dello stato per i servizi
In questa linea guida, le questioni che circondano l'utilizzo di servizi con o senza stato vengono esplorate in termini dell'effetto sulle prestazioni e sulla solidità ed inoltre quando l'interazione richiede un approccio transazionale. La nozione della gestione dello stato in un ambiente SOA può essere considerata divisa in tre categorie principali: Stato della transazione, Stato di sicurezza e Stato funzionale.
Relazioni
Elementi correlati
Descrizione principale

Introduzione

La nozione di componenti con e senza stato è particolarmente importante nello sviluppo di applicazioni e sistemi distribuiti, sebbene solo di recente sia entrata a far parte del vocabolario comune. Essenzialmente, la nozione è che se due componenti o servizi stanno comunicando ed esistono alcuni stati gestiti dal componente del server per la durata della conversazione con il client, un arresto anomalo nel componente del server (o un errore di rete) potrebbe significare che il client non è in grado di completare la conversazione ed è necessario ricominciare. Inoltre, rende meno difficile il reindirizzamento delle richieste del client ad uno di un insieme di componenti a meno che l'insieme di componenti non condivida alcuni archivi comuni per lo stato della conversazione. Ciò è diventato un problema ben noto nello sviluppo delle applicazioni web in cui lo stato relativo è gestito attentamente in modo da essere evitato dove possibile e gestito dal client, dalla stessa conversazione (passando lo stato in ciascun messaggio) oppure nei componenti dal lato server con lo stato, progettati attentamente. Ad esempio, lo stato comune per l'interazione web con stato è il carrello degli acquisti. Gli utenti si aspettano che il carrello degli acquisti persista mentre si allontanano brevemente dal computer, ma com'è possibile realizzare ciò con 100,000 utenti correnti?

Con ciò non si intende che i componenti con stato siano inefficienti, rappresentano semplicemente un'area possibile di errore delle prestazioni e di rimbalzo, a meno che non vengano gestiti attentamente e sviluppati secondo gli standard più rigorosi. Infatti, tutte le applicazioni del business contengono servizi che per propria natura gestiscono o rappresentano entità inerentemente con stato o contengono servizi a cui è necessario accedere secondo determinate sequenze logiche. Infatti l'architettura J2EE definisce bean di sessione separati con stato e senza stato per indicare in modo esplicito questi problemi e definire determinate restrizioni sui componenti. Ciò conduce ad una classificazione semplice per i servizi con stato, le ragioni per cui non è possibile non metterli al primo posto. E' possibile che un servizio sia con stato per uno dei motivi seguenti:

Il servizio contiene lo stato per conto del client; questo è l'esempio del carrello degli acquisti. In qualche modo, alcuni dati devono essere stati persistenti tra le chiamate tra il client ed il servizio, questi dati sono parte della conversazione e perciò, senza una particolare attenzione, è possibile collegare un client ad una risorsa del server fornita.

Il servizio gestisce una risorsa con stato; in questo caso il servizio tende a gestire un insieme di risorse o di entità, ciascuna delle quali con stato. Ad esempio un ordine dell'utente ha lo stato, uno scambio di rete ha lo stato e così via. Pertanto, l'interfaccia per un servizio che gestisce un tale oggetto chiudendo o rimandando un ordine o riavviando uno scambio, è modificare lo stato di un'entità particolare.

Il servizio ha un protocollo con stato; in questo caso le operazioni che fornisce hanno un ordinamento logico. Ad esempio le operazioni login(), dostuff() e logoff(), che è possibile significano che è impossibile chiamare l'operazione dostuff() o logoff() senza l'operazione login().

Un'altra forma di stato è stata trovata in molte architetture dei componenti, ma non è applicabile al mondo dei servizi, è la nozione di stato transazionale. E' possibile nel mondo dei componenti indicare che un metodo get() e update() potrebbero essere chiamati su un componente da un client all'interno dell'ambito di una transazione creata e mantenuta dal client. Si presume che il metodo update() modifichi alcuni degli archivi transazionali sottostanti. Ciò richiede quasi sempre l'intervento della piattaforma del middleware per coordinare le transazioni e garantire che i metodi che richiedono le transazioni vengano chiamati da un client con una transazione aperta. Per i servizi, non è considerato appropriato o desiderabile seguire un modello in cui le transazioni nel senso del commit classico a due fasi vengano tenute aperte su alcune chiamate del servizio. Sono ora in fase di sviluppo degli standard per le transazioni attraverso le chiamate del servizio, ma seguono un paradigma fondamentalmente diverso (compensazione) e vengono supportati differentemente dalle piattaforme del middleware.

La tecnica più ovvia, suggerita precedentemente, per lo sviluppo corretto dei servizi con stato è quella di esternare lo stato del servizio, rendendo così non solo esplicito che il servizio ha uno stato, ma che è possibile identificare questo stato come parte della specifica di servizio. Ciò verrà trattato per le due classi di servizi con stato, di seguito.

Poiché la maggior parte dei servizi del software verrà sviluppata in cima ad una piattaforma esistente del middleware come J2EE o Microsoft .NET, all'interno di tali architetture dono descritte tecniche di implementazione di aiuto per la gestione dello stato. Pertanto, questa linea guida focalizza l'attenzione sulle tecniche di progettazione per determinate classi di servizi con stato. E' senz'altro importante notare che questa non è affatto una nuova area problematica. Nello sviluppo del mainframe, lo sviluppo di transazioni conversazionali o non conversazionali in CICS (IBM Customer Information Control System) con i client con schermo verde (in realtà 3270 terminali) è stato appreso e descritto da sviluppatori, progettisti ed architetti per molti anni.

Stato di conversazione persistente

Questo è il caso in cui il suggerimento più semplice è quello, in primo luogo, di evitare la situazione. Laddove possibile, se una progettazione richiede la gestione dello stato durante una conversazione tra un servizio e gli utenti, è meglio decidere di intraprendere un altro approccio. In caso contrario, esternare questo stato passando tutti i dati sullo stato richiesti tra il servizio e l'utente con ogni messaggio che riporti l'intera conversazione. Questo approccio potrebbe significare che la dimensione dei messaggi è aumentata in modo significativo, ma il servizio stesso ora è interamente senza stato. Un altro approccio è di portare un identificativo di conversazione all'interno di ciascun messaggio e di conservare tutti gli stati delle conversazioni in un archivio permanente come un database. Se ciò ha conseguenze significative per le prestazioni dal lato server, potrebbe invece contrastare le prestazioni della rete e del client salvate con i messaggi di dimensioni minori.

Uno degli scopi principali del rendere questi servizi senza stato è quello di essere capaci di fornire un insieme di servizi identici che possano servire qualsiasi richiesta utilizzando le tecniche di bilanciamento del carico per distribuire i client. Questo bilanciamento del carico è possibile se tutto lo stato viene esternato completamente o persiste in un archivio comune.

Gestione delle risorse con stato

In questo caso, viene trattata la gestione delle risorse stesse che hanno uno stato esplicito. Infatti, lo stato rappresenta un aspetto importante della stessa risorsa. E' possibile che venga descritto lo stato della risorsa, l'ordine dell'utente o lo scambio di rete su menzionati utilizzando una macchina di stato, descrivendo non solo gli stati validi ma anche il modo in cui le operazioni fornite dal servizio interessano lo stato delle risorse sottostanti.

Tuttavia nel realizzare questa descrizione, è importante notare che questo stato è una parte intrinseca della risorsa. Tuttavia, ciò potrebbe non essere espresso in modo esplicito nel modello delle informazioni che lo rappresenta. E' inoltre importante notare che nella gestione di ogni insieme di entità, è possibile identificare se ogni risorsa singola che si sta utilizzando dispone o meno di un identificativo esplicito.

Si noti che dove un servizio rappresenta un accesso o una query allo stato di un'entità fisica come uno scambio di rete o un elemento di controllo del processo, non è possibile considerare di esternare lo stato dell'entità. Lo stato di una valvola è noto solo interrogando la valvola. Sebbene sia possibile costruire e rispondere con un messaggio che descrive lo stato corrente della valvola, questa non sarà una situazione permanente. Lo stato della valvola può cambiare durante la trasmissione o l'elaborazione di questo messaggio.

Nell'area dei servizi web, esiste un insieme di standard emergenti noti come WSRF (Web Services Resource Framework) che trattano i modelli dei servizi con stato e gli approcci allo stato di codifica, particolarmente nel caso dei servizi che rappresentano la gestione delle risorse con stato. Per ulteriori informazioni, consultare il sito IBM WS-ResourceFramework.

Specifiche di servizio con stato

L'esempio su menzionato coinvolge un servizio che dispone di sequenze logiche per le operazioni che fornisce. Molti servizi forniranno interfacce simili. In alcuni casi, ciò riporta alle risorse con stato tranne nel caso in cui l'ordinamento delle operazioni è basato sullo stato della risorsa gestita. In questo caso, l'ordinamento è basato sulla stessa conversazione. L'esempio seguente mostra una specifica di servizio con alcuni protocolli associati, verranno mostrate prima la specifica strutturale quindi una macchina di stato che descrive la specifica comportamentale.

Il diagramma viene descritto nel contenuto testuale.

L'ordine di acquisto può essere in uno degli stati {Open, Canceled, Fulfilled, Closed} e modifica lo stato in base alle operazioni fornite nella specifica precedente. Viene inoltre indicato che nel caso dell'auto transizione sullo stato Open, si esegue l'operazione OrderChanged inviando le notifiche della modifica.

Il diagramma viene descritto nel contenuto testuale.

In molti casi in cui i servizi vengono sviluppati all'interno di un business singolo e di un ambito tecnico, potrebbero non venire sviluppate le specifiche comportamentali dettagliate o potrebbero essere descritte meno formalmente in un testo. Dove i servizi sono esposti al di fuori di un tale scopo, ad esempio tra le partizioni, rappresentano una specifica logica per l'interazione tra le partizioni e dovrebbero essere sviluppati molto dettagliatamente. Inoltre, le specifiche dettagliate consentono un riutilizzo più efficace ed efficiente da parte degli utenti quando si prevede di utilizzare i servizi frequentemente.