crossbario / crossbar

Crossbar.io - WAMP application router
https://crossbar.io/
Other
2.05k stars 274 forks source link

Resource limit controls and meta API #2017

Open oberstet opened 2 years ago

oberstet commented 2 years ago

The following discusses a number of aspects and describes a design for an experimental prototype implementation of router-based resource / bandwidth limit controls for WAMP.

The goal of resource limit controls is to divide limited WAMP routing resources in a multi-user/role/realm in a user defined and controlled way.

Routing Resources

The computing resources consumed by Crossbar.io for core WAMP routing is primarily CPU, memory and network scaled by the following factors:

Static

Dynamic

Dynamic WAMP Control

Dynamic WAMP App Data

oberstet commented 2 years ago

Resource Limits

Scope

Resource limits can be applied at different resource scopes:

  1. realm: resource limits apply to the sum/set of all sessions on the given realm
  2. realm-authrole: resource limits apply to the sum/set of all sessions of the given authrole on the respective realm
  3. realm-authrole-authid: resource limits apply to the sum/set of all sessions of the given authid under the respective authrole and realm

Dimensions

Resource limits can be applied along different resource dimensions:

  1. number of sessions
  2. number of registrations
  3. number of subscriptions
  4. bandwidth in message traffic volume per second
    • guaranteed (per-session in kbps) - this is promised to be available continously and long-term
    • burst (per-session in kbps) - this may or may not be available for short-term bursts (needs to recover to be available again)
    • total (in kbps over all sessions in a scope) - hard limit beyond which resources will be denied or actively killed

A resource limits configuration stanza may therefor look like:

{
    "sessions": 100,
    "subscriptions": 500,
    "registrations": 500,
    "bandwidth": {
        "guaranteed": 200,
        "burst": 200,
        "total": 1000
    }
}

Here, "bandwidth" is following this rational / is to be understood in this way: "bandwidth" is based on sum of the uplink and downlink volume Bytes in terms of serialized WAMP messages at the WAMP transport level (e.g. before WebSocket or RawSocket framing and TLS encryption, but after CBOR or other serialization)


FIXME: Discuss multi-node cluster setups where the scope may apply at a per worker, per node or per cluster level.

oberstet commented 2 years ago

Node Configuration

The following is an example of a (incomplete) node configuration that illustrates the application of resource limits at different scopes (realm, role and authid), and using only one resource control dimension "sessions":

{
    "version": 2,
    "workers": [
        {
            "type": "router",
            "realms": [
                {
                    "name": "realm1",
                    "roles": [
                        {
                            "name": "anonymous",
                            "permissions": [],
                            "limits": {
                                "sessions": 1200
                            }
                        },
                        {
                            "name": "frontend",
                            "permissions": [],
                            "limits": {
                                "sessions": 800
                            }
                        }
                    ],
                    "limits": {
                        "sessions": 2000
                    }
                }
            ],
            "transports": [
                {
                    "type": "websocket",
                    "endpoint": {
                       "type": "tcp",
                       "port": 8080
                    },
                    "auth": {
                        "cookie": {},
                        "anonymous": {
                            "type": "static",
                            "realm": "realm1",
                            "role": "anonymous",
                            "authid": "${CBTID}",
                            "limits": {
                                "sessions": 10
                            }
                        },
                        "wampcra": {
                            "type": "static",
                            "users": {
                                "alice": {
                                    "secret": "${ALICE_SECRET}",
                                    "realm": "realm1",
                                    "role": "frontend",
                                    "limits": {
                                        "sessions": 600
                                    }
                                },
                                "bob": {
                                    "secret": "${BOB_SECRET}",
                                    "realm": "realm1",
                                    "role": "frontend",
                                    "limits": {
                                        "sessions": 400
                                    }
                                }
                            }
                        }
                    }
                }
            ]
        }
    ]
}

Above configuration would lead to the following behavior:

oberstet commented 2 years ago

Resource Management

Resource Policing

FIXME: discuss "resource policing" vs "resource shaping" as it applies for WAMP (background here and here)

Meta API

with arguments

and (in case of warnings)

One WAMP meta procedure registered:

One user WAMP procedure called:

Policy Enforcement

Implementation

oberstet commented 2 years ago

Dynamic Authenticators

Consider

{
    "pubkey": "...",
    "realm": "realm1",
    "authid": "alice",
    "role": "frontend",
    "extra": {"message": "Welcome, Alice!"},
    "cache": true,
    "limits": {
        "sessions": 400
    }
}

here

https://github.com/crossbario/crossbar-examples/blob/852680eee646cf5479bff18ec727a8026d9bdcda/authentication/cryptosign/dynamic/authenticator.py#L70

This would apply the authid-level ("alice") resource limits, that is "at most 400 sessions of alice" are accepted.

One question that needs to be answered when coding is how to combine the authid-level limits with any limits defined at the authrole and realm level.

oberstet commented 2 years ago

Resource management database tables

cfxdb.realmstore.ResourceLimit

cfxdb.realmstore.ResourceReservation

cfxdb.realmstore.ResourceReservationClaim

cfxdb.realmstore.ResourceUsage