zus-rs

Crates.iozus-rs
lib.rszus-rs
version1.1.4
created_at2026-01-21 11:45:18.824948+00
updated_at2026-01-21 12:19:27.172811+00
descriptionZUS RPC Framework - Rust implementation with cross-language compatibility
homepage
repositoryhttps://github.com/zus-dev/zus-rs
max_upload_size
id2058965
size86,186
Junfei Wang (Junfei-Wang_astg)

documentation

README

zus-rs: ZUS RPC Framework for Rust

Crates.io Documentation License

ZUS-RS is a high-performance, cross-language RPC framework for Rust with compatibility for Java and C++ implementations. It provides service discovery via ZooServer and supports QuickLZ/Snappy compression.

Features

  • ✨ Cross-Language RPC: Wire-compatible with Java and C++ implementations
  • πŸš€ High Performance: Built on Tokio async runtime
  • πŸ“¦ Protocol Buffer: Efficient binary serialization
  • πŸ—œοΈ Compression: QuickLZ (default) and Snappy support with smart params-only compression
  • πŸ” Service Discovery: Integration with ZooServer for dynamic service lookup
  • πŸ›‘οΈ Type Safe: Full Rust type safety with protobuf definitions
  • πŸ“Š Production Ready: Tested with comprehensive cross-language test suite

Quick Start

Installation

Add zus-rs to your Cargo.toml:

[dependencies]
zus-rs = "1.1.4"
tokio = { version = "1.35", features = ["full"] }

Or choose specific features:

# Just client
[dependencies]
zus-rs = { version = "1.1.4", features = ["client"] }

# Just server
[dependencies]
zus-rs = { version = "1.1.4", features = ["server"] }

# Protocol only (no RPC runtime)
[dependencies]
zus-rs = { version = "1.1.4", features = ["protocol"] }

Usage Patterns

ZUS-RS supports two connection styles, matching the C++ and Java implementations:

Style 1: Direct Connection (Without ZooServer)

  • Use when: You know the exact service address (development, simple deployments)
  • Address format: tcp://host:port or tcp://host1:port1,host2:port2 (comma-separated for multiple endpoints)
  • No service discovery: You manage service addresses manually

Style 2: ZooServer-Based Discovery (With ZooServer)

  • Use when: You need dynamic service discovery, load balancing, and automatic failover (production)
  • Address format: zns://zooserver:port/service/path/
  • Automatic features: Service discovery, health checks (every 3s), round-robin load balancing

Client Example - Direct Connection (Style 1)

use bytes::Bytes;
use zus_rs::RpcClient;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Connect to a single service directly
    let client = RpcClient::new("tcp://localhost:9527").await?;

    // Or connect to multiple endpoints (manual load balancing)
    // let client = RpcClient::new("tcp://host1:9527,host2:9527").await?;

    // Make RPC call
    let request = Bytes::from("Hello, World!");
    let response = client.sync_call("echo", request, 5000).await?;

    println!("Response: {}", String::from_utf8_lossy(&response));
    Ok(())
}

Client Example - ZooServer Discovery (Style 2)

use bytes::Bytes;
use zus_rs::RpcClient;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Connect via ZooServer - service discovery happens automatically
    let client = RpcClient::new(
        "zns://localhost:9528/zus/services/myservice/"
    ).await?;

    // The client automatically:
    // - Discovers all available service instances from ZooServer
    // - Monitors their health (every 3 seconds)
    // - Load balances requests across healthy instances (round-robin)
    // - Handles service instances joining/leaving dynamically

    // Make RPC call (same API regardless of connection style)
    let request = Bytes::from("Hello, World!");
    let response = client.sync_call("echo", request, 5000).await?;

    println!("Response: {}", String::from_utf8_lossy(&response));
    Ok(())
}

Server Example - Direct TCP (Style 1)

use bytes::Bytes;
use std::sync::Arc;
use zus_rs::{RpcServer, prelude::*};

struct EchoService;

#[async_trait]
impl Service for EchoService {
    fn service_name(&self) -> &str {
        "EchoService"
    }

