Progetto di Gottardi Gianpaolo
Matr. 197814
Reingegnerizzazione
di un’applicazione: da un modello
single-user ad un’architettura
distribuita tollerante ai guasti basata
sul discovery dinamico dei servizi
Reti di Calcolatori LS
Ch.mo Professor Antonio Corradi
Motivazioni del progetto

Introdurre un’infrastruttura per rendere distribuita
un’applicazione single-user preesistente
contemplando politiche di:
 Fault
tolerance, al fine di garantire il corretto
funzionamento del sistema anche a fronte del
guasti di un server;
 Discovery dinamico dei servizi
per rendere scalabile la soluzione
proposta;
Reti di calcolatori - 1
L’applicazione originale

Si tratta di un prodotto sviluppato in C#
demandato alla gestione a 360° di uno
studio odontoiatrico (quindi pazienti, cartelle
cliniche, appuntamenti, listini, fatture, report)
con particolare attenzione all’aspetto
legislativo.

Da tempo il committente aveva espresso
l’esigenza di poter utilizzare l’applicazione
all’interno di una rete locale, garantendo
l’accesso a più postazioni mobili
contemporaneamente.

Questo naturalmente ha richiesto una
profonda rivisitazione del software
precedente, portando al progetto di una
nuova infrastruttura al cui interno si prevede
l’assegnamento delle diverse funzionalità a
più server cooperanti tra loro.
Reti di calcolatori - 2
Soluzione precedente

Una prima (e molto semplice)
realizzazione prototipale prevedeva:



la condivisone di un unico database,
senza considerare l’eterogeneità dei
servizi;
la mutua esclusione degli accessi, garantita da un processo
coordinatore centralizzato e noto a tutti i client;
Naturalmente la soluzione era poco “robusta”: il server
costituiva un single point of failure ed in caso di guasti
gli effetti erano:


o condizioni di deadlock permanente conseguente al rifiuto delle
richieste di accesso al database;
o corruzione dei dati, a causa del loro aggiornamento
contemporaneo da parte di più client (in caso di intervento manuale
dell’utente, tasto reset);
Purtroppo, entrambi gli aspetti vanificavano di fatto
la validità dell’intero software….
Reti di calcolatori - 3
Scelte tecnologiche (1)

Per quanto riguarda l’ambiente di sviluppo, si prevede di
mantenere quello del software originario, ovvero Visual Studio
2005 e il linguaggio C#. Non sono sorti in fase progettuale motivi
sufficienti per spingere lo sviluppatore alla realizzazione di
un’applicazione ibrida.

Tale decisione è stata giustificata anche
dalla disponibilità, nell’ambiente scelto,
di un valido strumento di supporto
alla programmazione distribuita:
Microsoft .NET Remoting
Reti di calcolatori - 4
Scelte tecnologiche (2)

Per le motivazioni riportate di seguito, la persistenza dei
dati verrà garantita attraverso ADO .Net,
Reti di calcolatori - 5
Progetto (1)
Da un punto di vista macroscopico, l’architettura elaborata prevede l’adozione
del modello three-tier introducendo una netta separazione tra i livelli di
presentazione (i client), di business (la logica applicativa mantenuta dai server)
e di persistenza dei dati (database server). In particolare, la matrice sottostante
deriva dall’applicazione del patter PAC.
Reti di calcolatori - 6
Progetto (2)

Scalabilità e flessibilità sono stati i principi guida del
processo di sviluppo: a tal fine è stato introdotto il
DiscoveryServer per la pubblicazione dinamica dei
servizi;

La tolleranza ai guasti è garantita invece dall’adozione di
un modello standby: si associa un componente detto
Monitor ad ogni server, avente il compito di controllare
periodicamente la liveness di quest’ultimo. In caso di
guasto si provvede all’attivazione di una copia di standby
del servizio, in maniera trasparente all’utente.

