Fai spazio a JavaSpaces, parte 1

Questo articolo inizia un secondo thread della serie Jiniology . A giugno, Bill Venners ha lanciato Jiniology con una panoramica della tecnologia Jini, una nuova e potente infrastruttura per la creazione e la distribuzione di sistemi distribuiti organizzati come federazioni di servizi. Questo thread, che verrà presentato ogni due mesi in questa colonna, si concentra su JavaSpaces,un servizio Jini di base di Sun Microsystems che fornisce un mezzo di alto livello per creare applicazioni collaborative e distribuite. Se stai creando applicazioni con Jini, ti consigliamo di sapere come utilizzare JavaSpaces per coordinare i partecipanti in una federazione Jini. Ma è anche importante ricordare che puoi utilizzare JavaSpaces separatamente da Jini, come strumento per la creazione di sistemi distribuiti generali in Java. In entrambi i casi, vale la pena dare un'occhiata a JavaSpaces, perché può facilitare notevolmente la progettazione e la codifica delle applicazioni distribuite.

Fai spazio a JavaSpaces: leggi l'intera serie!

  • Parte 1. Semplifica lo sviluppo di app distribuite con JavaSpaces
  • Parte 2. Costruisci un server di calcolo con JavaSpaces
  • Parte 3. Coordina le tue app Jini con JavaSpaces
  • Parte 4. Esplora le transazioni Jini con JavaSpaces
  • Parte 5. Rendi il tuo server di elaborazione robusto e scalabile

In questa serie, inizieremo presentandovi l'esclusivo modello di programmazione JavaSpaces, che è abbastanza diverso da altri strumenti distribuiti e di rete con cui potreste avere familiarità. Negli articoli successivi, tratteremo i dettagli dell'API JavaSpaces e come utilizzarla per incollare i processi insieme in un'applicazione distribuita e descriveremo come JavaSpaces interagisce con altri componenti di Jini. In tutta la serie, vedrai che JavaSpaces è semplice (l'API consiste solo di una manciata di operazioni), espressiva (un gran numero di problemi può essere risolto utilizzando JavaSpaces) e potente (puoi costruire sofisticati sistemi distribuiti con piccole quantità del codice JavaSpaces).

Iniziamo.

Un nuovo modello di calcolo distribuito

La creazione di applicazioni distribuite con strumenti di rete convenzionali di solito comporta il passaggio di messaggi tra processi o il richiamo di metodi su oggetti remoti. Nelle applicazioni JavaSpaces, al contrario, i processi non comunicano direttamente, ma coordinano invece le loro attività scambiando oggetti attraverso uno spazio o memoria condivisa. Un processo può inserire writenuovi oggetti in uno spazio, takeoggetti da uno spazio oread(fare una copia di) oggetti in uno spazio; La figura 1 mostra diversi processi (rappresentati da Dukes) che interagiscono con gli spazi utilizzando queste operazioni. Quando si prendono o si leggono oggetti, i processi utilizzano una semplice corrispondenza, basata sui valori dei campi, per trovare gli oggetti che contano per loro. Se un oggetto corrispondente non viene trovato immediatamente, un processo può attendere fino all'arrivo di uno. In JavaSpaces, a differenza degli object store convenzionali, i processi non modificano gli oggetti nello spazio né invocano direttamente i loro metodi, mentre lì gli oggetti sono solo dati passivi. Per modificare un oggetto, un processo deve rimuoverlo esplicitamente, aggiornarlo e reinserirlo nello spazio.

Gli spazi sono archivi di oggetti con diverse proprietà importanti che contribuiscono a rendere JavaSpaces uno strumento potente ed espressivo. Diamo uno sguardo più da vicino:

  • Gli spazi sono condivisi: molti processi remoti possono interagire con uno spazio contemporaneamente: lo spazio stesso gestisce i dettagli dell'accesso simultaneo, lasciandoti concentrare sulla progettazione dei protocolli di alto livello tra i tuoi processi.

  • Gli spazi sono persistenti: gli spazi forniscono un'archiviazione affidabile per gli oggetti. Quando memorizzi un oggetto in uno spazio, rimarrà lì a tempo indeterminato fino a quando non verrà rimosso. È inoltre possibile richiedere un periodo di leasing durante il quale un oggetto deve essere archiviato. Una volta immagazzinato nello spazio, un oggetto rimarrà lì fino al termine del suo periodo di locazione (che può essere rinnovato) o fino a quando un processo non lo rimuove esplicitamente. Discuteremo i contratti di locazione in modo più approfondito più avanti in questa serie.

  • Gli spazi sono associativi: gli oggetti in uno spazio vengono individuati tramite la ricerca associativa, non per posizione di memoria o identificatore. La ricerca associativa fornisce un mezzo semplice per trovare gli oggetti a cui sei interessato in base al loro contenuto, senza dover sapere come viene chiamato l'oggetto, chi lo ha creato o dove è memorizzato. Per cercare un oggetto, crei un modello (un oggetto con alcuni o tutti i campi impostati su valori specifici e gli altri lasciati in modo nullda agire come caratteri jolly). Un oggetto nello spazio corrisponde a un modello se corrisponde esattamente ai campi specificati del modello. Vedrai che, con la ricerca associativa, puoi facilmente esprimere query per oggetti come "Ci sono attività da calcolare?" o "Ci sono risposte al fattore primo che ho chiesto? "

  • Gli spazi sono protetti dalle transazioni: JavaSpaces utilizza il servizio di transazione di Jini per garantire che un'operazione su uno spazio sia atomica (o l'operazione viene applicata o non lo è). Le transazioni sono supportate per singole operazioni su un singolo spazio, nonché per più operazioni su uno o più spazi (vengono applicate tutte le operazioni o nessuna). Come vedrai più avanti nella serie, le transazioni sono un modo importante per affrontare un fallimento parziale.

  • Gli spazi ti consentono di scambiare contenuto eseguibile: mentre in uno spazio, gli oggetti sono solo dati passivi: non puoi modificarli o richiamare i loro metodi. Tuttavia, quando leggi o prendi un oggetto da uno spazio, viene creata una copia locale dell'oggetto. Come con qualsiasi altro oggetto locale, puoi modificare i suoi campi pubblici e invocare i suoi metodi, anche se non hai mai visto un oggetto simile prima. Questa capacità offre un potente meccanismo per estendere il comportamento delle tue applicazioni attraverso uno spazio.

