Was sind ATQ Threads und wenn ja, warum?

Wer sich schon einmal mit den Performance Countern von Active Directory beschäftigt hat, kann vielleicht zum Schluss kommen, dass es davon zu viele gibt um den Überblick zu behalten.

Die Sache wird verschlimmert, wenn eine Abkürzung nicht bekannt ist, oder sich nicht auf den ersten Blick erschließt. „DRA“ ist auf der TechNet zum Beispiel noch zu finden als "Directory Replication Agent", aber für "ATQ" findet man die meisten Treffer beim Internet Information Server (IIS). Nur zwei der Counter werden im Branch Office Deployment Guide besprochen.

Es ist nun so, dass die "Async Thread Queue" von IIS und LSASS verwendet wird für die generelle Thread-Queue, die Sockets-Anfragen bedient. In LSASS bedient diese Queue vor allem die Anfragen über LDAP und Kerberos.

In der englischen Version von Windows kann man die Counter schön nach Namen sortieren und dort sind die Einträge (mit kurzer Erklärung):

ATQ Estimated Queue Delay – wie lange wartet ein Request in der Queue

ATQ Outstanding Queued Requests – Anzahl der Requests in der Queue

ATQ Request Latency – Wie lange dauert die Bearbeitung eines Requests

ATQ Threads LDAP – Threads benutzt durch LDAP Server

ATQ Threads Other – Threads benutzt durch andere Server, vor allem KDC

ATQ Threads Total – Alle Threads welche aktuell vorhanden sind

Ich erkläre die Counter in sinnvoller Reihenfolge:

ATQ Threads Total:

Die Threads werden in den unteren Performance Countern gezählt, der letzte Eintrag hat alle aktuell existierenden Threads, beschäftigt oder nicht. Das Maximum für die Threads ist festgelegt mit MaxPoolThreads als Multiplikator für die Anzahl der logischen CPU Cores.

Die Anzahl der Threads muss nicht dem Maximum entsprechen, die Anzahl kann dynamisch wachsen und schrumpfen.

ATQ Threads LDAP:

Hier wird die Anzahl der Threads gezählt, die aktuell mit LDAP-Anfragen beschäftigt sind. Wenn das messbar ist, sollten diese Threads aufwändige LDAP Queries bearbeiten, also mit Hilfe der CPUs, Speicher und Platten-IO an der Bearbeitung der Anfrage arbeiten ohne externe Abhängigkeiten.

Ihr solltet also normalerweise erwarten, dass der Server hohe CPU-Auslastung oder Disk IO zeigt, wenn oft viele der Threads aktiv sind.

Wir haben zwei Fälle gefunden, bei denen externe Abhängigkeiten dafür sorgen, dass die Threads sehr lange brauchen ohne extreme Auslastung des Servers:

  1. Über LDAP Pings hat Rol_Muc schon einen Blogeintrag geschrieben, es gibt dazu auch KB Artikel 2668820.
  2. Wenn der Server LDAP über SSL unterstützt und der Benutzer ein Zertifikat zur Anmeldung schickt, kann der Server eine lange Zeit damit verbringen, das Zertifikat zu überprüfen.

#2 ist vor allem problematisch, wenn der DC darin beschränkt ist, das Zertifikat zu überprüfen, weil er die CRL nicht erreichen kann. Wenn Ihr nicht genau wisst ob der DC LDAPS unterstützt hilft ein Blick auf den Counter „LDAP New SSL Connections/sec“. Wenn es da Messwerte gibt, wird sich das CAPI-Logging lohnen.

Als Lösungsansatz für die Client-Zertifikate bietet sich an:

-      Andere Zertifikate verwenden, die keine externe Verifizierung erfordern.

-      Dem DC externe CRL-Überprüfungen erlauben auf dem Proxyserver. Es kann sein, dass Eure Sicherheitsabteilung dabei einen leichten Krisenanfall bekommt.

-      Im SCHANNEL Handshake kann der Server dem Client Hinweise geben, ein Benutzerzertifikat zu schicken durch passende Root Zertifikate dem der Server traut. Mit dem Registry Eintrag SendTrustedIssuerList=0 könnt Ihr die Hinweise deaktivieren.

