Corruption du Dynamic Store

Un Dynamic Store ?

Chaque Zone Data Collector maintient en mémoire une base de données qui mémorise entre autres les serveurs de la zone et leur charge, les connexions utilisateurs et leur états. Ce dynamic est store est interogeable avec le programme queryds (disponible ici). La syntaxe de la commande est :

Queryds /table:tablename /query:querystring
 

Par exemple si nous voulons lister les connexions actives sur l’application “NotePad”

Queryds /table:Conn_Sessions /query:AppName==Notepad

Pour plus d’information, je vous laisse lire la documentation de Citrix à propos de QueryDS!

Corrompu ?

En effet, les informations contenu dans le dynamic store ne reflète plus la réalité de la charge des serveurs et des connexions utilisateurs. Ainsi, le répartition de charge se sera pas optimum… Mais les conséquences peuvent être plus importante! Si une application et/ou la ferme contiennent des limites de connexions utilisateurs, vous pouvez vous retrouver avec des utilisateurs incapable de se connecter à leurs applications. Et bien sur, il est impossible de fermer/reiniatiliser une connexion qui n’existe plus!

Réparer le dynamic store

Le redémarrage du service IMA n’est pas suffisant, il faut complètement redémarrer le ZDC, ce qui permets de réinitialiser le dynamic store. Après de plus ample recherche, le reboot du ZDC, ou la génération d’une élection n’a pas résolue le problème. Nous avons découvert une KB microsoft ( http://support.microsoft.com/kb/982303) à propos des Terminal Services qui retourne de mauvais compteur de sessions. Malheureusement, cette KB n’est pas forcément suffisante et il faudra passer le RollPack 1 sur la ferme 6.5. En cas d’urgence, un reboot du serveur remontant le mauvais nombre de session permet de réinitialiser les compteurs.

Surveiller la consistance du dynamic store

L’idée pour surveiller l’état du dynamic store est d’être capable de vérifier la différence d’état des sessions utilisateurs entre le réel et le dynamic store. En fait, ça revient à comparer les sessions Terminal Services et les sessions mémorisé dans la console Citrix.

Récupérer les sessions Terminal Services

Le module “PSTerminalServices” (disponible ici ) va nous permettre de récupérer les sessions TS sur les différents serveur.

PS > Get-Command -Module PSTerminalServices

CommandType Name                 Definition
----------- ----                 ----------
Function    Disconnect-TSSession ...
Function    Get-TSCurrentSession ...
Function    Get-TSProcess        ...
Function    Get-TSServers        ...
Function    Get-TSSession        ...
Function    Send-TSMessage       ...
Function    Stop-TSProcess       ...
Function    Stop-TSSession       ...

Le CmdLet Get-TSSession est tout indiqué pour récupérer les sessions TS d’un serveur.

get-TSSession -ComputerName CompName 

Récupérer les sessions mémorisées dans le Dynamic Store

Notre chance est que les CmdLet Citrix interroge le Dynamic Store, du coup, nous pouvons utiliser Get-XASession pour récupérer la liste des sessions depuis le dynamic store.

Mettre le tout ensemble

un petit oneliner pour checker chaque serveur :

Get-XAServer | %{ if( diff @(get-xaSession -ServerName $_.serverName | where { $_.SessionName -match "^ICA-" -and $_.state -ne 'Listening' -and $_.State -ne 'Down' -and $_.SessionID -gt 0 -and $_.AccountName.length -gt 0 } | select SessionId |% {$_.SessionId} | sort | unique ) @(get-TsSession -ComputerName $_.serverName | where { $_.WindowStationName -match "^ICA-" -and $_.state -ne 'Listening' -and $_.State -ne 'Down' -and $_.SessionID -gt 0 -and $_.UserName.length -gt 0 } | select SessionId |% {$_.SessionId} | sort | unique ) -passthru ){ $_.Servername } } 

Une version plus lisible :

add-pssnapin Citrix*
import-module PSTerminalServices
$sw = [Diagnostics.Stopwatch]::StartNew();
Get-XAServer | % {
    $server =  $_.ServerName
    try {
        $data1 = @();
	get-xasession -servername $_.serverName | where { $_.SessionName -match "^ICA-" -and $_.state -ne 'Listening' -and $_.State -ne 'Down' -and $_.SessionID -gt 0 -and $_.AccountName.length -gt 0 } |  select SessionId |%{ $data1+= $_.SessionID };
	$data1 = $data1 | sort | unique

        $data2 = @();
	Get-TSSEssion -ComputerName $_.ServerName | where { $_.WindowStationName -match "^ICA-" -and $_.State -ne 'Listening' -and $_.State -ne 'Down' -and $_.SessionID -gt 0 -and $_.UserName.length -gt 0 } | select SessionId |%{ $data2+= $_.SessionID };
	$data = $data2 | sort | unique

    }catch{
        write-host "Error : $server Inaccessible"
    }
    if( $data1 -and $data2 ) {
        $resultat = Compare-Object $data1 $data2 -Passthru
        if($resultat.length -gt 0 ){
	  Write-Host $_.ServerName $resultat.length
        }
    }
} 
  • Edit Nicolas 14/02/2012
    Complement d’information sur les résolutions possibles

Leave a Reply

Your email address will not be published. Required fields are marked *