2011-11-17 10 views
14

Costruiamo soluzioni aziendali a 3 livelli che in genere sono costituite da diversi moduli webapp e ejbjar che parlano tutti di un db e hanno diversi punti di integrazione esterni.Migliori pratiche di configurazione delle soluzioni JavaEE

Ogni modulo in genere richiede le proprie configurazioni che possono modificare la durata della soluzione. Il deploying diventa un incubo perché ora abbiamo 18 file di proprietà che devono essere ricordati per essere copiati e configurati anche impostando sorgenti di dati, code, requisiti di memoria ecc.

Sono fiducioso ma non ottimista sul fatto che ci possa essere un modo migliore. Alcune opzioni Abbiamo considerato/usato, ognuno con i suoi pro e contro:

  1. utilizzare i progetti Maven multipla e l'integrazione continua (es. Hudson o Jenkins) per costruire un barattolo di configurazione che include tutti i file di proprietà per ogni ambiente (dev, qa, prod) e quindi raggruppare tutto come un EAR. Ma poi le cose non possono essere facilmente modificate in produzione quando necessario.
  2. Metti la maggior parte delle impostazioni nel DB e disponi di una schermata semplice per modificarlo. Internamente possiamo avere un EJB di servizio di configurazione generico in grado di leggere e modificare i valori. Ogni modulo può avere una versione estesa personalizzata con getter e setter specifici.
  3. La versione controlla tutti i file delle proprietà, quindi li controlla in produzione e li controlla in un ramo di produzione dopo aver apportato le modifiche.