Per l’accesso mutuamente esclusivo / concorrente /
transazionale alla base dati, in fase progettuale si ritiene
opportuno l’impiego di un database server commerciale,
in quanto tali problematiche esulano dallo scopo del
presente lavoro.
Reti di calcolatori - 7
Progetto (3)
L’architettura risultante è dunque la seguente:
election
Client Manager
Standby copy
Monitor
election
Discovery
Server
Price-List Manager
Standby copy
Monitor
Client
Manager
Client
Price-list
manager
Client
DB
Server
Reti di calcolatori - 8
Prototipo (1)
La realizzazione di un prototipo funzionante, nel rispetto
dei vincoli temporali imposti, ha richiesto due compromessi:

impiego della tecnologia ADO.Net per la persistenza dei dati:
l’adozione di un database server avrebbe richiesto infatti tempi di
apprendimento / sviluppo / deployment troppo lunghi, per cui l’autore
ha preferito introdurre database Access locali ai server, gestiti
attraverso ADO.Net. A questa decisione segue la necessità del
mantenimento della coerenza tra i dati gestiti dai server primari e
quelli mantenuti dalla copia di standby.

implementazione completa dell’infrastruttura di supporto, ma
integrazione di un unico servizio completamente funzionante a
disposizione del cliente: sempre per motivi di tempo e per non dover
adottare soluzioni temporanee per la sincronizzazione dell’accesso
a dati condivisi (in vista dell’introduzione di un apposito database
server), il prototipo prevede l’erogazione di un unico servizio, ovvero
quello demandato alla gestione dei pazienti dello studio
odontoiatrico.
Reti di calcolatori - 9
Prototipo (2)
Gestione della persistenza: ogni componente lavora sulla propria copia
dei dati mediante un meccanismo basato su ADO .Net realizzato e
testato da tempo dall’autore. In estrema sintesi, una libreria estende le
funzionalità dei componenti propri del framework .Net consentendo non
solo il mantenimento dell’associazione e della consistenza tra la base
dati e il DataSet, ma anche la creazione automatica delle entità del
business layer.
Dal punto di vista prestazionale, a fronte di un transitorio iniziale dovuto
al caricamento dell’intero database nel DataSet (residente in memoria
principale) si ha un’estrema rapidità di esecuzione delle operazioni di
aggiornamento dei dati, aspetto molto importante
per la scelta delle politiche realizzate dal server.
Si vuole sottolineare come il punto precedente
richieda la specifica della sola linea di codice:
StudioDocument _document = new StudioDocument();
Reti di calcolatori - 10
I componenti
Pur delegando all’apposita relazione una
descrizione dettagliata dei singoli
componenti dell’architettura, si
presenteranno in seguito:

Le entità responsabili del soddisfacimento dei requisiti
funzionali: i server;

I client per l’interazione con l’utente;

Il DiscoveryServer per la pubblicazione dinamica dei
servizi;

Monitor e StandbyManager per garantire liveness e
fault tolerance del sistema.
Reti di calcolatori - 11
Cliente vs servitore (1)
Segue l’interfaccia del server Client_manager demandato alla
gestione dei pazienti:
Reti di calcolatori - 12
Cliente vs servitore (2) - Osservazioni

I primi tre metodi permettono l’aggiornamento dei dati contenuti nel
database e restituiscono all’utente un’indicazione della corretta esecuzione
dell’operazione mendiante la classe Response;

Get_client () consente il recupero di tutti i dati relativi ad un singolo paziente
per la loro visualizzazione
attraverso un’apposita form;

Get_client_list() invece restituisce
al client una lista di tutte e sole
le informazioni necessarie
al popolamento della ListView
a fianco
L’introduzione dei due diversi metodi
risponde all’esigenza di ottimizzare
la comunicazione tra i due componenti.
Reti di calcolatori - 13
Cliente vs servitore (3) - Osservazioni



La coppia di metodi di registrazione e
deregistrazione consente l’implementazione di
un meccanismo di call-back per segnalare ai
client variazioni della lista dei pazienti: grazie
alla serializzazione dei delegati offerta da .Net
Remoting, ogni modifica al database si riflette
nella generazione di un evento di tipo
BasicEvent contenente sia un’indicazione dell’
azione, sia un’istanza della classe ThinyClient.
I clienti registrati possono dunque aggiornare la
propria lista, naturalmente attraverso un thread
diverso da quello principale.
Anche se il modello potrebbe sembrare troppo
“accoppiato”, sono stati studiati diversi
accorgimenti per limitare gli svantaggi di questa
soluzione.
Reti di calcolatori - 14
Cliente vs servitore (3) - Osservazioni

