RTFM · Healthchecks
lb.saphira.tcp: can we open a connection?
Knock on the door. If something is listening on the port, the kernel completes the TCP handshake and the check passes. It is the default health check of the industry, and it is important to know exactly how little it promises.
What it proves
Layer 4: a TCP three-way handshake completes against real:$4. A process is listening, the firewall lets us through, and the queue accepted one more connection. It does not prove the application behind the port works; a half-configured database that instantly resets queries will pass this check all day. When your promise is "the service works", climb to a Layer 7 check.
How it works
The check delegates to the probe engine: saphira-lb-probe tcp. Addresses resolve through getaddrinfo, so $3 may be an IPv4 or IPv6 literal or a name; the connection uses the first family that succeeds.
lb_probe tcp --host "$LB_REAL" --port "${LB_RPORT:-$LB_VPORT}" --timeout "$LB_TIMEOUT"
Configuration
| Variable | Default | Meaning |
|---|---|---|
| LB_SAPHIRA_TIMEOUT | 3 | Connect timeout in seconds |
| (target port) | $4, else $2 | The real server port from the caller ABI; the virtual port is the fallback |
Wiring it up
# /etc/ha.d/ldirectord.cf
virtual = 203.0.113.10:443
protocol = tcp
scheduler = wlc
real = 192.168.20.11:443 gate 1
checktype = external
checkcommand = "/var/lib/lb/saphira/lb.saphira.tcp"
# haproxy.cfg
global
external-check
backend app_pool
mode tcp
option external-check
external-check command "/var/lib/lb/saphira/lb.saphira.tcp"
server app1 192.168.20.11:443 check inter 5s fall 3 rise 2
HAProxy's built-in plain TCP check is the same verdict with fewer moving parts; use the external script when you want the identical toolchain (and identical timeout semantics) across every service, or when ldirectord is the director.
Run it by hand
/var/lib/lb/saphira/lb.saphira.tcp 21 443 192.168.20.11 443
echo $?
# 0 = handshake completed
# 1 = refused (nothing listening / firewall reject) or timeout (silent drop)
refused vs timeout is diagnostic gold: refused means the packet arrived and something said "no"; timeout usually means a firewall dropped it on the way. Both are unhealthy; only one means you are talking to the right machine.
Failure modes
- Connection refused: nothing bound on that port, or a REJECT rule answered
- Timeout: packet silently dropped: wrong network, missing firewall rule, or dead host
- exit 2: no real server address was passed ($3 empty): a caller-ABI bug, not a server problem
Did we miss something?
If this page left something unanswered, found an error, or there is another subject you would like documented, tell us. Saphira’s documentation grows from real problems people need to solve.
Send feedback or request a new section →
Prefer not to do it yourself?
Everything needed to do the work yourself is documented here and remains free; we charge for human time, not for withholding knowledge. Sometimes the missing resource is simply time. The same people who build Saphira can provide paid professional help with implementation, migration, troubleshooting and administration.