Both agent loops made their first request the instant the service started, and the service is installed start=auto - so a patch reboot put the whole fleet on the wire together, twice per machine (a telemetry report and a command poll). The existing jitterseconds does not help: it spreads the gap between runs, not first contact. Measured on a 700-endpoint burst: simultaneous arrival drove TLS handshakes to 1482ms worst case and pinned CPU at 305% while the database sat idle at 3 active queries. Spreading the same arrivals over 30s cut worst-case handshake to 63.7ms with no server-side change. The server was never the constraint; simultaneity was. Raising the SQLAlchemy pool was tried and rejected - it moved the queue from SQLAlchemy into MySQL without adding throughput. StartupJitter is shared by both workers so the clamp and the randomisation cannot drift apart between them. Randomised in milliseconds rather than whole seconds because a 30s window at second granularity re-clumps a large fleet into 30 buckets of simultaneous arrivals - the same pile-up in miniature. Clamped to 300s and warned about when out of range: the command channel is how an operator would correct a bad value, so an unbounded delay would remove the means of recovery. The cost is up to startupjitterseconds of extra latency before a rebooted endpoint picks up a queued command, on top of a reboot the machine was already unreachable for. The once-only console switch bypasses the delay entirely, so smoke tests stay instant. Agent 1.12.0. Minor because the appsettings schema gains a key; packages without it fall back to the AgentConfig default. The shipped installer template in siteagent.py carries the new key, so the containers need rolling before newly built packages pick it up.
39 KiB
39 KiB