Otimização do Tomcat, Resolução de OOMs em Java, e Configuração do Redis com Sentinel

1. Métodos de Otimização do Tomcat

1.1 Otimização do Espaço de Memória

JVM_OPTS="-server -Xms4g -Xmx4g -XX:NewSize=512m -XX:MaxNewSize=1g"

-server           Modo de servidor
-Xms              Tamanho inicial do heap da memória
-Xmx              Limite máximo do heap da memória
-XX:NewSize=      Tamanho inicial da geração de objetos novos
-XX:MaxNewSize=   Tamanho máximo da geração de objetos novos

Recomenda-se configurar -Xms e -Xmx com o mesmo valor para evitar fragmentação de memória.

1.2 Ajuste do Pool de Threads

Parâmetros de configuração do conector no Tomcat:

  • connectionTimeout: Tempo de espera para uma conexão, em milissegundos.
  • maxThreads: Número máximo de threads (padrão: 200).
  • minSpareThreads e maxSpareThreads: Controlam o número de threads ociosas.
  • acceptCount: Tamanho máximo da fila de espera quando todas as threads estão ocupadas (padrão: 100).
  • URIEncoding: Formato de codificação para URIs, recomenda-se utf-8.
  • enableLookups: Se deve ou não realizar a resolução DNS reversa para o host do cliente. Recomenda-se desativar (false).
  • compression: Ative ("on") para habilitar a compressão de dados, equilibrando uso de CPU e tráfego de rede.
  • compressionMinSize: Tamanho mínimo em bytes para ativar a compressão.
  • compressableMimeType: Tipos MIME habilitados para compressão, ex: text/html, text/xml, application/json.

2. Diagnóstico e Resolução de Erros OutOfMemoryError (OOM) em Java

Utilize ferramentas de monitoramento como o JProfiler para analisar o heap da JVM. O erro java.lang.OutOfMemoryError é lançado quando a Máquina Virtual Java (JVM) não consegue alocar memória para um novo objeto e o Garbage Collector (coletor de lixo) não consegue liberar espaço suficiente.

Cenários comuns incluem vazamentos de memória (objetos mantidos em referência desnecessariamente), configuração insuficiente do tamanho do heap (-Xmx), ou operações que consomem memória excessivamente (como carregar grandes conjuntos de dados na memória de uma vez).

3. Características e Casos de Uso do Redis

3.1 Principais Características

  • Alto Desempenho: Capaz de mais de 100.000 operações por segundo (QPS), pois opera primariamente em memória e é escrito em C.
  • Modelo de Execução: Opera com um único thread principal para comandos, simplificando a lógica.
  • Persistência: Oferece mecanismos (RDB e AOF) para salvar dados em disco.
  • Estruturas de Dados: Suporta uma variedade de estruturas como strings, hashes, lists, sets e sorted sets.
  • Riqueza de Funcionalidades: Inclui Lua scripting, pub/sub, transações e pipelines.
  • Simplicidade: Código conciso e fácil de integrar com diversas linguagens de programação.
  • Escalabilidade: Suporta replicação (mestre-escravo), alta disponibilidade (Sentinel) e distribuição (Cluster).

3.2 Casos de Uso Comuns

  • Cache: Armazenamento temporário de resultados de consultas de banco de dados, páginas web ou sessões de usuário para acelerar o acesso.
  • Compartilhamento de Sessões: Gerenciar sessões de usuários em uma arquitetura de aplicação web distribuída.
  • Contadores e Classificações: Implementar contagens de curtidas, exibições ou raknings em tempo real.
  • Filas de Mensagens: Utilizar listas do Redis como filas simples de processamento para tarefas assíncronas.
  • Social Media: Modelar relacionamentos (seguidores, amigos em comum) e interações (likes, comentários).
  • Dados Geoespaciais: Usar comandos GEO para funcionalidades como "pessoas por perto".

4. Comparação entre os Modos de Persistência: RDB vs. AOF

