Quantcast
Channel: MSDN Blogs
Viewing all articles
Browse latest Browse all 35736

Monitorando aplicações COM+

$
0
0

Já faz um tempo que não publico nada, mas esta semana um outro colega esteve trabalhando num caso muito interessante. Ele estava fazendo o diagnóstico de uma aplicação Web que havia sido migrada para o Windows 2008 R2.

clip_image001Esta aplicação usa componentes COM+ e em algum momento, o componente simplesmente travava (cenário típico de Hang).
Os componentes são antigos, e não se tem o código-fonte dos mesmos. Após muita investigação, descobriu-se que o componente iniciava um outro processo no Windows para realizar uma tarefa específica. Quando o COM+, por algum motivo realizava o RECYCLE do processo DLLHOST.exe onde o componente estava sendo executado, este outro processo permanecia em execução.

Na próxima chamada ao componente, o mesmo tentava executar o outro processo, mas já havia uma instância em execução e por isso o componente travava. A melhor solução seria reescrever todo o componente de forma que o mesmo utilize técnicas mais modernas para executar as tarefas a que se propõe, mas infelizmente isso é impossível.

Neste caso, uma solução de contorno foi necessária. Para eliminar o travamento, bastou desabilitar o RECYCLING da aplicação COM+ no snap-in dos serviços de componente (Component Services).

Todavia, um novo problema surge com essa abordagem, que é o fato que agora o processo DLLHOST.exe do COM+ poderá travar em função de algum outro mau comportamento ou até mesmo devido ao processo natural de fragmentação de memória (outro dia faço um post sobre isso).

Para minimizar esse problema seria ideal ter uma ferramenta que monitore o comportamento da aplicação COM+ (“AppBugada”, no exemplo da imagem acima) e em caso de consumo de um certo limite de memória virtual, que ela seja automaticamente encerrada.

Para isso, um script foi usado a fim de monitorar a aplicação COM+. Veja abaixo um exemplo similar que também pode ser usado para fazer este tipo de objetivo:

NOTA: Este script é um código-exemplo, use por sua conta e risco. Não oferecemos suporte a este script e não nos responsabilizamos por eventuais consequências adversas devido ao seu uso num ambiente de produção.

strComputer = "."
strCOMAppName = "AppBugada"
constMemLimit = 999999999 'Bytes
constRunning = false
constCOMAppFound = false


Set objCOMCatalog = CreateObject("COMAdmin.COMAdminCatalog")
Set objCOMApps = objCOMCatalog.GetCollection("Applications")
objCOMApps.Populate

For each objCOMApp in objCOMApps
    If objCOMApp.Name = strCOMAppName then
        Set objCOMAppInstances = objCOMApps.GetCollection("ApplicationInstances",objCOMApp.Key)
        objCOMAppInstances.Populate
        For each objCOMInstance in objCOMAppInstances
            PID = objCOMInstance.Value("ProcessID")
            constRunning = not ( objCOMInstance.Value("IsPaused") or objCOMInstance.Value("HasRecycled"))
            If constRunning then
                Set objWMIService = GetObject("winmgmts:" _
                    & "{impersonationLevel=impersonate}!\\" _
                    & strComputer & "\root\cimv2")
                Set objProcesses = objWMIService.ExecQuery _
                   ("Select * from Win32_Process where ProcessId='" & PID & "'")
                For Each objProcess in objProcesses
                    Wscript.Echo "Process: " & objProcess.Name
                    sngProcessTime = (CSng(objProcess.KernelModeTime) + _
                        CSng(objProcess.UserModeTime)) / 10000000
                    Wscript.Echo "Processor Time: " & sngProcessTime
                    Wscript.Echo "Process ID: " & objProcess.ProcessID
                    Wscript.Echo "Peak Virtual Size: " _
                    & objProcess.PeakVirtualSize
                    Wscript.Echo "Virtual Size: " _
                    & objProcess.VirtualSize
                    If objProcess.VirtualSize > constMemLimit then
                        objProcess.Terminate()
                    End if
                Next
                Set objWMIService = nothing
                Set objProcesses = nothing
                Exit For
            Else
                Wscript.Echo "COM+ Application not running."
            End if
        Next
        Set objCOMAppInstances = nothing
        constCOMAppFound = true
        Exit For
    End if
Next

If constCOMAppFound = false then
        Wscript.Echo "COM+ Application not found."
End if

Set objCOMApps = nothing
Set objCOMCatalog = nothing

O Script usa a interface COMAdmin para monitorar as aplicações COM+ e classes WMI para coletar informações do processo DLLHOST.exe correspondente. Caso o processo atinja um certo limite de uso de memória virtual, o mesmo será terminado.

Valeu pessoal e até a próxima.

PT


Viewing all articles
Browse latest Browse all 35736

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>