detain/sshpool
Composer 安装命令:
composer require detain/sshpool
包简介
SSH command queue and connection pool runs tons of commands on a ssh host concurrently with completion callback.
README 文档
README
detain/sshpool is a small PHP library for running many shell commands
on a single SSH host concurrently. It maintains one SSH session, opens
multiple ssh2_exec channels in parallel up to a configurable cap,
collects each command's stdout / stderr / exit status, and fires a
per-command callback on completion. Commands can be queued while the
pool is already running, automatic retries with a back-off delay are
supported, and per-command timeouts kill long-running work.
Requirements
- PHP 8.0+
- The
ext-ssh2PHP extension - An SSH host you can authenticate to with a key pair
Password authentication is not currently wired through; the supported path is public/private key authentication via
ssh2_auth_pubkey_file.
Installation
composer require detain/sshpool
If you do not already have ext-ssh2 installed:
# Debian / Ubuntu sudo apt-get install php-ssh2 # RHEL / Alma / Rocky sudo dnf install php-pecl-ssh2
Quick Start
require 'vendor/autoload.php'; use Detain\SshPool\SshPool; $pool = new SshPool( 'example.com', // host 22, // port 'deploy', // ssh user '', // password (unused — pubkey auth) '/home/me/.ssh/id_rsa.pub', '/home/me/.ssh/id_rsa' ); $pool->setMaxThreads(10); $pool->setMaxRetries(2); foreach (['uptime', 'df -h', 'free -m'] as $cmd) { $pool->addCommand( $cmd, null, // auto id ['command' => $cmd], // user data passed to callback function ($cmd, $id, $data, $exit, $stdout, $stderr) { echo "[{$id}] {$cmd} (exit {$exit}):\n{$stdout}\n"; if ($stderr !== '') { fwrite(STDERR, "[{$id}] stderr: {$stderr}\n"); } }, 30 // 30s timeout ); } $pool->run();
Usage Patterns
One-shot synchronous command
For a single command where you want a synchronous result rather than a
callback, use runCommand():
$result = $pool->runCommand('hostname'); // $result === ['cmd' => 'hostname', 'exitStatus' => 0, 'out' => '...', 'err' => '']
runCommand() returns false if the channel cannot be opened.
Adding commands while the pool is running
addCommand() is safe to call from inside a completion callback. New
commands join $cmdQueue and the run loop picks them up on its next
iteration.
$pool->addCommand('first', null, null, function ($cmd, $id, $data, $exit) use ($pool) { if ($exit === 0) { // Chain a follow-up command. $pool->addCommand('second'); } }); $pool->run();
Non-blocking single iteration
run(true) performs one polling iteration (start any newly-available
commands, drain finished output, promote any due retries) and returns.
This is useful when you want to integrate the pool into your own event
loop.
while (!$done) { $done = $pool->run(true); // ... do other work ... }
Custom SSH connection methods
ssh2_connect() accepts an algorithm/method override array. Pass it
through the constructor's seventh argument when, for example, you need
to whitelist a deprecated host key algorithm against a legacy server:
$pool = new SshPool( $host, 22, $user, '', $pub, $priv, ['hostkey' => 'ssh-rsa'] );
Configuration
| Setter | Default | Effect |
|---|---|---|
setMaxThreads(int) |
50 |
Maximum number of channels open concurrently. Clamped to >= 1. |
setMaxRetries(int) |
0 |
Retry attempts on a non-zero exit status (or undersized output). 0 disables retry. |
setWaitRetry(int) |
15 |
Seconds to wait before promoting a retry back into the run queue. |
setMinConfigSize(int) |
0 |
Minimum stdout byte count required to consider a command successful. 0 disables. |
$pollInterval (public int) |
25000 |
Microseconds between run-loop polls in blocking mode. |
Public API
new SshPool( string $host, int $port, string $user, string $pass, string $pubKey, string $privKey, array $methods = [] ); string addCommand( string $cmd, ?string $id = null, mixed $data = null, ?callable $callback = null, int $timeout = 0 ); bool run(bool $once = false); array|false runCommand(string $cmd); void connect(); void disconnect(); resource|null getConnection();
Callback signature
function ( string $cmd, string $id, mixed $data, // user data passed to addCommand() int $exitStatus, // -1 if unknown / timed out string $stdout, string $stderr ): void;
Retry Semantics
A command is considered failed (and eligible for retry) when either:
- its exit status is non-zero, or
minConfigSize > 0andstrlen(stdout) < minConfigSize.
Failed commands are deferred for waitRetry seconds, then promoted
back into the run queue. The original timeout is preserved across
retries. After maxRetries attempts the completion callback is
invoked with the most recent exit status.
Timeouts
When addCommand($cmd, ..., $timeout) is given a non-zero $timeout,
the run loop closes the command's streams once
time() - start_time > $timeout. The callback is invoked just like
any other completion. If a real exit status was not yet observed, the
command is reported with exitStatus = -1.
The metadata property captures the actual duration and a boolean
timed_out flag per id:
$pool->metadata['my-id'] === [ 'exit_status' => -1, 'duration' => 30, 'timed_out' => true, ];
Development
composer install ./vendor/bin/phpunit # run the test suite ./vendor/bin/phpunit --filter Foo # run one test ./vendor/bin/phpunit --coverage-text
The tests use a FakeSshPool fixture
(tests/Fixtures/FakeSshPool.php) that bypasses ext-ssh2 so the
queue / callback / retry logic is verified without needing a live SSH
server.
License
GPL-3.0. See LICENSE.
Author
Joe Huss · detain@interserver.net
detain/sshpool 适用场景与选型建议
detain/sshpool 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1.71k 次下载、GitHub Stars 达 1, 最近一次更新时间为 2023 年 01 月 27 日, 在 PHP 生态内属于活跃度较高的组件。
我们在过去多个企业项目中使用过 detain/sshpool 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 detain/sshpool 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
统计信息
- 总下载量: 1.71k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1
- 点击次数: 9
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: GPL-3.0
- 更新时间: 2023-01-27