hollodotme / fast-cgi-proxy
用于将同步和异步请求分发到多个 php-fpm 套接字/池的代理。
Requires
- php: >=7.1
- hollodotme/fast-cgi-client: ~2.7.2
Requires (Dev)
- tm/tooly-composer-script: ~1.4.0
This package is auto-updated.
Last update: 2024-09-11 14:47:17 UTC
README
FastCGI 代理
描述
将同步和异步请求分发到多个 fastCGI 服务器的代理。
安装
composer require hollodotme/fast-cgi-proxy
使用方法
请求分发
代理可以通过以下方式将请求分发到多个 fastCGI 服务器:
- 随机
- 轮询
随机分发
要设置随机分发,请使用以下示例代码:
<?php declare(strict_types=1); namespace YourVendor\YourProject; use hollodotme\FastCGI\Proxy; use hollodotme\FastCGI\Collections\Random; use hollodotme\FastCGI\SocketConnections\NetworkSocket; use hollodotme\FastCGI\SocketConnections\UnixDomainSocket; $random = Random::fromConnections( new NetworkSocket( '127.0.0.1', 9000 ), new NetworkSocket( '10.100.10.42', 9000 ), new UnixDomainSocket( '/var/run/php7.3-fpm.sock' ) ); $proxy = new Proxy( $random );
现在发送请求时,代理将随机选择一个 fastCGI 服务器来处理请求。
轮询分发
要设置轮询分发,请使用以下示例代码:
<?php declare(strict_types=1); namespace YourVendor\YourProject; use hollodotme\FastCGI\Proxy; use hollodotme\FastCGI\Collections\RoundRobin; use hollodotme\FastCGI\SocketConnections\NetworkSocket; use hollodotme\FastCGI\SocketConnections\UnixDomainSocket; $roundRobin = RoundRobin::fromConnections( new NetworkSocket( '127.0.0.1', 9000 ), new NetworkSocket( '10.100.10.42', 9000 ), new UnixDomainSocket( '/var/run/php7.3-fpm.sock' ) ); $proxy = new Proxy( $roundRobin );
代理将按照它们被添加到 RoundRobin
实例的相同顺序将您的请求发送到下一个 fastCGI 服务器。在本例中,它将发送到
127.0.0.1:9001
10.100.10.42:9001
,/var/run/php7.1-fpm.sock
127.0.0.1:9001
(从头开始)- 等等...
发送请求
Proxy
类具有与底层 Client 类相同的用于发送同步和异步请求以及检索响应(响应式)的方法。因此,请参阅 hollodotme/fast-cgi-client 的文档以获取更多信息。
以下是一个可用方法的简要列表
-
$proxy->sendRequest(ProvidesRequestData $request) : ProvidesResponseData
发送一个同步请求并返回响应。(阻塞) -
$proxy->sendAsyncRequest(ProvidesRequestData $request) : int
发送一个异步请求并返回请求 ID。(非阻塞) -
$proxy->readResponse(int $requestId, ?int $timeoutMs = null) : ProvidesResponseData
读取并返回先前获得的请求 ID 的响应。
(阻塞直到读取响应或读取超时) -
$proxy->readResponses(?int $timeoutMs = null, int ...$requestIds) : \Generator|ProvidesResponseData[]
按给定请求 ID 的顺序读取并产生先前获得的请求 ID 的响应。
(阻塞直到读取所有响应或读取超时) -
$proxy->readReadyResponses(?int $timeoutMs = null) : \Generator|ProvidesResponseData[]
读取并产生所有已完成请求的响应。
(非阻塞,适用于循环中) -
$proxy->waitForResponse(int $requestId, ?int $timeoutMs = null) : void
等待先前获得的请求 ID 的响应并调用请求的响应回调。
(阻塞直到读取响应或读取超时) -
$proxy->waitForResponses(?int $timeoutMs = null) : void
等待先前获得的请求 ID 的响应并按完成请求的顺序调用相应的响应回调。
(阻塞直到读取所有响应或读取超时) -
$proxy->hasResponse(int $requestId) : bool
返回给定的请求 ID 是否有响应。(非阻塞) -
$proxy->handleResponse(int $requestId, ?int $timeoutMs = null) : void
调用已完成请求的相应响应回调。
(如果请求 ID 有响应,在调用此方法之前必须进行检查,请参阅$proxy->hasResponse(int $requestId)
)。 -
$proxy->hasUnhandledResponses() : bool
如果有未处理的响应,则返回 TRUE,否则返回 FALSE。 -
$proxy->getRequestIdsHavingResponse() : array
返回所有有响应的请求 ID。(非阻塞) -
$proxy->handleResponses(?int $timeoutMs = null, int ...$requestIds) : void
按给定请求 ID 的顺序调用已完成请求的相应响应回调。
(如果请求 ID 有响应,在调用此方法之前必须进行检查,请参阅$proxy->hasResponse(int $requestId)
或$proxy->getRequestIdsHavingResponse() : array
。) -
$proxy->handleReadyResponses(?int $timeoutMs = null) : void
按照完成请求的顺序调用相应的响应回调。
(非阻塞,简写为$proxy->handleResponses($timeoutMs, int ...$proxy->getRequestIdsHavingResponse())
)
集群请求
此功能自库的 v0.2.0
版本以来可用。
为了在众多快速CGI服务器上处理单个请求,引入了 ClusterProxy
类。因此,为了将请求分发到配置的快速CGI服务器之一,集群代理将向所有配置的快速CGI服务器发送相同的请求,并允许您读取/处理它们的响应(响应式)。
根据集群请求的概念,请求与响应之间始终存在一对一或多对多的关系。这就是为什么 ClusterProxy
类不提供基于请求ID的同步请求和单个响应读取。
要设置集群代理,请使用以下示例代码
<?php declare(strict_types=1); namespace YourVendor\YourProject; use hollodotme\FastCGI\ClusterProxy; use hollodotme\FastCGI\Collections\Cluster; use hollodotme\FastCGI\SocketConnections\NetworkSocket; use hollodotme\FastCGI\SocketConnections\UnixDomainSocket; $cluster = Cluster::fromConnections( new NetworkSocket( '127.0.0.1', 9000 ), new NetworkSocket( '10.100.10.42', 9000 ), new UnixDomainSocket( '/var/run/php7.3-fpm.sock' ) ); $clusterProxy = new ClusterProxy( $cluster );
在集群代理类中,以下方法集用于发送请求和处理响应
-
$clusterProxy->sendAsyncRequest(ProvidesRequestData $request) : void
向集群中的所有连接发送异步请求。 (非阻塞) -
$clusterProxy->readReadyResponses(?int $timeoutMs = null) : \Generator|ProvidesResponseData[]
读取并产生所有已完成请求的响应。
(非阻塞,适用于循环中) -
$clusterProxy->waitForResponses(?int $timeoutMs = null) : void
等待先前获得的请求 ID 的响应并按完成请求的顺序调用相应的响应回调。
(阻塞直到读取所有响应或读取超时) -
$clusterProxy->hasUnhandledResponses() : bool
如果有未处理的响应,则返回 TRUE,否则返回 FALSE。 -
$clusterProxy->handleReadyResponses(?int $timeoutMs = null) : void
按照完成请求的顺序调用相应的响应回调。
(非阻塞,意在结合$clusterProxy->hasUnhandledResponses()
在循环中使用)
集群状态
此功能自库的 v0.2.0
版本以来可用。
为了检索集群中所有快速CGI服务器的状态,引入了 ClusterProxy#getStatus()
方法。
目前此方法仅支持PHP-FPM的状态响应实现,但可以通过实现接口 hollodotme\FastCGI\Interfaces\ProvidesServerStatus
容易地扩展到其他快速CGI服务器。
<?php declare(strict_types=1); namespace hollodotme\FastCGI\Interfaces; interface ProvidesServerStatus { /** * Returns the original response object for the status request provided by hollodotme/fast-cgi-client * @see https://github.com/hollodotme/fast-cgi-client/blob/2.x-stable/src/Responses/Response.php * * @return ProvidesResponseData */ public function getResponse() : ProvidesResponseData; /** * Returns the connection object used for the status request * in order to identify the server that produced the status response * * @return ConfiguresSocketConnection */ public function getConnection() : ConfiguresSocketConnection; /** * Returns any data structure representing the status information of the server * @return mixed */ public function getStatus(); /** * Returns a list of any data structure representing current processes running on the server * @return array */ public function getProcesses() : array; }
集群状态示例
以下代码读取了库的 docker-compose 设置 中所有3个php-fpm容器的状态。
请注意:如果服务器配置中没有启用状态端点(PHP-FPM的 pm.status_path
),则 ClusterProxy#getStatus()
方法将抛出 RuntimeException
。
<?php declare(strict_types=1); namespace hollodotme\FastCGI\Examples; use hollodotme\FastCGI\ClusterProxy; use hollodotme\FastCGI\Collections\Cluster; use hollodotme\FastCGI\Responses\PhpFpmStatusResponse; use hollodotme\FastCGI\SocketConnections\NetworkSocket; require_once __DIR__ . '/../vendor/autoload.php'; $cluster = Cluster::fromConnections( new NetworkSocket( 'php71', 9001 ), new NetworkSocket( 'php72', 9001 ), new NetworkSocket( 'php73', 9001 ) ); $clusterProxy = new ClusterProxy( $cluster ); $statusResponses = $clusterProxy->getStatus( '/status?full' ); # If you do not want the list processes, use the following line to get the status only # $statusResponses = $clusterProxy->getStatus( '/status' ); /** @var PhpFpmStatusResponse $statusResponse */ foreach ( $statusResponses as $statusResponse ) { $connection = $statusResponse->getConnection(); $status = $statusResponse->getStatus(); $processes = $statusResponse->getProcesses(); $response = $statusResponse->getResponse(); echo '[ SERVER: ', $connection->getSocketAddress(), " ]\n"; echo '- Pool name: ', $status->getPoolName(), "\n"; echo '- Process manager: ', $status->getProcessManager(), "\n"; echo '- Started at: ', $status->getStartTime()->format( 'c' ), "\n"; echo '- Seconds since start: ', $status->getStartSince(), "\n"; echo '- Number of accepted connections: ', $status->getAcceptedConnections(), "\n"; echo '- Current listen queue: ', $status->getListenQueue(), "\n"; echo '- Listen queue maximum: ', $status->getMaxListenQueue(), "\n"; echo '- Listen queue length: ', $status->getListenQueueLength(), "\n"; echo '- Number of idle processes: ', $status->getIdleProcesses(), "\n"; echo '- Number of active processes: ', $status->getActiveProcesses(), "\n"; echo '- Number of total processes: ', $status->getTotalProcesses(), "\n"; echo '- Number of active processes maximum: ', $status->getMaxActiveProcesses(), "\n"; echo '- Times max children reached: ', $status->getMaxChildrenReached(), "\n"; echo '- Number of slow requests: ', $status->getSlowRequests(), "\n"; echo "\nPrinting processes:\n\n"; foreach ( $processes as $index => $process ) { echo '- [ PROCESS #', ($index + 1), " ]\n"; echo ' * PID: ', $process->getPid(), "\n"; echo ' * State: ', $process->getState(), "\n"; echo ' * Started at: ', $process->getStartTime()->format( 'c' ), "\n"; echo ' * Seconds since start: ', $process->getStartSince(), "\n"; echo ' * Number of requests processed: ', $process->getRequests(), "\n"; echo ' * Last request duration: ', $process->getRequestDuration(), "\n"; echo ' * Last request method: ', $process->getRequestMethod(), "\n"; echo ' * Last request URI: ', $process->getRequestUri(), "\n"; echo ' * Last content length: ', $process->getContentLength(), "\n"; echo ' * Last user: ', $process->getUser(), "\n"; echo ' * Last script: ', $process->getScript(), "\n"; echo ' * CPU usage of last request: ', $process->getLastRequestCpu(), "\n"; echo ' * Memory usage of last request: ', $process->getLastRequestMemory(), "\n"; echo "\n\n---\n\n"; } echo 'Processing duration: ', $response->getDuration(), " seconds\n\n"; }
此脚本产生的输出示例
[ SERVER: tcp://php71:9001 ]
- Pool name: network
- Process manager: dynamic
- Started at: 2019-06-10T14:56:45+00:00
- Seconds since start: 18094
- Number of accepted connections: 81
- Current listen queue: 0
- Listen queue maximum: 0
- Listen queue length: 128
- Number of idle processes: 1
- Number of active processes: 1
- Number of total processes: 2
- Number of active processes maximum: 2
- Times max children reached: 0
- Number of slow requests: 0
Printing processes:
- [ PROCESS #1 ]
* PID: 8
* State: Idle
* Started at: 2019-06-10T14:56:45+00:00
* Seconds since start: 18094
* Number of requests processed: 40
* Last request duration: 190
* Last request method: -
* Last request URI: -
* Last content length: 0
* Last user: -
* Last script: -
* CPU usage of last request: 0
* Memory usage of last request: 2097152
---
- [ PROCESS #2 ]
* PID: 9
* State: Running
* Started at: 2019-06-10T14:56:45+00:00
* Seconds since start: 18094
* Number of requests processed: 41
* Last request duration: 190
* Last request method: GET
* Last request URI: /status?full
* Last content length: 0
* Last user: -
* Last script: -
* CPU usage of last request: 0
* Memory usage of last request: 0
---
Processing duration: 0.0137939453125 seconds
[ SERVER: tcp://php72:9001 ]
- Pool name: network
- Process manager: dynamic
- Started at: 2019-06-10T14:56:46+00:00
- Seconds since start: 18093
- Number of accepted connections: 75
- Current listen queue: 0
- Listen queue maximum: 0
- Listen queue length: 128
- Number of idle processes: 1
- Number of active processes: 1
- Number of total processes: 2
- Number of active processes maximum: 2
- Times max children reached: 0
- Number of slow requests: 0
Printing processes:
- [ PROCESS #1 ]
* PID: 10
* State: Idle
* Started at: 2019-06-10T14:56:46+00:00
* Seconds since start: 18093
* Number of requests processed: 38
* Last request duration: 217
* Last request method: -
* Last request URI: -
* Last content length: 0
* Last user: -
* Last script: -
* CPU usage of last request: 0
* Memory usage of last request: 2097152
---
- [ PROCESS #2 ]
* PID: 11
* State: Running
* Started at: 2019-06-10T14:56:46+00:00
* Seconds since start: 18093
* Number of requests processed: 37
* Last request duration: 177
* Last request method: GET
* Last request URI: /status?full
* Last content length: 0
* Last user: -
* Last script: -
* CPU usage of last request: 0
* Memory usage of last request: 0
---
Processing duration: 0.027499914169312 seconds
[ SERVER: tcp://php73:9001 ]
- Pool name: network
- Process manager: dynamic
- Started at: 2019-06-10T14:56:45+00:00
- Seconds since start: 18094
- Number of accepted connections: 1706
- Current listen queue: 0
- Listen queue maximum: 1
- Listen queue length: 128
- Number of idle processes: 2
- Number of active processes: 1
- Number of total processes: 3
- Number of active processes maximum: 23
- Times max children reached: 0
- Number of slow requests: 0
Printing processes:
- [ PROCESS #1 ]
* PID: 331
* State: Idle
* Started at: 2019-06-10T17:00:25+00:00
* Seconds since start: 10674
* Number of requests processed: 383
* Last request duration: 185
* Last request method: -
* Last request URI: -
* Last content length: 0
* Last user: -
* Last script: -
* CPU usage of last request: 0
* Memory usage of last request: 2097152
---
- [ PROCESS #2 ]
* PID: 497
* State: Running
* Started at: 2019-06-10T17:31:02+00:00
* Seconds since start: 8837
* Number of requests processed: 59
* Last request duration: 244
* Last request method: GET
* Last request URI: /status?full
* Last content length: 0
* Last user: -
* Last script: -
* CPU usage of last request: 0
* Memory usage of last request: 0
---
- [ PROCESS #3 ]
* PID: 315
* State: Idle
* Started at: 2019-06-10T16:42:27+00:00
* Seconds since start: 11752
* Number of requests processed: 433
* Last request duration: 230
* Last request method: -
* Last request URI: -
* Last content length: 0
* Last user: -
* Last script: -
* CPU usage of last request: 0
* Memory usage of last request: 2097152
---
Processing duration: 0.029183149337769 seconds
贡献
欢迎贡献,并将获得全面认可。请参阅 贡献指南 了解详情。