WEB服务与NGINX(21)- nginx 的fastcgi反向代理功能
1. NGINX实现fastcgi反向代理
1.1 fastcgi概述
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服务器之间传递信息的标准化接口。
fastcgi
CGI协议虽然解决了语言解析器和web server之间通讯的问题,但是它的效率很低,因为web server每收到一个请求都会创建一个CGI进程,PHP解析器都会解析php.ini文件,初始化环境,请求结束的时候再关闭进程,对于每一个创建的CGI进程都会执行这些操作,所以效率很低,而FastCGI是用来提高CGI性能的,FastCGI每次处理完请求之后不会关闭掉进程,而是保留这个进程,使这个进程可以处理多个请求。这样的话每个请求都不用再重新创建一个进程了,大大提升了处理效率。
PHP
PHP是通用服务器端脚本编程语言,其主要用于web开发以实现动态web页面,它也是最早实现将脚本嵌入HTML源码文档中的服务器端脚本语言之一。同时,php还提供了一个命令行接口,因此,其也可以在大多数系统上作为一个独立的shell来使用,意味着php可以在其交互式窗口直接运行。
官方网站
php-fpm
PHP-FPM(FastCGI Process Manager:FastCGI进程管理器)是一个实现了Fastcgi的程序,并且提供进程管理的功能。进程包括master进程和worker进程。master进程只有一个,负责监听端口,接受来自webserver的请求。worker进程一般会有多个,每个进程中会嵌入一个PHP解析器,进行PHP代码的处理。
php本身只是解释器,配合fpm,让php以守护进程的方式运行,监听在某个套接字上,接收前端的web服务器的请求。
php-fpm运行过程:
请求资源先发送给web服务器,web服务器通过fastcgi客户端模块去请求fastcgi的服务端,即fpm运行的php server,由php server处理用户请求,将响应的数据交由WEB服务器返回给客户端。
php-fpm通常监听在TCP/9000端口。
1.2 nginx实现fastcgi相关参数
以下指令由ngx_http_fastcgi_module模块提供。
fastcgi_pass address:port
设置FastCGI服务器的地址,域名或IP地址和端口
address:后端的fastcgi server的地址
支持环境:location, if in location
fastcgi_index name
fastcgi默认的主页资源,URI的资源路径
支持环境:http, server, location
示例
fastcgi_index index.php;
fastcgi_param parameter value [if_not_empty]
支持环境:http, server, location
设置传递给FastCGI服务器的参数值,可以是文本,变量或组合,将 Nginx 中的变量翻译成 PHP 中能够理解的变量。
nginx支持http协议,要将用户的请求发送给后端的FastCGI,后端FastCGI使用的协议与http不同,需要与其协商达到互相通讯的目的, 要传递给 FastCGI服务器的参数值,可以是文本,变量或组合,安装nginx后在有写好的参数文件(/etc/nginx/fastcgi_params.default ),直接调用即可。
[root@nginx01 ~]# 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;
以上变量中缺少了一个关键参数,即告知前端nginx,php程序所在的路径,使用以下变量进行赋值:
fastcgi_param SCRIPT_FILENAME PATH/$fastcgi_script_name;
说明:
$fastcgi_script_name为客户端请求的uri,前面加上资源的目录,即为资源在磁盘中的绝对路径。
例如:
php程序放置在/data/nginx/html/xuzhichao/这个目录下,用户访问的URL是http://www.xuzhichao.com/index.php
此时需要把path写为/data/nginx/html/xuzhichao/,才可以找到php程序的路径
fastcgi_param SCRIPT_FILENAME /data/nginx/html/xuzhichao/$fastcgi_script_name;
fastcgi_cache_path
配置格式
fastcgi_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size
[inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time]
[manager_threshold=time] [loader_files=number] [loader_sleep=time]
[loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time]
[purger_threshold=time];
支持环境:http
参数:
path :缓存位置为磁盘上的文件系统路径
max_size=size:磁盘path路径中用于缓存数据的缓存空间上限
levels=levels:缓存目录的层级数量,以及每一级的目录数量
inactive=time:缓存有效时长,默认10分钟,需要在制定的时间满足fastcgi_cache_min_uses次数才会被视为活动缓存
key_zone=name:size:设置缓存被调用时的名称和key值在内存中缓存的大小
fastcgi_cache zone|off
调用指定的缓存空间来缓存数据
支持环境:http, server, location
fastcgi_cache_key string
设置nginx服务器在内存中为缓存数据建立索引时使用的关键字
支持环境: http, server, location
示例:fastcgi_cache_key $request_uri;
fastcgi_cache_methods GET|HEAD|POST
为哪些请求方法使用缓存
支持环境:http, server, location
默认值: fastcgi_cache_methods GET HEAD;
fastcgi_cache_min_uses number
缓存空间中的缓存项在inactive定义的非活动时间内至少要被访问到此处所指定的次数方可被认作活动项。
支持环境:http, server, location
默认值:fastcgi_cache_min_uses 1;
fastcgi_cache_valid
不同的响应码各自的缓存时长
配置格式:fastcgi_cache_valid [code …] time;
支持环境:http, server, location
fastcgi_keep_conn on|off
收到后端服务器响应后,fastcgi服务器是否关闭连接,建议启用长连接,可提升性能,高于1.1.4版本支持。
启用fastcgi_keep_conn功能可以极大提升nginx性能:
支持环境:http, server, location
默认设置:fastcgi_keep_conn off;
fastcgi_hide_header field
隐藏响应头制定信息
fastcgi_pass_header field
返回响应头指定信息
默认不会返回status,X-accel等参数。
1.3 nginx与php-fpm部署在一台服务器
1.3.1 php服务器部署
安装php相关程序包,默认base仓库中的php程序包版本较低,此处我们安装7.x系列的PHP软件包。
配置php的yum源:
#方法一:使用rpm包的方式自动生成php的yum源:
#需要安装两个包,第二个包依赖第一个包
[root@nginx01 ~]# rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
[root@nginx01 ~]# rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
#自动生成的repo文件
[root@nginx01 ~]# cat /etc/yum.repos.d/
webtatic-archive.repo webtatic-testing.repo epel-testing.repo webtatic.repo
#暂时禁用base源,使用webtatic源安装php
[root@nginx01 ~]# yum install php-fpm --disablerepo=base
......
Installed:
php72w-fpm.x86_64 0:7.2.34-1.w7
Dependency Installed:
libargon2.x86_64 0:20161029-3.el7 php72w-common.x86_64 0:7.2.34-1.w7
[root@nginx01 ~]# rpm -q php72w-fpm
php72w-fpm-7.2.34-1.w7.x86_64
#方法二:手动配置yum源,实际测试速度极慢,不建议使用
[root@nginx01 ~]# cat /etc/yum.repos.d/php.repo
[webtatic-php]
name = php repository
baseurl = http://us-east.repo.webtatic.com/yum/el7/x86_64/
gpgcheck = 1
#注意:需要卸载低版本的php-fpm包。
修改php-fpm的配置文件:
php-fpm主要使用的配置文件为/etc/php-fpm.conf 和/etc/php-fpm.d/www.conf 。
[root@nginx01 ~]# grep -Ev "^;|^$" /etc/php-fpm.conf
[global]
pid = /var/run/php-fpm/php-fpm.pid <==守护进程的pid
error_log = /var/log/php-fpm/error.log <==错误日志
daemonize = yes <==表示是否以守护进程的方式运行,定义为no,因为要托管到systemd上
include=/etc/php-fpm.d/*.conf
[root@nginx01 ~]# grep -Ev "^;|^$" /etc/php-fpm.d/www.conf
[www]
user = nginx <==php-fpm启动时使用的用户和用户组,需要和nginx用户保持一致,涉及到文件权限问题。
group = nginx
listen = 127.0.0.1:9000 <==监听的地址和端口
listen.allowed_clients = 127.0.0.1 <==允许客户端从哪个源IP进行访问,注释该行则允许所有客户端地址
pm = dynamic <==进程管理模式,有动态和静态两种,一般使用动态管理方式
pm.max_children = 500 <==静态方式下开启的php-fpm进程数量,动态模式下为php-fpm的最大进程数
pm.start_servers = 100 <==动态模式下php-fpm初始启动的进程数,不能小于最小空闲进程数,不能大于最大进程数
pm.min_spare_servers = 100 <==动态模式下,php-fpm最小子进程数
pm.max_spare_servers = 200 <==动态模式下,php-fpm最大子进程数
pm.max_requests = 500000 <==进程累计请求回收值,会重新生成进程
pm.status_path = /pm_status <==php-fpm状态访问URL
ping.path = /ping <==ping访问的地址,用于测试php-fpm运行状态
ping.response = pong <==ping的返回值pong
slowlog = /var/log/php-fpm/www-slow.log <==慢日志路径
php_admin_value[error_log] = /var/log/php-fpm/www-error.log <==错误日志路径
php_admin_flag[log_errors] = on <==开启错误日志
php_value[session.save_handler] = files <==php session 的存放方式,files表示以文件方式存放
php_value[session.save_path] = /var/lib/php/session <==php session的存放路径,需要运行php-fpm的用户拥有读写权限
php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache
#注意:修改配置文件需要重启php-fpm服务:
[root@nginx01 ~]# systemctl reload php-fpm.service
启动php-fpm服务:
[root@nginx01 ~]# systemctl start php-fpm.service
[root@nginx01 ~]# systemctl enable php-fpm.service
#查看监听的套接字:
[root@nginx01 ~]# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 127.0.0.1:9000 *:*
#查看php-fpm进程,共启动了100个子进程:
[root@nginx01 ~]# ps -ef | grep php-fpm
root 7029 1 0 12:54 ? 00:00:00 php-fpm: master process (/etc/php-fpm.conf)
nginx 7030 7029 0 12:54 ? 00:00:00 php-fpm: pool www
nginx 7031 7029 0 12:54 ? 00:00:00 php-fpm: pool www
nginx 7032 7029 0 12:54 ? 00:00:00 php-fpm: pool www
nginx 7033 7029 0 12:54 ? 00:00:00 php-fpm: pool www
nginx 7034 7029 0 12:54 ? 00:00:00 php-fpm: pool www
nginx 7035 7029 0 12:54 ? 00:00:00 php-fpm: pool www
nginx 7036 7029 0 12:54 ? 00:00:00 php-fpm: pool www
......
准备php的测试代码:
[root@nginx01 ~]# cat /data/nginx/html/xuzhichao/index.php
<?php
phpinfo();
?>
1.3.2 nginx部署
nginx的配置文件如下:
#1.nginx的配置文件如下:
[root@nginx01 ~]# cat /etc/nginx/nginx.conf
http {
......
fastcgi_cache_path /data/nginx/fastcgi_cache levels=1:1:1 keys_zone=fastcgi_cache:250m inactive=10m max_size=1g;
}
[root@nginx01 ~]# cat /etc/nginx/conf.d/xuzhichao.conf
server {
location ~ \.php$ {
#"$document_root"会调用root目录,若不写root指令对应的目录路径,则"$document_root"所对应的值为空.
root /data/nginx/html/xuzhichao;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#fastcgi_param SCRIPT_FILENAME /data/nginx/html/xuzhichao/$fastcgi_script_name;
include fastcgi_params;
fastcgi_cache fastcgi_cache;
fastcgi_cache_key $request_uri;
fastcgi_cache_methods GET HEAD;
fastcgi_cache_valid 200 301 302 30m;
fastcgi_cache_valid any 5m;
fastcgi_cache_min_uses 1;
fastcgi_keep_conn on;
}
#php-fpm的状态页,无需传递$document_root
location ~ ^/(pm_status|ping)$ {
access_log off;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
include fastcgi_params;
}
}
#2.重启nginx服务:
[root@nginx01 ~]# systemctl reload nginx.service
#3.客户端测试状态页:
[root@xuzhichao ~]# curl http://www.xuzhichao.com/pm_status
pool: www
process manager: dynamic
start time: 27/Jun/2021:15:36:25 +0800
start since: 13
accepted conn: 1
listen queue: 0
max listen queue: 0
listen queue len: 128
idle processes: 99
active processes: 1
total processes: 100
max active processes: 1
max children reached: 0
slow requests: 0
[root@xuzhichao ~]# curl http://www.xuzhichao.com/ping
pong
#4.nginx生成的缓存信息:
[root@nginx01 ~]# ll /data/nginx/fastcgi_cache/1/f/a/e251273eb74a8ee3f661a7af00915af1
-rw------- 1 nginx nginx 61566 Jun 27 15:32 /data/nginx/fastcgi_cache/1/f/a/e251273eb74a8ee3f661a7af00915af1
客户端测试php的主要如下:

1.4 nginx与php-fpm部署在不同的服务器
把php-fpm单独部署在192.168.20.21这台服务器上,192.168.20.20为nginx服务器。
php部署:
#1.php的安装同上节
#2.php的配置文件修改如下:
[root@apache01 ~]# grep "^[a-zA-Z]" /etc/php-fpm.d/www.conf
user = nginx <==用户建议修改为nginx,且uid与nginx服务器上的nginx用户保持一致,不改user,默认为apache也没问题。
group = nginx
listen = 192.168.20.21:9000 <==监听在192.168.20.21地址上
listen.allowed_clients = 192.168.20.20 <==允许客户端IP来访问,也可以注释该行,允许所有客户端访问php-fpm
pm = dynamic
pm.max_children = 500
pm.start_servers = 100
pm.min_spare_servers = 100
pm.max_spare_servers = 200
pm.max_requests = 500000
pm.status_path = /pm_status
ping.path = /ping
ping.response = pong
slowlog = /var/log/php-fpm/www-slow.log
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/session
php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache
#3.新建nginx用户:
[root@apache01 ~]# useradd -u 997 nginx
#4.新建php测试代码:目录对nginx需要有读权限
[root@apache01 ~]# mkdir /data/php
[root@apache01 ~]# vim /data/php/index.php
<?php
phpinfo();
?>
[root@apache01 ~]# ll /data/php/index.php
-rw-r--r-- 1 root root 21 Jun 27 16:46 /data/php/index.ph
#5.启动php-fpm服务
[root@apache01 ~]# systemctl start php-fpm
[root@apache01 ~]# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 192.168.20.21:9000 *:*
nginx的配置文件如下:
[root@nginx01 ~]# cat /etc/nginx/conf.d/xuzhichao.conf
server{
location ~ \.php$ {
root /data/nginx/html/xuzhichao;
fastcgi_pass 192.168.20.21:9000; <==php-fpm的地址
fastcgi_index index.php;
#fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME /data/php/$fastcgi_script_name; <==php-fpm服务器的php代码路径
include fastcgi_params;
fastcgi_cache fastcgi_cache;
fastcgi_cache_key $request_uri;
fastcgi_cache_methods GET HEAD;
fastcgi_cache_valid 200 301 302 30m;
fastcgi_cache_valid any 5m;
fastcgi_cache_min_uses 1;
fastcgi_keep_conn on;
}
location ~ ^/(pm_status|ping)$ {
access_log off;
fastcgi_pass 192.168.20.21:9000;
fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
include fastcgi_params;
}
}
[root@nginx01 ~]# systemctl reload nginx.service
客户端测试:
[root@xuzhichao ~]# curl http://www.xuzhichao.com/ping
pong
[root@xuzhichao ~]# curl http://www.xuzhichao.com/pm_status
pool: www
process manager: dynamic
start time: 27/Jun/2021:16:48:31 +0800
start since: 29
accepted conn: 4
listen queue: 0
max listen queue: 0
listen queue len: 128
idle processes: 99
active processes: 1
total processes: 100
max active processes: 2
max children reached: 0
slow requests: 0
WEB服务与NGINX(21)- nginx 的fastcgi反向代理功能的更多相关文章
- Nginx 之六: Nginx服务器的正向及反向代理功能
一:Nginx作为正向代理服务器: 1.正向代理:代理(proxy)服务也可以称为是正向代理,指的是将服务器部署在公司的网关,代理公司内部员工上外网的请求,可以起到一定的安全作用和管理限制作用,正向代 ...
- nginx的反向代理功能和缓存功能
html { font-family: sans-serif } body { margin: 0 } article,aside,details,figcaption,figure,footer,h ...
- Nginx服务器部署 负载均衡 反向代理
Nginx服务器部署负载均衡反向代理 LVS Nginx HAProxy的优缺点 三种负载均衡器的优缺点说明如下: LVS的优点: 1.抗负载能力强.工作在第4层仅作分发之用,没有流量的产生,这个特点 ...
- 使用Nginx压缩文件、设置反向代理缓存提高响应速度
Gzip压缩: 最开始,这个竟然要6m多(大到不寻常),响应的速度3分多钟. 所以先对返回的文件进行gzip压缩.判断返回的资源是否有使用gzip压缩,观察响应头部里面,如果没有 Content-En ...
- Centos 7 上使用nginx为Node.js配置反向代理时错误:(13: Permission denied) while connecting to upstream
错误来源:Centos 7 上使用nginx为Node.js配置反向代理时产生(13: Permission denied) while connecting to upstream的错误 nginx ...
- Nginx 反向代理功能-动静分离
Nginx 反向代理功能-动静分离 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- Nginx 反向代理功能-实现Nginx tcp负载均衡
Nginx 反向代理功能-实现Nginx tcp负载均衡 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- Nginx 反向代理功能-实现http反向代理
Nginx 反向代理功能-实现http反向代理 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- 使用Nginx对.NetCore站点进行反向代理
前言 之前的博客我已经在Linux上部署好了.NetCore站点且通过Supervisor对站点进行了进程守护,同时也安装好了Nginx.Nginx的用处非常大,还是简单说下,它最大的功能就是方便我们 ...
- nginx配置虚拟主机、反向代理和负载均衡
为了实现这个功能,需要修改nginx的配置文件,将nginx.conf清理一下,使结构更清晰. worker_processes ; events { worker_connections ; } h ...
随机推荐
- Java读取excel文件(.xlsx/.xls)和.csv文件存入MySQL数据库
1 package com.reliable.service; 2 3 import com.csvreader.CsvReader; 4 import com.reliable.bean.FileD ...
- 郑州IT微信交流群期待你的加入
我建了一个郑州IT微信交流群,找工作,找项目,人员招聘的都可以加入. 你有一个苹果,我有一个香蕉,合在一起,我们每个人都可以吃到两种水果了.广结人缘,扩大自己的人脉. 可以加我个人微信,拉你进群.
- 关于 ThreadLocalRandom 随机数生成器
ThreadLocalRandom 线程安全随机数获取. 示例随机整数:java.util.concurrent.ThreadLocalRandom.current().nextInt(); 线程Th ...
- Visual Studio快捷键总览,推荐VS+Resharper实现高效开发
VS2022之后,其实还挺好用的,但个人还是习惯VS+Resharper的强强组合,尤其是Ctrl+N快捷键的全局搜,比VS自带的Ctrl+T好用太多了,Ctrl+B还能直接查看反编译之后的dll的方 ...
- Python设计模式----3.单例模式
单例模式:主要目的是确保某一个类只有一个实例存在 代码: class A(): def __new__(self, *args, **kwargs): if not hasattr(self, 'na ...
- Python基于Excel数据加以反距离加权空间插值并掩膜图层
本文介绍基于Python中ArcPy模块,实现Excel数据读取并生成矢量图层,同时进行IDW插值与批量掩膜的方法. 1 任务需求 首先,我们来明确一下本文所需实现的需求. 现有一个记录有 ...
- HDD杭州站•ArkUI让开发更灵活
原文:https://mp.weixin.qq.com/s/cX48CPs61daKOC2J5znyJw,点击链接查看更多技术内容. 7月15日的HUAWEI Developer Day(简称HDD) ...
- 实训篇-JavaScript-打地鼠
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- Go 单元测试之mock接口测试
目录 一.gomock 工具介绍 二.安装 三.使用 3.1 指定三个参数 3.2 使用命令为接口生成 mock 实现 3.3 使用make 命令封装处理mock 四.接口单元测试步骤 三.小黄书Se ...
- NL2SQL实践系列(1):深入解析Prompt工程在text2sql中的应用技巧
NL2SQL实践系列(1):深入解析Prompt工程在text2sql中的应用技巧 NL2SQL基础系列(1):业界顶尖排行榜.权威测评数据集及LLM大模型(Spider vs BIRD)全面对比优劣 ...