# zus-rs: ZUS RPC Framework for Rust
[](https://crates.io/crates/zus-rs)
[](https://docs.rs/zus-rs)
[](https://github.com/zusrust/zus-rs/blob/main/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`:
```toml
[dependencies]
zus-rs = "1.1.4"
tokio = { version = "1.35", features = ["full"] }
```
Or choose specific features:
```toml
# 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)
```rust
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)
```rust
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)
```rust
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)
```rust
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
```bash
# 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:
```ini
[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
```bash
# 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:
| `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
```toml
# 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
```text
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 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
```rust
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:
```bash
# 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
- [Getting Started Guide](../docs/GETTING_STARTED.md)
- [Protocol Specification](../docs/protocol&wireformat.md)
- [ZooServer Architecture](../docs/ZOOSERVER_ARCHITECTURE.md)
- [Cross-Language Tests](../tests/cross-language/README.md)
- [Repository Organization](../docs/REPOSITORY_ORGANIZATION_ANALYSIS.md)
## Contributing
Contributions are welcome! Please see [CONTRIBUTING.md](../CONTRIBUTING.md) for guidelines.
## License
Licensed under either of:
- Apache License, Version 2.0 ([LICENSE-APACHE](../LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](../LICENSE-MIT) or http://opensource.org/licenses/MIT)
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