Configure Upstream Health Checks
Health checking determines whether upstream services are healthy or unhealthy based on their responsiveness. APISIX excludes unhealthy nodes while at least one healthy node remains. If all nodes are unhealthy, APISIX falls back to the original node set so that a reachable node can still serve traffic.
There are two general approaches to health check:
- Active checks: APISIX proactively and periodically sends requests to upstream services and determines the health of those based on the responses to these requests.
- Passive checks: APISIX determines the health of upstream services based on how they respond to client requests, without proactively probing.
This guide will show you how to configure both active and passive health checks for your upstream services.
Prerequisite(s)
- Install Docker.
- Install cURL to send requests to the services for validation.
- Follow the Getting Started tutorial to start a new APISIX instance in Docker or on Kubernetes.
- If you use the Admin API examples and authentication is enabled, export an admin-role key as
ADMIN_API_KEY. Configure the key underdeployment.admin.admin_key. The Docker quickstart disables authentication for local evaluation; keep it enabled in production.
Start Sample Upstream Services
Start two NGINX instances as sample upstream services in the same Docker network as APISIX:
DOCKER_NETWORK=apisix-quickstart-net
docker run -d -p 8080:80 --network=${DOCKER_NETWORK} --name nginx1 nginx
docker run -d -p 8081:80 --network=${DOCKER_NETWORK} --name nginx2 nginx
Verify both NGINX instances are running:
for port in 8080 8081; do
curl -s "http://127.0.0.1:$port" | grep -q "Welcome to nginx" &&
echo "NGINX welcome page available on port $port."
done
You should see the following response:
NGINX welcome page available on port 8080.
NGINX welcome page available on port 8081.
Configure Active Health Checks
Active checks determine the health of upstream services by periodically sending requests, or probes, to the services and seeing how they respond.
The examples below show how to:
- send a custom method and body in an active probe
- detect changes in upstream status with active checks
- observe how APISIX forwards requests when all upstream statuses are unhealthy
Active HTTP and HTTPS checks use GET with an empty body by default. Set http_method to any supported HTTP method and use http_req_body when the health endpoint expects a request payload. A nonempty body adds the corresponding Content-Length header automatically.
Send a POST Health Check
Configure the first sample NGINX service with a health endpoint that accepts only POST and logs the probe method, path, and content length:
docker exec nginx1 /bin/sh -c 'cat > /etc/nginx/conf.d/default.conf <<"EOF"
log_format health_probe "$request_method $uri $content_length";
server {
listen 80;
access_log /tmp/health-probe.log health_probe;
location = /health {
if ($request_method != POST) {
return 405;
}
return 200 "healthy\n";
}
location = /404 {
return 404;
}
location / {
return 200 "Welcome to nginx!\n";
}
}
EOF
nginx -s reload'
Create a route with a POST active check and a JSON body:
curl "http://127.0.0.1:9180/apisix/admin/routes/post-health-check" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"uri": "/post-health-check",
"upstream": {
"type": "roundrobin",
"nodes": {
"nginx1:80": 1
},
"checks": {
"active": {
"type": "http",
"http_method": "POST",
"http_path": "/health",
"http_req_body": "{\"status\":\"check\"}",
"req_headers": [
"Content-Type: application/json"
],
"healthy": {
"interval": 2,
"successes": 1
},
"unhealthy": {
"interval": 1,
"http_failures": 1
}
}
}
}
}'
Send a request through the route to start its health checker, wait for a probe, and inspect the NGINX access log:
curl -i "http://127.0.0.1:9080/post-health-check"
sleep 2
docker exec nginx1 /bin/sh -c "grep 'POST /health' /tmp/health-probe.log | tail -n 1"
The route request should return 200 OK. The log should confirm that the active probe used POST and sent the 18-byte body:
POST /health 18
Example: Status Change in Upstream Services
The following example demonstrates how APISIX active health checks respond in situations where healthy upstream services have become: partially unavailable, all unavailable, and all recovered.
Create a route to the two services and configure active health checks that run every 2 seconds:
- Admin API
- ADC
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "example-hc-route",
"uri":"/",
"upstream": {
"type":"roundrobin",
"nodes": {
"nginx1:80": 1,
"nginx2:80": 1
},
"checks": {
"active": {
"type": "http",
"http_path": "/",
"healthy": {
"interval": 2,
"successes": 1
},
"unhealthy": {
"interval": 1,
"timeouts": 3
}
}
}
}
}'
❶ type: the type of active health checks.
❷ http_path: the HTTP request path to actively probe.
❸ healthy.interval: the time interval in seconds for periodically checking healthy nodes.
❹ healthy.successes: the success count threshold for ruling if an upstream node is considered healthy.