Con il progredire di questa serie, ti mostreremo come queste proprietà giocano un ruolo chiave nel consentirti di creare applicazioni distribuite che funzionano bene nell'ambiente Jini, dove il networking è spesso spontaneo ei processi si uniscono e lasciano il calcolo in modo dinamico, a volte a causa del dispositivo o errore di rete.

Origini di JavaSpaces

Abbiamo descritto JavaSpaces come un nuovo modello di calcolo distribuito, ma le sue origini possono essere fatte risalire alla Yale University nei primi anni '80. Lì, il Dr. David Gelernter ha sviluppato uno strumento chiamato Linda per la creazione di applicazioni distribuite. Linda consiste in un piccolo numero di operazioni combinate con un archivio persistente chiamato spazio tupla. Queste operazioni sono ortogonali a qualsiasi particolare linguaggio di programmazione; fanno parte di un linguaggio di coordinamento che può essere aggiunto a qualsiasi altro linguaggio di calcolo.Il risultato della ricerca Linda è stato sorprendente: utilizzando un archivio di oggetti insieme a un numero limitato di operazioni semplici, è possibile implementare facilmente una vasta classe di problemi paralleli e distribuiti utilizzando tecniche che alleviano molte delle insidie ​​della costruzione di sistemi in rete. In altre parole, i sistemi spaziali non sono solo semplici (richiedono solo poche operazioni), ma anche espressivi (si prestano bene a risolvere molti problemi distribuiti).

Il lavoro del Dr. Gelernter ha ispirato il servizio JavaSpaces di Sun e ha anche influenzato la progettazione dei componenti di ricerca e rilevamento della tecnologia Jini di base (che vedrai man mano che la serie Jiniology avanza). Mentre JavaSpaces ha ereditato il modello spaziale da Linda, i progettisti di JavaSpaces hanno aggiornato il modello in modi significativi, sfruttando la potenza degli oggetti Java, Jini, RMI e la serializzazione degli oggetti.

JavaSpaces nel contesto

La nostra descrizione fino ad ora è stata un po 'astratta, quindi consideriamo alcuni esempi di applicazioni distribuite reali che puoi modellare come processi che scambiano oggetti attraverso gli spazi.

Sistemi di chat

Si consideri un semplice sistema di chat multiutente, in cui uno spazio funge da area chat che contiene tutti i messaggi che compongono una discussione. Per parlare, un partecipante deposita gli oggetti messaggio nello spazio. Tutti i membri della chat attendono la visualizzazione di nuovi oggetti messaggio, li leggono e ne visualizzano il contenuto. I ritardatari possono esaminare gli oggetti messaggio esistenti nello spazio per rivedere la discussione precedente. Infatti, poiché lo spazio è persistente, un nuovo partecipante può visualizzare la discussione molto tempo dopo che tutti gli altri se ne sono andati e i partecipanti possono persino tornare molto più tardi per riprendere la conversazione da dove si erano interrotti. L'elenco dei partecipanti alla chat può anche essere conservato nello spazio e aggiornato ogni volta che qualcuno si unisce o abbandona la conversazione.

Server di calcolo

Ora considera l'analisi dei dati del radiotelescopio in tempo reale per i segni di vita extraterrestre (proprio come fa il progetto SETI @ home). Tali dati sono voluminosi e analizzarli è un lavoro ad alta intensità di calcolo che ben si adatta al calcolo parallelo da parte di una rete di computer, in altre parole, un "server di calcolo". Utilizzando la tecnologia JavaSpaces, una serie di attività - ad esempio, un'attività per blocco di dati che deve essere analizzato - viene scritta nello spazio. Ogni computer partecipante cerca nello spazio un'attività, la rimuove, completa il lavoro di calcolo necessario, rilascia il risultato nello spazio e quindi continua a cercare altre attività. Questo approccio è scalabile in modo naturale: funziona allo stesso modo se sono disponibili 10 computer o 1.000. L'approccio fornisce anche un bilanciamento del carico naturale , poiché ogni lavoratore prende esattamente tutto il lavoro che può gestire in un dato periodo di tempo, con computer lenti che fanno meno lavoro e computer veloci che fanno di più.