-      Den Time-Out für CRL-Überprüfungen stark herunter setzen, siehe ChainUrlRetrievalTimeoutMilliseconds und ChainRevAccumulativeUrlRetrievalTimeoutMilliseconds auf der TechNet. Je nach Performance der internen CRL-Server kann man herunter gehen auf 200 und 500 Millisekunden.

ATQ Threads Other:

Auch hier kann es Anfragen mit externen Abhängigkeiten geben. Relativ klar ist der Fall eines Key Distribution Centers (KDC), der ein TGT ausstellen soll und selber kein Global Catalog ist. Die Liste der Universal und Globalen Gruppen muss da herkommen. Nun versucht LSASS immer einen GC zu haben und beschwert sich auch prominent im Eventlog, wenn das nicht klappt. Das ist also meist kein Problem.

Zeitgleich mit der Anfrage zu LDAPS haben wir einen zweiten Kunden mit starken Spitzen für diesen Counter, Other statt LDAP. Solche Anfragen kommen interessanterweise oft in Gruppen. Die Spikes waren sporadisch
und haben immer nur einige Minuten gedauert. Als ich einmal mit dem Kunden am Telefon war, ging „es“ gerade wieder los und wir haben über den Task Manager einen Memory Dump erzeugt.

In dem Dump habe ich dann (gesegnet mit Windows Source Zugriff) einige Threads gefunden, die an Kerberos Service Ticket Requests gearbeitet haben, und die aktuelle Aufgabe war ein RPC Call an einen anderen Domain Controller.

Ein Eintrag auf dem Callstack brachte dann Licht hinter die Sache, und die Parameter des Aufrufs haben dann dazu gepasst:

Der Kunde hatte Kerberos Forest Search Order (KFSO) aktiviert. Damit soll ein KDC einen SPN, den er im eigenen Forest nicht findet, in einem anderen Forest suchen und den TGS Request in den passenden Forest
umleiten.

In einer Analyse für die TechNet hatten wir vor einiger Zeit potentielle Engpässe beim Einsatz von KFSO untersucht. Und dabei war uns aufgegangen, dass der schlechteste Fall für den Domain Controller eintritt, wenn der Name nirgends zu finden ist. Er klappert alle Forests ab und geht leer aus.

Wir haben aufgrund der Analyse den Tipp gegeben, die Nutzung der ATQ Threads im Auge zu behalten, wenn man KFSO einsetzt. Das nenne ich mal einen Volltreffer.

Die SPNs im Fall des Kunden waren falsch zusammengesetzt. Der Kunde hat das korrigiert und dann gab es auch die Tickets. Der eigentliche Zugriff war nur verlangsamt, da der Client einen Fallback auf NTLM gemacht hat.

ATQ Queues und Latency:

Die ersten drei Performance Counter geben dem Admin Statistiken zur Bearbeitung der Anfragen. Nachdem die Anfragestruktur des Threadpools sehr unterschiedlich ist, könnt Ihr meist keine Schlüsse aus diesen Statistiken ziehen. Eine aufwändige LDAP Anfrage kann sich über Minuten ziehen, eine erfolgreiche Kerberos-Anfrage ist in wenigen Millisekunden erledigt.

Sie sind also eigentlich nur Indikatoren, dass der Pool stark beschäftigt ist, wenn die Werte nicht auf oder nahe 0 sind. Ein Grund für einen Alarm sind wartende Anfragen, angezeigt in "ATQ Outstanding Queued Requests". Es sollten immer Threads verfügbar sein.

Wenn die Rate der problematischen Anfragen recht hoch ist relativ zu den anderen Anfragen, dann können diese Counter einen Hinweis geben auf die Rate und durchschnittliche Laufzeit.

Und was ist mit anderen Thread Pools?

LSASS hat neben einzelnen Worker-Threads wie zum Beispiel für IPSec-Handshakes vor allem noch einen Pool RPC Server Threads für die verschiedenen RPC Server im Prozess. Diese RPC Server alle zu beschreiben ist Material für eine ganze Serie Blogs.

Der eine oder andere mag sich nun denken „so genau wollte ich das gar nicht wissen“. Ich finde aber, die interessanten Fakten stecken im Detail.

Schöne Grüße, Euer

Herbert