tourze/load-balancer

Installs: 5

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/tourze/load-balancer

1.0.0 2025-10-31 05:30 UTC

This package is auto-updated.

Last update: 2025-11-02 07:14:52 UTC


README

English | 中文

一个通用的、与框架无关的 PHP 负载均衡库。它提供了多种负载均衡策略,以满足从简单轮询到复杂动态负载分配的各种需求。

该库的核心设计原则是简单、灵活和可扩展。

特性

  • 多种策略: 内置多种常用负载均衡算法(随机、轮询、加权、IP哈希、最少连接、平滑加权轮询)。
  • 零依赖: 核心库除了 psr/cache 之外不依赖任何外部框架。
  • 强大的状态管理:
    • 支持通过可插拔的状态提供者 (State Provider) 管理有状态策略。
    • 内置内存 (InMemory)、APCu (Apcu) 和 PSR-6 缓存 (Cache) 三种提供者。
    • 轻松支持单机(内存、APCu)或分布式(Redis、Memcached)环境。
  • 易于使用: 提供简单的工厂类,可快速创建和使用。
  • 完全测试: 所有组件均经过单元测试,保证质量。

安装

通过 Composer 安装:

composer require tourze/load-balancer

如果你计划使用 CacheStateProvider,请确保你的项目已经依赖了一个实现 psr/cache 的库(例如 symfony/cache)。

# 例如,安装 symfony/cache
composer require symfony/cache

使用方法

快速开始

使用 LoadBalancerFactory 是最简单的入门方式。

use Tourze\LoadBalance\LoadBalancerFactory;
use Tourze\LoadBalance\Node;

// 1. 定义你的节点
$nodes = [
    new Node(key: 'server1', value: '192.168.1.100', weight: 10),
    new Node(key: 'server2', value: '192.168.1.101', weight: 20),
];

// 2. 使用工厂创建一个负载均衡器 (例如,平滑加权轮询)
$balancer = LoadBalancerFactory::createSmoothWeightedRoundRobin();

// 3. 选择一个节点
$selectedServer = $balancer->select($nodes);

echo $selectedServer;

节点 (Node)

Node 对象是所有负载均衡策略的基本单元。

new Node(
    string $key,   // 节点的唯一标识符
    mixed $value,  // 节点的实际值 (IP, 主机名, 对象等)
    int $weight = 1 // 节点的权重 (必须为非负整数)
);

可用策略

1. 随机策略 (RandomBalancer)

从节点列表中完全随机地选择一个。

$balancer = LoadBalancerFactory::createRandom();
$server = $balancer->select($nodes);

2. 轮询策略 (RoundRobinBalancer)

按顺序逐个选择节点。这是一个有状态的策略。

$balancer = LoadBalancerFactory::createRoundRobin();

$server1 = $balancer->select($nodes); // server1
$server2 = $balancer->select($nodes); // server2
$server3 = $balancer->select($nodes); // server1 (循环)

3. 加权随机策略 (WeightedBalancer)

根据节点的权重进行随机选择,权重越高的节点被选中的概率越大。

$nodes = [
    new Node('A', 'A', 90), // 90% 概率
    new Node('B', 'B', 10), // 10% 概率
];
$balancer = LoadBalancerFactory::createWeighted();
$server = $balancer->select($nodes); // 'A' 或 'B'

4. IP 哈希策略 (IpHashBalancer)

确保来自同一个 IP 地址的请求总是被分配到同一个节点。非常适合用于实现会话保持。

$clientIp = '8.8.8.8';
$balancer = LoadBalancerFactory::createIpHash($clientIp);

// 对于同一个 IP,选择结果总是相同的
$server = $balancer->select($nodes);

5. 最少连接数策略 (LeastConnectionsBalancer)

选择当前活动连接数最少的节点。这是一个动态策略,需要外部逻辑来更新连接数。

$balancer = LoadBalancerFactory::createLeastConnections();
$nodes = [
    $node1 = new Node('A', 'A'),
    $node2 = new Node('B', 'B'),
];

// 模拟连接建立
$balancer->incrementConnection($node1);
$balancer->incrementConnection($node1); // A 有 2 个连接
$balancer->incrementConnection($node2); // B 有 1 个连接

// 选择时会返回连接数最少的节点 B
$server = $balancer->select($nodes); // 返回 'B'

// 模拟连接断开
$balancer->decrementConnection($node1);

6. 平滑加权轮询策略 (SmoothWeightedRoundRobinBalancer)

Nginx 使用的平滑加权算法。它能确保请求分发平滑,避免在短时间内集中请求高权重节点。

对于权重为 {A:5, B:1, C:1} 的节点,7次请求的序列将是 A, A, B, A, C, A, A,分布非常均匀。

$balancer = LoadBalancerFactory::createSmoothWeightedRoundRobin();
$nodes = [
    new Node('A', 'A', 5),
    new Node('B', 'B', 1),
    new Node('C', 'C', 1),
];

// 多次调用 select() 将得到一个平滑的、可预测的序列

状态管理

对于有状态的策略(如 RoundRobinBalancer, LeastConnectionsBalancer),你可以通过注入一个 StateProviderInterface 的实现来控制状态的存储。

InMemoryStateProvider (默认)

状态仅在当前 PHP 进程的生命周期内有效。无需任何配置。

// 工厂方法默认使用 InMemoryStateProvider
$balancer = LoadBalancerFactory::createRoundRobin();

ApcuStateProvider (单机跨进程)

如果你的环境安装并启用了 APCu 扩展,可以使用它在同一台服务器的多个进程间共享状态。

use Tourze\LoadBalance\State\ApcuStateProvider;

// 检查环境是否支持
if (function_exists('apcu_fetch')) {
    $stateProvider = new ApcuStateProvider('my_app_prefix_');
    $balancer = LoadBalancerFactory::createRoundRobin($stateProvider);
}

CacheStateProvider (分布式)

这是最灵活的方式,可以对接任何实现了 PSR-6 (Psr\Cache\CacheItemPoolInterface) 的缓存系统,如 Redis、Memcached 等。

示例:使用 Symfony Cache 对接 Redis

use Symfony\Component\Cache\Adapter\RedisAdapter;
use Tourze\LoadBalance\State\CacheStateProvider;

// 1. 创建一个 PSR-6 缓存池实例 (这里以 Redis 为例)
$redisClient = RedisAdapter::createConnection('redis://localhost');
$cachePool = new RedisAdapter($redisClient);

// 2. 创建 CacheStateProvider
$stateProvider = new CacheStateProvider($cachePool, 'my_app_prefix_');

// 3. 将它注入到负载均衡器中
$balancer = LoadBalancerFactory::createLeastConnections($stateProvider);

// 现在,所有状态都将通过 Redis 进行存储和同步

贡献

欢迎提交 PR 和 issue!