PHP开发 之 FastCGI与PHP-FPM

目录

  • FastCGI

  • PHP-FPM

  • FPM配置

  • Nginx配置

FastCGI

FastCGI = Fast + CGI

因此 想要理解FastCGI的关键就在于CGI

CGI = Common Gateway Interface

Common Gateway Interface (CGI) offers a standard protocol for web servers

to execute programs that execute like Console applications (also called Command-line interface programs) running on a server that generates web pages dynamically

上述定义摘自Wiki - Common Gateway Interface

理解了CGI 那么想要理解"Fast"的CGI就很容易了

FastCGI's main aim is to reduce the overhead associated with interfacing the web server and CGI programs

allowing a server to handle more web page requests at once

那么FastCGI时如何做到更优的性能的呢? 答案就是

Instead of creating a new process for each request, FastCGI uses persistent processes to handle a series of requests

上述定义摘自Wiki - FastCGI

PHP-FPM

我们已经知道FastCGI是Web Server和应用程序之间的通信协议

那么无论是Web Server 还是应用程序都需要遵守并实现FastCGI协议

当前主流的Web Server都支持FastCGI

  • Apache HTTP Server

  • Lighttpd

  • Microsoft IIS

  • Nginx

同时主流的编程语言也都有相应的实现 详细参考Language bindings for the FastCGI API

而已经成为PHP官方标配的最佳实现就是这里的主角: PHP-FPM

PHP-FPM = PHP - FastCGI Process Manager

PHP-FPM (FastCGI Process Manager) is an alternative PHP FastCGI implementation

with some additional features useful for sites of any size, especially busier sites

上述定义摘自Home - PHP-FPM

FPM配置

PHP-FPM作为进程管理器 (当然它不仅仅是进程管理器 详见上述讨论) 它的默认配置如下

cat /etc/php/7.0/fpm/pool.d/www.conf | grep -v '^$' | grep -v ';'
[www]
user = www-data
group = www-data
listen = /run/php/php7.0-fpm.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
ps ax | grep fpm -v grep
 1244 ?        Ss     2:49 php-fpm: master process (/etc/php/7.0/fpm/php-fpm.conf)
15985 ?        S      0:02 php-fpm: pool www
15986 ?        S      0:01 php-fpm: pool www
17604 ?        S      0:00 php-fpm: pool www

这里 有一个读者容易忽视的配置

listen = /run/php/php7.0-fpm.sock

那么 类似*.sock的listen方式和下面的配置有何区别呢

listen = 127.0.0.1:9000

答案就是

/run/php/php7.0-fpm.sock
1 Web Server与PHP-FPM的通信基于文件系统socket效率相对更高
2 但是仅限于Web Server与PHP-FPM在同一台服务器

127.0.0.1:9000
1 Web Server与PHP-FPM的通信基于网络TCP效率相对较低
2 但是Web Server与PHP-FPM可以不局限于同一台服务器

Nginx配置

当我们使用Nginx作为Web Server时 对于PHP项目的配置通常如下

server {
    location / {
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        fastcgi_param SCRIPT_FILENAME /path/to/index.php;
    }
}
cat /etc/nginx/fastcgi_params
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  REQUEST_SCHEME     $scheme;
fastcgi_param  HTTPS              $https if_not_empty;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;

fastcgi_param HTTP_IF_NONE_MATCH $http_if_none_match;
fastcgi_param HTTP_IF_MODIFIED_SINCE $http_if_modified_since;

细心的读者 可能已经发现除了/etc/nginx/fastcgi_params还有/etc/nginx/fastcgi.conf

那么 两者的内容有何区别呢?

diff /etc/nginx/fastcgi_params /etc/nginx/fastcgi.conf -c
*** /etc/nginx/fastcgi_params   Wed Nov 15 17:16:27 2017
--- /etc/nginx/fastcgi.conf Tue Apr 26 22:51:14 2016
***************
*** 1,4 ****
--- 1,5 ----

+ fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
  fastcgi_param  QUERY_STRING       $query_string;
  fastcgi_param  REQUEST_METHOD     $request_method;
  fastcgi_param  CONTENT_TYPE       $content_type;
***************
*** 23,28 ****

  # PHP only, required if PHP was built with --enable-force-cgi-redirect
  fastcgi_param  REDIRECT_STATUS    200;
-
- fastcgi_param HTTP_IF_NONE_MATCH $http_if_none_match;
- fastcgi_param HTTP_IF_MODIFIED_SINCE $http_if_modified_since;
--- 24,26 ----

关于diff命令 更多参考diff

原来 由于很多开发者进行如下的硬编码

fastcgi_param SCRIPT_FILENAME /path/to/index.php;

所以 为了规范起见引入了/etc/nginx/fastcgi.conf

fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;

参考

  • CGI specification

  • FastCGI Specification

  • CGI,FastCGI,PHP-CGI与PHP-FPM

  • 搞不清FastCgi与PHP-fpm之间是个什么样的关系

  • Web Service(Nginx、Apache、IIS)、CGI、FastCGI与PHP-FPM概念、之间关系和处理流程

  • 如何通俗地解释 CGI、FastCGI、php-fpm 之间的关系?

  • PHP FastCGI Example

  • 如何正确配置Nginx+PHP

  • Performance of unix sockets vs TCP ports

  • PHP-FPM: Socket vs TCP/IP and sysctl tweaking

你可能感兴趣的:(PHP开发 之 FastCGI与PHP-FPM)