Skip to main content
Version: 3.10.x

a7-recipe-health-check

Overview

Health checks monitor backend nodes and remove unhealthy nodes from load balancing. In current API7 EE usage, define the upstream and health check configuration on a service, then attach routes to that service with service_id.

API7 EE supports:

  • Active checks: gateway probes each node.
  • Passive checks: gateway observes real traffic responses.

Use both for production services that need automatic failure detection and recovery.

Health Check Configuration Reference

Active Health Check

FieldDescription
upstream.checks.active.typehttp, https, or tcp
upstream.checks.active.http_pathHTTP path to probe
upstream.checks.active.healthy.successesConsecutive successes to mark healthy
upstream.checks.active.unhealthy.http_failuresConsecutive HTTP failures to mark unhealthy
upstream.checks.active.unhealthy.timeoutsConsecutive timeouts to mark unhealthy

Passive Health Check

FieldDescription
upstream.checks.passive.typehttp, https, or tcp
upstream.checks.passive.unhealthy.http_statusesStatus codes treated as unhealthy
upstream.checks.passive.unhealthy.http_failuresConsecutive failures to mark unhealthy
upstream.checks.passive.healthy.successesConsecutive successes to mark healthy

Step-by-Step: Configure Health Checks

1. Create a service with active HTTP health checks

a7 service create --gateway-group default -f - <<'EOF'
{
"id": "backend-service",
"name": "backend-service",
"upstream": {
"type": "roundrobin",
"nodes": [
{"host": "backend-1", "port": 8080, "weight": 1},
{"host": "backend-2", "port": 8080, "weight": 1},
{"host": "backend-3", "port": 8080, "weight": 1}
],
"checks": {
"active": {
"type": "http",
"http_path": "/health",
"healthy": {
"interval": 5,
"successes": 2,
"http_statuses": [200]
},
"unhealthy": {
"interval": 3,
"http_failures": 3,
"http_statuses": [500, 502, 503]
}
}
}
}
}
EOF

2. Create a route that uses the service

a7 route create --gateway-group default -f - <<'EOF'
{
"id": "api",
"name": "api",
"paths": ["/api/*"],
"service_id": "backend-service"
}
EOF

Health checks run only for services that are referenced by at least one route. Verify route wiring with:

a7 service get backend-service --gateway-group default --output json
a7 route list --gateway-group default --service-id backend-service --output json

3. Passive health check

a7 service create --gateway-group default -f - <<'EOF'
{
"id": "backend-passive-service",
"name": "backend-passive-service",
"upstream": {
"type": "roundrobin",
"nodes": [
{"host": "backend-1", "port": 8080, "weight": 1},
{"host": "backend-2", "port": 8080, "weight": 1}
],
"checks": {
"passive": {
"type": "http",
"unhealthy": {
"http_failures": 3,
"http_statuses": [500, 502, 503],
"timeouts": 3
},
"healthy": {
"successes": 5,
"http_statuses": [200, 201, 202, 203, 204]
}
}
}
}
}
EOF

Attach the passive-check service to a route before sending traffic through it:

a7 route create --gateway-group default -f - <<'EOF'
{
"id": "api-passive",
"name": "api-passive",
"paths": ["/api-passive/*"],
"service_id": "backend-passive-service"
}
EOF

Passive-only checks cannot recover a node that receives no traffic. Combine passive checks with active checks for full recovery coverage.

4. Combined active + passive checks

a7 service create --gateway-group default -f - <<'EOF'
{
"id": "production-backend-service",
"name": "production-backend-service",
"upstream": {
"type": "roundrobin",
"nodes": [
{"host": "backend-1", "port": 8080, "weight": 1},
{"host": "backend-2", "port": 8080, "weight": 1},
{"host": "backend-3", "port": 8080, "weight": 1}
],
"checks": {
"active": {
"type": "http",
"http_path": "/health",
"healthy": {
"interval": 5,
"successes": 2,
"http_statuses": [200]
},
"unhealthy": {
"interval": 2,
"http_failures": 3,
"timeouts": 2,
"http_statuses": [500, 502, 503, 504]
}
},
"passive": {
"type": "http",
"unhealthy": {
"http_failures": 3,
"http_statuses": [500, 502, 503],
"timeouts": 3
},
"healthy": {
"successes": 3,
"http_statuses": [200, 201, 204]
}
}
}
}
}
EOF

Attach or update a route to reference the combined-check service:

a7 route create --gateway-group default -f - <<'EOF'
{
"id": "api-production",
"name": "api-production",
"paths": ["/api-production/*"],
"service_id": "production-backend-service"
}
EOF

Config Sync

version: "1"
services:
- id: production-backend-service
name: production-backend-service
upstream:
type: roundrobin
nodes:
- host: backend-1
port: 8080
weight: 1
- host: backend-2
port: 8080
weight: 1
- host: backend-3
port: 8080
weight: 1
checks:
active:
type: http
http_path: /health
healthy:
interval: 5
successes: 2
http_statuses: [200]
unhealthy:
interval: 2
http_failures: 3
timeouts: 2
http_statuses: [500, 502, 503, 504]
passive:
type: http
unhealthy:
http_failures: 3
http_statuses: [500, 502, 503]
timeouts: 3
healthy:
successes: 3
http_statuses: [200, 201, 204]
routes:
- id: api
name: api
paths:
- /api/*
service_id: production-backend-service

Troubleshooting

SymptomCauseFix
Health checks not runningRoute does not reference the serviceVerify with a7 route list --gateway-group default --service-id <service>
All nodes marked unhealthyHealth endpoint returns unexpected statusVerify http_statuses includes the response code
Node not recoveringPassive-only checks have no traffic to observeAdd active health checks
Probe hits wrong endpointDefault http_path is /Set http_path to the real health endpoint
TLS probe failsCertificate verification failsSet https_verify_certificate: false or fix certificates
No standalone health commandCurrent a7 does not expose upstream health statusVerify config with a7 service get --gateway-group default and use gateway observability
Command failed with 401Invalid tokenRefresh your token using a7 context create
Service not foundDifferent gateway groupEnsure --gateway-group matches where the service was created

This page is generated from a7-recipe-health-check/SKILL.md in the api7/a7 repository. Browse all skills on the AI Agent Skills page.