2009-10-14 5 views
58

Esistono modelli o procedure ottimali che possono essere utilizzati per semplificare la modifica dei profili di configurazione per le applicazioni Web Java in più ambienti. per esempio. URL JDBC, end-point SOAP, ecc.Modelli di configurazione di applicazioni Web Java

Come sfondo per aiutare a chiarire la mia domanda, lavoro con diverse grandi applicazioni web java che durante un determinato ciclo di rilascio si spostano attraverso 6 diversi ambienti; sviluppo, integrazione, controllo qualità, prestazioni e infine distribuzione su più server di produzione. In ogni ambiente, la configurazione deve cambiare. Al momento, la maggior parte delle modifiche alla configurazione per ogni distribuzione viene eseguita manualmente, il che richiede sia tempo che essere aperto agli errori.
Esiste un modo per rimuovere l'intervento manuale da questo processo?

+0

Risposte correlate: http://stackoverflow.com/questions/1634458/can-i-use-a-single-war-file-in-multiple-environments-should-i – McDowell

+1

JNDI (java.sun.com/ products/jndi) è stato creato appositamente per risolvere questo problema, ed è quello che uso di solito per i sistemi di produzione, dal momento che si adatta bene (funziona se ho 1 ambiente o 6). Separa chiaramente anche le responsabilità degli sviluppatori e degli amministratori di sistema. Detto questo, se sai che avrai solo 6 ambienti, e che il numero non cambierà praticamente mai, la soluzione di Jeremy dovrebbe funzionare, e credo che sia la convenzione più recente rispetto ai framework di configurazione (ad es. Grails). –

+0

Per inciso, l'installazione di JNDI richiede la configurazione manuale, ma lo si fa solo una volta per ambiente (una specie di installazione del server dell'app o del sistema operativo dell'ambiente). –

risposta

14

Tendo a lavorare di più con .NET ultimamente, quindi il mio Java è abbastanza arrugginito. Sono abbastanza sicuro che ciò funzionerebbe in qualsiasi lingua con un piccolo ritocco.

Utilizziamo un'estensione del sistema di configurazione .NET che ci consente di utilizzare l'ambiente e/o le impostazioni specifiche dell'applicazione in combinazione con una configurazione più globale. Il sistema di configurazione utilizza un'impostazione globale per ogni macchina identifica come dev, beta o produzione (impostazione predefinita). Un set di file caricati in ordine e l'impostazione dell'ultimo file sostituisce qualsiasi impostazione definita in un file precedentemente caricato. I file vengono caricati nel seguente ordine:

  1. impostazioni globali
  2. impostazioni specifiche delle applicazioni
  3. ambiente specifico di applicazione sovrascrive

Tutti i file sono in controllo del codice sorgente, e dal momento che l'ambiente è definito su la macchina su cui è in esecuzione l'applicazione; poiché non accederà alla configurazione "beta" a meno che la configurazione della macchina non lo identifichi come "beta", possiamo promuovere tutti i file di configurazione senza il timore di indirizzare inavvertitamente la nostra applicazione di produzione su un database di sviluppo.

+0

Penso che questa sia la migliore risposta alla domanda di rilevamento automatico e caricamento della configurazione basata sull'ambiente corrente senza alcun lavoro manuale durante l'implementazione dell'applicazione . Permette anche il caso in cui la configurazione può differire tra i server nello stesso ambiente. L'utilizzo di questo e l'uso di Commons Configuration per l'override come suggerito da John Munsch andrebbe a risolvere il problema. –

6

Ciò dipende in gran parte dalle opzioni fornite dai server di applicazioni Web. Disponiamo di più ambienti per JBoss con diversi URL JDBC, il nome JNDI rimane lo stesso su tutti i server, solo la configurazione dell'istanza locale cambia, quindi non c'è nulla di sbagliato da costruire a costruire.

Suppongo che la risposta breve sia che la pratica migliore è esternalizzare le configurazioni e mantenere un buon file sul posto con le impostazioni corrette per ciascun server e fare in modo che l'app Web legga tale configurazione. La natura esatta dell'esternalizzazione e della lettura dipenderà dalla configurazione specifica e dal server delle applicazioni.

