Building a Java Microservice with Spring Boot and Consul

Service discovery removes hard-coded IP addresses from internal calls. A registry records healthy instances, lets clients select one, and keeps traffic moving during restarts or rolling deployments. Consul provides those catalogue and health functions in a tool that developers can also run locally.

Creating a Java microservice with Spring Boot and Consul for service discovery follows a compact pattern: register the application, publish a safe health signal, and resolve peers through logical service names. Business code then depends on capabilities such as inventory or payments rather than locations that change during scaling.

Australian engineering teams in Sydney, Melbourne and Brisbane commonly combine container platforms with hybrid cloud. A lightweight discovery layer suits teams that need reliable internal routing but are not ready to operate a complete service mesh, and it leaves room to move workloads later.

Why Consul belongs in the architecture

Consul maintains a service catalogue and coordinates health checks across nodes. Spring Cloud Consul links that catalogue to Spring’s registration lifecycle: an instance appears after startup and is withdrawn during a controlled shutdown. Several healthy instances may share one service name, so clients receive a current list rather than a fixed address.

Discovery finds producers; it does not replace authentication, define contracts or enforce resilience policy. An API gateway can still handle edge traffic, while domain services use logical names internally. This separation helps Australian merchants isolate payment orchestration across card, bank-transfer and buy-now-pay-later channels without coupling checkout code to payment infrastructure.

Prepare the Spring Boot project

Add spring-cloud-starter-consul-discovery, spring-cloud-starter-loadbalancer and spring-boot-starter-actuator to the build. The first integrates registration, the second resolves service names, and Actuator supplies health information. Pin compatible Spring Boot and Spring Cloud release trains through the Spring Cloud BOM rather than mixing versions.

Keep service identity and runtime location separate in application.yml:

spring:
  application:
    name: orders-service
  cloud:
    consul:
      host: ${CONSUL_HOST:localhost}
      port: ${CONSUL_PORT:8500}
      discovery:
        instance-id: ${spring.application.name}-${random.value}
        health-check-path: /actuator/health
        health-check-interval: 10s
management:
  endpoints:
    web:
      exposure:
        include: health,info

Run a Consul development agent locally, open its web interface at localhost:8500, and start the application. Environment-specific hosts, ports and credentials should come from configuration rather than source control.

Register and refresh service instances

On startup, the starter registers the service name, host and port, then renews its lease with the local Consul agent. If heartbeats stop or the health check fails, the catalogue stops offering that instance to new callers. This detects failures earlier than leaving clients to discover stale endpoints through failed requests.

Give every instance a unique identifier and publish only useful metadata, such as version, environment and Australian region. Never place customer records, tokens or payment data in tags. During a rolling deployment, keep old and new healthy instances overlapping briefly so callers can transition without an outage.

Call discovered services safely

A load-balanced client resolves a logical URI through Consul and selects an available instance:

@Bean
@LoadBalanced
RestClient.Builder balancedBuilder(RestClient.Builder builder) {
    return builder;
}

Give outbound calls explicit connect and read timeouts. Retry only idempotent operations: a payment capture needs an idempotency key and must not be replayed after an ambiguous response. Use circuit breakers for repeatedly failing dependencies. Australian on-call rotations covering Perth and eastern-state business hours still need the same predictable client behaviour.

Health checks and operational visibility

Configure Consul to probe /actuator/health, expose only required actuator endpoints, and restrict them to internal traffic. Separate liveness from readiness: a running process may still be unable to accept work because a dependency is unavailable. The readiness result should drive both orchestration and catalogue health.

Metrics, traces and logs should use the same service identifier as the catalogue. A practical monitoring dashboard shows how Prometheus and Grafana can present request rates, errors and latency. Correlate those signals with Consul membership changes, including discovery failures that occur while the monitored service itself remains healthy.

Under the Australian Privacy Act 1988 and Australian Privacy Principles, where applicable, keep personal information out of tags and diagnostic messages. The Notifiable Data Breaches scheme makes prompt containment and accurate incident records essential. Health responses should communicate status without revealing sensitive records.

Compare deployment models

Choose the Consul topology around the platform already in use. Virtual machines may use a Consul server cluster and local agents; Kubernetes commonly uses agents, sidecars or controller-based registration. Managed container services reduce node administration, but governance for instances, health checks and permissions remains necessary.

Australian latency and resilience needs vary. AWS availability zones in Sydney and Melbourne can host geographically separated workloads, while any single-region design still needs a recovery path. Compare failure domains, operating effort and agent cost instead of assuming the most distributed topology is automatically best.

Deployment model Discovery mechanics Operational effort Suitable for
Consul on virtual machines Agents advertise healthy instances Medium Existing estates needing explicit control
Consul with Kubernetes Agents, sidecars or controllers reconcile entries Medium to high Teams running dynamic container workloads
Platform service discovery The platform handles registration and health Low Small teams prioritising speed

Production readiness recommendations

Make the operational contract explicit and test it under realistic failures:

Together, these controls keep discovery dependable, protect operational data and provide Australian engineering teams with a clear path from local development to production operation.