How discovery works
How Axelix Master learns which Spring Boot instances exist and keeps their state up to date, either by finding them in Kubernetes on its own or by letting each instance register itself.
Master can only show and manage an instance it knows about. It learns about instances in one of two ways: Master finds them itself (auto-discovery), or the instance announces itself to Master (self-registration).
Two ways to be discovered
┌─ Kubernetes cluster ─────────────────────────────┐
│ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ orders-service │ │ billing-service │ │
│ └────────▲─────────┘ └─────────▲────────┘ │
│ │ │ │ ┌────────────────────┐
│ └────────────┬───────────┘ │ │ inventory-service │
│ │ │ │ (VM, Docker, ...) │
│ │ auto-discovery: │ └─────────┬──────────┘
│ │ Master finds the pods │ │
│ │ and polls them │ │ self-registration:
│ ┌───────┴───────┐ │ │ the service registers
│ │ Axelix Master │◀────────────────┼───────────────┘ once, then heartbeats
│ └───────────────┘ │
│ │
└──────────────────────────────────────────────────┘Every service in these diagrams is a Spring Boot application built with the Axelix build plugin and running the Axelix starter.
| Auto-discovery | Self-registration | |
|---|---|---|
| Who starts the call | Master calls the service | The service calls Master |
| Where it works | Kubernetes only | Anywhere the service can reach Master |
| How to turn it on | axelix.master.discovery.auto.enabled on Master | axelix.sbs.discovery.self-registration on the service |
When Master runs in the same Kubernetes cluster as your services, auto-discovery needs no setup on the service side. Self-registration covers everything else, such as plain VMs, Docker Compose, or a network that Master cannot scan.
Both ways work at the same time
The choice is made per service, not for the whole fleet. One Master can auto-discover the services in its Kubernetes cluster and, at the same time, accept self-registration from the services that run elsewhere. For example, three applications on VMs can self-register while every service in the cluster is auto-discovered.
Full state once, then small updates
Starting with Axelix 1.3.0, both ways follow the same idea. Master receives the full state of an instance only once:
in the registration request with self-registration, or in the first axelix-metadata call with auto-discovery. After
that, the instance sends only small, frequent updates: a heartbeat with self-registration, or an answer to
axelix-ping with auto-discovery.
Each update has two jobs. First, it tells Master that the instance is still alive. Second, it carries the little that changes over time: the instance's health, its heap usage, and its transaction statistics, so a new problematic transaction shows up in Master without a new registration. The diagrams below show this behavior.
Before 1.3.0, Master received the full state every time: on every auto-discovery scan, and with every self-registration heartbeat.
Auto-discovery
Axelix Master Kubernetes API orders-service
│ │ │
│ which pods are there? │ │
│─────────────────────────────▶│ │
│◀─────────────────────────────│ │
│ │
│ first scan: axelix-metadata │
│────────────────────────────────────────────────────────────▶│
│◀──────────────────────────────────────── full registration ─│
│ │
│ every next scan (each minute by default): axelix-ping │
│────────────────────────────────────────────────────────────▶│
│◀─────────────────────────────── health, heap, transactions ─│The first call returns the full registration: build coordinates, versions, and the insights Axelix collects. After it, the instance appears in Master. Master signs its calls with its own JWT, so the signing key on Master and on the service must match.
Each scan replaces the whole list of auto-discovered instances. As a result, a pod that Kubernetes no longer reports disappears at the next scan. A pod that Master cannot reach drops out too, and comes back on the next scan that reaches it.
Instances with a starter older than 1.3.0 have no axelix-ping, so Master reads the full axelix-metadata from them
on every scan.
Self-registration
inventory-service Axelix Master
│ │
│ on startup: register (full description, │
│ actuator URL, instance name) │
│──────────────────────────────────────────────────▶│ the instance appears
│ │
│ every 15 s: heartbeat (health, heap, │
│ transactions) │
│──────────────────────────────────────────────────▶│
│──────────────────────────────────────────────────▶│
│ │
│ heartbeat after Master lost the instance │
│──────────────────────────────────────────────────▶│
│◀─────────────────────────────── unknown instance ─│
│ register again │
│──────────────────────────────────────────────────▶│
│ │
╳ the service stops, heartbeats stop │
│ removed after 45 sWith a starter older than 1.3.0, every heartbeat is a full registration.
Master can lose an instance when it restarts with an empty database, or when it has removed the instance after missed heartbeats. In both cases the next heartbeat makes the service register again, so the whole fleet reappears within one heartbeat interval. The registration and the heartbeats are signed with the shared JWT signing key, and Master rejects them when the keys differ.
What Master needs in both cases
Discovery only tells Master that an instance exists. Every UI page, MCP tool, and action (such as changing a log level) is still a call from Master to the service. So Master must be able to reach the service's actuator endpoints over HTTP, whichever way the service was discovered. If the application protects its actuator endpoints with its own security, see Troubleshooting for how to let Master's calls through.