Con tutti questi è ancora necessario configurare fonti dati e le code, ecc in modo specifico contenitore :(

risposta

0

utente una tabella di database semplice (Sezione, Key, Value). Aggiungere "Versione" se ne avete bisogno, e avvolgere l'intera cosa in una semplice classe ConfigurationService con metodi come getInt(String section, String key)

Non un sacco di lavoro, e rende il codice di applicazione molto ordinato, e tweaking con la configurazione molto semplice.

+1

E si scopre una modifica della configurazione in un cambiamento di database. L'app del mio attuale datore di lavoro fa questo. Non è divertente. Replichiamo i database tra gli ambienti e, in caso di necessità, le impostazioni. Costruiamo database diversi per scopi diversi in dev, e dobbiamo configurare le impostazioni in. Non è possibile modificare un file e riavviare se si desidera modificare qualcosa, è necessario colpire il database. Ho lavorato con delle belle configurazioni basate su file e le ho preferite. –

+0

@TomAnderson - spiega perché la modifica di una riga di database è più complicata rispetto alla modifica di un file. Invece di "sostituire i database tra envs", dovrai "replicare i file di configurazione tra envs". Ad ogni modo, non trasformiamo questo in una vera discussione (magari continuate su Chat se volete), solo dicendo che sono molto simili per natura, e trovo che DB sia più facile da usare per grandi configurazioni. – ripper234

+0

Questo è un posto migliore per discutere, perché la discussione è lì per le generazioni future da leggere. Ad ogni modo, non volevo dire che questo approccio non va bene, mi dispiace; solo che arriva con le sue complicazioni. –

2
  1. Сonsider che associa un oggetto di configurazione personalizzato a JNDI. Quindi cerca questo oggetto nelle tue app per configurarle. Vantaggi: è possibile utilizzare l'oggetto di configurazione personalizzato anziché il piuttosto generico Map o Properties.
  2. Un altro modo è utilizzare JMX per configurare le applicazioni necessarie. Vantaggi: è possibile associare direttamente gli oggetti da configurare a MBean Server e quindi utilizzare strumenti noti come jconsole o visualvm per configurare i componenti dell'applicazione.

Entrambi i modi supportano la riconfigurazione dinamica delle applicazioni in fase di runtime. Preferirei usare JMX.

2

Ho attraversato diversi cicli di ricerca di modi per farlo. Non ho ancora una risposta definitiva.

L'ultimo ciclo si è concluso con un processo basato su file di proprietà. L'idea era che ogni istanza del server fosse configurata con un singolo file delle proprietà che configurava tutto. Il file è stato letto dagli script di avvio, per impostare i parametri di memoria, dal server dell'app e dall'applicazione stessa.

La cosa fondamentale, tuttavia, è che questo file non è stato gestito direttamente. Piuttosto, era un prodotto del processo di costruzione.Disponevamo di una serie di file per scopi diversi, mantenuti nel controllo della versione e una fase di creazione che univa quelli appropriati. Questo ti consente di individuare elementi comuni condivisi lungo vari assi.

Ad esempio, abbiamo avuto lo sviluppo, l'integrazione continua, QA, SVS, messa in scena, e ambienti di produzione, ognuno con il proprio database. I server in ambienti diversi richiedevano impostazioni di database diverse, ma ogni server in un determinato ambiente utilizzava le stesse impostazioni. Quindi, c'erano qualcosa come development-db.properties, qa-db.properties e così via. In ogni ambiente, disponevamo di diversi tipi di server: server Web, server di gestione dei contenuti, server di elaborazione batch, ecc. Ciascuno aveva le impostazioni JVM, per le dimensioni dell'heap e così via, diversi da altri tipi di server, ma coerenti tra i server di ambienti. Quindi, avevamo qualcosa come web-jvm.properties, cms-jvm.properties, batch-jvm.properties e così via. Abbiamo anche avuto modo di avere delle sostituzioni per sistemi specifici - produzione-cms-jvm.properties sorta di cosa. Avevamo anche un common.properties che impostava proprietà comuni e valori predefiniti sensibili che potevano essere ignorati laddove necessario.

Il nostro processo di costruzione era in realtà un po 'più complicato di una semplice raccolta le giuste opzioni da ciascun gruppo; avevamo un file master per ogni server in ogni ambiente che specificava quali altri file includere. Abbiamo consentito ai file di specificare altri file da includere, in modo da poter creare un grafico delle importazioni per massimizzare il riutilizzo.

ha finito per essere piuttosto complicato. Troppo complicato, penso. Ma ha funzionato, e ha reso molto, molto facile apportare modifiche che interessano molti server in modo controllato. Abbiamo persino unito un insieme di file di input dallo sviluppo e un altro da operazioni che contenevano informazioni riservate. Era un approccio molto flessibile.

2

So che questo è già stato risposto e la mia risposta non è necessariamente generica, ma qui è il mio prendere su cose:

nota, qui sto solo considerando le proprietà del sistema/risorsa e non impostazioni dell'applicazione. A mio avviso, le impostazioni dell'applicazione (come una soglia di pagamento o altre impostazioni devono essere archiviate in un database, in modo che il sistema possa essere riconfigurato senza dover riavviare un servizio o causare tempi di inattività mediante la ridistribuzione o la rilettura di un file delle proprietà) .

Per le impostazioni che influiscono sul modo in diverse parti di un sistema di connettersi con l'altro (come endpoint del servizio web, ecc), mi farebbe uso dell'albero JNDI.

connettività di database e la connettività JMS sarebbero poi set-up utilizzando la console di WebSphere e possono essere gestiti dagli amministratori Websphere. Questi possono anche essere creati come script JACL che possono essere inseriti nel controllo della versione se necessario.

Oltre alle risorse JNDI, per proprietà aggiuntive, come nomi utente per chiamate di servizi Web a un back-end, ecc., Vorrei utilizzare "Associazioni spazio nomi" di Websphere. Questi binding possono essere modificati utilizzando la console Websphere e accessibili tramite JNDI utilizzando il nome "cell/persistent/mypassword".

Così ho potuto creare il bind "mypassword" (una stringa), e la gestione per esso ricade sull'amministratore di Websphere (lontano dagli occhi dello sviluppatore o da altre persone che non dovrebbero avere accesso ai sistemi di produzione), mentre lo stesso EAR il file può essere usato su dev, test, pre-produzione e produzione (che è preferibile avere file EAR diversi per sistemi diversi, poiché la probabilità che altre differenze si insinuino si riducano).

Il codice Java dovrebbe quindi utilizzare una semplice ricerca JNDI (e possibilmente memorizzare il valore in memoria).

Vantaggi rispetto file di proprietà:

  • Non avere un file "vulnerabili", che avrebbe bisogno di essere protetto in quanto le proprietà di sistema contengono le password.
  • non dover aggiungere le politiche di sicurezza di Java per consentire l'accesso a quella posizione del file

vantaggi rispetto proprietà del database:

  • non legato ad avere una base di dati legato a un server applicazioni.

Speranza che aiuta

1

utilizzare i progetti Maven multipla e l'integrazione continua (ad es. Hudson o Jenkins) per costruire un barattolo di configurazione che include tutti i file di proprietà per ogni ambiente (dev, QA, prod) e quindi raggruppare tutto come come un EAR. Ma poi le cose non possono essere facilmente modificate nella produzione quando necessario.

Penso che la configurazione dovrebbe essere nel database dell'istanza dell'applicazione. La configurazione locale della macchina può essere diversa da dev e QA, PROD, DR ecc.

Quello che ti serve è un modo per ottenere la configurazione del database in modo semplice.

Creo un progetto separato con una dipendenza fornita di configurazione di Apache commons Ha molti modi di memorizzare i dati, ma mi piacciono i database e le configurazioni vivono nell'ambiente del database.

import javax.sql.DataSource; 
    import org.apache.commons.configuration.DatabaseConfiguration; 

    public class MYConfig extends DatabaseConfiguration { 

     public MYConfig(DataSource datasource) { 
      super(datasource, "TABLE_CONFIG", "PROP_KEY", "PROP_VALUE"); 
     } 
    } 

Mettete la maggior parte delle impostazioni nel DB e avere uno schermo semplice modificare esso. Internamente possiamo avere un EJB di servizio di configurazione generico che può leggere e modificare i valori. Ogni modulo può avere una versione personalizzata estesa con getter e setter specifici.

Configurazioni di Commons come semplice API, è possibile quindi scrivere la GUI come desiderato. Puoi fare l'interfaccia in qualsiasi modo tu voglia. O come una rapida vittoria non hanno interfaccia.

di controllo di versione di tutti i file di proprietà quindi controllare che sulla produzione e controllare in un ramo di produzione dopo aver apportato modifiche.

Il controllo della versione è ottimo. Aggiungi un altro DatabaseConfiguration utilizzando la composizione. La classe che si estende è la configurazione attiva e quella composta è la verifica. C'è un altro costruttore può avere una versione. Basta sovraccaricare i giusti metodi per ottenere l'effetto desiderato.

import javax.sql.DataSource; 
    import org.apache.commons.configuration.DatabaseConfiguration; 

    public class MYConfig extends DatabaseConfiguration { 
     final DatabaseConfiguration audit; 

     public MYConfig(DataSource datasource) { 
      super(datasource, "TABLE_CONFIG", "PROP_KEY", "PROP_VALUE"); 

      audit = new DatabaseConfiguration("TABLE_CONFIG_AUDIT", "PROP_KEY", "PROP_VALUE"); 
     } 
     @Override 
     public void addProperty(String key, Object value) { 
      Object wasValue = super.getProperty(key); 
      super.addProperty(key, value); 
      audit.put(key,wasValue);//add version code 
     } 
    } 

http://commons.apache.org/proper/commons-configuration/