Monitoraggio dell’attività di oggetti CORBA operanti su rete LAN (COAMonitor-CORBA Object Activity Monitor)
Introduzione
Il progetto mira
all’implementazione di un sistema di monitoraggio distribuito per l’attività
svolta da un certo numero di oggetti CORBA residenti sui nodi di una rete LAN e
a fornirne una rappresentazione visuale all’amministratore della rete . La
quantificazione dell’attività, è basata su misure dei tempi d’elaborazione e di trasmissione e sul conteggio delle
singole operazioni svolte dagli oggetti. L’amministratore avrà in tal modo
conoscenza dell’entità del carico cui ogni nodo è sottoposto sia singolarmente
sia in relazione all’attività svolta sull’insieme dei nodi monitorati.
L’attività sui nodi è stimolata
da applicazioni Client che richiedono questo o quel servizio ad oggetti remoti
o locali. L’accesso a questi servizi è possibile solo dopo che applicazioni
server hanno costruito e attivato gli oggetti che li forniscono, per cui la
scelta dell’attività da monitorare non sarà basata sui singoli oggetti, ma
sulle applicazioni che li utilizzano o che ne rendono possibile l’uso. Una
volta effettuata la scelta, il Monitor rileverà le azioni svolte su tutti gli
oggetti coinvolti.
Il progetto non è basato su
conoscenze a priori dell’attività da monitorare: non si conosce l’identità
degli oggetti e i servizi che rendono disponibili, non si conosce la loro
allocazione sui nodi e non si conosce il numero di applicazioni in esecuzione.
Tutte queste informazioni dovranno essere rilevate a tempo di esecuzione
tramite l’uso di servizi dinamici resi disponibili dall’architettura CORBA e
dalla sua implementazione VisiBroker.
Il Monitor dovrà rispettare il
principio di minima intrusione il quale afferma che le attività di gestione e
monitoraggio dei sistemi devono
influire il meno possibile sulle applicazioni principali, introducendo il più
basso overhead possibile.
Progetto e Implementazione
CORBA e VisiBroker
CORBA(Common Object Request Broker Architecture) è un’architettura nata dal lavoro del comitato OMG(Object Management Group). Nasce dall’esigenza di colmare le eterogeneità e di fornire interoperabilità tra sistemi comunicanti in rete. Grazie al supporto alla comunicazione ORB, al protocollo IIOP e ad un linguaggio comune di dichiarazione delle interfacce IDL (Interface Definition Language) permette alle applicazioni che si vogliono adattare all’architettura, di comunicare nonostante i differenti linguaggi con cui sono implementate, le differenti tipologie di macchine, sistemi operativi e architetture di rete su cui lavorano. L’architettura di CORBA è basata sugli oggetti, il linguaggio di dichiarazione IDL e il mappaggio di questo linguaggio nei più usati linguaggi di programmazione consente una netta separazione tra le interfacce e le implementazioni. Questa è l’essenza dell’architettura, da questa separazione nasce la possibilità di coordinare l’attività di oggetti eterogenei che hanno conoscenza reciproca solo attraverso le interfacce.
La specifica CORBA è stata implementata da diversi produttori, tra cui l’Inprise sviluppatrice di VisiBroker. L’Inprise è strettamente legata alla Borland che introduce l’implementazione nei suoi prodotti di sviluppo (JBuilder, C++Builder). VisiBroker fornisce un set completo di strumenti per la costruzione e la gestione di applicazioni distribuite basate su oggetti CORBA. Alcuni strumenti derivano direttamente dalla specifica OMG, altri sono stati ampliati, altri ancora sono specifici di questa implementazione.
Di seguito descriverò le funzionalità dei servizi che intendo utilizzare nella realizzazione del progetto.
Componente fondamentale di VisiBroker è lo SmartAgent, che funge da directory service dinamico e distribuito, il quale permette alle applicazioni client di ottenere un facile accesso alle implementazioni degli oggetti Server in base al nome con cui vengono registrati presso l’agente. La cooperazione tra SmartAgent permette di ottenere bilanciamento del carico e controllo sulle connessioni, che possono venire ripristinate in caso di errori o ridirette in caso di caduta dell’oggetto servitore.
Sugli SmartAgent si basano le funzionalità del Location Service, un’estensione a CORBA che tiene traccia e permette di conoscere e ritrovare tutte le istanze degli oggetti attivi in rete e di ottenere notifica dei cambiamenti della disponibilità di queste tramite un servizio di callback implementato da componenti denominati Trigger.
Tra gli strumenti specificati da CORBA, che VisiBroker ha rivisitato e presentato in una forma più dettagliata ci sono gli Interceptor. Gli Interceptor permettono di definire estensioni alle funzionalità dell’ORB, dando visione di operazioni normalmente nascoste all’utente. Gli Interceptor possono essere usati per personalizzare il codice di clienti e servitori, al fine di bilanciare il carico, monitorare le applicazioni, implementare politiche di sicurezza. Anch’essi agiscono tramite un meccanismo asincrono di callback, attivato dall’ORB.
Struttura dell’applicazione.
L’applicazione è essenzialmente formata da due componenti: uno d’intercettazione dell’attività (Interceptor) e uno di raccolta e presentazione dei dati ottenuti (Monitor).
Assumeremo come ipotesi di progetto che un Monitor possa
seguire le attività di un massimo di 10 applicazioni contemporaneamente, e che
un’applicazione possa essere monitorata da un solo Monitor per volta.
La presenza del pacchetto COAMonitor (CORBA Object Activity Monitor) su un nodo, rende disponibile le funzionalità sia del Monitor che dell’Interceptor. Permette quindi sia alle applicazioni locali di essere monitorate, sia la visualizzazione dei risultati del monitor.
Ad ogni applicazione rimane associato un Interceptor che viene caricato dinamicamente al momento dell’inizializzazione del supporto alla comunicazione(ORB).
Specifica della comunicazione tra i componenti.
La comunicazione tra i componenti è realizzata usando l’architettura CORBA. Interceptor e Monitor non ricoprono il classico rapporto di cliente e di servitore, se non inizialmente. Tale paradigma viene ribaltato dall’uso del meccanismo di callback: il Monitor si registra presso gli Interceptor, chiamandone un metodo che accetta come parametro il riferimento ad un oggetto Listener residente sul nodo del Monitor. Durante la prima fase il Monitor è il client e l’Interceptor il server, una volta avvenuta la registrazione, il Monitor ottiene tramite i Listener la notifica degli eventi rilevati, nonchè tutte le informazioni necessarie alla caratterizzazione dell’operazione intercettata.
Nella Fig. 1 è descritto uno scenario tipico di
funzionamento del Monitor: due Monitor dopo aver rilevato la presenza di un
certo numero di Interceptor, manifestano il loro interesse a monitorare alcune
delle applicazioni presenti; gli Interceptor rispondono con un messaggio
testuale che conferma la registrazione e cominciano immediatamente ad inviare i
dati monitorati. L’insieme delle applicazioni rimane suddivisa in sottoinsiemi
disgiunti, ognuno di essi associato ad un Monitor.
Figura 1
Utilizzo di VisiBroker e dei suoi
servizi.
Il progetto verrà realizzato,
usando JBuilder4 della Borland nella sua versione Enterprise. Questa versione
contiene l’implementazione VisiBroker 4.1 delle specifiche CORBA fornite dalla
OMG nella sua versione 2.3.
I due servizi che in particolare
si prestano alla realizzazione dei nostri scopi, come già anticipato sono: per
l’implementazione dell’Interceptor, l’ insieme di interfacce Interceptor i cui metodi vengono chiamati
automaticamente dall’ORB dopo la registrazione presso quest’ultimo degli
oggetti che le implementano.
Ogni interfaccia è legata ad un
insieme di eventi ben preciso, ad esempio i metodi dell’interfaccia
POALifeCycleInterceptor rispondono alla creazione di un nuovo oggetto servitore
e alla sua distruzione, il BindInterceptor si occupa invece dei tentativi di connessione da parte di un
Client ad un oggetto remoto, etc.
Solo una parte di questi eventi è
utile ai nostri scopi, quindi solo un sottoinsieme di queste interfacce verrà
utilizzata.
Per quanto riguarda il lato Monitor,
viene utilizzato il Location Service le cui
funzionalità sono accessibili a tempo di esecuzione tramite
l’interfaccia Agent, i cui metodi colloquiano direttamente con lo SmartAgent e
permettono di eseguire ricerche all’interno dell’insieme degli oggetti
registrati. In particolare verrà utilizzato per conoscere quali applicazioni
monitorabili sono attualmente in esecuzione sulla rete.
Interceptor
Componenti principali.
I componenti fondamentali dell’Interceptor sono : InterceptorServiceLoader, MonitorBinder, ISPOAInterceptor, ISBindInterceptor, ISServerInterceptor,ISClientInterceptor.
Il primo componente viene associato ad una
particolare proprietà dell’ORB, chiamata dynamicLibs che può essere settata
dalla linea di comando che attiva l’applicazione da monitorare oppure
attraverso un file testuale di proprietà dell’ORB .Il valore di questa
proprietà è rappresentato dal riferimento ad un oggetto che implementa
un’interfaccia ServiceLoader, il cui metodo init() viene chiamato quando
un’applicazione esegue il metodo omonimo
dell’ORB.
Il MonitorBinder viene creato in conseguenza della
chiamata a questo metodo. Essendo un oggetto CORBA la sua inizializzazione
consiste nella costruzione del POA (Portable Object Adapter ) e
dell’attivazione dell’oggetto servitore che implementa l’interfaccia IDL
corrispondente. Quest’operazione lo rende capace di accettare invocazioni
remote; il MonitorBinder viene registrato presso il POA e quindi presso il
Location Service con il nome dell’applicazione a cui è associato.
Il suo compito è di registrare e cancellare i
Listener presso gli Interceptor e di smistarne il riferimento al
InterceptorServiceLoader il quale a sua volta lo smista agli altri componenti
che hanno necessità di comunicare con il Monitor
Sempre in conseguenza dell’inizializzazione dell’ORB
il ServiceLoader crea i primi due
componenti d’intercettazione i quali costruiscono i seguenti secondo un
protocollo descritto in dettaglio nella sezione seguente.
Per rispettare il principio di
minima intrusione, oltre alla minimizzazione del numero di operazioni svolte
dall’Interceptor come causa della rilevazione di un evento, si sono
escluse dall’intercettazione tutte le
operazioni svolte dagli oggetti che fanno parte del sistema di monitoraggio
Creazione e funzionamento dei componenti
d’intercettazione.
Ogni operazione di Bind andata a buon fine, da luogo alla creazione di un ClientRequestInterceptor, il quale rileva le invocazioni ai metodi di oggetti remoti di cui il client ha ottenuto il riferimento.
Per il lato Server ogni aggiunta di un nuovo POA crea un nuovo ServerRequestInterceptor, che intercetta la ricezione da parte di un oggetto servitore di una richiesta.
In tal modo è l’Interceptor stesso a stabilire quale ruolo dell’applicazione monitorata in base all’attività che svolge.
La scelta di adottare due Interceptor diversi per l’attività Client e per quella Server nasce oltre che dall’esigenza di ottenere una maggior granularità nelle rilevazioni, anche per una questione di correttezza delle misure; se adottassi un solo tipo d’Interceptor il risultato del monitoraggio di un’invocazione sarebbe, l’identificazione dell’oggetto server interessato e il tempo che il cliente deve attendere per ottenere una risposta. Tale tempo potrebbe essere sommato sia ai tempi totali di occupazione del nodo client sia del nodo server col risultato che sul nodo server verrebbero conteggiati anche i tempi di trasmissione che non interessano le misure di questo nodo.
La Fig.2 amplia ciò che è stato illustrato nella Fig.1 e cioè come l’Interceptor si adatti all’applicazione che monitorizza, e come il normale flusso di richiesta da parte di un Client e risposta da parte di un Server generi un’attività supplementare da parte dell’ORB che invia segnali agli Interceptor in base agli eventi rilevati e come questi inviano i loro risultati al Monitor, che si suppone risiedere su un altro nodo.
Figura 2
I metodi degli Interceptor ottengono come parametri tutte le informazioni necessarie alla caratterizzazione dell’evento. Ad esempio l’invocazione di un metodo da parte di un Client viene notificata al ClientRequestInterceptor tramite tre metodi, chiamati in sequenza. Il primo viene chiamato prima del marshalling dei parametri, il secondo viene chiamato dopo tale operazione il terzo viene chiamato a risposta ottenuta o all’accertato fallimento della richiesta. Ognuno di questi metodi permette di ottenere l’identita dell’oggetto coinvolto il nome del metodo invocato, l’esito, il tempo di esecuzione, etc.
La sequenza delle invocazioni
rimane associata in modo univoco all’operazione grazie ad un identificatore.
Più chiamate contemporanee ad uno stesso metodo ottengono due diversi
identificatori e le relative sequenze d’invocazione rimangono ben distinte e al
sicuro da interferenze reciproche.
Monitor
Componenti principali.
Il Monitor è costituito da
un’interfaccia grafica (Figura 3) che permette all’utente un’interazione
semplice e intuitiva sia per la registrazione delle applicazioni monitorate sia
per la visualizzazione dei dati raccolti.
Figura 3
Un gestore delle connessioni agli
Interceptor chiamato InterceptorTreeManager, permette di connettersi e
disconnettersi dalle applicazioni disponibili. Il nome del componente deriva
dal fatto che l’insieme degli Interceptor viene presentato all’utente sotto
forma di albero. Le funzionalità permesse dall’organizzazione con cui si è
scelto di disporre gli Interceptor è discussa in una sezione successiva.
Altri componenti fondamentali
sono i DataManager che raccolgono e inviano all’interfaccia utente i dati
provenienti dai Listener. I DataManager sono di tre tipi:
InterceptorDataManager gestisce direttamente i dati di una specifica
applicazione monitorata; quindi ne
esiste uno per ogni applicazione. NodeDataManager gestisce i dati
corrispondenti a tutte le applicazioni di un certo nodo e ne esiste uno per
ogni nodo. RootDataManager raccoglie i dati di tutti i nodi su cui risiedono
applicazioni in via di monitoraggio.
La comunicazione con gli Interceptor
è gestita dall’InterceptorListener. E’ un’oggetto CORBA che una volta
registrato presso l’Interceptor raccoglie, tramite il passaggio di parametri ai
suoi metodi, i dati di ogni tipo di rilevazione eseguita nonché i messaggi da
presentare all’utente.
Registrazione
e cancellazione dagli Interceptor.
All’avvio dell’applicazione
Monitor viene eseguita un’indagine presso lo SmartAgent, che fornisce come
risultato una lista dei MonitorBinder attualmente in esecuzione. La presenza di
un MonitorBinder è sinonimo della presenza di un Interceptor e quindi di
un’applicazione monitorabile. Come accennato in precedenza, l’insieme viene
ordinato all’interno di un albero a tre livelli: un nodo radice da cui discende
un figlio per ogni nodo e per ognuno di questi tanti figli quante sono le
applicazioni monitorabili su quel nodo.
Questa rappresentazione ad albero
è presentata all’utente sull’interfaccia grafica.Tramite l’albero è possibile,
scegliere l’Interceptor presso cui registrarsi o cancellarsi, visualizzare
selettivamente i dati riguardanti un’applicazione oppure visualizzare le
statistiche relative all’intero nodo. Per ogni nodo dell’albero viene creata,
al momento della registrazione, una struttura contenente tutti gli oggetti
necessari alla raccolta e presentazione dei dati sull’interfaccia. Nel caso di
un nodo foglia la struttura conterrà
anche il riferimento all’Interceptor (in realtà al MonitorBinder
corrispondente).
La cancellazione dei Listener dagli Interceptor avviene automaticamente alla chiusura del Monitor, o per scelta dell’utente tramite un bottone presente sull’interfaccia grafica.
La terminazione di un’applicazione viene rilevata, dallo SmartAgent,
come conseguenza dell’ indisponibilità del
MonitorBinder associato. La verifica dello stato degli oggetti viene
fatta dall’agente ad intervalli regolari (ogni 2 minuti impostazione di
Default), perciò l’utente potrebbe non avere notizie immediate sullo stato di
un nodo o di un’applicazione, ma se si tentasse di registrasi o cancellarsi
presso l’Interceptor, corrispondente all’applicazione terminata o caduta, il
nodo dell’albero scelto, verrebbe cancellato e la conseguente notifica
dell’avvenuta terminazione sarebbe stampata nell’apposita TextArea
dell’interfaccia utente.
Dati intercettati.
Client Side
·
Identificazione del nodo
§
host name
§
host IP adress
Queste
informazioni le ottengo dallo SmartAgent.
·
Informazioni sul bind
§
object name
§
interface name
§
risultato dell’operazione
§
tempo di binding
§
corpo dell’eccezione eventualmente rilevata
Ottenuti
dalla combinazione dei metodi del BindInterceptor.
·
Richieste del cliente
§
object name
§
nome dell’operazione
§
tempo di esecuzione
§
risultato dell’operazione(successo o insuccesso)
§
corpo dell’eccezione eventualmente rilevata
Ottenuti
dal ClientRequestInterceptor.
Server Side
·
Identificazione del nodo
§
host name
§
host IP address
Queste informazioni le ottengo
dallo SmartAgent
·
Creazione di un nuovo Object Adapter.
Ottenuti dal
POALifeCycleInterceptor.
·
Richieste all’oggetto target
§
nome dell’oggetto
§
nome dell’operazione
§
tempo di esecuzione
§
risultato dell’operazione
§
corpo dell’eccezione eventualmente rilevata.
Ottenuti dal
ServerRequestInterceptor.
System performance information
Informazioni generali sul sistema
ottenuti dal rapporto tra i dati ottenuti dai singoli Interceptor su un determinato nodo e i dati riguardanti
l’insieme delle applicazioni monitorate sull’intero sistema.
·
Client Request
Concentration Rate
Si calcola come il rapporto tra la somma del numero di chiamate su un nodo e la somma del numero di chiamate su tutti i nodi. Viene presentata all’utente in percentuale.
·
Client Average Request WaitingTime Rate
Rapporto tra la somma dei tempi di attesa di una risposta in seguito ad una invocazione sul nodo e la somma dei tempi di attesa su tutti i nodi, in percentuale.
Le stesse misure vengono applicate al lato
server(Server Reply Concentration Rate, Server Processing Concentration Rate),
con la differenza che i tempi sono riferiti all’elaborazione della richiesta e
alla produzione del relativo risultato.
Testing
I test sono stati svolti sulle macchine Windows NT del LAB2, monitorando un’applicazione campione che invoca metodi su oggetti CORBA remoti. I metodi invocati non fanno altro che introdurre un certo ritardo che simuli una qualche elaborazione e forniscono un risultato sull’interfaccia grafica Client.
La sensibilità delle misure temporali effettuate dal Monitor è dell’ordine del millesimo di secondo, per cui tutte le operazioni di durata inferiore non vengono rilevate e non vanno a sommarsi ai tempi totali di elaborazione del nodo.
Le misure effettuate dal Monitor mostrano errori per difetto inferiori al 5%. Di seguito vengono mostrati i dati rilevati che ci hanno permesso di trarre queste conclusioni (Tabelle 2,3). Sono stati simulati due diversi tempi d’elaborazione, e per ognuno di essi tre sequenze di chiamate ottenute da loop di lunghezza crescente. I tempi riportati sono espressi in millisecondi.
Ritardo = 1 sec. |
||
N° invocazioni |
Client |
Server |
1 |
997 |
967 |
10 |
9894 |
9640 |
100 |
99145 |
97506 |
Tabella 1
Ritardo = 3 sec. |
||
N° invocazioni |
Client |
Server |
1 |
2981 |
2941 |
10 |
29868 |
29514 |
100 |
299089 |
295758 |
Tabella 2
Le stesse prove sono state effettuate per testare l’efficienza dell’ISServerInterceptor, in caso di concorrenza nelle invocazioni ai metodi di uno stesso oggetto servitore. Come nel caso precedente sono state eseguite sequenze di invocazioni, prima da parte di due client poi da parte di 5. Le sequenze sono state eseguite in modo che l’inizio dell’ultima fosse antecedente alla fine della prima.
Le tabelle riportate di seguito mostrano un peggioramento della precisione all’aumentare delle applicazioni concorrenti fino a superare il 10%, con 5 applicazioni client concorrenti.
Ritardo = 1 sec. |
|||
N° invocazioni |
Client1 |
Client2 |
Server |
10 |
9610 |
9705 |
18995 |
Tabella 3
Ritardo =1 sec. |
||||||
N°invocazioni |
Client1 |
Client2 |
Client3 |
Client4 |
Client5 |
Server |
10 |
9094 |
9065 |
9098 |
8958 |
9072 |
44240 |
Tabella 4
.
Un altro test necessario alla prova di applicazioni di monitoraggio e di gestione più in generale, è il calcolo dell’overhead introdotto dalle operazioni svolte per ottenere il servizio. Questo test è stato svolto misurando i tempi che il cliente deve attendere per l’ottenimento del risultato di una semplice operazione aritmetica svolta da un oggetto remoto, prima in assenza di Monitor, poi con Monitor attivo. La Tabella 3 riporta i risultati di una serie d’invocazioni consecutive, ottenute da un loop di invocazioni; i tempi sono sempre espressi in millisecondi
Invocazioni |
Monitor
disattivo |
Monitor attivo |
1° |
2 |
23 |
2° |
1 |
34 |
3° |
2 |
22 |
4° |
1 |
21 |
5° |
1 |
23 |
6° |
1 |
24 |
7° |
2 |
11 |
8° |
0 |
28 |
9° |
3 |
23 |
Medie |
1,4 |
23 |
Tabella 5
Il risultato mostra un overhead medio di 21,6 msec. questo tempo è indipendente dalla durata dell’elaborazione e quindi la sua rilevanza diminuisce al crescere dei tempi di questa.
Conclusioni
Lo scopo che mi sono prefissato non è tanto quello della realizzazione di uno strumento di misura preciso e completo, ma quanto di sviluppare un esempio non banale del funzionamento dell’architettura CORBA, della comunicazione tra i suoi oggetti, di alcuni degli strumenti messi a disposizione dal VisiBroker, nonché delle facilities che JBuilder4 fornisce nella costruzione di applicazioni.
I maggiori vantaggi offerti dall’uso di JBuilder sono sicuramente quelli dedicati alla costruzione dell’interfaccia grafica e non tanto nell’impostazione dei componenti necessari all’uso degli oggetti CORBA. Il codice scritto automaticamente da JBuilder4 per l’implementazione d’interfacce agli oggetti remoti sia sul lato client sia sul lato server sono volti allo sviluppo di applicazioni standard, cioè di applicazioni in cui i ruoli di cliente e servitore sono ben definite e in cui sul lato client l’interfaccia utente racchiude tutto il codice d’inizializzazione e utilizzo degli oggetti remoti, per cui di questo codice ad applicazione ultimata ne è rimasto ben poco.
Una lacuna riscontrata nell’uso del Location Service di VisiBroker, per le esigenze di quest’applicazione è il ritardo con cui viene notificata l’indisponibilità di un oggetto, per cui alcune funzionalità che inizialmente avevo pensato di affidare interamente al servizio e al suo sistema di Trigger sono state coadiuvate con codice specifico di gestione di alcune eccezioni sollevate dal sistema, appunto a causa della lentezza con cui viene notificata l’indisponibilità degli oggetti.
Bibliografia
Per il linguaggio Java:
- “Java2 i fondamenti”/C.S.Horstmann, G.Cornell
- “Java2 Tecniche avanzate”/ C.S.Horstmann, G.Cornell
Per il pacchetto VisiBroker:
- Manuale in linea VisiBroker4.1
(http://www.inprise.com/techpubs/books/vbj/vbj41/framesetindex.html)
-
“The Official VisiBroker for Java Handbook”/M.McCaffrey, B.Scott
Per
la scelta delle grandezze da rilevare:
- Proceedings
1998 Asia Pacific Software Engineering Conference .IEEE Comput. Soc, Los Alamitos, CA, USA; 1998; pp.338-45.