Requêtes RPC et Résolution Netlogon
Le compteur MSExchangeIS\Demandes RPC
Que représente ce compteur ?
Un compteur important à surveiller sur un serveur de boîtes aux lettres est le compteur MSExchangeIS\Demandes RPC (ou RPC Requests sur un serveur installé en anglais).
Ce compteur représente le nombre de threads dans le processus store disponible pour traiter les requêtes RPC des clients Outlook.
Il y a au maximum 100 threads sous Exchange 2003 et 500 threads sous Exchange 2007 et Exchange 2010.
Quel impact ?
Lorsque le compteur atteint 500 (valeur maximale), le serveur de boîte aux lettres refuse toutes les nouvelles demandes des postes clients car il ne peut pas en traiter plus de 500 à la fois.
L'impact au niveau des postes Outlook sont des déconnections. Ce symptôme touche tous les postes clients se connectant au serveur Exchange. Bien sûr les postes utilisant le mode cache d'Outlook sont moins impactés.
Il est donc important de surveiller la valeur de ce compteur.
Quelle Valeur à ne pas dépasser ?
La recommandation pour ce compteur est de ne pas dépasser 70.
La liste des compteurs à surveiller et leurs valeurs recommandées pour les serveurs de boîtes aux lettres Exchange 2007 est disponible sur ce lien :
https://technet.microsoft.com/fr-fr/library/bb201689(EXCHG.80).aspx
Les causes possibles d’une valeur au-dessus des recommandations
La cause d’une trop grande valeur pour MSExchangeIS\Demandes RPC est une charge trop importante par rapport aux performances du serveur : donc de façon générale un problème de performance ou de charge du serveur.
Les causes peuvent donc être diverses.
Cela peut être lié à une charge trop importante :
Les postes clients peuvent générer trop de requêtes par rapport à ce qui a été prévu lors du dimensionnement du serveur. Il faut donc vérifier les valeurs des compteurs prévus lors du dimensionnement et avoir une base de référence de performance.
La charge peut provenir de certains clients qui consomment beaucoup trop de ressources comme par exemple via des addins Outlook (de façon normale pour une application riche ou tout à fait anormale à cause d’une erreur dans l’addin qui consommerait toute les ressources).
Pour rechercher cela on peut utiliser l’outil exmon pour identifier les utilisateurs qui consomment le plus et utiliser les throttling policy pour définir une consommation maximum par utilisateur.
D’autres types de causes sont des lenteurs sur la machine qui ralentiraient le traitement des requêtes :
Nous avons déjà rencontré le cas d’antivirus ou d’outil d’audit qui interfèreraient avec le fonctionnement des threads, des lenteurs d’accès aux disques (pour cela vérifier les compteurs de performance disques), des lenteurs d’accès réseau, Active Directory, page pool et non page pool sous Exchange 2003 etc…
De façon générale toutes les ressources dont les threads Exchange pourraient avoir besoin et dont la lenteur d’accès va ralentir le traitement.
Quel plan d’action si la valeur n’est pas dans les recommandations ou quelles actions pour éviter de rencontrer le problème :
De façon générale, la recherche de cette problématique se fait en vérifiant la valeur des compteurs de performances système et Exchange par rapport aux recommandations et aux valeurs prévues lors du dimensionnement.
Il est également conseillé de collecter régulièrement certains compteurs. Cela permet de comparer les valeurs lors d’un fonctionnement normal et d’identifier exactement le moment ou le compteur s’est mis à augmenter de façon anormale. Lorsqu’on connait ce moment exact, on peut regarder les changements effectués à ce moment précis ou les événements des serveurs à cette heure-ci.
Le cas particulier des résolutions de SIDs
L’analyse du problème du coté Exchange
Nous allons nous intéresser dans cet article du cas particulier des résolutions de SID avec netlogon.
Nous avons pris un dump de la mémoire du processus store et identifié que beaucoup de threads attendaient la thread 150
CritSec at 0000000056038640. Owned by thread 150.
Waiting Threads: 97 98 99 102 103 104 110 113 114 116 117 118 119 120 121 122 123 125 126 129 130 131 133 134 143 144 145 146 149 151 152 153 154 156 157 158 159 161 162 163 166 170 257 258 259 260 263 264 265 269 270 271 272 273 275 276 277 278 279 280 281 282 283 284 286 287 288 290 291 292 294 295 296 297 298 299 300 301 302 303 305 307 308 309 310 312 313 315 317 318 319 320 321 322 323 324 325 326 328 329 330 334 335 336 337 338 340 341 342 343 344 345 346 347 348 365 366 367 371 381 388 392 393 394
En se positionnant sur la thread 150, on peut voir qu’elle attendait le retour de la fonction LookupAccountSidInternal
0:150> knL
# Child-SP RetAddr Call Site
00 00000000`58b1b848 00000000`7751c730 ntdll!ZwWaitForSingleObject+0xa
01 00000000`58b1b850 000007fe`ff1ef805 kernel32!WaitForSingleObjectEx+0x9c
02 00000000`58b1b910 000007fe`ff1eff47 rpcrt4!UTIL_GetOverlappedResultEx+0x45
03 00000000`58b1b950 000007fe`ff1ed0f9 rpcrt4!NMP_SyncSendRecv+0xc7
04 00000000`58b1b9c0 000007fe`ff1ed494 rpcrt4!OSF_CCONNECTION::TransSendReceive+0xd7
05 00000000`58b1ba20 000007fe`ff1ed38b rpcrt4!OSF_CCONNECTION::SendFragment+0xc4
06 00000000`58b1bb70 000007fe`ff1ecfbc rpcrt4!OSF_CCALL::SendNextFragment+0x22b
07 00000000`58b1bc20 000007fe`ff1ecc78 rpcrt4!OSF_CCALL::FastSendReceive+0xc9
08 00000000`58b1bd30 000007fe`ff1ecbad rpcrt4!OSF_CCALL::SendReceiveHelper+0x68
09 00000000`58b1bd60 000007fe`ff28fb67 rpcrt4!OSF_CCALL::SendReceive+0x4d
0a 00000000`58b1bdc0 000007fe`ff28fe01 rpcrt4!NdrpClientCall3+0x1c7
0b 00000000`58b1c010 000007fe`fdc6d84c rpcrt4!NdrClientCall3+0xdd
0c 00000000`58b1c390 000007fe`fdc6d61a advapi32!LsaICLookupSids+0x152
0d 00000000`58b1c470 000007fe`fdc6da0d advapi32!LsaLookupSids+0x70
0e 00000000`58b1c500 000007fe`fdc6dbaa advapi32!LookupAccountSidInternal+0xcd
0f 00000000`58b1c5e0 00000001`3fb57392 advapi32!LookupAccountSidW+0x32
10 00000000`58b1c630 00000001`3fb57786 store!XCRACKER::HrGetNT4CompatibleNameFromSid+0xa2
11 00000000`58b1c910 00000001`3fb5ebfd store!XCRACKER::HrGetNameFormatsFromBinarySid+0xe6
12 00000000`58b1c970 00000001`3fb5bce0 store!XFR::HrCrackNames+0xdd
13 00000000`58b1c9f0 00000001`3fb5d77c store!XCRACKSESS::HrFinish+0x40
14 00000000`58b1ca20 00000001`3f9e228e store!XNTSD::HrCrackNames+0xbc
15 00000000`58b1ca60 00000001`3f50388d store!EcConstructXMLForNTSD+0xee
16 00000000`58b1cc00 00000001`3f58140a store!MINIMSG::EcGetOnePropOrSize+0x1540
17 00000000`58b1cf60 00000001`3f505ad2 store!MINIMSG::EcGetPartialProp+0x1d4
18 00000000`58b1d030 00000001`3f5c54aa store!OMSG::EcGetProps+0xc20
19 00000000`58b1d400 00000001`3f525f03 store!OMSG::EcUpdateMsgFolder+0xa32
1a 00000000`58b1d5e0 00000001`3f571fd5 store!OMSG::EcSaveChangesReally+0x1392
1b 00000000`58b1db10 00000001`3f573e3b store!OMSG::EcSaveChanges2+0x17ca
1c 00000000`58b1ddc0 00000001`3f584956 store!EcSaveOneMessage+0xc0
…
Nous voyons donc que nous sommes en attente d’une résolution de SID (ou identité de sécurité).
Une SID est un numéro dans l’active directory associé à un compte.
Le but pour Exchange était donc de vérifier de quel compte il s’agit.
Le processus utilisé par Netlogon pour vérification les SIDs
Dans notre cas, notre serveur Exchange hébergeait les boîtes de différentes forêts (c’est ce qu’on appelle des boîtes aux lettres liées ou linked mailbox dans Exchange).
La résolution de SID qui prenait du temps se produisait pour les SID d’une forêt particulière : pour des comptes qui n’étaient pas dans la forêt du serveur Exchange mais dans une autre forêt avec laquelle nous avions une trust.
Netlogon est le service Windows qui s’occupe entre autre de la résolution de SID (mais il a d’autres rôle également comme l’authentification NTLM).
La vérification de résolution de SID demandée par Exchange suit ce chemin :
La requête est reçue par le processus Netlogon qui tourne sur le serveur Exchange puis qui cherche à résoudre la SID sur ce DC le plus proche.
Si le SID qu’il faut résoudre appartient à une autre forêt avec laquelle la forêt a un trust, une requête va être formulée vers le DC de l’autre forêt et le résultat final va être envoyé à ce DC qui va relayer l’information au serveur Exchange qui a effectué cette requête.
La cause et résolution de notre problème
Dans notre cas, le DC du domaine du serveur Exchange ne pouvait pas contacter le DC de l’autre forêt pour résoudre la SID.
Les DCs de l’autre forêt avaient été mis à jour vers Windows 2008. Les ports pour le fonctionnement de netlogon sous Windows 2008 sont différents de Windows 2003 : https://support.microsoft.com/kb/832017
La cause du problème était que les firewalls n’avait pas été modifiés pour ouvrir ces ports.
Donc le DC du domaine Exchange attendait longtemps pour finalement envoyer un retour négatif au serveur Exchange qu’il n’arrivait pas à résoudre la SID dans le temps indiqué.
La résolution de SID qui ne fonctionne pas n’est donc pas totalement bloquante pour Exchange mais elle ralentit les performances car on est obligé d’attendre le temps maximum pour la réponse (timeout).
Pour résoudre ce problème nous avons ouvert les ports sur le firewall.
Identifier facilement si vous êtes dans ce cas
Sur le DC utilisé par votre serveur Exchange, vous trouverez certainement des événements indiquant que le trust ne fonctionne pas vers la forêt qui pose problème.
Recherchez particulièrement les événements 5783 dans les journaux d’annuaire du domaine contrôleur.
Vous pouvez reproduire ce problème de résolution de SID en utilisant cette commande powershell sur le serveur Exchange :
Get-mailbox aliasdelamailboxdansledomainequialeprobleme –verbose
Vous devez également avoir des remontées utilisateurs particulières pour la forêt qui pose problème : ces personnes ne peuvent pas du tout se connecter sur Exchange alors que les autres forêts ont le souci de connections de façon aléatoire lorsque l’on atteint la valeur 500 au niveau du compteur.
Prévenir ce type de situation
Si vous êtes dans une configuration ou des trusts avec de multiples forêts dont les utilisateurs accèdent à votre serveur Exchange, vous devez être plus vigilent :vous êtes dans une configuration plus à risque car dès qu’une seule trust échoue, tout le monde est impacté.
Le service Netlogon utilise 2 threads pour traiter les requêtes (un peu de la même façon qu’Exchange en utilise 500 pour les requêtes RPC) et donc lorsque 2 requêtes pour un SID ne peuvent pas être résolues, cela bloque les requêtes suivantes jusqu’à obtenir un timeout.
Il est possible d’augmenter le nombre de threads utilisé par netlogon en utilisant la clé MaxConcurrentAPI à 5 : voir l’article https://support.microsoft.com/kb/326040.Cela nécessite un reboot.
Les services Netlogon existant à la fois sur le serveur Exchange et le DC dans le domaine auquel Exchange soumet la requête, cette action doit être effectuée sur le serveur Exchange et les DCs utilisés par Exchange.
Il y a également des compteurs Netlogon: https://support.microsoft.com/kb/928576
Pour identifier ces valeurs de compteurs anormales ou les échecs des trust, vous pouvez utiliser les managements de SCOM.