MODIFICA: Queste configurazioni non esistono come parte della guerra (orecchio nel nostro caso) in questo modo non vengono sovrascritte.

+0

Grazie per la risposta. Noi esternalizziamo la configurazione e la posizione di questi file è la stessa su tutti i server (WEB-INF/config). Tuttavia, i file di configurazione devono essere collocati in quella posizione dopo ogni distribuzione. I file si trovano al di fuori della guerra estesa o come mai non sono sovrascritti o devono essere rimessi in posizione dopo una nuova installazione? –

+2

@Donal Boyle, mettere la tua configurazione in WEB-INF/config non lo sta davvero esternalizzando, dato che fa ancora parte della tua webapp. –

2

Innanzitutto disporre di tutte le impostazioni di configurazione che cambiano di frequente in un unico punto. È davvero difficile, se è necessario configurare JNDI, modificare i valori del database e modificare i file di proprietà, tutti allo stesso tempo, al fine di completare la configurazione. Preferisci il mezzo che è più facile da modificare e anche più semplice verificare che tutto sia impostato correttamente. Direi che i file di proprietà sono la soluzione migliore. Puoi facilmente modificarli e ti servirà solo una rapida occhiata per vedere che tutto va bene. Se si opta per i file di proprietà, selezionare attentamente una posizione standard per loro e assegnare una variabile ambientale per il percorso.

Aiuta anche se si dispone di un semplice test che verifica che tutto sia impostato correttamente. Ad esempio è possibile avere una pagina di test che visualizza i parametri di configurazione ed esegue alcuni test di base, come provare a connettersi al database o ai server remoti.

+0

Mi piace l'idea della pagina di prova. Qualcosa del genere renderebbe molto più semplice confermare/negare la configurazione errata. –

+0

questa non è una buona pratica e non porta il lavoro manuale fuori dal processo come l'OP ha chiesto – anton1980

11

Ecco alcune pratiche possibili che ho utilizzato o incontrato. La combinazione di questi è solitamente necessaria nella pratica.

Sostituendo i valori delle variabili in conffiles quando si costruisce

Ecco un esempio di come questo può essere fatto con Apache Ant. proprietà Ant (${var.name}) possono essere controllati con i file di configurazione di generazione:

<filterset id="variables.to.replace"> 
    <filter token="APPNAME" value="${app.name}"/> 
    <filter token="WEBAPP-PATH" value="${webapp.path}"/> 
    <filter token="ENCRYPT-ALGORITHM" value="${encrypt.algorithm}"/> 
    <filter token="ERROR-MAILTO" value="${error.mailTo}"/> 
    <!--...--> 
</filterset> 

<!-- Then, when building & copying the conf, replace the variables: --> 
<copy todir="${properties.target.dir}"> 
    <!-- env specific conf files --> 
    <fileset dir="${basedir}/env/${run.env}/webapp/WEB-INF/classes" /> 
    <filterset refid="variables.to.replace"/> 
</copy> 

La cosa buona è che si ottiene un buon controllo sulle diverse configurazioni in fase di compilazione. Ciò che è negativo è che il sistema tende a diventare molto complesso e difficile da mantenere se si utilizza questo metodo in modo estensivo per un gran numero di diverse configurazioni. Inoltre, dover costruire i conffiles significa anche rallentare i cicli di sviluppo.

Sostituendo le variabili da conf all'interno guerra al webapp all'avvio

Questo è quello che faccio di solito quando si utilizza Spring Framework, anche se v'è solo una configurazione possble, ottenere i benefici della separazione degli interessi. Con Spring, è possibile sostituire i valori di conf con PlaceholderPropertyConfigurer all'interno del contesto Spring all'avvio di webapp. In questo caso, devi comunque scegliere la configurazione corretta, che può essere configurata per esempio in fase di costruzione.

Rispetto al tempo di costruzione in sostituzione, è più semplice manipolare temporaneamente i valori in una webapp non compressa, se necessario. Ovviamente, è necessario riavviare la webapp se si modifica qualcosa e le modifiche manuali non verranno mantenute tra le ridistribuzioni di webapp. Anche Spring è limitato al contesto Spring, quindi this doesnt' work e.g. in web.xml (ma probabilmente le variabili in web.xml dovrebbero essere comunque evitate a causa dei suoi limiti).

