Atualizar o site .NET sem recarregar

13

I utilizado para desenvolver sites em PHPe ASP classice se algo precisava ser mudado. Você pode apenas alterar um / vários arquivos e ninguém realmente notaria. Talvez se alguém solicitasse o arquivo alterado durante o upload, mas isso é como meio segundo de margem. Para a maioria dos sites menores, isso não é problema.

Mas os sites mais recentes são criados C# MVCe, quando você faz alterações no código, é necessário reconstruir o site e fazer upload dos DLLarquivos alterados . Mas quando você altera seus DLLarquivos, ele reinicia seu site e redefine tudo ativo sessions. Ele também precisa recarregar tudo e, com sites grandes, pode levar alguns minutos para carregar tudo. Todos que estavam navegando no site perceberão e precisam fazer login novamente.

As principais atualizações do site não são tão comuns, então isso não é um problema. Mas temos atualizações "pequenas" regulares para promoções. Como 'Preencha este formulário e ganhe três meses de assinatura grátis' ou 'Os 10 primeiros para carregar uma imagem de ... receberão um preço'. Eu acho que você vai entender. Algumas promoções são semelhantes e podem ser tratadas com um módulo que mostra as informações corretas com base nas configurações, mas muitas vezes exige código personalizado.

Eu estava pensando em um sistema em que cada promoção é seu próprio DLLarquivo com base em uma interface e, em seguida, carrega o DLLdinamicamente usando Type.GetType, Activator.CreateInstancee InvokeMember. Embora isso possa funcionar, estou me perguntando se é o caminho certo a seguir.

Então, minha pergunta: como você atualiza um .NETsite em tempo real, sem recarregar o site inteiro e interromper a sessão (como reciclar pool de aplicativos).

Hugo Delsing
fonte
Em resposta ao seu comentário de recompensa: os grandes sites em que trabalho lidam com pequenas alterações no código da mesma maneira que lidam com grandes alterações no código: por meio de balanceadores de carga e sessões fora do processo - porque todo o código implantado na vida precisa passar por um processo de revisão / assinatura e não podemos simplesmente soltar código nos servidores. Acho que nossas definições de "grande" podem não corresponder;)
Zhaph - Ben Duguid 26/02/15

Respostas:

11

Consulte "Inicialização de aplicativos" IIS 7.5, Windows 2008 R2 (mais difícil de configurar) IIS 8, Windows 2012

A Inicialização do aplicativo permite que qualquer aplicativo (pool de aplicativos, não site) reinicie e se sobreponha e use o antigo, ainda executando o aplicativo anterior enquanto aquece o início do novo aplicativo. Depois que o novo aplicativo for ativado (determinado pelos URLs que você pode definir), ele começará a usar o novo aplicativo e desligará o anterior. O uso da Inicialização de Aplicativos em conjunto com métodos para garantir que a sessão permaneça entre as reinicializações do pool de aplicativos pode permitir que o site seja reiniciado sem problemas. (Zhaph tem uma boa nota sobre a chave da máquina.)

Além dos links acima para a configuração de Inicialização de aplicativo, você vai querer ver o que aciona uma reinicialização do site - como a reinicialização do site não usa a inicialização do aplicativo, a reinicialização do site não será perfeita.

Você pode configurar o IIS para que uma atualização de DLL não acione imediatamente a reinicialização do site, nem altere o web.config (altos valores de ChangeNotification nos arquivos de configuração httpRuntime e externos, conforme relevantes para o seu site).

O resultado final é que você pode atualizar as DLLs / código sem reiniciar o site e forçar a reinicialização do aplicativo que usará o aquecimento de segundo plano do AppInitialization para a alteração contínua do código.

Fazer essas coisas em conjunto funciona muito bem para reinicializações contínuas.

jeffreypriebe
fonte
Um bom conjunto de passos lá - certamente algo a considerar :)
Zhaph - Ben Duguid
Parece o que eu estava procurando. Vou tentar e configurá-lo. Obrigado
Hugo Delsing
@HugoDelsing Espero que funcione muito bem para você.
jeffreypriebe
Obrigado, foi isso que acabei usando e funciona muito bem.
Hugo Delsing
@HugoDelsing Fico feliz em saber que funcionou para você também.
jeffreypriebe
5

Existem várias maneiras de lidar com o que você está solicitando e alguns aspectos diferentes da sua pergunta:

Lidar com pequenas atualizações para promoções

O que você realmente procura aqui é um sistema de gerenciamento de conteúdo ou similar que permita editar o conteúdo rapidamente (pense em Wordpress / Drupal ou do ponto de vista .NET N2 CMS, Umbraco, Orchard, etc.), no entanto algumas coisas que você poderia tentar se não seguisse esse caminho.