    async fn do_work(
        &self,
        method: &str,
        params: Bytes,
        _context: zus_rs::server::RequestContext,
    ) -> zus_common::Result<Bytes> {
        match method {
            "echo" => Ok(params),
            _ => Err(zus_common::ZusError::MethodNotFound(method.to_string())),
        }
    }
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Start server without ZooServer - clients connect via tcp://host:9527
    let mut server = RpcServer::new("0.0.0.0".to_string(), 9527);
    server.register_service(Arc::new(EchoService));
    server.start().await?;
    Ok(())
}

Server Example - With ZooServer Registration (Style 2)

use bytes::Bytes;
use std::sync::Arc;
use zus_rs::{RpcServer, prelude::*};
use zus_discovery::ZusZooClient;

struct EchoService;

#[async_trait]
impl Service for EchoService {
    fn service_name(&self) -> &str {
        "EchoService"
    }

    async fn do_work(
        &self,
        method: &str,
        params: Bytes,
        _context: zus_rs::server::RequestContext,
    ) -> zus_common::Result<Bytes> {
        match method {
            "echo" => Ok(params),
            _ => Err(zus_common::ZusError::MethodNotFound(method.to_string())),
        }
    }
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Connect to ZooServer
    let zoo_client = Arc::new(
        ZusZooClient::new(vec!["localhost:9528".to_string()]).await?
    );

    // Start server WITH ZooServer registration
    // Server will automatically register at /zus/services/rust/0.0.0.0:9527
    let mut server = RpcServer::new("0.0.0.0".to_string(), 9527)
        .with_zoo_client(zoo_client);

    server.register_service(Arc::new(EchoService));
    server.start().await?;
    Ok(())
}

Running ZooServer (Standalone)

To use Style 2 (ZooServer-based discovery), you need a running ZooServer instance. ZUS-RS includes a production-ready ZooServer implementation.

Quick Start

# Run with default settings (binds to 0.0.0.0:9528)
cargo run --bin zooserver

# Run with a config file
cargo run --bin zooserver -- path/to/config.cfg

# Run with debug logging
RUST_LOG=debug cargo run --bin zooserver

Configuration File

Create a .cfg file to customize ZooServer:

[zusnet]
# Maximum concurrent connections (default: 1000)
maxconnects=1000

# Idle connection timeout in seconds (default: 60)
idleconntimeout=60

# Enable compression (default: true)
COMPRESS=true

# Compression threshold in bytes (default: 4096)
COMPRESS_THRESHSIZE=4096

[zooserver]
# Server listening port (default: 9528)
srvport=9528

Example: Full Setup with ZooServer

# Terminal 1: Start ZooServer
cargo run --bin zooserver

# Terminal 2: Start your service (registers with ZooServer)
cargo run --bin your-service

# Terminal 3: Run client (discovers service via ZooServer)
cargo run --bin your-client

ZooServer Features

  • Service Discovery: Services register at paths like /zus/services/myservice/tcp:host:port
  • Ephemeral Nodes: Auto-cleanup when services disconnect
  • Distributed Locking: Path-based distributed locks
  • Session Management: Automatic timeout (default: 10s)
  • Health Monitoring: Clients send periodic heartbeats via SyncPath

For more details, see zooserver/README.md.

Feature Flags

Choose the features you need to minimize dependencies:

Feature Description Use Case
default Client + Server + Protocol Full-featured applications
minimal Protocol definitions only Message definitions for FFI
protocol Protocol + Codec + Compression Custom transport layer
client RPC client functionality Client applications
server RPC server functionality Service implementations
full Everything Development and testing

Examples

# Microservice (server only)
[dependencies]
zus-rs = { version = "1.1.4", features = ["server"] }

# Client application
[dependencies]
zus-rs = { version = "1.1.4", features = ["client"] }

# Protocol implementation (custom transport)
[dependencies]
zus-rs = { version = "1.1.4", features = ["protocol"] }

