PHP内置服务器的负载均衡?

8

我的开发环境包括单线程的内置PHP服务器。非常好用:

APP_ENV=dev php -S localhost:8080 -c php.ini web/index.php

其中一个问题是内置服务器是单线程的。这使得许多并行XHR按顺序解析。最糟糕的是,它不能很好地模拟我们的生产环境。在这种设置中,一些并发的前端问题根本不存在。

我的问题:

有没有现有的解决方案可以异步代理到同一PHP内置服务器的多个实例?

例如,我会在不同的端口上运行几个终端会话来运行内置服务器,然后每个请求都路由到这些实例中的不同实例。换句话说,我希望使用最简单的设置(如果可能的话,不使用Apache或Nginx)并行运行多个应用程序实例。


1
你考虑过使用PHP-FPM吗? - scrowler
1
我建议不要这样做,因为它会变得很复杂。更好的解决方案是运行一个复制您的生产环境的虚拟机。这样可以进行更准确的测试,而不会影响您的本地设置。 - Matt S
2个回答

6

像inetd或tcpserver这样的超级服务器非常好用。我是后者的粉丝:

tcpserver等待传入连接,并针对每个连接运行您选择的程序。

有了这个,现在您想使用反向代理从网络中获取HTTP协议,然后将其交给特定于连接的PHP服务器。非常简单:

$ cat proxy-to-php-server.sh
#!/bin/bash -x

# get a random port -- this could be improved
port=$(shuf -i 2048-65000 -n 1)

# start the PHP server in the background
php -S localhost:"${port}" -t "$(realpath ${1:?Missing path to serve})" &
pid=$!
sleep 1

# proxy standard in to nc on that port
nc localhost "${port}"

# kill the server we started
kill "${pid}"

好的,现在你已经准备就绪了。开始监听你的主端口:

tcpserver -v -1 0 8080 ./proxy-to-php-server.sh ./path/to/your/code/

这是发生的事情:
  • tcpserver 在所有接口上监听端口8080(0 8080),并在启动和每个连接(-v -1)时打印调试信息。
  • 对于该端口上的每个连接,tcpserver会生成代理助手,服务于给定的代码路径(path/to/your/code/)。专业提示:将其设置为绝对路径。
  • 代理脚本在随机端口上启动了一个特制的PHP Web服务器。(这可以改进:脚本没有检查端口是否正在使用。)
  • 然后代理脚本将其标准输入(来自tcpserver服务的连接)传递给特制服务器。
  • 交互发生后,代理脚本终止特制服务器。
这应该可以让您进入正确方向。我没有进行广泛测试。(仅在GNU/Linux,Centos 6上进行测试。)您需要调整代理调用内置PHP服务器以匹配您的用例。
请注意,这不是一个“负载平衡”服务器,严格来说:它只是一个并行的临时服务器。不要期望太高的生产质量!

安装tcpserver

$ curl -sS http://cr.yp.to/ucspi-tcp/ucspi-tcp-0.88.tar.gz | tar xzf -
$ cd ucspi-tcp-0.88/
$ curl -sS http://www.qmail.org/moni.csi.hu/pub/glibc-2.3.1/ucspi-tcp-0.88.errno.patch | patch -Np1
$ sed -i 's|/usr/local|/usr|' conf-home
$ make
$ sudo make setup check

1
首先,非常感谢@bishop的工作,我解决了我的问题。 其次,我发现你可以通过更改以下内容来加快请求时间:将sleep 1更改为**sleep 0.1**只需在您的系统上检查一下sleep命令是否支持小数秒即可。有关更多信息,请参见:https://serverfault.com/questions/469247/how-do-i-sleep-for-a-millisecond-in-bash-or-ksh - Jiab77

3
我同意复制生产环境的虚拟副本是最好的选择。您不仅要避免问题,还要在副本中遇到相同的问题。此外,在备用设置下,很难保证您会遇到全部相同的问题。
然而,如果您确实希望这样做,您没有太多选择。您可以将传入请求定向到一个中间软件,然后将它们分派给PHP后端处理——这将是Apache和Nginx解决方案;或者您可以不使用中间软件,直接由单个php线程处理请求。
如果您不想使用中间软件,那么客户端和您之间只有一层:网络。理论上,您可以为自己设置轮询DNS。您可以为自己分配多个IP地址,每个IP地址都加载了一个监听PHP服务器,并让客户端连接跨越它们。请注意,这将把每个客户端分配给特定的进程——这可能不是您正在寻找的并行级别。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接