Implementing Health Checks
1. Configuring Passive Health Checks
Passive health checks in Nginx are configured using the health_check directive within the upstream block. These checks are performed by Nginx based on the responses it receives from backend servers.
| Directive | Description | Values |
|---|---|---|
| health_check | Enables passive health checks for the upstream group | on or off |
| interval | Time between health checks | Time value (e.g., 5s, 1m) |
| fails | Number of failed requests before marking server as unhealthy | Integer (default: 1) |
| passes | Number of successful requests before marking server as healthy | Integer (default: 1) |
| uri | URI to request for health check | String (default: /) |
| method | HTTP method to use for health check | GET, HEAD, or POST |
| headers | Custom headers to include in health check requests | Key-value pairs (e.g., Host: example.com) |
Example: Basic Passive Health Check Configuration
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
health_check on;
interval 30s;
fails 2;
passes 1;
}
Example: Custom URI and Method
upstream api {
server 10.0.0.5:80;
server 10.0.0.6:80;
health_check on;
uri /health;
method GET;
interval 15s;
fails 3;
passes 2;
}
Note: Passive health checks do not actively probe servers but rely on response codes and timeouts to determine server status.
2. Setting Fail Timeout
| Directive | Values | Description |
|---|---|---|
| proxy_next_upstream_timeout | time |
Sets the time during which a request can be passed to the next server |
| proxy_next_upstream_tries | number |
Limits the number of attempts to pass a request to the next server |
| keepalive_timeout | time |
Configures the timeout for keep-alive connections |
Example: Configuring proxy_next_upstream_timeout
location /api/ {
proxy_pass http://backend;
proxy_next_upstream_timeout 5s;
proxy_next_upstream_tries 3;
}
Note: The
proxy_next_upstream_timeout directive controls how long Nginx waits before trying the next server in a failover setup.
3. Using Active Health Checks
Active health checks in Nginx are used to monitor the status of backend servers by sending periodic requests to them. These checks help ensure that traffic is only routed to healthy servers.
| Directive | Description | Default | Example |
|---|---|---|---|
| health_check | Enables active health checks for a server or upstream block. | Off | health_check; |
| health_check_path | Specifies the path to send health check requests to. | / | health_check_path /health; |
| health_check_interval | Defines the interval between health checks in seconds. | 5s | health_check_interval 10s; |
| health_check_timeout | Defines the timeout for health check requests in seconds. | 1s | health_check_timeout 2s; |
| health_check_failures | Number of consecutive failures before marking a server as unhealthy. | 1 | health_check_failures 3; |
| health_check_passes | Number of consecutive successes before marking a server as healthy. | 1 | health_check_passes 2; |
Example: Basic Active Health Check Configuration
upstream backend {
server 192.168.1.10:80;
server 192.168.1.11:80;
health_check;
health_check_path /health;
health_check_interval 10s;
health_check_timeout 2s;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
Note: The
health_check directive requires the nginx-module-http-healthcheck module to be compiled into Nginx. If not available, you may need to use a third-party module or alternative monitoring solutions.
4. Configuring Health Check Interval
| Directive | Values | Description |
|---|---|---|
| health_check_interval | 5s |
Interval between health checks for upstream servers |
| health_check_timeout | 1s |
Timeout for each individual health check request |
| health_check_requests | 2 |
Number of successful checks before marking server as healthy |
| health_check_fails | 1 |
Number of failed checks before marking server as unhealthy |
Example: Setting Health Check Interval
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
health_check_interval 30s;
health_check_timeout 5s;
health_check_requests 2;
health_check_fails 1;
}
5. Setting Health Check URI
| Directive | Values | Description |
|---|---|---|
| health_check | uri=/health |
Defines the URI used for health checks |
| health_check | uri=/status |
Alternative URI for health check endpoint |
Example: Basic Health Check URI Configuration
location / {
proxy_pass http://backend;
health_check uri=/health;
}
Example: Custom Health Check URI with Parameters
location / {
proxy_pass http://backend;
health_check uri=/api/health?format=json;
}
6. Using Match Block for Conditions
| Field | Description | Example |
|---|---|---|
| match | Defines a condition to match against request attributes | match $request_method = POST |
| variable | Variable to test in the match block | match $uri ~ /api/ |
| operator | Operator to use for matching (e.g., =, ~, !~) | match $args !~ debug |
Example: Match block for URI pattern
location / {
match $uri ~ /api/ {
proxy_pass http://backend;
}
}
Example: Match block with method and header
location / {
match $request_method = POST {
match $http_content_type ~ application/json {
proxy_pass http://json_backend;
}
}
}
Note: The
match block is a feature introduced in Nginx 1.25.0 and allows for more flexible conditional logic than traditional if blocks.
7. Configuring Health Check Port
| Directive | Values | Description |
|---|---|---|
| health_check | port=8080 |
Defines the port to use for health checks |
| health_check | port=8081 |
Alternative port for health checks |
8. Understanding Health Check States
| State | Description | Notes |
|---|---|---|
| healthy | Backend server is responding correctly to health checks. | Server is considered ready to receive traffic. |
| unhealthy | Backend server is not responding or returning errors. | Server is excluded from load balancing until it becomes healthy again. |
| draining | Server is marked for removal but still handles ongoing requests. | Used during graceful shutdown or maintenance mode. |
| initializing | Server has started but has not yet passed its first health check. | Temporary state before server is considered fully operational. |
Example: Health Check Configuration
upstream backend {
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
location / {
proxy_pass http://backend;
proxy_next_upstream error timeout invalid_header non_idempotent;
}
}
9. Monitoring Upstream Health Status
| Directive | Description | Default | Notes |
|---|---|---|---|
| health_check | Enables health checks for upstream servers | Off | Must be used within an upstream block |
| health_check_interval | Interval between health checks | 5s | Can be set to 0 to disable periodic checks |
| health_check_timeout | Timeout for each health check request | 1s | Must be less than health_check_interval |
| health_check_failures | Number of failures before marking server as unhealthy | 1 | Set to 0 to disable automatic marking |
| health_check_passes | Number of passes before marking server as healthy | 1 | Useful for avoiding flapping states |
| health_check_status | HTTP status codes to consider as healthy | 200-399 | Can be overridden to specific codes |
Example: Basic Health Check Configuration
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
health_check;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
Example: Advanced Health Check with Custom Parameters
upstream api_backend {
server 10.0.0.1:3000 weight=3;
server 10.0.0.2:3000 weight=2;
health_check interval=10s fails=3 passes=2 timeout=2s status=200-399;
}
server {
listen 80;
location /api/ {
proxy_pass http://api_backend;
}
}
Note: Health checks are performed using a GET request to
/ by default. You can customize the path and method using additional directives like health_check_path or health_check_method.
Warning: Setting
health_check_interval too low can cause excessive load on upstream servers. Ensure that the interval is sufficient to avoid overwhelming the backend.
10. Implementing Custom Health Endpoints
| Directive | Description | Example |
|---|---|---|
| location | Defines the URI for the health check endpoint | /health |
| access_log | Disables access logging for the health endpoint | off |
| return | Specifies the HTTP status code to return | 200 |
Example: Health Check with Status File
location /health {
access_log off;
return 200 "Service is healthy";
}
Note: The health endpoint should return a 200 status code when the service is healthy and a non-200 status code when it's not.
11. Configuring Health Check Passes
| Directive | Values | Description |
|---|---|---|
| health_check | on | off |
Enables or disables health checks for the upstream server group. |
| health_check_interval | time |
Sets the interval between health checks. Default is 5s. |
| health_check_timeout | time |
Sets the timeout for each health check request. Default is 1s. |
| health_check_passes | number |
Number of consecutive successful checks required to mark a server as healthy. Default is 1. |
| health_check_status | 200, 204, 301, 302 |
HTTP status codes that indicate a healthy server. |
Example: Basic Health Check Configuration
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
health_check;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
Example: Custom Health Check Passes
upstream api_backend {
server 10.0.0.1:3000;
server 10.0.0.2:3000;
health_check;
health_check_passes 3;
health_check_interval 10s;
health_check_timeout 2s;
}
12. Using Mandatory Health Checks
| Directive | Description | Values | Notes |
|---|---|---|---|
| health_check | Enables health checks for upstream servers | on | off |
Default: off |
| health_check_interval | Interval between health checks | Time value (e.g., 5s, 1m) |
Default: 5s |
| health_check_timeout | Timeout for health check requests | Time value (e.g., 1s, 30s) |
Default: 1s |
| health_check_pass | Pass to use for health checks | String | Optional, defaults to default |
| health_check_status | Status codes to consider as healthy | HTTP status codes (e.g., 200, 204) |
Default: 200, 204 |
| health_check_uri | URI to check for health status | Path (e.g., /health) |
Default: / |
| health_check_host | Host header to send with health check | String | Default: $host |
| health_check_port | Port to send health check requests to | Number (e.g., 80, 8080) |
Default: $server_port |
| health_check_http_version | HTTP version to use for health checks | 1.0 | 1.1 |
Default: 1.0 |
| health_check_healthy | Conditions to consider a server healthy | Count, time, or status | Default: 1 success |
| health_check_unhealthy | Conditions to consider a server unhealthy | Count, time, or status | Default: 1 failure |
Example: Basic Health Check Configuration
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
health_check;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
Example: Advanced Health Check with Custom URI and Timeout
upstream api {
server 10.0.0.1:3000;
server 10.0.0.2:3000;
health_check uri=/health timeout=5s interval=10s;
}
server {
listen 80;
location /api/ {
proxy_pass http://api;
}
}
Note: The
health_check directive is available starting from Nginx version 1.15.0.
Warning: If
health_check is enabled but no health_check_uri is specified, it will default to /, which may not be the correct endpoint for health checks.