我有一个 PHP 脚本,需要联系另一台服务器以获取有关某些内容的信息。
我目前正在使用 SSH (通过ControlMaster auto
)来实现此目的,它工作正常。
然而,问题是延迟太高——仅仅shell_exec
需要ssh example.com
80 毫秒,这远远高于服务器之间的实际延迟(0.2 毫秒,因为它们通过以太网电缆连接)。
所以现在我只想简单地思考通过现有的 SSH 连接传递数据而不是尝试将新的 SSH 连接复用到现有连接中。
但是,我不知道该怎么做。将数据传递到stdin
的最佳方法是什么现存的SSH 连接example.com
,然后从其stdout
?读取结果输出
(BASH 解决方案在这里很好——我不需要任何特定于 PHP 的东西。)
答案1
如果你正在使用ControlMaster auto
你已经重用现有的 TCP 连接,但是TCP连接建立还是很快的。
80 毫秒的延迟可能是由以下因素的组合引起的:
- php
shell_exec
启动一个新的 shell(尝试exec
一下?) - 通过现有连接设置新 ssh 通道的额外开销
- 通过新的 ssh 通道在远程服务器上执行命令
如果您需要更快的响应,请首先单独测量其中的每一个,然后努力减少缓慢部分的延迟。如果您发现 #2 正如您所怀疑的那样减慢了您的速度,您可以尝试通过现有的永久 ssh 通道发送命令,可能通过命名管道使用您的远程命令循环读取(@symcbean 提出的警告将适用)。
像这样的东西
mkfifo /tmp/f_in
mkfifo /tmp/f_out
tail -f /tmp/f_in | ssh [email protected] 'bash -c "while read name; do echo hello \$name; done"' > /tmp/f_out &
time response=$(head -n 1 /tmp/f_out & echo dwurf > /tmp/f_in); echo $response
所有这些都不会像创建可查询信息的网络服务那么快。我也预计它会非常不可靠。
答案2
如果您有一个“静态”ssh 连接,那么 php 脚本的实例将如何绑定到它才能使用它?
很快我们就开始讨论锁定语义(很难在 php 中实现)。然后是扩展问题。您当前的解决方案可以很好地扩展,因为每个 ssh 连接都是离散的。
我现在假设您控制两个盒子上运行的代码。如果您使用 ssh 的原因是 ssh 服务器正在运行一些专有代码,那么这会消除解决方案的许多模式。
如果它们通过以太网连接,那么我们是否应该假设网络是可信的?为什么不使用 rsh 之类的东西?
客户端和服务器之间的权限分离重要吗?
这听起来像是 XY 问题。
这里唯一实用的解决方案是:
1) 编写一个在 ssh 客户端运行的服务器,该服务器维护开放的 ssh 连接,并分时访问从本地主机连接的客户端,而无需 ssh 的开销。这并非微不足道,也无法扩展。
2) 使用低延迟协议和任何相关的身份验证/完整性/机密性来实现客户端和服务器。这也不是小事。而且您没有告诉我们您目前使用 ssh 的方式和原因。