Leggendo il conf locale da un file predefinito

Questo approccio è probabilmente il più facile da configurare: basta inventare un percorso del file di configurazione, ad esempio, $HOME/mywebapp/conf.properties e rendi la tua webapp in qualche modo leggibile all'avvio.

La cosa buona è che non ci si deve preoccupare della conf quando si costruisce/distribuisce la webapp. Ad ogni modo, dovresti avere alcuni preregolati conf, che possono essere sovrascritti dal locale conf.

Avere la conf in un database

Questa è la soluzione più flessibile per superiori parametri conf, ma può anche complicarsi in alcuni casi. Avere il conf in una tabella con name e value colonne dovrebbe funzionare per la maggior parte dei casi.

Ovviamente, non è possibile configurare gli URL di connessione JDBC in una tabella di database, ma questa è una buona soluzione per un semplice conf di testo/numerico che influisce sull'operazione webapp dopo che è stata impostata la connessione db. Per evitare una penalizzazione delle prestazioni, assicurati di aver memorizzato nella cache in qualche modo il conf se verrà acceduto frequentemente.

pratiche extra

Come sottolineato da kgiannakakis, ma aiuta anche a impostare una pagina di diagnostica di configurazione di qualche tipo per la vostra applicazione.

0

ci sono alcuni modi possibili per avvicinarsi a questo:

  • file di proprietà uso come si fa, ma aggiunge un file "meta-proprietà" che viene utilizzato per selezionare il file proprietà utilizzata mediante la definizione di una mappa tra un valore di ambiente (ad esempio localhost hostname) sul nome file della proprietà da caricare.

  • inserire le proprietà in un database e definire la connessione del database alle tabelle delle proprietà nel server applicazioni come risorsa prelevata dall'app Web.

  • non inserire i file di proprietà nel file .war o .ear, ma creare un archivio properties-deployhost.jar contenente i file di proprietà per host di destinazione. legare l'appropriato.file jar al web-app schierato aggiungendolo al percorso di classe (per esempio tramite librerie condivise nella configurazione del server applicazioni per web-app.)

Solo il primo di questi non ha bisogno di passaggi manuali aggiuntivi quando si esegue la distribuzione a spese di dover aggiornare la fonte di configurazione e creare nuovi file di distribuzione quando i sistemi di destinazione vengono rinominati.

Sono sicuro che molte varianti su questi e sul vostro approccio sono possibili, qual è la scelta migliore dipende dalla vostra situazione.

0

Quello che facciamo funziona piuttosto bene.

All'avvio, i nostri programmi leggono un file di configurazione in un percorso hardcoded. Diciamo che è:

/config/fun_prog/config.xml 

Ogni programma ha un percorso hard coded diversa (FunProgram è in fun_prog, Super server è in sup_serv, qualunque cosa), quindi non c'è bisogno di preoccuparsi di loro camminando gli uni sugli altri.

I file XML vengono letti da una piccola libreria di configurazione che abbiamo creato. Il file XML contiene le informazioni di connessione DB, in genere i dati di configurazione del server di posta, gli indirizzi email per inviare notifiche, se deve funzionare in modalità test, URL di servizi esterni, ecc.

Quindi, quando è necessario apportare modifiche, copia il file di configurazione, modifica quello che vogliamo e riavvia il programma. Dato che abbiamo una configurazione standard del server, qualsiasi programma può essere distribuito su qualsiasi server semplicemente copiando questi file (e il necessario httpd.conf armeggiare).

Non è lussuoso, ma funziona molto bene. È estremamente semplice da comprendere, aggiungere nuove opzioni di configurazione, backup e modifica. Funziona su tutte le piattaforme (unix è ovvio, Windows traduce i percorsi che iniziano con/in c: \ quindi funziona anche senza modifiche).

Le nostre workstation eseguono fondamentalmente lo stesso software del server, solo con alcune modifiche in tale file di configurazione.

1

Il buon esempio di ciò che si desidera viene utilizzato in Seam o Grails (preso in prestito da Rails).Ci sono profili, di default tre: prod, dev, test, ma puoi definirne di più se vuoi.

