From 15d32be7d41bf535f7c83a261a1ae5a70bdab33f Mon Sep 17 00:00:00 2001 From: MatMaul Date: Tue, 9 May 2023 17:43:57 +0000 Subject: deploy: 64a11fb61fac47f652858d7e2109d077874135e0 --- latest/workers.html | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 3 deletions(-) (limited to 'latest/workers.html') diff --git a/latest/workers.html b/latest/workers.html index 20e89c55e7..39584d0da6 100644 --- a/latest/workers.html +++ b/latest/workers.html @@ -76,7 +76,7 @@ @@ -435,14 +435,73 @@ may wish to run multiple groups of workers handling different endpoints so that load balancing can be done in different ways.

For /sync and /initialSync requests it will be more efficient if all requests from a particular user are routed to a single instance. This can -be done e.g. in nginx via IP hash $http_x_forwarded_for; or via -hash $http_authorization consistent; which contains the users access token.

+be done in reverse proxy by extracting username part from the users access token.

Admins may additionally wish to separate out /sync requests that have a since query parameter from those that don't (and /initialSync), as requests that don't are known as "initial sync" that happens when a user logs in on a new device and can be very resource intensive, so isolating these requests will stop them from interfering with other users ongoing syncs.

+

Example nginx configuration snippet that handles the cases above. This is just an +example and probably requires some changes according to your particular setup:

+
# Choose sync worker based on the existence of "since" query parameter
+map $arg_since $sync {
+    default synapse_sync;
+    '' synapse_initial_sync;
+}
+
+# Extract username from access token passed as URL parameter
+map $arg_access_token $accesstoken_from_urlparam {
+    # Defaults to just passing back the whole accesstoken
+    default   $arg_access_token;
+    # Try to extract username part from accesstoken URL parameter
+    "~syt_(?<username>.*?)_.*"           $username;
+}
+
+# Extract username from access token passed as authorization header
+map $http_authorization $mxid_localpart {
+    # Defaults to just passing back the whole accesstoken
+    default                              $http_authorization;
+    # Try to extract username part from accesstoken header
+    "~Bearer syt_(?<username>.*?)_.*"    $username;
+    # if no authorization-header exist, try mapper for URL parameter "access_token"
+    ""                                   $accesstoken_from_urlparam;
+}
+
+upstream synapse_initial_sync {
+    # Use the username mapper result for hash key
+    hash $mxid_localpart consistent;
+    server 127.0.0.1:8016;
+    server 127.0.0.1:8036;
+}
+
+upstream synapse_sync {
+    # Use the username mapper result for hash key
+    hash $mxid_localpart consistent;
+    server 127.0.0.1:8013;
+    server 127.0.0.1:8037;
+    server 127.0.0.1:8038;
+    server 127.0.0.1:8039;
+}
+
+# Sync initial/normal
+location ~ ^/_matrix/client/(r0|v3)/sync$ {
+	proxy_pass http://$sync;
+}
+
+# Normal sync
+location ~ ^/_matrix/client/(api/v1|r0|v3)/events$ {
+	proxy_pass http://synapse_sync;
+}
+
+# Initial_sync
+location ~ ^/_matrix/client/(api/v1|r0|v3)/initialSync$ {
+	proxy_pass http://synapse_initial_sync;
+}
+location ~ ^/_matrix/client/(api/v1|r0|v3)/rooms/[^/]+/initialSync$ {
+	proxy_pass http://synapse_initial_sync;
+}
+

Federation and client requests can be balanced via simple round robin.

The inbound federation transaction request ^/_matrix/federation/v1/send/ should be balanced by source IP so that transactions from the same remote server -- cgit 1.5.1