# Minimal (just message definitions)
[dependencies]
zus-rs = { version = "1.1.4", features = ["minimal"] }

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              zus-rs (convenience)                β”‚
β”‚  Feature flags: minimal, protocol, client, serverβ”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚              β”‚              β”‚
        ↓              ↓              ↓
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ client  β”‚   β”‚ server  β”‚   β”‚ protocol β”‚
   β”‚ feature β”‚   β”‚ feature β”‚   β”‚ feature  β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚              β”‚              β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚  zus-rpc-{client,server}     β”‚
        β”‚  zus-discovery (ZooServer)   β”‚
        β”‚  zus-common (codec/compress) β”‚
        β”‚  zus-proto (protobuf msgs)   β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Module Organization

use zus_rs::proto;       // Protocol Buffer definitions (always available)
use zus_rs::common;      // Codec and compression (protocol feature)
use zus_rs::discovery;   // ZooServer client (client/server features)
use zus_rs::client;      // RPC client (client feature)
use zus_rs::server;      // RPC server (server feature)

// Or use the prelude for common imports
use zus_rs::prelude::*;

Cross-Language Compatibility

ZUS-RS is wire-compatible with Java and C++ implementations:

  • βœ… Java: Full compatibility tested with integration tests
  • βœ… C++: Production-tested compatibility
  • βœ… Protocol: Same 40-byte RPC header format
  • βœ… Compression: Same QuickLZ/Snappy algorithms
  • βœ… Validation: Same CRC16/CRC32 checksums

Compression Strategy

ZUS-RS implements params-only compression for requests to match Java's decoder architecture:

  • Requests: Method name stays uncompressed, only params data is compressed
  • Responses: Full body compression
  • Threshold: 4096 bytes (4KB) default, configurable
  • Algorithms: QuickLZ Level 1 (default), Snappy fallback

This ensures perfect cross-language compatibility:

βœ… Java Client β†’ Rust Server
βœ… Rust Client β†’ Java Server
βœ… C++ Client β†’ Rust Server
βœ… Rust Client β†’ C++ Server

Address Format Reference

Direct Connection (tcp://)

Single endpoint:   tcp://host:port
Multiple endpoints: tcp://host1:port1,host2:port2,host3:port3

Examples:

  • tcp://localhost:9527
  • tcp://192.168.1.10:9527
  • tcp://service1.example.com:9527,service2.example.com:9527

ZooServer Discovery (zns://)

Format: zns://zooserver1:port1[,zooserver2:port2]/service/path/

Examples:

  • zns://localhost:9528/zus/services/myservice/
  • zns://zoo1:2181,zoo2:2181/zus/services/myservice/
  • zns://10.0.1.1:2181/zus/services/echo/

Note: The service path should end with / and correspond to where servers register themselves in ZooServer.

Performance

  • Throughput: ~100K requests/sec (localhost, no compression)
  • Latency: < 1ms p99 (localhost)
  • Compression Ratio: ~70% reduction (5440 bytes β†’ 477 bytes typical)
  • Memory: Low overhead with zero-copy where possible

Examples

See zus-examples/ for complete examples:

  • Simple Client: Basic RPC calls (example-client)
  • Simple Server: Service implementation (example-server)
  • Telemetry Server: Server with OpenTelemetry integration (example-server-telemetry)
  • ZooServer Discovery: Service registration and discovery
  • Cross-Language: Interoperability with Java/C++

Testing

Run tests for all feature combinations:

# Test default features
cargo test -p zus-rs

# Test minimal features
cargo test -p zus-rs --no-default-features --features minimal

# Test client only
cargo test -p zus-rs --no-default-features --features client

# Test server only
cargo test -p zus-rs --no-default-features --features server

# Test all features
cargo test -p zus-rs --all-features

Documentation

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

License

Licensed under either of:

at your option.

Credits

Developed by the ZUS Rust Team as a modern, cross-language compatible RPC framework.

Version: 1.1.4 Last Updated: 2026-01-21 Status: Production Ready

Commit count: 0

cargo fmt