pingap-upstream 0.13.1

Upstream for pingap
Documentation

Pingap Upstream

Crates.io License Docs.rs

pingap-upstream is a core crate within the Pingap project, providing robust and flexible upstream management for backend services. Built on top of the Pingora framework, it handles service discovery, load balancing, and health checking.

Core Features

  • Multiple Load Balancing Strategies: Choose the best algorithm for your needs.

    • Round Robin: Distributes requests evenly across all healthy backends.
    • Consistent Hashing: Provides sticky sessions by hashing request attributes to a specific backend.
    • Transparent: Acts as a direct passthrough proxy without load balancing, forwarding requests to the original host.
  • Flexible Consistent Hashing Keys: When using consistent hashing, you can define the key based on various request attributes:

    • Client IP Address
    • URL Path, Query, or full URL
    • HTTP Header value
    • Cookie value
  • Dynamic Service Discovery: Automatically discover and update backend servers from different sources:

    • Static: A fixed list of backend addresses.
    • DNS: A-record or SRV-record based discovery.
    • Docker: Discover backends from Docker container labels.
  • Active Health Checking: Periodically probes backend servers to ensure they are healthy. Unhealthy backends are automatically and temporarily removed from the load balancing pool.

  • Advanced Configuration:

    • TLS & SNI: Secure connections to backends with configurable TLS and Server Name Indication.
    • HTTP/2 & ALPN: Supports ALPN for negotiating HTTP/1.1 or HTTP/2 with backends.
    • Connection Timeouts: Fine-grained control over connection, read, write, and idle timeouts.
    • TCP Control: Advanced options for TCP keepalives, buffer sizes, and TCP Fast Open.
  • Runtime Management:

    • Upstreams can be dynamically added, updated, or removed at runtime without service interruption.
    • Exposes health and connection metrics for monitoring and observability.

Core Concepts

Upstream

The Upstream struct is the central component, representing a logical group of backend servers. It encapsulates the configuration for load balancing, health checks, TLS, timeouts, and service discovery for that group.

SelectionLb

This enum represents the configured load balancing strategy for an Upstream:

  • RoundRobin(LoadBalancer<RoundRobin>)
  • Consistent { lb: LoadBalancer<Consistent>, hash: HashStrategy }
  • Transparent

HealthCheckTask

A background service that runs periodically for all configured upstreams. It is responsible for:

  1. Triggering service discovery updates (e.g., re-resolving DNS).
  2. Executing health checks against each backend.
  3. Sending notifications when an upstream's health status changes (e.g., all backends become unhealthy).

Usage

This crate is primarily used within the pingap proxy application. The general workflow is as follows:

  1. Define upstream configurations (e.g., in a YAML file).
  2. The pingap application parses these configurations into UpstreamConf structs.
  3. An Upstream instance is created for each configuration.
  4. The HealthCheckTask is started to monitor all upstreams.
  5. When a request arrives, the proxy selects the appropriate Upstream and calls new_http_peer() to get a healthy, configured backend connection.

Conceptual Code Example

use pingap_upstream::{Upstream, UpstreamConf};
use std::sync::Arc;
use std::collections::HashMap;

fn main() {
    // Configuration would typically be loaded from a file
    let mut conf = UpstreamConf::default();
    conf.addrs = vec!["127.0.0.1:8080".to_string()];
    conf.algo = Some("round_robin".to_string());

    // Create a new Upstream
    let upstream = Upstream::new("my_service", &conf, None).unwrap();
    let upstream = Arc::new(upstream);

    // In a request handling context, a peer would be created.
    // This is a simplified representation.
    // let http_peer = upstream.new_http_peer(&session, &client_ip);
    
    println!("Upstream '{}' created successfully.", upstream.name);
}

License

This project is licensed under the Apache-2.0 License.