Pergunta

Atualmente estou trabalhando em um projeto j2ee que tem sido em beta por um tempo agora. Agora nós estamos apenas batendo para fora alguns dos problemas com o processo de implantação. Especificamente, há uma série de arquivos incorporados na guerra (alguns arquivos XML e .properties) que precisam diferentes versões implantação dependendo se você está em um dev, testando ou ambiente de produção. Coisas como loglevels, pools de conexão, etc.

Então eu queria saber como os desenvolvedores aqui estruturar o seu processo de implantação webapps. Você offload tanto configuração possível para o servidor de aplicativos? Você substituir os arquivos de configurações de programação antes de implantar? Escolha uma versão durante o processo de criação? Manualmente editar as guerras?

Também o quão longe você vai na prestação de dependências através de bibliotecas estáticas Os servidores de aplicativos e quanto você colocar no-se a guerra? Tudo isso apenas para obter algumas idéias do que o comum (ou talvez melhor) a prática é no momento.

Foi útil?

Solução

Eu trabalho em um ambiente onde separado equipe executa o servidor de configuração do QA e servidores de produção para as nossas aplicações. Cada aplicação é geralmente implantados em dois servidores em QA e três servidores em produção. Minha equipe dev descobriu que é melhor para minimizar a quantidade de configuração necessária no servidor, colocando o máximo de configuração possível na guerra (ou ouvido). Isso faz com que a configuração do servidor mais fácil e também minimiza a chance de que a equipe de servidor incorretamente configurar o servidor.

Não temos configuração específica da máquina, mas temos de configuração específicas do ambiente (Dev, QA, e Produção). Temos arquivos de configuração armazenados no arquivo de guerra que são nomeados pelo ambiente (Ex. Dev.properties, qa.properties, prod.properties). Nós colocamos uma propriedade -D na linha de comando java do servidor de VM para especificar o ambiente (ex. Java -Dapp.env = prod ...). A aplicação pode olhar para a propriedade do sistema app.env e usá-lo para determinar o nome do arquivo de propriedades para uso.

Suponho que se você tem um pequeno número de propriedades específicas da máquina, em seguida, você pode especificá-los como propriedades -D também. Configuração Commons oferece uma maneira fácil de combinar arquivos de propriedades com as propriedades do sistema.

Nós configurar pools de conexão no servidor. Nós nomear o pool de conexão o mesmo para todos os ambientes e simplesmente apontar os servidores que são atribuídos a cada ambiente de banco de dados apropriado. A aplicação só tem de saber o nome do pool de uma conexão.

Outras dicas

Eu acho que se as propriedades são máquina / específico de implantação, então eles pertencem na máquina. Se eu estou indo para embrulhar as coisas em uma guerra, deve ser drop-innable, o que significa que nada de específico da máquina que está sendo executado. Esta ideia vai quebrar se a guerra tem propriedades dependentes da máquina na mesma.

O que eu gostaria de fazer é construir um projeto com um arquivo properties.example, cada máquina tem um .properties que vive em algum lugar a guerra pode acessá-lo.

Uma forma alternativa seria ter tarefas de formigas, por exemplo, para dev-guerra, fase-guerra, prod-guerra e têm os conjuntos de propriedades parte do projeto, cozido em na guerra-build. Eu não gosto disso tanto porque você vai acabar tendo coisas como locais de arquivos em um servidor individual como parte de sua compilação de projeto.

arquivos de configuração WRT, acho que resposta de Steve é ??o melhor até agora. Gostaria de acrescentar a sugestão de fazer os arquivos externos em relação ao caminho de instalação do arquivo de guerra -. Dessa forma, você pode ter várias instalações da guerra no único servidor com configurações diferentes

por exemplo. Se o meu dev.war fica descompactado em /opt/tomcat/webapps/dev, então eu usaria ServletContext.getRealPath para encontrar a pasta base e nome da pasta guerra, então, em seguida, os arquivos de configuração viveriam em ../../config/dev relação à guerra, ou /opt/tomcat/config/dev para absoluto.

Também concordo com Bill em colocar o mínimo possível nestes arquivos de configuração externos. Usando o banco de dados ou JMX dependendo do seu ambiente para armazenar tanto quanto faz sentido. Configuração Commons Apache tem um agradável objeto para manipulação de configurações apoiados por uma tabela de banco de dados.

Em relação bibliotecas, eu concordo com desconhecido ter todas as libs na pasta WEB-INF/lib no arquivo de guerra (auto-embalados). A vantagem é que cada instalação do aplicativo é autônomo, e você pode ter diferentes versões da guerra usando diferentes versões das bibliotecas ao mesmo tempo.