Il metodo Print_client_report invia al server la richiesta di
stampa di report relativi ad uno o più pazienti. La peculiarità
di quest’operazione è l’attributo “OneWay()”: il processo di
stampa è infatti computazionalmente oneroso e tipicamente
richiede alcuni secondi. Possedendo un effetto visibile e
potendo così discriminare facilmente sul successo o meno della richiesta, al
metodo è stata associata una politica di tipo Fire&Forget : il client invoca
l’operazione e prosegue nella computazione senza preoccuparsi di un
eventuale valore di ritorno. Il server non si fa direttamente carico del
servizio, ma lo delega ad un thread creato ex-novo.

Il metodo Are_you_alive è connesso alla gestione della
liveness del server, ed è presente nell’interfaccia al solo
fine dichiarativo.
Il server è registrato presso l’infrastruttura .Net Remoting come
WellKnownObject in modalità Singleton. Per evitare problemi con eventuali
firewall, si preferisce l’utilizzo del canale Http al Tcp; conseguentemente i
messaggi di richiesta verranno inoltrati in formato Soap anzichè binario.

Reti di calcolatori - 15
Server vs Monitor (1) – Check della liveness
Il Monitor, unico per ogni server, è chiamato a svolgere tre compiti:
 pubblicare il servizio interagendo con il DiscoveryServer;
 inviare periodicamente messaggi di heartbeating per assicurarsi della
vitalità del server controllato;
 in caso di mancata risposta, aggiornare l’entry del DiscoveryServer ed
attivare la copia di standby, attraverso il suo controllore (StandbyManager).
Il primo punto è espletato tramite
l’invocazione del metodo Subscribe
del DiscoveryServer.
Il secondo mediante la creazione di
un thread, responsabile dell’invio
dei messaggi “Are you alive”.
L’abilitazione della copia di standby invece avviene conseguentemente
all’inoltro della richiesta di election al StandbyManager.
Reti di calcolatori - 16
Server vs Monitor (2) – Osservazioni

Lato server, per evitare di introdurre carico
computazionale connesso a funzionalità che
non riguardano la logica applicativa, è stato
sviluppato un sink che filtra i messaggi in
ingresso, costruisce la risposta alle richieste
di liveness e l’invia al mittente senza
interessare i livelli sovrastanti. Il sink (che di
fatto realizza il pattern Interceptor) è
posizionato immediatamente al di sopra del
formatter in quanto lavora su messaggi e
non stream di dati o envelope Soap.

Lato client, è prevista una classe statica che
ha il compito sia di gestire i servizi, attivando
e rendendo disponibile a livello applicativo i
remote refereces, sia di effettuare il
recovery nel caso in cui si verifichino problemi di connessione con il server.
Il funzionamento dell’intero sistema si basa sull’assunzione di affidabilità del
mezzo trasmissivo, da cui risulta improbabile la perdita di messaggi. Si tratta di
una supposizione verosimile in quanto l’ambiente di deployment sarà una
piccola rete locale con non più di dieci client (come indicato dal committente).
Reti di calcolatori - 17
DiscoveryServer

Il componente è stato introdotto sia
per una maggior scalabilità,
sia per l’aggiornamento dinamico
degli Url dei servizi (garantendo il
recovery dei client).

L’Url di un server è richiesto solo al primo accesso di un client.
La lista dei servizi è implementata attraverso un’Hashtable formata
dall’insieme delle coppie [NomeServizio,Url].


Non essendo prevista la persistenza dei dati, l’attivazione dev’esser
necessariamente effettuata in modalità Singleton.

Benché il prototipo preveda l’implementazione del solo Client_manager,
rendendo equivalente l’impiego dei metodi Lookup_service() e
Get_services(), l’utilizzo del secondo è consigliato per l’applicazione di
release in quanto limita l’interazione tra i client ed il DiscoveryServer
Reti di calcolatori - 18
StandbyManager e checkpointing (1)

