development, howto, sysadmin

howto #2 – Como apresentar uma “tela de manutenção” em servidores Apache proxy reverso enquanto faz deploy em seu backend

fabio / 31 de outubro de 2016

Começando a série de howtos, vai uma dica bem simples para quem gerencia servidor Apache Httpd como proxy reverso, que é exibir uma mensagem de indisponibilidade do sistema enquanto se faz manutenção em servidor ou deploy de aplicação em backend.

O cenário nesse caso é o seguinte (no fluxo do protocolo HTTP):

Situação normal: Cliente -> REQUEST -> servidor proxy reverso/load balancer -> REQUEST -> servidor backend

Situação de indisponibilidade: Cliente -> REQUEST -> servidor proxy reverso/load balancer -> REDIRECT p/ página de erro

O problema que se tenta resolver é que durante um deploy ou uma manutenção o usuário não recebe uma notificação do que está ocorrendo, geralmente recebe uma tela de erro 404 do servidor de aplicação no primeiro caso ou uma mensagem de erro do Apache ao não conseguir contatar o backend no segundo.

A solução é alcançada utilizando o mod_rewrite e um arquivo de mapa (hashtable), o código deve ser posto no início da configuração do VirtualHost (explicações abaixo):

1: RewriteEngine On
2: RewriteMap maintenanceApps txt:/var/www/unavailable-apps/vhost.conf.maintenance
3: RewriteCond %{REQUEST_FILENAME} ^(/\w+)/?
4: RewriteCond ${maintenanceApps:%1|NOT_FOUND} !NOT_FOUND
5: RewriteRule ^(.*) /messages/unavailable/index.html?app=${maintenanceApps:%1} [R=302,NE,L]

Vamos explicar o que ocorre na configuração do Apache exibida anteriormente linha a linha:

Linha 1: RewriteEngine On

Ligamos o módulo mod_rewrite.

Linha 2: RewriteMap maintenanceApps txt:/var/www/unavailable-apps/vhost.conf.maintenance

Declaramos que “maintenanceApps” é um mapa a partir de conteúdo texto contido no arquivo “/var/www/unavailable-apps/vhost.conf.maintenance”.

Linha 3: RewriteCond %{REQUEST_FILENAME} ^(/\w+)/?

Definimos a primeira condição de match para o redirecionamento, sendo: REQUEST_FILENAME deve ser uma palavra iniciada por “/”, seguida por uma ou mais letras e terminada com “/”, além disso, criamos um grupo de expressão regular com “/” e a palavra a seguir.

Linha 4: RewriteCond ${maintenanceApps:%1|NOT_FOUND} !NOT_FOUND

Definimos a segunda condição de match, procuramos no mapa “maintenanceApps” o valor que encontramos no grupo de captura da linha anterior, caso ele não exista, retornamos o valor “NOT_FOUND”, sendo que o critério é verdadeiro quando o valor for diferente de “NOT_FOUND”.

Obs.: quando duas ou mais linhas RewriteCond estão em sequência são avaliadas com operador lógico AND, caso se queira utilizar OR se deve definir [OR] ao final da linha.

Linha 5: RewriteRule ^(.*) /messages/unavailable/index.html?app=${maintenanceApps:%1} [R=302,NE,L]

Redirecionamos o cliente para a página de aviso, enviando a ele um HTTP 302 com a URL “/messages/unavailable/index.html?app=[VALOR ENCONTRADO NO MAPA CORRESPONDENTE AO INÍCIO DA URL REQUISITADA]”. As flags entre [] significam:

  • R=302, força um redirect externo (via cliente) com código HTTP 302.
  • NEnoescape: não escape caracteres.
  • L, last, para de executar regras do mod_rewrite.

O conteúdo do arquivo “/var/www/unavailable-apps/vhost.conf.maintenance” para exibir mensagem de indisponível para a aplicação “/appteste” seria:

1: /appteste "Aplicação de teste"

O primeiro campo da hashtable é a URL a procurar no cabeçalho da requisição e o segundo é o valor do parâmetro “app” enviado à página para customização de mensagem. O código HTML de “/messages/unavailable/index.html” pode, então, utilizar o parâmetro “app” e exibir uma mensagem explicativa ao cliente utilizando o segundo parâmetro.

A vantagem desse método com mapa é que o servidor não precisa receber um HUP ou USR1 para se reconfigurar com novos valores de aplicações indisponibilizadas, a contrapartida é que o acesso a disco pode aumentar (mas aí contamos com o buffercache do Linux ;).

Então, o fluxo de trabalho ao realizar um deploy ou uma manutenção em um cluster inteiro fica:

  1. Inserir linha /app-context “mensagem ou nome da aplicação para exibição ao user” no arquivo “/var/www/unavailable-apps/vhost.conf.maintenance”
  2. Realizar operação
  3. Remover linha /app-context “mensagem ou nome da aplicação para exibição ao user” do arquivo “/var/www/unavailable-apps/vhost.conf.maintenance”

O processo de aviso fica totalmente automático, os usuários são avisados com uma mensagem amigável e nenhuma request chegará ao backend desnecessariamente.

Em um post futuro mostrarei como automatizar melhor utilizando o consul-template em substituição ao arquivo de mapa.

Note que é importante esse trecho estar no início da configuração do VirtualHost, pois se a aplicação estiver em manutenção, o usuário é logo redirecionado à página de aviso.

 

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *