lunes, 4 de agosto de 2008

Sesiones colgadas de Forms en E-business

Muy a menudo, me encuentro con clientes que quieren agregar muchos nodos aplicativos a un E-business suite porque tienen mucha carga en los nodos, y aparentemente no soportan más conexiones.

Sé que esto no va relacionado a base de datos completamente, pero para los Applications DBAs, suele ser un dolor de cabeza el estar revisando las cargas de CPU en los servidores de aplicaiones.

Me ha tocado administrar instancias de E-Business que tienen más de 2,000 usuarios concurrentes con sólo 2 servidores aplicativos, y el desempeño es excelente. Me ha tocado estar en ambientes donde la carga de un servidor de aplicación es altísima y sólo tiene 50 usuarios concurrentes.

La razón parece estar siempre ligada a procesos que se quedan en el limbo o en "stupid mode". Cada uno de estos procesos puede consumir hasta el 100% de un CPU, y si tenemos 10 de estos procesos, y sólo 6 procesadores, el servidor "estará corriendo como un perro con dos patas".



Hace un tiempo hice un script para facilitar la detección de estos procesos y finalmente eliminarlos con la tranquilidad de que no son procesos que existen en la aplicación.

sesiones_colgadas.sh


#!/usr/bin/ksh
##########################################
# Script para eliminar las sesiones
# colgadas de forms.
#
# Valida que las sesiones de forms
# Consuman mucho CPU y lleven corriendo
# mas de 5 minutos. Si cumplen estas
# caracteristicas, se evaluan a nivel
# base de datos, si no hay proceso
# relacionado, el cliente se mata.
#
#
# Elaborado por: Hugo E. Contreras
# Fecha: Abril 10, 2008
#
# Resource IT
##########################################

# Variables de ambiente
export ORACLE_HOME=/u01/oracle/PROD/apps/tech_st/10.1.2
export TWO_TASK=PROD
export USUARIO=monitor
export PASSWORD=******


for SerPid in `ps -eo pcpu,pid,etime,cmd|grep frmweb|sort -n|awk '$1 >10 && $3 > "05:00" {print $2}'`
do
ABC=`sqlplus -s $USUARIO/$PASSWORD << EOF
set head off
set pagesize 0
set feed off
select count(1) from v\\$session where process ='$SerPid';
exit;
EOF`

echo "el Sid $SerPid tiene $ABC sesion(es) en la base de datos"

if [ $ABC -lt 1 ]
then
echo "Se procede a matar el proceso $SerPid"
kill -9 $SerPid
fi

done



Hay muchas cosas a configurar en este script, y dependiendo del release del e-business, algo más puede cambiar, estas son algunas consideraciones que se deben de tener.

Si es 11i, el ORACLE_HOME a usar es el 8.0.6, en este caso el script está pensado para 12.0.3. En el caso de 11i, el proceso a buscar es f60webmx, para 12i es frmweb.

En caso de tener un RAC configurado como base de datos, lo primero es usar la vista GV$SESSION en lugar de V$SESSION. Algo adicional, es que se debe de evaluar el nombre del equipo, es decir

AND machine = `hostname`

Ya que pudiera ser que alguna instancia del RAC tuviera un proceso padre (gv$session.process) con el mismo número en una instancia distinta.

En caso de tener más de 1 application server, sea o no un RAC, también se debe poner la condición

AND machine = `hostname`

Esto es porque dos o más servidores de aplicación pudieran usar el mismo spid para un proceso de forms.

Alguna consideración en el caso de solaris; el comando

ps -eo pcpu,pid,etime,cmd

debe ser cambiado por

ps -eo pcpu,pid,etime,comm

Seguramente muchas otras cosas pueden cambiar entre HP-UX, Aix, Solaris o diferentes sabores de Linux, pero la idea es casi la misma:

Obtener la lista de procesos que contienen el ejecutable que nos interesa, buscar sólo aquellos que consumen más del 10% de 1 CPU y que lleven por lo menos 5 minutos activas.

Cuando todas estas condiciones se cumplen, se evalúa contra la base de datos para corroborar que el proceso hijo todavía existe, en caso de no existir, el proceso es eliminado a través de un kill -9.

El script se debe de ejecutar en el servidor de aplicación.