A causa delle peculiarità del
prototipo, il compito di
questo componente non è
solo l’attivazione della copia
di standby di un server, ma
è anche responsabile dell’aggiornamento del database su cui essa opera,
come si può notare dall’interfaccia a lato.
Per il checkpointing è stato introdotto nel
server primario un Updater_sink che provvede
all’invocazione degli opportuni metodi:


in maniera trasparente rispetto al livello
applicativo;
in modalità event-driven,
dipendentemente dall’esito
dell’operazione, analizzando il risultato
dei livelli a monte.
Reti di calcolatori - 19
StandbyManager e checkpointing (2)

L’attributo [OneWay()] dei metodi dell’interfaccia esplica la politica
ottimista adottata; seguono le motivazioni alla base di questa scelta:
la fase di checkpointing è subordinata al successo dell’operazione
sul server primario; un problema è segnalato all’utente ma non
influenza il StandbyManager;
 la limitata complessità delle operazioni di aggiornamento del
DataSet rende remota la possibilità che il manager sollevi eccezioni
durante tale fase, a meno di un suo fallimento totale;
 il prototipo mira all’esposizione dell’intera architettura: sarebbero
possibili numerosi accorgimenti per garantire l’allineamento delle
copie, ma lo sforzo sarebbe vanificato dall’introduzione futura di un
database server.

Reti di calcolatori - 20
StandbyManager e copia del servizio (2)


La classe Configurator si occupa dell’attivazione sia del StandbyManager,
sia della copia secondaria, mediante un meccanismo ad eventi:
 La ricezione di un messaggio di election genera l’evento
“Disable_server”;
 Il relativo event handler è registrato dal metodo
Configurator.Init_manager() che contemporaneamente attiva anche
canale e servizio remoto (il StandbyManager);
 In caso di elezione, l’event handler provvede alla disconnessione del
manager dal canale di comunicazione e alla registrazione dinamica
della copia di standby;
Si sottolinea che il componente implementato può
esser configurato sia come server primario, sia come
copia secondaria, semplicemente agendo sul file
di configurazione dell’applicazione (flag Is_primary_copy).
Reti di calcolatori - 21
Conclusioni


L’intero lavoro è stato svolto prestando particolare attenzione alla flessibilità
e scalabilità del prodotto software: a tal fine, per ogni componente sono stati
introdotti parametri di configurazione, modificabili dall’amministratore di
sistema.
Il prototipo, seppur limitato nei servizi, ha portato all’arricchimento
dell’autore sotto diversi aspetti:
 sperimentazione delle problematiche affrontate nel corso di Reti d.C.;
 acquisizione di esperienza in merito a “nuove” tecnologie, come
Microsoft .Net Remoting;
 confronto diretto con il cosiddetto “chatty vs. chunky trade-off”;
 definizione di un modello sufficientemente “robusto”
per soddisfare le richieste del committente e
contemporaneamente limitare gli interventi
futuri del programmatore.
Reti di calcolatori - 22
Sviluppi futuri
Seguono alcune linee guida per evoluzioni future del prodotto (in ordine di
priorità):







introduzione di un database sever per il superamento delle limitazioni del
prototipo;
implementazione degli innumerevoli servizi previsti dall’applicazione originale
e loro integrazione nell’architettura progettata;
sviluppo di un LogServer per unificare la raccolta di informazioni in merito sia
al funzionamento normale del sistema, sia all’occorrenza di guasti;
utilizzo di nuovi interceptor e dei contesti per garantire l’identificazione degli
utenti e la sicurezza dei loro accessi;
realizzazione di canali di trasporto personalizzati per problematiche connesse
alla privacy dei pazienti, adottando a tal scopo strumenti per crittografare i
flussi di dati;
perfezionamento del deployment, con avvio automatico in background dei vari
server al boot del sistema operativo;
Cessione (dietro compenso) del prodotto finale
al committente.
Reti di calcolatori - 23