ndg-example-app
Postgres, Redis, and NATS in one namespace on ndg-tenant-sfc. This page is served by one of two replicas, and which one you get changes as the Service load-balances. That matters for the last panel; see step 4.
What happens when you post
-
Postgres
INSERT INTO guestbook … RETURNING idsame on every replicaOne database, two replicas talking to it. The row is committed before the request returns, so every replica reads back an identical list.
-
Redis
INCRthe counter,SADDyour name same on every replicaAlso one server shared by both replicas.
SADDis a set, so posting twice under the same name adds nothing the second time — while the counter still goes up. -
NATS core publish to
…same on every replicaEach replica holds its own subscription, and core NATS delivers a copy to every subscriber. Both replicas see every message, so the live feeds match. Nothing is stored: this is fan-out, and a replica that was restarted missed everything published while it was gone.
-
JetStream stores the same message in
…on the hub differs per replicaBoth replicas bind the same durable pull consumer (
…), which is a work queue: the hub hands each message to exactly one of them, which acknowledges it. So each replica's durable feed holds only the subset it personally handled.
Postgres and Redis are shared state, and core NATS fans out to both replicas — those three look the same no matter who serves you. The durable feed is the one thing that is per-replica: it is an in-memory list of the messages this replica was handed by the shared consumer. Reload, land on the other replica, and you see the other half of the messages. Add them together and you get the messages in stream count, which is the hub's own total and is the same for everyone. Restarting a pod empties its durable feed but not the stream.
Postgres — CloudNativePG shared
…
Latest rows
Redis — redis-operator shared
…
Set members
NATS — leaf + JetStream
…
Live feed — core subscription all replicas
Durable feed — handled by this replica this replica only