Configure Connection, TLS, and Observability
Tune the gRPC connection, enable TLS/mTLS and auth tokens, and wire up health checks and Micrometer metrics.
Every KubeMQ Spring Boot setting is bound under the kubemq.* prefix from KubeMQProperties and resolved at startup by the auto-configuration. This guide walks the connection settings you will tune most often — broker address and client identity, gRPC timeouts and keep-alive, TLS/mTLS, auth tokens, per-environment profiles, and the health, metrics, and tracing surfaces — using the exact property names and defaults the starter ships with.
All snippets assume the starter is on the classpath:
dependencies {
implementation("io.kubemq:kubemq-spring-boot-starter:1.0.0")
}And a broker to connect to — the gRPC API listens on 50000, the shared HTTP/REST and dashboard endpoints on 9090:
docker run -d \ --name kubemq \ -p 50000:50000 \ -p 9090:9090 \ -e KUBEMQ_TOKEN=YOUR_LICENSE_KEY \ europe-docker.pkg.dev/kubemq/images/kubemq:nextPrerequisites
kubemq-spring-boot-starteron the classpath, in a Spring Boot 3.2.0+ application (see Getting Started with Spring Boot)- The broker above running and reachable
spring-boot-starter-actuatorand a Micrometer registry (for examplemicrometer-registry-prometheus) added if you use the Health or Metrics & Tracing sections below
Connection Basics
The four top-level properties establish which broker the application talks to and who it is. kubemq.enabled is the master switch for the entire auto-configuration — set it to false to disable KubeMQ wiring without removing the dependency (useful for tests or environments where the broker is absent).
kubemq:
enabled: true # master switch; default true
address: localhost:50000 # broker gRPC address, host:port
client-id: my-service # sent with every request; empty = SDK generates a UUID
auth-token: ${KUBEMQ_AUTH_TOKEN:} # JWT/OIDC token; never hardcodeThe defaults from KubeMQProperties are address: localhost:50000, an empty client-id (the SDK generates a UUID per process), and an empty auth-token. Externalize the address with a placeholder so the same artifact runs against any broker, exactly as the connection-auth-token example does:
spring:
application:
name: kubemq-example-connection-auth-token
main:
web-application-type: none
kubemq:
# Broker address (override with KUBEMQ_ADDRESS env var)
address: ${KUBEMQ_ADDRESS:localhost:50000}
# Unique client identifier for this example
client-id: spring-connection-auth-token
# WARNING: Never commit auth tokens to source control. Use environment variables only.
auth-token: ${KUBEMQ_AUTH_TOKEN:}Give every service a stable, descriptive client-id. It shows up in broker-side dashboards and connection metadata, which makes diagnosing "who is connected" far easier than reading randomly generated UUIDs.
Connection Tuning
The kubemq.connection.* block (bound to KubeMQProperties.Connection) controls the gRPC channel itself: the request timeout, the maximum inbound message size, and keep-alive ping behaviour. The defaults are tuned for typical workloads.
kubemq:
connection:
timeout: 30s # default 30s — per-request gRPC deadline
max-receive-size: 100MB # default 100MB — max inbound message size
keep-alive:
time: 30s # default 30s — interval between keep-alive pings
timeout: 10s # default 10s — wait for a ping ack before failingProp
Type
Durations accept Spring's ISO-style suffixes (30s, 2m, 500ms) and DataSize accepts 100MB, 512KB, and similar. Raise max-receive-size if you publish payloads larger than 100 MB; shorten keep-alive.time if you sit behind a proxy that aggressively closes idle connections.
TLS and mTLS
TLS is configured under kubemq.tls.* (bound to KubeMQProperties.Tls) and is disabled by default. There are two postures:
- One-way (server) TLS — the client verifies the broker's certificate against a CA bundle. Set
enabled: trueandca-cert-file(pluscert-fileif your broker requires the client to present one). - Mutual TLS (mTLS) — both sides authenticate. Provide
cert-fileandkey-filefor the client identity, andca-cert-fileto verify the broker.
kubemq:
address: ${KUBEMQ_ADDRESS:localhost:50000}
client-id: spring-connection-tls
tls:
enabled: true
cert-file: ${KUBEMQ_TLS_CERT:/path/to/client.crt}
ca-cert-file: ${KUBEMQ_TLS_CA_CERT:/path/to/ca.crt}
# Ensure the broker certificate SAN matches the hostname in kubemq.address.kubemq:
address: ${KUBEMQ_ADDRESS:localhost:50000}
client-id: spring-connection-mtls
tls:
enabled: true
cert-file: ${KUBEMQ_TLS_CERT:/path/to/client.crt}
key-file: ${KUBEMQ_TLS_KEY:/path/to/client.key}
ca-cert-file: ${KUBEMQ_TLS_CA_CERT:/path/to/ca.crt}
# Ensure the broker certificate SAN matches the hostname in kubemq.address.Prop
Type
The broker certificate's SAN must match the hostname in kubemq.address, and hostname verification should never be disabled in production. Keep certificate and key paths out of source control — point them at mounted secrets or environment-resolved paths.
Auth Tokens
kubemq.auth-token carries a JWT or OIDC token that the broker validates on connect. It is sent with every request alongside the client-id. Because it is a credential, resolve it from the environment and never write the literal value into a committed file:
kubemq:
address: ${KUBEMQ_ADDRESS:localhost:50000}
client-id: my-service
auth-token: ${KUBEMQ_AUTH_TOKEN:}export KUBEMQ_AUTH_TOKEN="$(cat /var/run/secrets/kubemq/token)"
java -jar my-service.jarAn empty auth-token (the default) means the application connects without presenting a token — appropriate only when the broker does not enforce authentication.
Profile-Based Configuration
Use Spring profiles to keep per-environment settings in application-{profile}.yml. The autoconfigure-profiles example ships a base file plus dev, staging, and prod overlays. The base file selects the active profile and holds shared defaults:
spring:
profiles:
active: ${SPRING_PROFILES_ACTIVE:dev}
kubemq:
address: ${KUBEMQ_ADDRESS:localhost:50000}
client-id: spring-autoconfigure-profilesEach overlay layers only what changes for that environment:
kubemq:
address: ${KUBEMQ_ADDRESS:localhost:50000}
client-id: spring-profiles-dev
logging:
level:
io.kubemq: DEBUGkubemq:
address: staging-broker:50000
client-id: spring-profiles-stagingkubemq:
address: ${KUBEMQ_ADDRESS:prod-broker:50000}
client-id: spring-profiles-prod
tls:
# Set paths via env in production — never commit key material or PEM files.
enabled: ${KUBEMQ_TLS_ENABLED:true}
ca-cert-file: ${KUBEMQ_TLS_CA_CERT:}
cert-file: ${KUBEMQ_TLS_CERT:}
key-file: ${KUBEMQ_TLS_KEY:}Activate a profile with --spring.profiles.active=prod or the SPRING_PROFILES_ACTIVE environment variable.
Health
The starter contributes two Actuator surfaces, both backed by pings to all three KubeMQ SDK clients (PubSubClient, QueuesClient, CQClient). They are configured under kubemq.health.* (bound to KubeMQProperties.Health).
kubemq:
health:
enabled: true # default true
timeout: 5s # default 5s — per-ping deadline
cache-duration: 15s # default 15s — reuse the last result within this window
management:
endpoints:
web:
exposure:
include: health,info
endpoint:
health:
show-details: when-authorizedKubeMQHealthIndicator rolls up into the standard Spring Boot /actuator/health endpoint: UP with host and version details when every client responds to a ping, DOWN with the failing exception type otherwise. Results are cached for cache-duration so frequent probes do not flood the broker, and each ping is bounded by timeout.
The dedicated KubeMQEndpoint exposes /actuator/kubemq, which probes the three clients individually and reports a per-client breakdown:
{
"status": "connected",
"clients": {
"pubsub": { "status": "connected", "host": "kubemq-host", "version": "2.x.x", "errorType": null },
"queues": { "status": "connected", "host": "kubemq-host", "version": "2.x.x", "errorType": null },
"cq": { "status": "connected", "host": "kubemq-host", "version": "2.x.x", "errorType": null }
}
}The top-level status is connected only when all three clients are connected; if any client fails its ping it is marked disconnected (with the exception type in errorType) and the aggregate becomes degraded. Expose the endpoint by adding kubemq to the management exposure list:
management:
endpoints:
web:
exposure:
include: health,info,kubemqshow-details: always and exposing Actuator endpoints without authentication are for local development only. In production use when-authorized with Spring Security, or bind the management port to loopback.
Metrics & Tracing
The starter integrates with Micrometer in two complementary ways, controlled by separate switches.
kubemq.metrics.* (bound to KubeMQProperties.Metrics) governs the kubemq.connection.state gauge, registered by KubeMQMetricsAutoConfiguration when kubemq.metrics.enabled is true (the default). The gauge probes all three clients and caches the result for scrape-interval so scraping does not overload the broker — it reads 1.0 when connected and 0.0 when not.
kubemq.template.observation-enabled (bound to KubeMQProperties.Template, default true) drives Micrometer Observation instrumentation on the KubeMQTemplate send path and the listener receive path, producing timers, counters, and — when a tracer is present — distributed traces.
management:
endpoints:
web:
exposure:
include: health,prometheus,metrics
metrics:
export:
prometheus:
enabled: true
kubemq:
address: ${KUBEMQ_ADDRESS:localhost:50000}
client-id: spring-observability-micrometer
metrics:
enabled: true # default true — registers kubemq.connection.state gauge
scrape-interval: 30s # default 30s — gauge probe caching window
template:
observation-enabled: true # default true — send/receive Observation instrumentationAdd the Actuator and a registry to the project to scrape these meters:
dependencies {
implementation("io.kubemq:kubemq-spring-boot-starter:1.0.0")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("io.micrometer:micrometer-registry-prometheus")
}Prop
Type
Kotlin DSL Alternative
The Kotlin starter (kubemq-spring-boot-starter-kotlin) adds a type-safe configuration DSL. Expose a KubeMQConfigurerDsl bean built with the kubemq { } builder to set the address, identity, TLS, and connection tuning programmatically instead of in YAML:
import io.kubemq.spring.boot.kotlin.KubeMQConfigurerDsl
import io.kubemq.spring.boot.kotlin.kubemq
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import java.time.Duration
@Configuration
class KubeMQConfig {
@Bean
fun kubemqConfigurer(): KubeMQConfigurerDsl = kubemq {
address = "broker.example.com:50000"
clientId = "my-service"
tls {
enabled = true
certFile = "/certs/client.pem"
keyFile = "/certs/client-key.pem"
caCertFile = "/certs/ca.pem"
}
connection {
timeout = Duration.ofSeconds(15)
}
}
}The tls { } and connection { } blocks map one-to-one onto the same KubeMQProperties.Tls and KubeMQProperties.Connection fields shown above. For Kotlin services that drive suspend-function listeners, kubemq.kotlin.dispatcher selects the coroutine dispatcher (default, io, or unconfined; default default):
kubemq:
kotlin:
dispatcher: io # default | io | unconfinedGraceful Shutdown & Reconnection
kubemq.listener.shutdown-timeout (default 30s, on KubeMQProperties.Listener) bounds how long the listener infrastructure waits for in-flight work to finish during shutdown. Combined with Spring's lifecycle hooks (SmartLifecycle, @PreDestroy), it lets a service drain cleanly on SIGTERM:
kubemq:
listener:
shutdown-timeout: 30s # default 30s — wait for in-flight work before stoppingReconnection is handled automatically by the underlying SDK clients. To observe or react to connection state changes, register a ConnectionStateListener on an injected client:
@PostConstruct
public void registerConnectionStateListener() {
pubSubClient.addConnectionStateListener(new ConnectionStateListener() {
@Override public void onConnected() { log.info("Connection established"); }
@Override public void onDisconnected() { log.warn("Connection lost — reconnecting automatically"); }
@Override public void onReconnecting(int attempt) { log.info("Reconnection attempt #{}", attempt); }
@Override public void onReconnected() { log.info("Reconnection successful — subscriptions recovered"); }
@Override public void onClosed() { log.info("Connection closed"); }
});
}When a listener throws, provide a KubeMQErrorHandler bean to centralize error handling instead of relying on the default logging:
@Configuration
public class ReconnectionErrorConfig {
@Bean
public KubeMQErrorHandler kubemqErrorHandler() {
return new KubeMQErrorHandler() {
@Override
public void handleError(Throwable t) {
log.error("KubeMQ listener error [{}]: {}", t.getClass().getSimpleName(), t.getMessage());
}
};
}
}Full Property Reference
This guide covers the connection, security, and observability properties you tune most often. For the complete list of kubemq.* properties — including the per-pattern listener settings (kubemq.listener.queues.*, commands, queries) — see the Configuration Reference; for the KubeMQTemplate API and annotations, see the API Reference.
Related
- Getting Started — add the starter and send your first message
- Concepts — how auto-configuration wires the SDK clients
- Configuration Reference — every configuration property
- API Reference — the template API and listener annotations
Was this page helpful?