mirror of
https://github.com/outbackdingo/patroni.git
synced 2026-08-25 14:53:37 +00:00
Add read-only and read-write API routes (#1038)
Patroni is great behind a load balancer like HAProxy. API routes are handy to direct the traffic to a valid node depending on its role. We could have one route for writes directed to the primary node and one route for reads directed to the replicas. In a two nodes setup, when we lose a node, there's one host left: the primary. Then, the read traffic will be dropped, even if the primary can handle it. This commit adds read-only and read-write routes. Read-only route enables reads on the primary. Read-write route is an alias for '/master', '/primary' or '/leader' route.
This commit is contained in:
committed by
Alexander Kukushkin
parent
51b02e65a5
commit
0e0b364302
+9
-6
@@ -85,19 +85,22 @@ class RestApiHandler(BaseHTTPRequestHandler):
|
||||
patroni = self.server.patroni
|
||||
cluster = patroni.dcs.cluster
|
||||
|
||||
if not cluster and patroni.ha.is_paused():
|
||||
primary_status_code = 200 if response['role'] == 'master' else 503
|
||||
else:
|
||||
primary_status_code = 200 if patroni.ha.is_leader() else 503
|
||||
|
||||
replica_status_code = 200 if not patroni.noloadbalance and response.get('role') == 'replica' else 503
|
||||
status_code = 503
|
||||
|
||||
if patroni.ha.is_standby_cluster() and ('standby_leader' in path or 'standby-leader' in path):
|
||||
status_code = 200 if patroni.ha.is_leader() else 503
|
||||
elif 'master' in path or 'leader' in path or 'primary' in path:
|
||||
# Round-robing across all masters in pause mode if DCS is not accessible
|
||||
if not cluster and patroni.ha.is_paused():
|
||||
status_code = 200 if response['role'] == 'master' else 503
|
||||
else:
|
||||
status_code = 200 if patroni.ha.is_leader() else 503
|
||||
elif 'master' in path or 'leader' in path or 'primary' in path or 'read-write' in path:
|
||||
status_code = primary_status_code
|
||||
elif 'replica' in path:
|
||||
status_code = replica_status_code
|
||||
elif 'read-only' in path:
|
||||
status_code = 200 if primary_status_code == 200 else replica_status_code
|
||||
elif cluster: # dcs is available
|
||||
is_synchronous = cluster.is_synchronous_mode() and cluster.sync \
|
||||
and cluster.sync.sync_standby == patroni.postgresql.name
|
||||
|
||||
Reference in New Issue
Block a user