Modo Vantagens Desvantagens
RDB (Redis Database) - Gera snapshots (cópias) dos dados em momentos específicos, permitindo backups e recuperação rápida para grandes volumes de dados. - O prcoesso de salvamento ocorre em um fork do processo principal, minimizando o impacto no desempenho. - Arquivos compactos, ideais para backups e transferência. - Não é um backup em tempo real. Pode-se perder dados entre os últimos snapshots. - O processo de fork pode consumir tempo e memória adicional em conjuntos de dados muito grandes.
AOF (Append Only File) - Maior durabilidade dos dados. Com a estratégia fsync everysec, no máximo 1 segundo de dados é perdido em uma falha. - Arquivo de log legível e contínuo, o que ajuda na depuração. - Suporta reescrita em segundo plano para compactar o arquivo. - O arquivo AOF geralmente é maior que o RDB equivalente, ocupando mais espaço em disco. - A recuperação de um AOF completo pode ser mais lenta do que a de um RDB. - Pode conter bugs em operações complexas de reescrita (embora seja robusto).

5. Implementação do Redis Sentinel e Simulação de Falha

5.1 Instalação do Redis a partir do Código Fonte

# Pré-requisitos e compilação
yum -y install gcc jemalloc-devel
wget https://download.redis.io/releases/redis-7.0.12.tar.gz
tar -xzf redis-7.0.12.tar.gz
cd redis-7.0.12
make PREFIX=/opt/redis install

# Configuração do ambiente
echo 'PATH=/opt/redis/bin:$PATH' > /etc/profile.d/redis.sh
source /etc/profile.d/redis.sh
mkdir -p /opt/redis/{etc,log,data,run}
cp redis.conf /opt/redis/etc/
useradd -r -s /sbin/nologin redis
chown -R redis:redis /opt/redis

# Ajuste do arquivo de configuração principal (exemplo para o nó primário)
cat > /opt/redis/etc/redis.conf << EOF
bind 0.0.0.0
protected-mode no
requirepass s3nhA_F0rt3
port 6379
daemonize yes
pidfile /opt/redis/run/redis-server.pid
logfile /opt/redis/log/redis-server.log
dir /opt/redis/data
EOF

5.2 Configurando a Replicação Mestre-Escravo

Configurar os nós escravos (10.0.0.11, 10.0.0.12) para replicar o nó mestre (10.0.0.10).

# Nos nós escravos, adicionar ao final do redis.conf:
replicaof 10.0.0.10 6379
masterauth s3nhA_F0rt3

Após reiniciar os serviços, no mestre você pode verificar a conexão com o comando redis-cli -a s3nhA_F0rt3 INFO replication.

5.3 Configurando o Sentinel

Criar o arquivo sentinel.conf com a seguinte configuração básica (repetir em todos os três sentinelas):

cat > /opt/redis/etc/sentinel.conf << EOF
port 26379
daemonize yes
pidfile /opt/redis/run/redis-sentinel.pid
logfile /opt/redis/log/redis-sentinel.log
dir /tmp

# Monitorar o mestre com nome 'prod_db', endereço, porta e quórum (2 sentinelas precisam concordar)
sentinel monitor prod_db 10.0.0.10 6379 2
sentinel auth-pass prod_db s3nhA_F0rt3
sentinel down-after-milliseconds prod_db 5000
sentinel failover-timeout prod_db 60000
sentinel parallel-syncs prod_db 1
EOF

Iniciar o sentinel: redis-sentinel /opt/redis/etc/sentinel.conf

5.4 Simulando uma Falha no Mestre

Parar o serviço Redis no nó mestre (10.0.0.10):

# No mestre
redis-cli -a s3nhA_F0rt3 SHUTDOWN NOSAVE

Após alguns segundos, as sentinelas detectarão a falha e elegerão um novo mestre entre os escravos. Você pode verificar o novo status no sentinel com:

redis-cli -p 26379 SENTINEL get-master-addr-by-name prod_db

O comando acima retornará o endereço IP e a porta do novo nó mestre eleito.

Tags: tomcat java JVM OutOfMemoryError Redis

Publicado em 6-19 00:15