truongbo/proxy-rotation

具有负载均衡策略的代理轮转

v2.2.2 2023-01-05 06:13 UTC

This package is auto-updated.

Last update: 2024-09-05 09:41:54 UTC


README

Proxy Rotation Logo

描述

  • 实现Nginx简单的负载均衡策略,构建用于与Guzzle或其他工具一起使用的包代理轮转
  • 仅使用有效、一致和简单的策略轮转代理

可选功能

策略

多端点

自动重试连接并在端点之间切换

下一个功能

  • 使用备用主机(如果主主机不可访问,Guzzle将自动连接到备用主机以获取数据...) ✔️
  • 为每个主机配置单独的策略,更智能 ✔️
  • 在连接失败时自动重试连接主机(配置重试次数、响应代码类型) ✔️
  • 负载均衡,为每个集群应用不同的策略
  • 等等...

安装

安装包

composer require truongbo/proxy-rotation

运行测试

./vendor/bin/phpunit

发布包文件(配置)

php artisan vendor:publish --provider="TruongBo\ProxyRotation\ProxyRotationServiceProvider"

快速使用

您需要选择一个轮转策略,并通过轮转进行配置

use TruongBo\ProxyRotation\Rotation;
use TruongBo\ProxyRotation\Strategy\RoundRobin;

$rotation = new Rotation(new RoundRobin(counter: 0));

初始化由代理节点组成的集群

use TruongBo\ProxyRotation\ProxyServer\ProxyCluster;
use TruongBo\ProxyRotation\ProxyServer\ProxyNode;

$proxy_cluster = new ProxyCluster(
        cluster_name: 'cluster1', 
        array_proxy_node: [
            new ProxyNode(name: 'proxy-node1'),
            new ProxyNode(name: 'proxy-node2'),
            new ProxyNode(name: 'proxy-node3'),
            new ProxyNode(name: 'proxy-node4'),
        ]);

然后,我们应该将ProxyMiddleware连接到Guzzle,以便代理均衡可以工作

use GuzzleHttp\HandlerStack;
use GuzzleHttp\Client;
use TruongBo\ProxyRotation\Middleware\ProxyMiddleware;

$stack = HandlerStack::create();
$stack->push(new ProxyMiddleware(rotation: $rotation,proxy_cluster: $proxy_cluster));

$client = new Client([
    'handler' => $stack,
]);

完成,现在检查一下

while (true) {
    /** @var ResponseInterface $response */
    $response = $client->get('https://httpbin.org/ip');

    // ...
}

结果:(使用proxy-node作为您的代理地址)

+-------------+
| proxy-node1 |
| proxy-node2 |
| proxy-node3 |
| proxy-node4 |
| proxy-node1 |
| proxy-node2 |
| proxy-node3 |
| proxy-node4 |
| etc...      |
+-------------+

排序节点

排序以调整节点的顺序,升序或降序

use TruongBo\ProxyRotation\ProxyServer\ProxyCluster;
use TruongBo\ProxyRotation\ProxyServer\ProxyNode;

$proxy_cluster = new ProxyCluster(
        cluster_name: 'cluster1', 
        array_proxy_node: [
            new ProxyNode(name: 'proxy-node1',weight: 1000),
            new ProxyNode(name: 'proxy-node2',weight: 20),
            new ProxyNode(name: 'proxy-node3',weight: 200),
            new ProxyNode(name: 'proxy-node4',weight: 10),
        ]);
        
$proxy_cluster->sort("desc");

顶级代理节点将被更多使用,反之亦然,例如

+-------------+-------------+
| name        | weight      |
+-------------+-------------+
| proxy-node1 | 1000        |
| proxy-node3 | 200         |
| proxy-node2 | 20          |
| proxy-node4 | 10          |
+-------------+-------------+

排序节点可以帮助您更好地使用频率策略。使用升序进行逆序。

最大使用

  • 将代理使用次数存储在缓存中并计数。如果使用次数超过限制,代理将暂时闲置,时间为配置的时间段。
  • 仅与随机、频率和轮询策略一起使用

示例

$cluster = new ProxyCluster('cluster1', [
            new ProxyNode(name: 'node1',weight: 3,max_use: 4,max_use_wait: 10),
            new ProxyNode(name: 'node2',weight: 1,max_use: 2,max_use_wait: 20),
        ]);

其他一切将自动运行

随机

  • $input_random : 代理是如何随机选择的?
- both : All proxy nodes are random
- has_weight : Only the weighted proxy node will be random
- no_weight : Only proxy nodes without weights can be random

配置

use TruongBo\ProxyRotation\Rotation;
use TruongBo\ProxyRotation\Strategy\Random;
use TruongBo\ProxyRotation\ProxyServer\ProxyCluster;
use TruongBo\ProxyRotation\ProxyServer\ProxyNode;

$rotation = new Rotation(new Random(input_random: "both"));

$proxy_cluster = new ProxyCluster(
        cluster_name: 'cluster1', 
        array_proxy_node: [
            new ProxyNode(name: 'proxy-node1',weight: 20),
            new ProxyNode(name: 'proxy-node2'),
            new ProxyNode(name: 'proxy-node3'),
            new ProxyNode(name: 'proxy-node4',weight: 100),
        ]);

输出(两者)

