负载均衡PHP内置服务器?

时间:2016-10-03 23:51:16

标签: php multithreading load-balancing reverse-proxy

我的开发环境由单线程内置PHP服务器组成。效果很好:

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

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

我的问题:

我可以利用哪种现有解决方案将请求异步代理到同一PHP内置服务器的多个实例?

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

2 个答案:

答案 0 :(得分:5)

super-server,如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 :(得分:3)

我同意复制生产环境的虚拟副本是最好的选择。您不仅仅想要引发问题,而是想让自己陷入相同的问题。此外,您无法保证在备用设置下会遇到所有相同的问题。

但是,如果你想这样做,你就没有多少选择。您可以将传入的请求定向到一个中间软件,然后将它们发送到php后端 - 这将是Apache,Nginx解决方案 - 或者您不需要,并且请求由单个php线程直接处理

如果您不愿意使用该插入的软件,那么您和客户之间只有一层:网络。理论上,您可以为自己设置循环DNS。你给自己多个IP,加载一个监听每个IP的PHP服务器,然后让你的客户端连接遍布它们。请注意,这会将每个客户分配给一个特定的流程 - 这可能不是您正在寻找的并行级别。