Health checks
Akka Management supports two kinds of health checks:
- Readiness checks: should the application receive external traffic, for example waiting for the following to complete
- Joining a Cluster
- Establishing a connection to a database or queuing system
- Liveness checks: should the application be left running
Readiness checks can be used to decide if a load balancer should route traffic whereas liveness checks can be used in environments which can restart a hung process.
This matches Kubernetes Health checks. See Kubernetes Liveness and Readiness Probes: How to Avoid Shooting Yourself in the Foot for a good overview of how to use readiness and liveness probes.
Akka Management provides endpoints for readiness and liveness checks out of the box at /ready
and /alive
(paths can be configured, see below). Configuration settings are used to add checks to back those endpoints. When called, each endpoint will only report to be healthy when all the configured health checks (for the particular kind, readiness or liveness) are succeeding.
Defining a Health Check
A health check must extend Function0[Future[Boolean]]
Supplier[CompletionStage[Boolean]]
and have either a no argument constructor or a constructor with a single argument of type ActorSystem.
A general type is used rather than a specific interface so that modules such as akka-cluster
can provide health checks without depending on Akka management.
Having access to the ActorSystem
allows loading of any external resource via an Akka extension e.g. Cluster
or a database connection. Health checks return a Future
CompletionStage
so that an asynchronous action can be taken.
- Scala
-
source
class ExampleHealthCheck(system: ActorSystem) extends (() => Future[Boolean]) { override def apply(): Future[Boolean] = { Future.successful(true) } }
- Java
-
source
public class BasicHealthCheck implements Supplier<CompletionStage<Boolean>> { public BasicHealthCheck(ActorSystem system) { } @Override public CompletionStage<Boolean> get() { return CompletableFuture.completedFuture(true); } }
Typically the ActorSystem
is used to get a hold of any state needed to execute the check e.g.
- Scala
-
source
class ClusterHealthCheck(system: ActorSystem) extends (() => Future[Boolean]) { private val cluster = Cluster(system) override def apply(): Future[Boolean] = { Future.successful(cluster.selfMember.status == MemberStatus.Up) } }
- Java
-
source
class ClusterCheck implements Supplier<CompletionStage<Boolean>> { private final Cluster cluster; public ClusterCheck(ActorSystem system) { cluster = Cluster.get(system); } @Override public CompletionStage<Boolean> get() { return CompletableFuture.completedFuture(cluster.selfMember().status() == MemberStatus.up()); } }
Note that Cluster Http Management includes a health check for cluster membership that is configurable for which states are considered healthy.
Any of the above health checks can be configured as either readiness checks or liveness checks.
Configuring health checks
Health checks are picked up from configuration. Modules are expected to provide health checks e.g. Cluster Http Management provides a cluster readiness check.
Application specific health checks can be added a name = <fully qualified class name>
to akka.management.health-checks.readiness-checks
or akka.management.health-checks.liveness-checks
e.g.
sourceakka.management {
health-checks {
readiness-checks {
# Default health check for cluster. Overwrite the setting to replace it with
# your implementation or set it to "" (empty string) to disable this check.
cluster-membership = "akka.management.cluster.scaladsl.ClusterMembershipCheck"
}
}
}
Hosting health checks as an Akka Management Route
Health checks can be hosted via the Akka management HTTP server. The akka.management.HealthCheckRoutes
is enabled by default as an Akka management route provider.
By default all readiness checks are hosted on /ready
and liveness checks are hosted on /alive
. If all of the checks for an endpoint succeed a 200
is returned, if any fail or return false
a 500
is returned. The paths are configurable via akka.management.health-checks.readiness-path
and akka.management.health-checks.liveness-path
e.g.
sourceakka.management.health-checks {
readiness-path = "health/ready"
liveness-path = "health/alive"
}
The akka.management.HealthCheckRoutes
can be disabled with the following configuration but that also means that the configured readiness-checks
and liveness-checks
will not be used.
akka.management.http.routes {
health-checks = ""
}