+-------------+-------------+
| name        | weight      |
+-------------+-------------+
| proxy-node3 | 0           |
| proxy-node1 | 20          |
| proxy-node2 | 0           |
| proxy-node4 | 100         |
+-------------+-------------+

频率

使用排序节点更有效

use TruongBo\ProxyRotation\ProxyServer\ProxyCluster;
use TruongBo\ProxyRotation\ProxyServer\ProxyNode;
use TruongBo\ProxyRotation\Strategy\Frequency;

$rotation = new Rotation(new Frequency(frequency: 0.8, depth: 0.2));

$proxy_cluster = new ProxyCluster(
        cluster_name: 'cluster1', 
        array_proxy_node: [
            new ProxyNode(name: 'proxy-node1',weight: 2048),
            new ProxyNode(name: 'proxy-node2',weight: 1024),
            new ProxyNode(name: 'proxy-node3',weight: 512),
            new ProxyNode(name: 'proxy-node4',weight: 256),
            new ProxyNode(name: 'proxy-node5',weight: 256),
            new ProxyNode(name: 'proxy-node6',weight: 64),
            new ProxyNode(name: 'proxy-node7',weight: 32),
            new ProxyNode(name: 'proxy-node8',weight: 16),
            new ProxyNode(name: 'proxy-node9',weight: 8),
            new ProxyNode(name: 'proxy-node10',weight: 4),
        ]);
        
$cluster->sort("desc");

频率策略选择节点的概率可以如下可视化:

+--------------+--------+
| nodes        | chance |
+--------------+--------+
| proxy-node1  | 40%    |
| proxy-node2  | 40%    |
+--------------+--------+
| proxy-node3  | 2.5%   |
| proxy-node8  | 2.5%   |
| proxy-node5  | 2.5%   |
| proxy-node6  | 2.5%   |
| proxy-node4  | 2.5%   |
| proxy-node7  | 2.5%   |
| proxy-node9  | 2.5%   |
| proxy-node10 | 2.5%   |
+-----------+-----------+

轮询

代理将依次轮转($counter:从某个地方开始计数)

use TruongBo\ProxyRotation\Rotation;
use TruongBo\ProxyRotation\Strategy\RoundRobin;
use TruongBo\ProxyRotation\ProxyServer\ProxyCluster;
use TruongBo\ProxyRotation\ProxyServer\ProxyNode;

$rotation = new Rotation(new RoundRobin(counter: 0));

$proxy_cluster = new ProxyCluster(
        cluster_name: 'cluster1', 
        array_proxy_node: [
            new ProxyNode(name: 'proxy-node1'),
            new ProxyNode(name: 'proxy-node2'),
            new ProxyNode(name: 'proxy-node3'),
            new ProxyNode(name: 'proxy-node4'),
        ]);

输出

+-------------+
| proxy-node1 |
| proxy-node2 |
| proxy-node3 |
| proxy-node4 |
| proxy-node1 |
| proxy-node2 |
| proxy-node3 |
| proxy-node4 |
| etc...      |
+-------------+
  • 如果代理被限制使用,您可以在一定时间内干预代理的使用。使用最大使用

加权轮询

此代理节点被调用的次数是初始化ProxyNode时传入的权重参数($counter:从某个地方开始计数)

use TruongBo\ProxyRotation\Rotation;
use TruongBo\ProxyRotation\Strategy\WeightedRoundRobin;
use TruongBo\ProxyRotation\ProxyServer\ProxyCluster;
use TruongBo\ProxyRotation\ProxyServer\ProxyNode;

$rotation = new Rotation(new WeightedRoundRobin(counter: 0));

$proxy_cluster = new ProxyCluster(
        cluster_name: 'cluster1', 
        array_proxy_node: [
            new ProxyNode(name: 'proxy-node1', weight: 3),
            new ProxyNode(name: 'proxy-node2'),
            new ProxyNode(name: 'proxy-node3', weight: 1),
            new ProxyNode(name: 'proxy-node4', weight: 1),
        ]);

输出

+-------------+
| proxy-node1 |
| proxy-node1 |
| proxy-node1 |
| proxy-node3 |
| proxy-node4 |
| etc...      |
+-------------+
  • 没有权重的代理节点将不会被使用

多动态

根据传入的可调用条件动态更改策略(如果您不了解,绝对不要使用)

use TruongBo\ProxyRotation\Rotation;
use TruongBo\ProxyRotation\Strategy\WeightedRoundRobin;
use TruongBo\ProxyRotation\ProxyServer\ProxyCluster;
use TruongBo\ProxyRotation\ProxyServer\ProxyNode;

$rotation = new Rotation(new MultipleDynamic(
            new RoundRobin(counter: 0),
            new Random(input_random: "has_weight"),
            new WeightedRoundRobin(counter: 0),
        ));

$proxy_cluster = new ProxyCluster(
        cluster_name: 'cluster1', 
        array_proxy_node: [
            new ProxyNode(name: 'proxy-node1', weight: 3),
            new ProxyNode(name: 'proxy-node2'),
            new ProxyNode(name: 'proxy-node3', weight: 1),
            new ProxyNode(name: 'proxy-node4', weight: 1),
        ]);

        while (true) {
            $node = $rotation->pick($cluster, function (ProxyNode $proxy_node){
                //condition switch between strategies in here.
            });

            echo $node?->name;
        }