Sistemi di brokeraggio

Come terzo esempio, si consideri un sistema di aste online che riunisce acquirenti e venditori di beni e servizi. Supponiamo che tu, in quanto potenziale acquirente, descriva l'articolo (come un'auto) che desideri acquistare e il prezzo che sei disposto a pagare, racchiudi le informazioni in una voce e scrivi la risultante voce di richiesta di acquisto in uno spazio. Allo stesso tempo, i potenziali venditori monitorano continuamente lo spazio per l'arrivo di voci di acquisto che corrispondono agli articoli nel loro inventario. Ad esempio, i concessionari Mazda monitorano lo spazio per le voci che descrivono Mazda, mentre i concessionari di auto usate monitorano lo spazio per tutte le richieste di auto usate. Quando una richiesta di corrispondenza viene trovata e letta, un potenziale venditore scrive una voce di offerta nello spazio, indicando un prezzo di offerta. In qualità di potenziale acquirente, monitori continuamente lo spazio per le offerte sulle richieste in sospeso e,quando ne trovi una accettabile, rimuovi le offerte e contatta il venditore (possibilmente attraverso lo spazio tramite un'altra voce).

Una breve panoramica dell'API

Ora è il momento di introdurre l'API JavaSpaces. Come abbiamo già detto, è semplice; infatti, nel resto di questo articolo tratteremo tutto ciò che è necessario sapere (salvo alcuni dettagli minori) al riguardo. Tuttavia, prima di descrivere l' JavaSpaceinterfaccia ei suoi metodi, dobbiamo prima parlare delle voci.

Inserimenti

Un oggetto memorizzato in uno spazio è chiamato

iscrizione.

Per essere una voce, un oggetto deve solo implementare il

Entry

interfaccia. Ad esempio, definiamo una voce di messaggio che puoi scrivere in uno spazio:

import net.jini.core.entry.Entry;

public class Message implementa Entry {public String content;

// un costruttore senza argomenti public Message () {}}

Qui abbiamo definito una Messageclasse con un campo stringa che conterrà il contenuto del messaggio. Poiché vogliamo usare questa classe con spazi, dobbiamo implementare l'interfaccia net.jini.core.entry.Entry, che si trova nel pacchetto net.jini.core.entry. È importante sottolineare che Entryè un'interfaccia marker; in altre parole, l'interfaccia non contiene costanti o metodi e quindi non richiede alcun lavoro speciale per l'implementazione, a parte l'aggiunta implements Entryalla definizione della classe.

Oltre a implementare l' Entryinterfaccia, ci sono alcune altre convenzioni che le nostre voci devono seguire. Avremo altro da dire sulle ragioni negli articoli successivi, ma per ora guarderemo solo a grandi linee. Una voce deve avere un costruttore pubblico che non ha argomenti (un cosiddetto no-arg costruttore); questo requisito deriva dalla serializzazione sottostante che si verifica quando le voci vengono trasferite dentro e fuori gli spazi. Nota che la nostra definizione di Messagecontiene un costruttore senza argomenti. Un'altra convenzione è che i campi di una voce dovrebbero essere dichiaratipublic; ciò consente ad altri processi di trovare le voci negli spazi tramite ricerca associativa, in base ai valori di quei campi. Una terza convenzione è che i campi di una voce devono contenere riferimenti a oggetti, piuttosto che a tipi primitivi (ovvero, se è necessario definire un campo di tipo primitivo come int, è necessario utilizzare Integerinvece la classe wrapper corrispondente ). Per assicurarti di coprire tutte le tue basi nella definizione delle voci, ti consigliamo di fare riferimento a JavaSpaces Principles, Patterns, and Practice o alla Sun Microsystems JavaSpaces Specification per i dettagli. Come accennato, toccheremo anche alcuni dei punti più fini negli articoli successivi.

Oltre a questi requisiti, una voce è come qualsiasi altra classe Java; puoi istanziarlo, invocarne i metodi e assegnare valori ai suoi campi pubblici. Ora che abbiamo definito una Messageclasse di ingresso, vediamo quali operazioni sono disponibili per interagire con le voci negli spazi.

L'interfaccia JavaSpace

Per interagire con uno spazio, è necessario ottenere l'accesso a un oggetto che implementa l' JavaSpaceinterfaccia. Esistono molti modi per ottenere l'accesso a un tale oggetto (è possibile, ad esempio, utilizzare la ricerca Jini o il registro RMI) e tratteremo i dettagli di questa operazione nel prossimo articolo. Per ora ci concentreremo JavaSpacesull'interfaccia stessa.