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
Requires
- composer-runtime-api: ^2.0
- psr/cache: ^2.0 || ^3.0
- symfony/cache: ^7.3
Requires (Dev)
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^11.5
- tourze/phpunit-base: 1.*
This package is auto-updated.
Last update: 2025-11-02 07:14:52 UTC
README
一个通用的、与框架无关的 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!