Como o ASP.NET é realmente recarregado apenas se você tocar em certos tipos de arquivo (web.config (s), principalmente o conteúdo das pastas /bin/e /app_code/) - e possui um limite configurável para "outras alterações de arquivo" (basicamente depois de modificado) Em muitos arquivos do seu site, o pool de aplicativos será reiniciado - NumRecompilesBeforeAppRestart). Você pode fazer algo em que verifica uma pasta diferente em busca de .htmlarquivos estáticos (ou seja ) que você extrai e exibe conforme necessário, ou utiliza o LoadControlmétodo que segue um caminho de string para um .ascxcontrole de usuário e o carrega dinamicamente - como você determina qual mostrar é uma pergunta diferente e mais adequada ao StackOverflow - no entanto, recomendo uma solução baseada em convenção de nomenclatura.

Você também pode usar algo como o MEF - Managed Extensibility Framework (que faz parte integrante do .NET framework desde a versão 4), que permite escrever uma arquitetura baseada em plugins e especificar uma pasta fora do /bin/diretório para monitorar .DLLs novos - embora eu não tenha tentado isso para verificar se ele evitará o problema de reinicialização do aplicativo, usei isso com bom efeito em um ambiente da Web para adicionar funcionalidades comuns a um site.

Se isso não agradar, a única outra opção em que posso pensar seria adicionar os controles como "code-in-front", como fizemos no ASP clássico - ou seja, com um <script runat="server">bloco em vez de uma classe "code-behind" compilada que contém a lógica para executar o controle - o que irá eliminar a necessidade de uma mudança DLL, à custa de alguma perda de desempenho pela primeira vez como o controle é compilado em tempo real - novamente você precisa equilibrar isso com o NumRecompilesBeforeAppRestartse Estamos fazendo muitas pequenas mudanças.

Como persisto as sessões nas reinicializações de aplicativos?

Esta é possivelmente uma questão mais fácil de resolver e envolve três etapas principais:

  1. Configure o MachineKey (IIS7, mas ainda vale para 8) como um valor constante, e não AutoGenerate- isso significa que, quando o AppPool reciclar, ele usará a mesma chave e poderá descriptografar cookies de sessão, viewstate etc. a reciclagem.
  2. Ou configurar um servidor de estado ou configurar um banco de dados para armazenar estado da sessão .
  3. Alterne de usar InProcpara StateServerou SQLServerno elemento SessionState no seu web.config.

Dessa forma, você terá sessões persistentes que sobreviverão à reinicialização do aplicativo. No entanto, eles não são "gratuitos" - tudo o que você armazena na sessão agora deve ser serializável, e você sofrerá um pequeno impacto no desempenho, pois cada carregamento de página exigirá viagens de rede adicionais para obter e potencialmente liberará os dados da sessão.

No entanto, se você estiver em uma posição em que leva "vários minutos" para o aplicativo reiniciar após uma implantação, convém mudar para um ambiente com balanceamento de carga ou, pelo menos, uma configuração de armazenamento temporário / ativo com troca a quente (como o fornecido pelo Azure / AWS / etc.) - dessa forma, você pode colocar um servidor off-line enquanto o atualiza ou prepará-lo com o novo código e depois trocá-lo - desde que você tenha tomado as medidas necessárias para resolver os problemas compartilhados. sessões (veja acima), isso funcionará bem, sem impacto para seus usuários.

Zhaph - Ben Duguid
fonte
Obrigado pela sua longa resposta. Infelizmente CMSnão é o que eu quero. Não quero alterar o conteúdo, quero alterar o código. A parte sobre as sessões foi apenas um exemplo. Mudá-lo não resolverá o problema de o site ficar inativo por um ou dois minutos ao recarregar DLLarquivos. A MEFparte foi interessante, mas é uma solução de terceiros para o sistema em que eu estava pensando. Então, marque com +1 o esforço, mas infelizmente não é realmente uma resposta para minha pergunta.
Hugo Delsing
1
Atualizei minha resposta para abordar alguns desses pontos: o MEF foi lançado pela MS e faz parte da estrutura do .NET desde a v4. Você pode tentar usar o código-in-front para seus novos controles, alternativamente, adotar uma configuração de balanceamento de carga / staging-live que permitiria obter um servidor funcionando e, em seguida, trocá-lo no.
Zhaph - Ben Duguid
1
Descrevi uma solução alternativa usando a Inicialização de aplicativos. O benefício é que toda a configuração do código e do servidor é "normal" sem controles especiais de balanceamento de carga ou carregamento dinâmico, mantendo o ambiente de execução mais simples. Obviamente, uma configuração de balanceamento de carga / armazenamento temporário em tempo real pode ser útil por outros motivos.
jeffreypriebe