Centrifugo Documentation

repository·master·Indexed 27 days ago

https://github.com/centrifugal/centrifugo

A real-time messaging server supporting scalable WebSocket and other protocol connections. This documentation covers internal implementations including a custom Gorilla WebSocket fork, PostgreSQL MapBroker migration conventions, proxy protocol transform rules, and detailed guides for benchmarking with k6, Kafka consumer testing, and local environment setup using Redis, Clickhouse, and NATS.

Tokens
8.6K
Snippets
21
Records
51
Agent score
94%

What's inside Centrifugo

  1. Overview of the internal WebSocket implementation

    master

    The project uses a custom fork of the Gorilla WebSocket library, specifically adapted for Centrifuge's requirements. Key differences from the original Gorilla implementation include:

    • Optimized Upgrades: Reduced allocations (from 9 down to 3) during the upgrade process.
    • HTTP/2 Support: Supports WebSocket over HTTP/2 (RFC 8441) on the server side.
    • Subprotocol Handling: The selected subprotocol is not stored internally; instead, it is returned during the Upgrade or Dial operations.
    • Client Changes: The Client no longer uses a custom Proxy.
    • Concurrency: Concurrent use detection is handled on a best-effort basis.
    • Handlers: It is not possible to set a custom CloseHandler.
    • Linting: Includes various lint fixes for the Centrifuge environment.
  2. Run Centrifugo benchmarking with k6

    master

    To benchmark Centrifugo using the provided k6 script, you must first run a Centrifugo instance with a specific configuration that enables JWT authentication and client-side subscriptions. The script connects to Centrifugo using a JWT per user, subscribes to the test channel, waits for a period, and then exits.

    Prerequisites:

    • k6 installed on your system.
    • A running Centrifugo instance configured with the settings below.
    • Ensure your system is tuned to handle high connection volumes.

    Steps:

    1. Start Centrifugo with the required configuration.
    2. Execute the benchmark script using k6.
    k6 run benchmark.js
  3. Perform manual MapBroker migrations

    master

    If you are not relying on EnsureSchema() for automatic upgrades, follow this manual path:

    1. Fresh install: Apply the initial schema using internal/pgmapbroker/internal/sql/schema_all.sql.
    2. Check current version: Run the following query to verify the current schema version:
      SELECT schema_version FROM cf_map_schema_version WHERE id = 1;
    3. Apply migrations: Execute migration files located in internal/pgmapbroker/internal/sql/migrations/ in sequential order.

    Note: Keeping EnsureSchema() enabled is safe; it acts as a no-op if the database version already matches the code version.

  4. Create a local Redis cluster for development or benchmarking

    master

    Use the create_cluster.sh script to spin up a local Redis cluster consisting of N nodes with M replicas each. This is intended for development and benchmarking purposes. The script will continue running the cluster nodes until it is interrupted.

    All cluster data is persisted to a local directory named cluster_data. By default, the Redis nodes are configured to run without RDB or AOF enabled (--save "" --appendonly no).

  5. Add a new MapBroker migration

    master

    To add a new migration to the MapBroker schema, follow this developer workflow:

    1. Increment the schemaVersion in internal/pgmapbroker/pgmapbroker.go.
    2. Create a new SQL migration file at internal/pgmapbroker/internal/sql/migrations/NNN.sql (where NNN is the sequence number). The SQL must be idempotent and target both the standard and binary prefixes.
    3. Add an entry to the schemaMigrations map in the code to embed the new file.
    4. Update the schema.sql template so that fresh installs receive the latest schema state.
    5. Run make pg-schemas to regenerate necessary files.

    Invariant: A fresh install via DDL must produce an identical schema to an upgrade performed via sequential migrations.

  6. Create local isolated Redis master instances

    master
    Use the start_instances.sh script to spin up a specified number of isolated Redis master instances for development or benchmarking purposes. Instances start from port 6000. By default, these instances run without RDB or AOF enabled (--save "" --appendonly no). The instances will continue running until the script is interrupted.
  7. Manage PostgreSQL MapBroker schema with EnsureSchema

    master

    The EnsureSchema() function automatically manages the PostgreSQL schema for MapBroker. It handles the creation of both JSONB and BYTEA schema variants in a single call.

    Automatic Handling:

    • New tables (CREATE TABLE IF NOT EXISTS)
    • New indexes (CREATE INDEX IF NOT EXISTS)
    • Function body changes (CREATE OR REPLACE FUNCTION)
    • New function parameters with DEFAULT values

    Manual Migrations Required For:

    • Adding new columns (ALTER TABLE ADD COLUMN IF NOT EXISTS)
    • Changing column types (ALTER TABLE ALTER COLUMN TYPE)
    • Changing function signatures (requires DROP FUNCTION + CREATE)
    • Dropping columns (requires a two-phase approach: stop using the column in code first, then drop it via migration)