Nel progetto Seam la compilazione viene eseguita dai file Ant. Ogni file che il contenuto può variare è definito per ogni profilo, ad es. origine dati, script SQL o file di proprietà.

import-dev.sql
import-prod.sql
import-test.sql

Quando il file formica viene eseguito con il profilo scelto, file appropriato viene preso e il nome del profilo viene troncato da quel nome di file.

Di seguito è frammento di codice che è possibile inserire nei vostri obiettivi

<copy tofile="${war.dir}/WEB-INF/classes/import.sql" 
     file="${basedir}/resources/import-${profile}.sql"/> 

JDBC URL, nomi dei driver può essere esternalizzata a file di proprietà (ovviamente con i nomi profilo come suffissi)

<filterset id="persistence"> 
    <filter token="transactionManagerLookupClass" value="${transactionManagerLookupClass}"/> 

<copy tofile="${war.dir}/WEB-INF/classes/META-INF/persistence.xml" 
    file="${basedir}/resources/META-INF/persistence-${profile}.xml"> 
    <filterset refid="persistence"/> 
</copy> 

o i valori delle proprietà che puoi passare alla chiamata di form di form da riga di comando. Questo è un breve esempio di ciò che è stato fatto in Seam.

Un'altra opzione è quella utilizzata Maven. In modo del tutto fatto da proprietà e da profiles, ma è possibile utilizzare anche moduli separati per dividere la configurazione e creare altri moduli con funzionalità principali. Esempi tipici di casi di utilizzo di proprietà e profili di Maven sono la configurazione di esecuzione per più database, server di distribuzione ecc. È ancora più difficile quando si desidera creare la configurazione per diversi fornitori, ma per Maven questo non è un problema :)

Grande esempio di utilizzare i profili Maven è questo modulo postale Carlos Sanchez blog.

Per riassumere, raccomando caldamente di cercare Ant/Seam una parametrizzazione Maven (profili). Queste soluzioni hanno un altro vantaggio: script ant o maven possono essere eseguiti nel server CI (come Hudson) e consentono di eseguire/test simultaneamente tutti i profili.

31

Sono sorpreso che nessuno abbia citato l'API Jakarta Commons Configuration (http://commons.apache.org/configuration/) per rispondere a questa domanda. Ti consente di avere una gerarchia di file (o altre fonti di configurazione come XML, JNDI, JDBC, ecc.). Questo è ciò di cui parlava Jeremy Seghi e ti dà un buon modo per avere sia i valori predefiniti che gli override locali.

La parte migliore è che si tratta di una soluzione di lavoro testata in modo da non dover fare qualcosa da soli.

+0

+1 per questa raccomandazione. Sono stato messo al corrente di questa libreria solo dopo aver postato questa domanda. Dovrebbe essere molto utile anche se finora non vedo un modo integrato per caricare automaticamente diversi file di configurazione in base all'ambiente corrente. –

0

prega di dare un'occhiata al seguente URL: http://issues.apache.org/jira/browse/CONFIGURATION-394

Il quadro di configurazione che stiamo cercando è qualcosa in cima alla configurazione Commons Apache e deve supportare Concurrency Problemi, problemi di JMX e la maggior parte dei negozi (ad es. file di proprietà, file .xml o PreferencesAPI).

Ciò che il team weblogic fornisce su "Console di amministrazione" è intersettoriale che attraverso di esso è possibile avere aggiornamenti transazionali (atomici) sulle configurazioni in modo che gli ascoltatori registrati vengano avvisati.

I ragazzi di Apache insistono sul fatto che questo progetto non rientra negli ambiti della configurazione di Commons, forse!

Ho allegato un semplice framework di configurazione, guarda per favore.

+1

Sembra simile a quello che il mio amico intende fare con tools4j-conifg - http://stoffe.deephacks.org/2012/02/01/tools4j-config/ – Kristian

1

È possibile utilizzare il modello di configurazione dei componenti nella lingua di propria scelta

E 'descritto nei libri POSA (credo che nel 4 ° volume)

(in Java è possibile utilizzare il componente commons-configuration) .