Liveness Probe

The web server answers the Kubernetes liveness and startup probes, /healthz/, in its ASGI application, before Django and its middleware, so that a busy pod, or one whose Redis or database stalls, is not restarted. The readiness probe, /readiness/, still goes through Django.

An ASGI application that answers the liveness probe, /healthz/, before Django does.

Kubernetes restarts a pod whose liveness probe fails. When /healthz/ was a Django view, its answer depended on the whole middleware stack, which reads the session from Redis and the user from the database. A pod under load, or one whose Redis or database stalled, then failed its liveness probe and was restarted, which moved its load onto the other pods. Liveness should only say whether the server process is alive and its event loop is running, which this application answers without a thread, a query or a cache lookup. Whether the pod can serve requests is the readiness probe’s question, /readiness/, which still goes through Django, so a pod that can’t is taken out of the service rather than restarted.

See helm/charts/smarter/templates/deployment-app.yaml.

smarter.lib.django.healthz.HEALTHZ_PATHS = frozenset({'/healthz', '/healthz/'})

The liveness probe’s paths.

class smarter.lib.django.healthz.HealthzASGIMiddleware(app)[source]

Bases: object

Answer GET and HEAD requests for /healthz/ with 200 OK, and pass every other request to the app.

Parameters:

app (Callable[[HTTPScope | WebSocketScope | LifespanScope, Callable[[], Awaitable[HTTPRequestEvent | HTTPDisconnectEvent | WebSocketConnectEvent | WebSocketReceiveEvent | WebSocketDisconnectEvent | LifespanStartupEvent | LifespanShutdownEvent]], Callable[[HTTPResponseStartEvent | HTTPResponseBodyEvent | HTTPResponseTrailersEvent | HTTPServerPushEvent | HTTPDisconnectEvent | WebSocketAcceptEvent | WebSocketSendEvent | WebSocketResponseStartEvent | WebSocketResponseBodyEvent | WebSocketCloseEvent | LifespanStartupCompleteEvent | LifespanStartupFailedEvent | LifespanShutdownCompleteEvent | LifespanShutdownFailedEvent], Awaitable[None]]], Awaitable[None]]) – The ASGI application to wrap, e.g. Django’s.

Example:

application = HealthzASGIMiddleware(get_asgi_application())
__init__(app)[source]