A desvantagem é que ele vai usar mais memória como cada aplicação web terá sua própria cópia das classes, carregados por seu próprio carregador de classe.

Se este poses uma preocupação real, então você pode colocar os frascos na pasta biblioteca comum para o servlet container ($CATALINA_HOME/lib para tomcat). Todas as instalações do seu aplicativo web em execução no mesmo servidor tem que usar as mesmas versões das bibliotecas embora. (Na verdade, isso não é rigorosamente verdade como você poderia colocar substituindo versões na pasta WEB-INF/lib individual, se necessário, mas isso está ficando muito confuso para manter.)

Eu iria construir um instalador automatizado para as bibliotecas comuns, neste caso, com o InstallShield ou NSIS ou equivalente para seu sistema operacional. Algo que pode torná-lo fácil de dizer se você tem o atualizado conjunto mais de bibliotecas, e upgrade, downgrade, etc.

Eu costumo fazer arquivos de duas propriedades:

  • um para especificidades de aplicativos (mensagens, "mágicos" palavras internas) embutido no aplicativo,
  • o outro para fins específicos ambiente (acesso db, os níveis de log e caminhos ...) exposta no classpath de cada servidor e "colada" (não fornecido com o meu app). Normalmente eu "mavenise" ou "anttise" estes um para colocar valores específicos, dependendo do env-alvo.
  • frescos dos indivíduos usar JMX para manter sua conf aplicativo (conf pode ser modificado em tempo real, sem reimplementar), mas é muito complexo para as minhas necessidades.

O Server (estática?) Bibliotecas: I fortemente desencorajar o uso da biblioteca servidor em meus aplicativos como acrescenta dependência ao servidor:

  1. IMO, meu aplicativo deve ser "auto-embalados": deixar cair a minha guerra, e isso é tudo. Eu vi guerras com 20 Mbs de frascos na mesma, e isso não é preocupante para mim.
  2. A comum de melhores práticas é limitar suas dependências externas ao que é oferecido pelo dogma J2EE: API J2EE (uso de Servlets, EJBs, JNDI, JMX, JMS ...). Sua aplicação tem de ser "agnóstico servidor".
  3. Colocar dependências em seu aplicativo (guerra, orelha, wathever) é auto-documentado: você sabe quais bibliotecas a sua aplicação depende. Com libs do servidor, você tem que documentar claramente essas dependências como eles são menos óbvios (e logo seus desenvolvedores vai esquecer este pequeno mágico).
  4. Se você atualizar seu appserver, as chances de que o servidor lib você depende também vai mudar. editores AppServer não são supostamente para manter a compatibilidade em seus libs internos de versão para versão (e na maioria das vezes, eles não fazem).
  5. Se você usar uma lib amplamente utilizado incorporado em seu Appserver (commons logging Jacarta, aka JCL, vem à mente) e quer ugrade-lo da versão para obter os recursos mais recentes, você pega o enorme risco de que seu Appserver não vai apoiar -lo.
  6. Se você depende de um objeto de servidor estática (em um campo estático de uma classe de servidor, por exemplo, um mapa ou um log), você terá que reiniciar o appserver para limpar este objeto. Você perde a capacidade de hot-redeploy seu aplicativo (objeto servidor antigo será ainda existe entre reafectações). Usando objetos de grande Appserver (exceto aqueles definidos pelo J2EE) pode levar a erros sutis, especialmente se este objeto é compartilhado entre vários aplicativos. É por isso que desencorajam fortemente o uso de objetos que reside em um campo estático de um lib Appserver.

Se for absolutamente necessário "este objeto no frasco deste appserver", tente copiar o frasco em seu aplicativo, esperando não há nenhuma dependência em frasco de outro servidor, e verificando política de carregamento de classe do seu aplicativo (eu levo o hábito de colocar um "pai última" política de carregamento de classe em todos os meus aplicativos: Eu tenho certeza que não vai ser 'poluída' por frascos do servidor - mas eu não sei se é uma 'melhor prática')

Eu coloquei toda a configuração no banco de dados. O recipiente (Tomcat, WebSphere, etc) me dá acesso à conexão de banco de dados inicial e a partir de então, tudo sai do banco de dados. Isto permite que vários ambientes, agrupamento, e mudanças dinâmicas sem tempo de inactividade (ou pelo menos sem um redeploy). Especialmente interessante é ser capaz de alterar o nível de log on the fly (embora você precisará de uma tela de administração ou de uma reciclagem fundo para pegar as mudanças). Obviamente, isso só funciona para coisas que não são necessários para obter o aplicativo começou, mas geralmente, você pode obter no banco de dados muito rapidamente após a inicialização.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top