PHP-PM is a process manager, supercharger and load balancer for PHP applications.
It's based on ReactPHP and works best with applications that use request-response frameworks like Symfony's HTTPKernel. The approach of this is to kill the expensive bootstrap of PHP (declaring symbols, loading/parsing files) and the bootstrap of feature-rich frameworks. See Performance section for a quick hint. PHP-PM basically spawns several PHP instances as worker bootstraping your application (eg. the whole Symfony Kernel) and hold it in the memory to be prepared for every incoming request: This is why PHP-PM makes your application so fast.
More information can be found in the article: Bring High Performance Into Your PHP App (with ReactPHP)
ppm start
- done. (if configured with ppm config
)Does your app/library support PPM? Show it!
[![PPM Compatible](https://raw.githubusercontent.com/php-pm/ppm-badge/master/ppm-badge.png)](https://github.com/php-pm/php-pm)
To get PHP-PM you need beside the php binary also php-cgi, which comes often with php. If not available try to install it:
Debian/Ubuntu (https://www.digitalocean.com/community/tutorials/how-to-upgrade-to-php-7-on-ubuntu-14-04)
apt-get install php7.0-cgi
By default cgi bin is in /usr/lib/cgi-bin/php
, so you need to run:
sudo ln -s /usr/lib/cgi-bin/php /usr/bin/php7.0-cgi
Red Hat/Centos (RHEL-7, 6) (https://webtatic.com/packages/php70/)
install Webtatic first
yum install php70w-cli
Mac OS X - Homebrew (https://github.com/Homebrew/homebrew-php)
brew install php70
Mac OS X - Macports
port install php70-cgi
By default, PPM looks for a binary named php-cgi
. If your PHP installation uses
a different binary name, you can specify the full path to that binary with the php-cgi
configuration option (for example: ppm config --cgi-path=/opt/local/bin/php-cgi70
).
On Ubuntu for example per default pcntl_*
functions are disabled.
If you get Warning: pcntl_signal() has been disabled for security reasons
, you should activate these functions:
Open /etc/php5/cgi/php.ini
, find line disable_functions = pcntl_alarm,pcntl_fork, ...
and place a ;
in front of it:
; This directive allows you to disable certain functions for security reasons.
; It receives a comma-delimited list of function names.
; http://php.net/disable-functions
;disable_functions = pcntl_alarm,pcntl_fork, ...
$ git clone https://github.com/php-pm/php-pm.git
$ cd php-pm
$ composer install
$ ln -s `pwd`/bin/ppm /usr/local/bin/ppm
$ ppm --help
# change minimum-stability to dev in your composer.json (until we have a version tagged): "minimum-stability": "dev"
composer require php-pm/php-pm:dev-master
composer require php-pm/httpkernel-adapter:dev-master #if you have httpkernel (laravel, symfony)
./vendor/bin/ppm config --bootstrap=symfony #places a ppm.json in your directory
./vendor/bin/ppm start #reads ppm.json and starts the server like you want
Once configured (composer and ppm.json) you can start your app on your development machine or server instantly:
composer install
./vendor/bin/ppm start
When debug
is enabled, PHP-PM detects file changes and restarts its worker automatically.
To get the maximum performance you should usually use --app-env=prod
with disabled
debug --debug=0
. Also make sure xdebug is disabled. Try with different amount of workers.
Usually a 10% over your cpu core count is good. Example: If you have 8 real cores (excl. hyper-threading) use --workers=9
.
To get even more performance (for static file serving or for rather fast applications) try a different event loop (see https://github.com/reactphp/event-loop).
If you get strange issues in your application and you have no idea where they are coming from try
using only one worker --workers=1
and enable -v
or -vv
.
When debugging you should use xdebug as you're used to. If you set a break point and hold the application, then only one worker is stopped until you release the break point. All other workers are fully functional.
Note for XDebug and PHPStorm: Since php-pm uses at least two processes, there are two xdebug instances as well. PHPStorm is per default configured to only accept one connection at a time. You need to increase that. You won't get xdebug working with your application if you don't increase that count.
In all workers the STDOUT is redirected to the connected client. So take care, var_dump
, echo
are not displayed on the console.
STDERR is not redirected to the client, but to the console. So, for very simple debugging you could use error_log('hi')
and you'll see it on the console.
Per default exceptions and errors are only displayed on the console, prettified with Symfony/Debug component.
HttpKernel for Symfony/Laravel - https://github.com/php-pm/php-pm-httpkernel
Drupal - https://github.com/php-pm/php-pm-drupal
Zend - https://github.com/php-pm/php-pm-zend
Start
cd ~/my/path/to/symfony/
ppm start
ppm start ~/my/path/to/symfony/ --bootstrap=Symfony --bridge=HttpKernel
cd ~/my/path/to/symfony/
./vendor/bin/ppm start
cd my-project
composer require php-pm/httpkernel-adapter:dev-master
$ ./bin/ppm start --bootstrap=symfony
cd my-project
composer require php-pm/httpkernel-adapter:dev-master
$ ./vendor/bin/ppm start --bootstrap=laravel
cd my-project
composer require php-pm/httpkernel-adapter:dev-master
$ ./bin/ppm start --bootstrap=drupal
cd my-project
composer require php-pm/zend-adapter:dev-master
$ ./bin/ppm start --bridge=Zf2 --bootstrap=Zf2
For all Wordpress lovers out there: PPM is not going to work with Wordpress due to the lack of request-response abstraction. We highly doubt that Wordpress is ever going to be compatible because its architecture is written in a way that makes it currently impossible to serve multiple requests in one application process.
6x4GHz Intel i7, 16GB RAM. 10 concurrent, 1000 total request: ab -c 10 -n 1000 http://127.0.0.1:8080/
ppm start --bootstrap=symfony --app-env=prod --logging=0 --debug=0 --workers=20
PHP Version | Dynamic at Jarves | Static file |
---|---|---|
7.0.3, StreamSelectLoop | 2387,67 | 3944,52 |
5.6.18, StreamSelectLoop | 1663,56 | 2636,09 |
5.6.18, LibEventLoop | 1811,76 | 3441,72 |
https://github.com/bestmomo/laravel5-example
ppm start --bootstrap=laravel --app-env=prod --debug=0 --logging=0 --workers=20
php70-event
, but you can try LibEventLoop php56-libevent
)Please help us fix these issues by creating pull requests. :)
Example config for NGINX:
server {
root /path/to/symfony/web/;
server_name servername.com;
location / {
try_files $uri @ppm;
}
location @ppm {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:8080;
}
}
To get the real remote IP in your Symfony application for example, don't forget to add ppm (default 127.0.0.1
)
as trusted reverse proxy.
# app/config/config.yml
# ...
framework:
trusted_proxies: [127.0.0.1]
More information at http://symfony.com/doc/current/cookbook/request/load_balancer_reverse_proxy.html.
Since PPM has also a static file server (which isn't quite as fast as nginx, but works for basic usage, see Performance section), you can use PPM directly on your server or local. Do not run ppm as root (to get port like 80 working), as it does not set a new UID of the current process and would run all the time as root, which is highly unrecommended.
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。