【Nginx】Nginx实现FastCGI详解

张开发
2026/4/17 6:12:20 15 分钟阅读

分享文章

【Nginx】Nginx实现FastCGI详解
前情提要本篇博客详细的介绍了FastCGI及相关的实战案例同时还介绍了PHP的动态扩展模块memcached以及相关整合及实验案例环境系统RHEL9.6nginx版本nginx version: nginx/1.28.2一、FastCGI简介1.1 CGI的由来最早的Web服务器只能简单地响应浏览器发来的HTTP请求并将存储在服务器上的HTML文件返回给浏览器也就是静态HTML文件但是后期随着网站功能增多网站开发也越来越复杂以至于出现动态技术比如像php(1995年)、Java(1995)、Python(1991)语言开发的网站但是nginx/apache服务器并不能直接运行 php、Java这样的文件apache实现的方式是打补丁但是nginx却通过与第三方基于协议实现即通过某种特定协议将客户端请求转发给第三方服务处理第三方服务器会新建新的进程处理用户的请求处理完成后返回数据给Nginx并回收进程最后nginx在返回给客户端那这个约定就是通用网关接口(common gateway interface简称CGI)CGI协议 是web服务器和外部应用程序之间的接口标准是cgi程序和web服务器之间传递信息的标准化接口。1.2 为什么会有FastCGICGI协议虽然解决了语言解析器和 Web Server 之间通讯的问题但是它的效率很低因为 Web Server 每收到一个请求都会创建一个CGI进程PHP解析器都会解析php.ini文件初始化环境请求结束的时候再关闭进程对于每一个创建的CGI进程都会执行这些操作所以效率很低而FastCGI是用来提高CGI性能的FastCGI每次处理完请求之后不会关闭掉进程而是保留这个进程使这个进程可以处理多个请求。这样的话每个请求都不用再重新创建一个进程了大大提升了处理效率。1.3 什么是PHP-FPMPHP-FPM(FastCGI Process ManagerFastCGI进程管理器)是一个实现了Fastcgi的程序并且提供进程管理的功能。进程包括master进程和worker进程。master进程只有一个负责监听端口接受来自web server 的请求worker进程一般会有多个每个进程中会嵌入一个PHP解析器进行PHP代码的处理。二、FastCGI配置指令简介Nginx基于模块ngx_http_fastcgi_module实现通过fastcgi协议将指定的客户端请求转发至php-fpm处理其配置指令如下fastcgi_pass address:port; #转发请求到后端服务器address为后端的fastcgi server的地址可用位置location, if in location fastcgi_index name; #fastcgi默认的主资源示例fastcgi_index index.php; fastcgi_param parameter value [if_not_empty]; #设置传递给FastCGI服务器的参数值可以是文本变量或组合可用于将Nginx的内置变量赋值给自定义key fastcgi_param REMOTE_ADDR $remote_addr; #客户端源IP fastcgi_param REMOTE_PORT $remote_port; #客户端端口 fastcgi_param SERVER_ADDR $server_addr; #请求的服务器IP地址 fastcgi_param SERVER_PORT $server_port; #请求的服务器端口 fastcgi_param SERVER_NAME $server_name; #请求的server name #Nginx默认配置示例: location ~ \.php$ { root /scripts; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; #默认脚本路径 #fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; #此文件默认系统已提供存放的相对路径为prefix/conf }三、FastCGI实战案例 : Nginx与php-fpm在同一服务器编译安装更方便自定义参数或选项推荐大家使用源码编译官方网站www.php.net3.1 PHP源码编译下载源码包和依赖# 下载源码包和依赖 [rootNginx ~]# wget https://www.php.net/distributions/php-8.3.30.tar.gz [rootNginx ~]# wget https://mirrors.aliyun.com/rockylinux/9.7/devel/x86_64/os/Packages/o/oniguruma-devel-6.9.6-1.el9.6.x86_64.rpm #依赖解压[rootNginx ~]# tar zxf php-8.3.30.tar.gz [rootNginx ~]# ls anaconda-ks.cfg lee.png nginx-1.29.4.tar.gz test.c daolian.png nginx-1.28.1 php-8.3.30 echo-nginx-module-0.64 nginx-1.28.1.tar.gz php-8.3.30.tar.gz echo-nginx-module-0.64.tar.gz nginx-1.29.4 test [rootNginx ~]# cd php-8.3.30源码编译# 下载依赖 [rootNginx ~]# dnf install gcc -y [rootNginx ~]# dnf install systemd-devel.x86_64 -y [rootNginx ~]# dnf install libxml2-devel.x86_64 -y [rootNginx ~]# dnf install sqlite-devel.x86_64 -y [rootNginx ~]# dnf install libcurl-devel.x86_64 -y [rootNginx ~]# dnf install libpng-devel.x86_64 -y [rootNginx ~]# dnf search oniguruma -y [rootNginx ~]# rpm -ivh oniguruma-devel-6.9.6-1.el9.6.x86_64.rpm # 找不到依赖就强制安装 警告oniguruma-devel-6.9.6-1.el9.6.x86_64.rpm: 头V4 RSA/SHA256 Signature, 密钥 ID 350d275d: NOKEY 错误依赖检测失败 oniguruma 6.9.6-1.el9.6 被 oniguruma-devel-6.9.6-1.el9.6.x86_64 需要 [rootNginx ~]# rpm -ivh oniguruma-devel-6.9.6-1.el9.6.x86_64.rpm --nodeps 警告oniguruma-devel-6.9.6-1.el9.6.x86_64.rpm: 头V4 RSA/SHA256 Signature, 密钥 ID 350d275d: NOKEY Verifying... ################################# [100%] 准备中... ################################# [100%] 正在升级/安装... 1:oniguruma-devel-6.9.6-1.el9.6 ################################# [100%] [rootNginx ~]# cd php-8.3.30/ [rootNginx php-8.3.30]# ./configure \ --prefix/usr/local/php \ #安装路径 --with-config-file-path/usr/local/php/etc \ #指定配置路径 --enable-fpm \ #用cgi方式启动程序 --with-fpm-usernginx \ #指定运行用户身份 --with-fpm-groupnginx \ --with-curl \ #打开curl浏览器支持 --with-iconv \ #启用iconv函数转换字符编码 --with-mhash \ #mhash加密方式扩展库 --with-zlib \ #支持zlib库用于压缩http压缩传输 --with-openssl \ #支持ssl加密 --enable-mysqlnd \ #mysql数据库 --with-mysqli \ --with-pdo-mysql \ --disable-debug \ #关闭debug功能 --enable-sockets \ #支持套接字访问 --enable-soap \ #支持soap扩展协议 --enable-xml \ #支持xml --enable-ftp \ #支持ftp --enable-gd \ #支持gd库 --enable-exif \ #支持图片元数据 --enable-mbstring \ #支持多字节字符串 --enable-bcmath \ #打开图片大小调整,用到zabbix监控的时候用到了这个模块 --with-fpm-systemd #支持systemctl 管理cgi [rootNginx php-8.3.30]# ./configure --prefix/usr/local/php --with-config-file-path/usr/local/php/etc --enable-fpm --with-fpm-usernginx --with-fpm-groupnginx --with-curl --with-iconv --with-mhash --with-zlib --with-openssl --enable-mysqlnd --with-mysqli --with-pdo-mysql --disable-debug --enable-sockets --enable-soap --enable-xml --enable-ftp --enable-gd --enable-exif --enable-mbstring --enable-bcmath --with-fpm-systemd [rootNginx php-8.3.30]# make make instsall配置PHP[rootNginx php-8.3.30]# cd /usr/local/php/etc [rootNginx etc]# cp -p php-fpm.conf.default php-fpm.conf [rootNginx etc]# vim php-fpm.conf [global] ; Pid file ; Note: the default prefix is /usr/local/php/var ; Default Value: none pid run/php-fpm.pid [rootNginx etc]# cd php-fpm.d/ [rootNginx php-fpm.d]# cp www.conf.default www.conf [rootNginx php-fpm.d]# vim www.conf 41 listen 0.0.0.0:9000 [rootNginx php-fpm.d]# cp /root/php-8.3.30/php.ini-production /usr/local/php/etc/php.ini [rootNginx php-fpm.d]# vim /usr/local/php/etc/php.ini 989 date.timezone Asia/Shanghai [rootNginx ~]# cp /root/php-8.3.30/sapi/fpm/php-fpm.service /lib/systemd/system/ [rootNginx ~]# vim /lib/systemd/system/php-fpm.service # Mounts the /usr, /boot, and /etc directories read-only for processes invoked by this unit. #ProtectSystemfull #注释此参数 [rootNginx ~]# systemctl daemon-reload [rootNginx ~]# systemctl enable --now php-fpm [rootNginx ~]# netstat -antlupe | grep php tcp 0 0 0.0.0.0:9000 0.0.0.0:* LISTEN 0 329917 165562/php-fpm: mas配置环境变量[rootNginx ~]# vim ~/.bash_profile export PATH$PATH:/usr/local/nginx/sbin:/usr/local/php/sbin:/usr/local/php/bin [rootNginx ~]# source ~/.bash_profile [rootNginx ~]# php -m3.2 PHP整合Nginx访问测试创建php目录和测试网页[rootNginx ~]# mkdir /webdata/dragon.org/php/html -p [rootNginx ~]# vim /webdata/dragon.org/php/html/index.php ?php phpinfo(); ?编辑Nginx子配置文件[rootNginx ~]# vim /usr/local/nginx/conf.d/php.conf server { listen 80; server_name php.dragon.org; root /webdata/dragon.org/php/html; location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi.conf; } }访问测试浏览器访问php.dragon.org/index.php四、php的动态扩展模块php的缓存模块memcachedMemcached不是数据库而是纯内存的分布式缓存系统——它像书桌上的便签纸临时存放你频繁查阅的资料用完即丢只为让你少跑几次书架数据库。其核心原理是用内存空间换访问速度通过Key-Value存储LRU淘汰客户端一致性哈希三要素在微秒级响应高并发请求但绝不持久化数据。软件下载http://pecl.php.net/package/memcache4.1 利用memcache实现php的缓存加速安装memcached[rootNginx ~]# dnf install memcached.x86_64 -y配置memcached[rootNginx ~]# vim /etc/sysconfig/memcached PORT11211 USERmemcached MAXCONN1024 CACHESIZE64 OPTIONS-l 0.0.0.0,::1 [rootNginx ~]# systemctl enable --now memcached.service [rootNginx ~]# netstat -antlupe | grep memcache tcp 0 0 0.0.0.0:11211 0.0.0.0:* LISTEN 991 437305 166169/memcached tcp6 0 0 ::1:11211 :::* LISTEN 991 437306 166169/memcached升级php对memcached的支持[rootNginx ~]# php -m #查看php支持的插件 [rootNginx ~]# tar zxf memcache-8.2.tgz [rootNginx ~]# cd memcache-8.2/ [rootNginx memcache-8.2]# dnf install autoconf -y [rootNginx memcache-8.2]# phpize [rootNginx memcache-8.2]# ./configure make make install [rootNginx memcache-8.2]# ls /usr/local/php/lib/php/extensions/no-debug-non-zts-20230831/ memcache.so opcache.so [rootNginx memcache-8.2]# vim /usr/local/php/etc/php.ini 939 extensionmemcache [rootNginx memcache-8.2]# systemctl restart php-fpm.service [rootNginx memcache-8.2]# php -m | grep memcache memcache测试性能[rootNginx memcache-8.2]# vim memcache.php define(ADMIN_USERNAME,admin); // Admin Username define(ADMIN_PASSWORD,123); // Admin Password $MEMCACHE_SERVERS[] 172.25.254.10:11211; // add more as an array #$MEMCACHE_SERVERS[] mymemcache-server2:11211; // add more as an array [rootNginx memcache-8.2]# cp -p memcache.php /webdir/timinglee.org/php/html/ [rootNginx memcache-8.2]# cp -p example.php /webdir/timinglee.org/php/html/ #测试 # 关闭memcache [rootNginx memcache-8.2]# systemctl stop memcached.service [rootNginx memcache-8.2]# ab -n 1000 -c 300 php.dragon.org/index.php This is ApacheBench, Version 2.3 $Revision: 1913912 $ Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking php.dragon.org (be patient) Completed 100 requests Completed 200 requests Completed 300 requests Completed 400 requests Completed 500 requests Completed 600 requests Completed 700 requests Completed 800 requests Completed 900 requests Completed 1000 requests Finished 1000 requests Server Software: nginx/1.28.2 Server Hostname: php.dragon.org Server Port: 80 Document Path: /index.php Document Length: 78477 bytes Concurrency Level: 300 Time taken for tests: 0.200 seconds Complete requests: 1000 Failed requests: 994 # 可见几乎全部失败 (Connect: 0, Receive: 0, Length: 994, Exceptions: 0) Total transferred: 78641900 bytes HTML transferred: 78478900 bytes Requests per second: 5000.98 [#/sec] (mean) Time per request: 59.988 [ms] (mean) Time per request: 0.200 [ms] (mean, across all concurrent requests) Transfer rate: 384068.55 [Kbytes/sec] received Connection Times (ms) min mean[/-sd] median max Connect: 0 1 1.5 0 4 Processing: 3 50 14.0 56 60 Waiting: 1 50 14.0 56 60 Total: 7 51 12.7 56 62 Percentage of the requests served within a certain time (ms) 50% 56 66% 57 75% 57 80% 57 90% 58 95% 59 98% 59 99% 61 100% 62 (longest request) # 开启memcache [rootNginx memcache-8.2]# systemctl start memcached.service [rootNginx memcache-8.2]# ab -n 1000 -c 300 php.dragon.org/index.php This is ApacheBench, Version 2.3 $Revision: 1913912 $ Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking php.dragon.org (be patient) Completed 100 requests Completed 200 requests Completed 300 requests Completed 400 requests Completed 500 requests Completed 600 requests Completed 700 requests Completed 800 requests Completed 900 requests Completed 1000 requests Finished 1000 requests Server Software: nginx/1.28.2 Server Hostname: php.dragon.org Server Port: 80 Document Path: /index.php Document Length: 78479 bytes Concurrency Level: 300 Time taken for tests: 0.193 seconds Complete requests: 1000 Failed requests: 105 # 可见失败大幅减少 (Connect: 0, Receive: 0, Length: 105, Exceptions: 0) Total transferred: 78641890 bytes HTML transferred: 78478890 bytes Requests per second: 5174.32 [#/sec] (mean) Time per request: 57.979 [ms] (mean) Time per request: 0.193 [ms] (mean, across all concurrent requests) Transfer rate: 397381.38 [Kbytes/sec] received Connection Times (ms) min mean[/-sd] median max Connect: 0 1 1.3 0 4 Processing: 5 49 13.1 55 60 Waiting: 1 49 13.1 54 60 Total: 7 50 11.9 55 62 Percentage of the requests served within a certain time (ms) 50% 55 66% 55 75% 56 80% 57 90% 57 95% 58 98% 59 99% 60 100% 62 (longest request)五、nginxmemcached高速缓存5.1 重新编译nginx部署方法在我们安装的nginx中默认不支持memc和srcache功能需要借助第三方模块来让nginx支持此功能所以nginx需要重新编译[rootNginx ~]# systemctl stop nginx.service [rootNginx ~]# cp /usr/local/nginx/conf/ /mnt/ -r [rootNginx ~]# rm -fr /usr/local/nginx/ [rootNginx ~]# rm -rf nginx-1.29.4 nginx-1.28.1 [rootNginx ~]# tar zxf nginx-1.28.1.tar.gz [rootNginx ~]# cd nginx-1.28.1/ [rootNginx ~]# tar zxf srcache-nginx-module-0.33.tar.gz [rootNginx ~]# tar zxf memc-nginx-module-0.20.tar.gz [rootNginx ~]# cd nginx-1.28.1/ [rootNginx nginx-1.28.1]# ./configure --prefix/usr/local/nginx --usernginx --groupnginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module --add-module/root/memc-nginx-module-0.20 --add-module/root/srcache-nginx-module-0.33 [rootNginx nginx-1.28.1]# make make install [rootNginx ~]# cd /usr/local/nginx/conf [rootNginx conf]# rm -fr nginx.conf [rootNginx conf]# cp /mnt/conf/nginx.conf /mnt/conf/conf.d/ . -r [rootNginx conf]# systemctl start nginx.service5.2 整合memcached# 编辑配置文件 [rootNginx conf]# vim /usr/local/nginx/conf/conf.d/php.conf upstream memcache { server 127.0.0.1:11211; keepalive 512; } server { listen 80; server_name php.timinglee.org; root /webdir/timinglee.org/php/html; index index.php index.html; location /memc { internal; memc_connect_timeout 100ms; memc_send_timeout 100ms; memc_read_timeout 100ms; set $memc_key $query_string; set $memc_exptime 300; memc_pass memcache; } location ~ \.php$ { set $key $uri$args; srcache_fetch GET /memc $key; srcache_store PUT /memc $key; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi.conf; } } [rootNginx conf]# nginx -s reload #测试 [rootNginx conf]# ab -n 10000 -c500 http://php.dragon.org/index.php This is ApacheBench, Version 2.3 $Revision: 1913912 $ Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking php.dragon.org (be patient) Completed 1000 requests Completed 2000 requests Completed 3000 requests Completed 4000 requests Completed 5000 requests Completed 6000 requests Completed 7000 requests Completed 8000 requests Completed 9000 requests Completed 10000 requests Finished 10000 requests Server Software: nginx/1.28.2 Server Hostname: php.dragon.org Server Port: 80 Document Path: /index.php Document Length: 153 bytes Concurrency Level: 500 Time taken for tests: 0.380 seconds Complete requests: 10000 Failed requests: 0 # 可见没有失败性能非常qian Non-2xx responses: 10000 Total transferred: 3030000 bytes HTML transferred: 1530000 bytes Requests per second: 26289.09 [#/sec] (mean) Time per request: 19.019 [ms] (mean) Time per request: 0.038 [ms] (mean, across all concurrent requests) Transfer rate: 7778.90 [Kbytes/sec] received Connection Times (ms) min mean[/-sd] median max Connect: 0 8 1.4 8 12 Processing: 4 11 2.3 11 20 Waiting: 1 8 2.3 8 13 Total: 10 19 2.0 18 25 Percentage of the requests served within a certain time (ms) 50% 18 66% 19 75% 20 80% 20 90% 21 95% 22 98% 23 99% 24 100% 25 (longest request)

更多文章