《Nginx 高级应用:变量、Rewrite、反向代理与 OpenResty 扩展》(3)

Nginx变量使用

引用nginx的变量需要添加模块

  • nginx的变量可以在配置文件中引用,作为功能判断或者日志等场景使用
  • 变量可以分为内置变量自定义变量
  • 内置变量是由nginx模块自带,通过变量可以获取到众多的与客户端访问相关的值。

升级Nginx支持echo模块

模块获取方法

https://github.com/openresty/echo-nginx-module/tags

添加之前

bash 复制代码
[root@Nginx ~]# systemctl stop nginx.service

[root@Nginx ~]# tar zxf echo-nginx-module-0.64.tar.gz
[root@Nginx ~]# cd nginx-1.28.1/
[root@Nginx nginx-1.28.1]# make clean	#清理已经生成的Makefile
rm -rf Makefile objs
#重新检测并编译生成Makefile
[root@Nginx nginx-1.28.1]# ./configure  --prefix=/usr/local/nginx --user=nginx --group=nginx --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/echo-nginx-module-0.64
[root@Nginx nginx-1.28.1]# make

[root@Nginx nginx-1.28.1]# rm -rf /usr/local/nginx/sbin/nginx
[root@Nginx nginx-1.28.1]# cp objs/nginx /usr/local/nginx/sbin/ -p

#测试是否成功添加
bash 复制代码
[root@nginx nginx-1.28.1]# vim /usr/local/nginx/conf.d/vhosts.conf
......
location /vars {
        default_type text/html;
        echo $remote_addr;
    }
......

[root@nginx nginx-1.28.1]# nginx -s reload
[root@nginx nginx-1.28.1]# curl www.fjw.org/vars
172.25.254.100

内置变量

以下是常用的内置变量

bash 复制代码
$remote_addr;
#存放了客户端的地址,注意是客户端的公网IP

$args;
#变量中存放了URL中的所有参数
#例如:https://search.jd.com/Search?keyword=手机&enc=utf-8
#返回结果为: keyword=手机&enc=utf-8

$is_args
#如果有参数为? 否则为空

$document_root;
#保存了针对当前资源的请求的系统根目录,例如:/webdata/nginx/timinglee.org/lee。

$document_uri;
#保存了当前请求中不包含参数的URI,注意是不包含请求的指令
#比如:http://lee.timinglee.org/var?\id=11111会被定义为/var
#返回结果为:/var

$host;
#存放了请求的host名称

limit_rate 10240;
echo $limit_rate;
#如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置, 则显示0

$remote_port;
#客户端请求Nginx服务器时随机打开的端口,这是每个客户端自己的端口

$remote_user;
#已经经过Auth Basic Module验证的用户名

$request_body_file;
#做反向代理时发给后端服务器的本地资源的名称

$request_method;
示例:
#请求资源的方式,GET/PUT/DELETE等

$request_filename;
#当前请求的资源文件的磁盘路径,由root或alias指令与URI请求生成的文件绝对路径,
#如:webdata/nginx/timinglee.org/lee/var/index.html

$request_uri;
#包含请求参数的原始URI,不包含主机名,相当于:$document_uri?$args,
#例如:/main/index.do?id=20190221&partner=search

$scheme;
#请求的协议,例如:http,https,ftp等

$server_protocol;
#保存了客户端请求资源使用的协议的版本,例如:HTTP/1.0,HTTP/1.1,HTTP/2.0等

$server_addr;
#保存了服务器的IP地址

$server_name;
#虚拟主机的主机名

$server_port;
#虚拟主机的端口号

$http_user_agent;
#客户端浏览器的详细信息

$http_cookie;
#客户端的所有cookie信息

$cookie_<name>
#name为任意请求报文首部字部cookie的key名

$http_<name>
#name为任意请求报文首部字段,表示记录请求报文的首部字段,name的对应的首部字段名需要为小写,如果有横线需要替换为下划线
$http_<name>的示例
echo $http_user_agent;
echo $http_host;

$sent_http_<name>
#name为响应报文的首部字段,name的对应的首部字段名需要为小写,如果有横线需要替换为下划线,此变量有问题 

$arg_<name>
#此变量存放了URL中的指定参数,name为请求url中指定的参数

实验配置

bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
    listen  80;
    server_name www.fy.org;
    root    /web/html;
    location /vars {
            default_type text/html;
            echo $remote_addr;
            echo $args;
            echo $is_args;
            echo $document_root;
            echo $document_uri;
            echo $host;
            echo $remote_port;
            echo $remote_user;
            echo $request_method;
            echo $request_filename;
            echo $request_url;
            echo $scheme;
            echo $server_protocol;
            echo $server_addr;
            echo $server_name;
            echo $server_port;
            echo $server_user_agent;
            echo $http_cookie;
            echo $cookie_key1;
            echo $http_Accept;
            echo $arg_name;
     }
}

#测试
[root@nginx ~]# curl -A "fjwyyy" -b "fjw=a,key1=2" -ufjw:fjw www.fy.org/vars?name=fjw
172.25.254.10
name=fjw
?
/web/html
/vars
www.fy.org
41430
fjw
GET
/web/html/vars
/vars?name=fjw
http
HTTP/1.1
172.25.254.10
www.fy.org
80
fjwyyy
fjw=a,key1=2
2
*/*
fjw

自定义变量

bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
    listen  80;
    server_name www.fy.org;
    root    /web/html;
	location /var {
        default_type text/html;
        set $name fjwyyy;
        echo $name;
        set $tomcat_port 8080;		#手动设定
        echo $tomcat_port;
        set	$web_port $server_port	#变量传递
    }
}

#测试
[root@nginx ~]# curl www.fy.org/var
fjwyyy
8080
80

Nginx版本隐藏

编译前可以对其进行版本隐藏并自定义nginx

bash 复制代码
[root@nginx nginx-1.26.1]# vim src/core/nginx.h

测试

Nginx Rewrite相关功能

什么是rewrite

  • Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求
  • 此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库
  • rewrite是nginx服务器的重要功能之一,用于实现URL的重写,URL的重写是非常有用的功能
  • 比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的 链接,就可以设置为访问
  • 另外还可以在一定程度上提高网站的安全性。

if指令

​ 用于条件匹配判断,并根据条件判断结果选择不同的Nginx配置,可以配置在server或location块中进行 配置,Nginx的if语法仅能使用if做单次判断,不支持使用if else或者if elif这样的多重判断

​ 使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,否则认为false,变量与表达式之间 使用以下符号链接:

复制代码
= 			#比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false
!= 			#比较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false
~ 			#区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~ 			#区分大小写字符,判断是否匹配,不满足匹配条件为真,满足匹配条件为假
~* 			#不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~* 		#不区分大小字符,判断是否匹配,满足匹配条件为假,不满足匹配条件为真
-f 和 !-f 	#判断请求的文件是否存在和是否不存在
-d 和 !-d 	#判断请求的目录是否存在和是否不存在
-x 和 !-x 	#判断文件是否可执行和是否不可执行
-e 和 !-e 	#判断请求的文件或目录是否存在和是否不存在(包括文件,目录,软链接)
#注意:
#如果$变量的值为空字符串或0,则if指令认为该条件为false,其他条件为true

用法示例

bash 复制代码
[root@nginx nginx-1.28.1]# mkdir /webdir/fjw.org/fjw/html -p
[root@nginx nginx-1.28.1]# echo fjw test > /webdir/fjw.org/fjw/html/index.html

[root@nginx nginx-1.28.1]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
    listen 80;
    server_name www.fjw.org;
    root /webdata/nginx/fjw.org/fjw/html/;

    location / {
        root /webdir/fjw.org/fjw/html;
        if ( $http_user_agent ~ firefox ) {
            return 200 "test if messages";
        }
    }
}

[root@nginx nginx-1.28.1]# nginx -s reload
#测试
[root@nginx nginx-1.28.1]# curl -A "firefox" www.fjw.org
test if messages
[root@nginx nginx-1.28.1]# curl www.fjw.org
fjw test

set指令

指定key并给其定义一个变量,变量可以调用Nginx内置变量赋值给key 另外set定义格式为set $key value,value可以是text, variables和两者的组合,可以用于自定义变量。

用法如下:

bash 复制代码
[root@nginx nginx-1.28.1]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
    listen 80;
    server_name www.fjw.org;
    root /webdata/nginx/fjw.org/fjw/html/;

    location / {
        set $testname fjw;
        echo $testname;
    }
}

[root@nginx nginx-1.28.1]# nginx -s reload
#测试
[root@nginx nginx-1.28.1]# curl www.fjw.org
fjw

break指令

  • 用于中断当前相同作用域(location)中的其他Nginx配置
  • 与该指令处于同一作用域的Nginx配置中,位于它前面的配置生效
  • 位于后面的 ngx_http_rewrite_module 模块中指令就不再执行

!NOTE

注意: 如果break指令在location块中后续指令还会继续执行,只是不执行 ngx_http_rewrite_module 模块的指令,其它指令还会执行

用法如下:

bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
    listen 80;
    server_name www.fjw.org;
    root /webdata/nginx/fjw.org/fjw/html/;

    location / {
        set $test1 fjw1;
        set $test2 fjw2;
        if ($http_user_agent = firefox){
            break;
        }
        set $test3 fjw3;
        echo $test1 $test2 $test3;
    }
}

[root@nginx ~]# nginx -s reload

#测试
[root@nginx ~]# curl www.fjw.org
fjw1 fjw2 fjw3
[root@nginx ~]# curl -A "firefox" www.fjw.org
fjw1 fjw2

return指令

return用于完成对请求的处理,并直接向客户端返回响应状态码,比如:可以指定重定向URL(对于特殊重 定向状态码,301/302等) 或者是指定提示文本内容(对于特殊状态码403/500等),处于此指令后的所有配 置都将不被执行。

bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
    listen 80;
    server_name www.fjw.org;
    root /webdata/nginx/fjw.org/fjw/html/;

    location / {
        return 200 "hello world";
    }
}

[root@nginx ~]# nginx -s reload

[root@nginx ~]# curl www.fjw.org
hello worl

rewrite指令

通过正则表达式的匹配来改变URI,可以同时存在一个或多个指令,按照顺序依次对URI进行匹配, rewrite主要是针对用户请求的URL或者是URI做具体处理

正则表达式格式

复制代码
. #匹配除换行符以外的任意字符
\w #匹配字母或数字或下划线或汉字
\s #匹配任意的空白符
\d #匹配数字
\b #匹配单词的开始或结束
^ #匹配字符串的开始
$ #匹配字符串的结束
* #匹配重复零次或更多次
+ #匹配重复一次或更多次
? #匹配重复零次或一次
(n) #匹配重复n次
{n,} #匹配重复n次或更多次
{n,m} #匹配重复n到m次
*? #匹配重复任意次,但尽可能少重复
+? #匹配重复1次或更多次,但尽可能少重复
?? #匹配重复0次或1次,但尽可能少重复
{n,m}? #匹配重复n到m次,但尽可能少重复
{n,}? #匹配重复n次以上,但尽可能少重复
\W #匹配任意不是字母,数字,下划线,汉字的字符
\S #匹配任意不是空白符的字符
\D #匹配任意非数字的字符
\B #匹配不是单词开头或结束的位置
[^x] #匹配除了x以外的任意字符
[^fjw] #匹配除了fjw 这几个字母以外的任意字符

rewrite flag

利用nginx的rewrite的指令,可以实现url的重新跳转,rewrite有四种不同的flag,分别是redirect(临时 重定向302)、permanent(永久重定向301)、break和last。其中前两种是跳转型的flag,后两种是代理型

  • 跳转型指由客户端浏览器重新对新地址进行请求
  • 代理型是在WEB服务器内部实现跳转

flag 说明

复制代码
redirect;
#临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端
#由客户端重新发起请求;使用相对路径,或者http://或https://开头,状态码:302

permanent;
#重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端
#由客户端重新发起请求,状态码:301

break;
#重写完成后,停止对当前URL在当前location中后续的其它重写操作
#而后直接跳转至重写规则配置块之后的其它配置,结束循环,建议在location中使用
#适用于一个URL一次重写

last;
#重写完成后,停止对当前URI在当前location中后续的其它重写操作,
#而后对新的URL启动新一轮重写检查,不建议在location中使用
#适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户

redirect与permanent

区别:

redirect

bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
    listen 80;
    server_name www.fjw.org;
    root /webdata/nginx/fjw.org/fjw/html/;

    location / {
        rewrite / http://www.baidu.com redirect;
    }
}

[root@nginx ~]# nginx -s reload

#测试
[root@nginx ~]# curl -I www.fjw.org
HTTP/1.1 302 Moved Temporarily			#定向方式返回值
Server: nginx/1.28.1
Date: Sat, 07 Feb 2026 07:08:13 GMT
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Keep-Alive: timeout=60
Location: http://www.baidu.com			#定向效果

permanent

bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
    listen 80;
    server_name www.fjw.org;
    root /webdata/nginx/fjw.org/fjw/html/;

    location / {
        rewrite / http://www.baidu.com permanent;
    }
}

[root@nginx ~]# nginx -s reload

#测试
[root@nginx ~]# curl -I www.fjw.org
HTTP/1.1 301 Moved Permanently
Server: nginx/1.28.1
Date: Sat, 07 Feb 2026 07:10:44 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Keep-Alive: timeout=60
Location: http://www.baidu.com

break与last

  • 无 break/last:默认执行完当前 location 所有 rewrite,有return则执行无则匹配 location,URL 是所有 rewrite 叠加结果;
  • break:终止后续 rewrite,不重匹配 location,停在当前 location 处理,且不执行return;
  • last:终止后续 rewrite,重匹配 location,跳转到新的 location 处理,可以执行return。

生成测试文件,主要为break做对照

bash 复制代码
[root@nginx ~]# echo old page > /webdata/nginx/fjw.org/fjw/html/old
[root@nginx ~]# echo new page > /webdata/nginx/fjw.org/fjw/html/new
[root@nginx ~]# echo final page > /webdata/nginx/fjw.org/fjw/html/final

1.无 break/last(对照组)

配置rewrite ^/old /new;(无任何终止指令)

执行流程

  1. 执行第一条 rewrite:/old/new
  2. 继续执行第二条 rewrite:/new/final(因为没有终止指令,会执行完所有 rewrite);
  3. 不触发重新匹配 location,留在 /old 这个 location;
  4. 执行 return 指令,返回响应。
  5. 因为return存在导致不会跳转到/final这个location,被return响应了正常return不存在会重定向跳转至/final的location中。
bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
    listen 80;
    server_name www.fjw.org;
    root /webdata/nginx/fjw.org/fjw/html/;

    location /old {
        rewrite ^/old /new;
        #rewrite ^/old /new break;
        #rewrite ^/old /new last;
        rewrite ^/new /final;

        return 200 "未跳出 /old location,rewrite后内部URI:$uri\n";
    }

    location /new {
        return 200 "匹配到 /new location,rewrite后内部URI:$uri\n";
    }

    location /final {
        return 200 "匹配到 /final location,rewrite后内部URI:$uri\n";
    }
}


[root@nginx ~]# nginx -t
[root@nginx ~]# nginx -s reload

#测试
[root@nginx ~]# curl www.fjw.org/old
未跳出 /old location,rewrite后内部URI:/final

2.加 break(对比组 1)

配置rewrite ^/old /new break;

执行流程

  1. 执行第一条 rewrite:/old/new
  2. 遇到 break,终止当前 location 内后续所有 rewrite 规则(第二条 rewrite ^/new /final 不执行);
  3. 不触发重新匹配 location,留在 /old 这个 location;
  4. 不执行 return 指令,开始查找/new文件或目录下的默认发布文件
  5. break特性优先查找文件/目录,查找不到返回404,不会运行return
bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
    listen 80;
    server_name www.fjw.org;
    root /webdata/nginx/fjw.org/fjw/html/;

    location /old {
        #rewrite ^/old /new;
        rewrite ^/old /new break;
        #rewrite ^/old /new last;
        rewrite ^/new /final;

        return 200 "未跳出 /old location,rewrite后内部URI:$uri\n";
    }

    location /new {
        return 200 "匹配到 /new location,rewrite后内部URI:$uri\n";
    }

    location /final {
        return 200 "匹配到 /final location,rewrite后内部URI:$uri\n";
    }
}

[root@nginx ~]# nginx -t
[root@nginx ~]# nginx -s reload

#测试
[root@nginx ~]# curl www.fjw.org/old
new page	

3.加 last(对比组 2)

配置rewrite ^/old /new last;

执行流程

  1. 执行第一条 rewrite:/old/new
  2. 遇到 last,终止当前 location 内后续所有 rewrite 规则(第二条 rewrite ^/new /final 不执行);
  3. 触发重新匹配 location:用新 URL /new 匹配到 location /new
  4. 执行 location /new 内的 return 指令,返回响应。
bash 复制代码
server {
    listen 80;
    server_name www.fjw.org;
    root /webdata/nginx/fjw.org/fjw/html/;

    location /old {
        #rewrite ^/old /new;
        #rewrite ^/old /new break;
        rewrite ^/old /new last;
        rewrite ^/new /final;

        return 200 "未跳出 /old location,rewrite后内部URI:$uri\n";
    }

    location /new {
        return 200 "匹配到 /new location,rewrite后内部URI:$uri\n";
    }

    location /final {
        return 200 "匹配到 /final location,rewrite后内部URI:$uri\n";
    }
}

[root@nginx ~]# nginx -t
[root@nginx ~]# nginx -s reload

#测试
[root@nginx ~]# curl www.fjw.org/old
匹配到 /new location,rewrite后内部URI:/new

三者核心差异对照表

指令情况 是否执行完当前 location 所有 rewrite 是否触发重新匹配 location 最终匹配的 location 最终 URL 是否执行return
无 break/last ✅ 是(执行全部) ✅ 是 /old /final ✅ 是
加 break ❌ 否(执行到 break 终止) ❌ 否 /old /new ❌ 否
加 last ❌ 否(执行到 last 终止) ✅ 是 /new /new ✅ 是

!NOTE

break不跳转location但也不执行return,会直接查找匹配到的uri进行查找文件/目录下的发布文件,查找不到返回404

全站加密https

制作key

bash 复制代码
[root@nginx ~]# mkdir /usr/local/nginx/certs/

[root@nginx ~]# openssl req -newkey rsa:2048 \
> -nodes -sha256 -keyout  /usr/local/nginx/certs/fjw.org.key \
> -x509 -days 365 -out  /usr/local/nginx/certs/fjw.org.crt

编辑配置文件

bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
    listen 80;
    listen 443 ssl;
    server_name www.fjw.org;
    root /webdata/nginx/fjw.org/fjw/html/;
    ssl_certificate /usr/local/nginx/certs/fjw.org.crt;
    ssl_certificate_key /usr/local/nginx/certs/fjw.org.key;
    ssl_session_cache shared:sslcache:20m;
    ssl_session_timeout 10m;

    location / {
        if ($scheme = http ){
            rewrite /(.*) https://$host/$1 redirect;
         #return 301 https://$host$request_uri;	#也可以直接使用return直接返回
        }
    }
}

[root@nginx ~]# nginx -s reload

#测试
[root@nginx ~]# curl -kIL www.fjw.org
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.28.1
Date: Sat, 07 Feb 2026 20:40:30 GMT
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Keep-Alive: timeout=60
Location: https://www.fjw.org/

HTTP/1.1 200 OK
Server: nginx/1.28.1
Date: Sat, 07 Feb 2026 20:40:30 GMT
Content-Type: text/html
Content-Length: 12
Last-Modified: Tue, 03 Feb 2026 00:47:36 GMT
Connection: keep-alive
Keep-Alive: timeout=60
ETag: "698145a8-c"
Accept-Ranges: bytes

判断文件是否存在

bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
    listen 80;
    listen 443 ssl;
    server_name www.fjw.org;
    root /webdata/nginx/fjw.org/fjw/html/;
    ssl_certificate /usr/local/nginx/certs/fjw.org.crt;
    ssl_certificate_key /usr/local/nginx/certs/fjw.org.key;
    ssl_session_cache shared:sslcache:20m;
    ssl_session_timeout 10m;

    location / {
        if ($scheme = http ){
            rewrite ^/(.*) https://$host/$1 redirect;
        }

        if ( !-e $request_filename ){
            rewrite ^/(.*) /index.html;
        }
    }
}

[root@nginx ~]# nginx -s reload
#测试
[root@nginx ~]# curl -Lk www.fjw.org
www.fjw.org
[root@nginx ~]# curl -Lk www.fjw.org/fjw
www.fjw.org
[root@nginx ~]# curl -Lk www.fjw.org/666
www.fjw.org

防盗链

防盗链基于客户端携带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标 记信息,如果别人只链接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是盗 链,referer就是之前的那个网站域名,正常的referer信息有以下几种:

复制代码
none: 				#请求报文首部没有referer首部,
		 	 		#比如用户直接在浏览器输入域名访问web网站,就没有referer信息。
		 	 		
blocked: 			#请求报文有referer首部,但无有效值,比如为空。

server_names: 		#referer首部中包含本主机名及即nginx 监听的server_name。

arbitrary_string: 	#自定义指定字符串,但可使用*作通配符。示例: *.fjw.org
www.fjw.*

regular expression: #被指定的正则表达式模式匹配到的字符串,要使用~开头,例如:
~*\.baidu\.com

实现盗链

bash 复制代码
[root@nginx ~]# mkdir /webdata/nginx/fjw.org/fjw/html/img
[root@nginx ~]# mkdir /webdata/nginx/fjw.org/fjw/html/daolian

#在img与daolian目录下放下测试图片

#生成一个测试主机下载httpd服务,导入一个盗链主页
[root@RS1 ~]# dnf install httpd -y
[root@RS1 ~]# systemctl start httpd
[root@RS1 ~]# vim /var/www/html/index.html
<html>
        <head>
                <meta http-equiv=Content-Type content="text/html;charset=utf-8">
                <title>盗链</title>
        </head>

        <body>
                <img src="http://www.fjw.org/img/linux.jpg" >
                <h1 style="color:red">欢迎大家</h1>
                <p><a href=http://www.fjw.org>点击点击点击</a>出门见喜</p>
        </body>

</html>

在浏览器测试访问

访问的图片是别的主机的图片

点击后是www.fjw.org域名的默认发布页

查看nginx日志

bash 复制代码
[root@nginx ~]# > /usr/local/nginx/logs/access.log
[root@nginx ~]# cat /usr/local/nginx/logs/access.log

可以查看到http_referer值如果有盗链情况的话

实现防盗链

bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
    listen 80;
    server_name www.fjw.org;
    root /webdata/nginx/fjw.org/fjw/html/;

    location / {
        valid_referers none blocked server_names *.fjw.org ~/.baidu/.;
        if ($invalid_referer){
            return 404;
        }
    }

    location /img {
       valid_referers none blocked server_names *.fjw.org ~/.baidu/.;
       if ($invalid_referer){
           rewrite ^/ http://www.fjw.org/daolian/yaya.jpg;
       }
    }
}

使用浏览器访问测试

Nginx反向代理功能

反向代理:reverse proxy,指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户的 一种方式,这是用的比较多的一种方式。

Nginx 除了可以在企业提供高性能的web服务之外,另外还可以将 nginx 本身不具备的请求通过某种预 定义的协议转发至其它服务器处理,不同的协议就是Nginx服务器与其他服务器进行通信的一种规范,主 要在不同的场景使用以下模块实现不同的功能

模块名称 核心定位 协议 / 场景 对接服务类型
ngx_http_proxy_module HTTP/HTTPS 反向代理(最常用) HTTP 协议 后端 HTTP 服务(Tomcat/Java/Node.js)
ngx_http_upstream_module 配置后端服务集群(负载均衡) HTTP 协议 配合 ngx_http_proxy_module 使用
ngx_stream_proxy_module TCP/UDP 四层反向代理 TCP/UDP 协议(四层) 非 HTTP 服务(MySQL/Redis/SSH)
ngx_http_fastcgi_module 对接 FastCGI 协议服务 FastCGI 协议 PHP-FPM(PHP 解析服务)
ngx_http_uwsgi_module 对接 uWSGI 协议服务 uWSGI 协议 Python WSGI 应用(Django/Flask)

同构与异构

  • 同构代理:用户不需要其他程序的参与,直接通过http协议或者tcp协议访问后端服务器
  • 异构代理:用户访问的资源时需要经过处理后才能返回的,比如php,python,等等,这种访问资源需 要经过处理才能被访问

七层反向代理

基于ngx_http_proxy_module模块实现

配置简单的代理

实验环境

bash 复制代码
#172.25.254.10 RS1	172.25.254.20 RS2

[root@RSX ~]# dnf install httpd -y
[root@RSX ~]# systemctl enable --now httpd
[root@RSX ~]# echo RS2 - 172.25.254.20 > /var/www/html/index.html


#测试 在Nginx主机中
[root@nginx ~]# curl  172.25.254.10
RS1 - 172.25.254.10
[root@nginx ~]# curl  172.25.254.20
RS2 - 172.25.254.20

配置反向代理

bash 复制代码
[root@RS2 ~]# mkdir  /var/www/html/web
[root@RS2 ~]# echo 172.25.254.20 web > /var/www/html/web/index.html

[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
    listen 80;
    server_name www.fjw.org;

    location / {
        proxy_pass http://172.25.254.10:80;
    }

    location /web {
        proxy_pass http://172.25.254.20:80;
    }
}

[root@nginx ~]# nginx -s reload

#测试
[root@nginx ~]# curl  172.25.254.20/web/
172.25.254.20 web
[root@nginx ~]# curl  172.25.254.10
RS1 - 172.25.254.10

配置参数

参数名 默认值 核心作用 关键说明 / 示例
proxy_pass 无(必填) 定义客户端请求转发的后端服务器地址 / 集群 1. 后端地址末尾无 / :追加location路径(如location /web + proxy_pass http://172.25.254.30:8080 → 转发到http://172.25.254.30:8080/web),类比root;2. 后端地址末尾有 / :替换location路径(如location /web + proxy_pass http://172.25.254.40:8080/ → 转发到http://172.25.254.40:8080/),类比alias;3. location用正则匹配(~/*)时,proxy_pass不能加 /
proxy_hide_header field 无(默认不隐藏) 隐藏后端服务器返回的指定响应头,不传递给客户端 示例:proxy_hide_header ETag;(隐藏后端的 ETag 响应头)
proxy_pass_header field 无(默认不透传 Date/Server 等) 强制透传后端服务器的指定响应头给客户端 示例:proxy_pass_header Server;(透传后端的 Server 响应头)
proxy_pass_request_body on 控制是否向后端服务器发送 HTTP 请求的实体部分(如 POST 的表单数据) 默认开启,关闭(off)会导致后端无法接收 POST 数据
proxy_pass_request_headers on 控制是否将客户端的请求头转发给后端服务器 默认开启,关闭(off)会导致后端丢失 Cookie/Referer 等关键头信息
proxy_set_header field value 无(按需配置) 修改 / 新增客户端请求头,转发给后端服务器 核心场景:proxy_set_header X-Forwarded-For $remote_addr;(传递客户端真实 IP);proxy_set_header Host $host;(传递客户端访问的域名)
proxy_connect_timeout 60s Nginx 与后端服务器建立 TCP 连接的超时时间 超时返回 504 错误,建议调小(如6s),示例:proxy_connect_timeout 6s;
proxy_read_timeout 60s Nginx 向后端发请求后,等待后端返回响应的超时时间 后端处理慢(如大数据查询)可调大,示例:proxy_read_timeout 120s;
proxy_send_timeout 60s Nginx 向后端发送请求数据的超时时间 大文件上传场景可调大,示例:proxy_send_timeout 120s;
proxy_http_version 1.0 设置 Nginx 代理使用的 HTTP 协议版本 长连接场景建议设为1.1(需配合proxy_set_header Connection "";),示例:proxy_http_version 1.1;
proxy_ignore_client_abort off 客户端中断请求时,是否继续等待后端响应 off(默认):客户端中断→Nginx 立即中断后端请求,记录 499 日志;on:忽略客户端中断,等待后端响应完成

总结

  1. 核心转发控制proxy_pass是基础,重点关注末尾/的拼接规则,正则匹配场景需禁用/
  2. 头信息管理proxy_hide_header隐藏后端响应头,proxy_pass_header透传关键头,proxy_set_header传递客户端真实信息(如 IP / 域名);
  3. 超时配置:三个超时参数默认 60s,需按后端服务性能调整(短连接调小,长处理调大);
  4. 默认行为:请求体 / 请求头默认转发,客户端中断请求默认终止后端处理,无需额外配置即可满足大部分场景。

以下为部分参数的实验

proxy_hide_header filed

bash 复制代码
[root@nginx ~]#  vim /usr/local/nginx/conf.d/vhosts.conf
server {
    listen 80;
    server_name www.fjw.org;

    location / {
        proxy_pass http://172.25.254.10:80;
        proxy_hide_header Content-Type;
    }

    location /web/ {
        proxy_pass http://172.25.254.20:80;
    }
}

[root@nginx ~]# nginx -s reload
#测试

配置访问前

配置访问后

proxy_pass_header field

bash 复制代码
[root@nginx ~]#  vim /usr/local/nginx/conf.d/vhosts.conf
server {
    listen 80;
    server_name www.fjw.org;

    location / {
        proxy_pass http://172.25.254.10:80;
        proxy_pass_header Server;
    }

    location /web/ {
        proxy_pass http://172.25.254.20:80;
    }
}

[root@nginx ~]# nginx -s reload

配置访问前

配置访问后

proxy_set_header

bash 复制代码
[root@RS1 ~]# vim /etc/httpd/conf/httpd.conf
	LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{X-Forwarded-For}i\"" combined
	
[root@RS1 ~]# systemctl restart httpd

[root@nginx ~]#  vim /usr/local/nginx/conf.d/vhosts.conf
server {
    listen 80;
    server_name www.fjw.org;

    location / {
        proxy_pass http://172.25.254.10:80;
        proxy_set_header X-Forwarded-For $remote_addr;	#开启IP透传参数
    }

    location /web/ {
        proxy_pass http://172.25.254.20:80;
    }
}

[root@nginx ~]# nginx -s reload

#测试
[Administrator.DESKTOP-VJ307M3] ➤ curl  www.fjw.org
RS1 - 172.25.254.10

#查看RS日志
[root@RS1 ~]# cat /etc/httpd/logs/access_log
172.25.254.100 - - [03/Feb/2026:15:12:49 +0800] "GET / HTTP/1.0" 200 20 "-" "curl/7.65.0" "172.25.254.1"

实现动静分离

bash 复制代码
[root@RS1 ~]# dnf install php -y
[root@RS1 ~]# vim /var/www/html/index.php
<?php
    echo RS1 - 172.25.254.10
    phpinfo()
?>

[root@RS1 ~]# systemctl enable --now php-fpm

[root@nginx ~]#  vim /usr/local/nginx/conf.d/vhosts.conf
server {
    listen 80;
    server_name www.fjw.org;

    location ~* \.(php|js)$ {
        proxy_pass  http://172.25.254.10:80;
    }

    location / {
        proxy_pass http://172.25.254.20:80;
    }
}

[root@nginx ~]# nginx -s reload

测试

访问静态网页

访问动态网页

缓存后端动态资源实现加速

配置缓存加速

bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
proxy_cache_path /usr/local/nginx/proxy_cache levels=1:2:2 keys_zone=proxycache:20m inactive=120s max_size=1g;

[root@nginx ~]#  vim /usr/local/nginx/conf.d/vhosts.conf
server {
    listen 80;
    server_name www.fjw.org;

    location ~* \.(php|js)$ {
        proxy_pass  http://172.25.254.10:80;
        proxy_cache proxycache;
        proxy_cache_key $request_uri;
        proxy_cache_valid 200 302 301 10m;
        proxy_cache_valid any 1m;
    }

    location / {
        proxy_pass http://172.25.254.20:80;
    }
}

[root@nginx ~]# systemctl restart nginx.service

#缓存之前的目录
[root@nginx ~]# tree  /usr/local/nginx/proxy_cache/
/usr/local/nginx/proxy_cache/

0 directories, 0 files

#进行缓存后查看缓存目录
[root@nginx ~]# tree /usr/local/nginx/proxy_cache/
/usr/local/nginx/proxy_cache/
└── 1
    └── af
        └── 15
            └── e251273eb74a8ee3f661a7af00915af1

3 directories, 1 file

七层反向代理负载均衡

基于ngx_http_proxy_modulengx_http_upstream_module模块实现

实验环境

复制代码
172.25.254.100  		#Nginx 代理服务器
172.25.254.10  			#后端web A,Apache部署
172.25.254.20  			#后端web B,Apache部署

配置参数

server 节点核心参数(功能 + 默认值 + 关键说明)

参数名 默认值 核心作用 关键说明
weight=number 1 权重控制 数值越大,被分配的请求越多,实现加权轮询(类似 LVS 的 WRR/WLC);例如weight=5表示该节点优先级更高
max_conns=number 0(无限制) 并发连接限制 限制当前后端服务器的最大活动连接数,避免单节点过载,Nginx 1.11.5 + 支持
max_fails=number 1 故障判定阈值 客户端访问时,对选中的后端服务器连续检测失败次数达到该值,即标记为不可用;仅在有客户端请求时触发检测,非周期性探测
fail_timeout=time 10s 故障恢复检测间隔 对已标记为不可用的后端服务器,每隔该时间重试检测;若恢复可用,则重新参与调度
backup 未启用 备份服务器 所有主服务器不可用时,才会启用该节点,用于容灾兜底
down 未启用 手动下线 标记服务器为 down 状态,实现平滑下线(维护时使用),不参与请求调度
resolve 未启用 域名解析更新 server地址为域名时,域名 A 记录变化后自动应用新 IP,无需重启 Nginx

实现负载均衡

bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
server {
......
include "/usr/local/nginx/conf.d/*.conf";
}

[root@nginx ~]# vim /usr/local/nginx/conf.d/up.conf
upstream webserver {
    server 172.25.254.10:80 weight=1 fail_timeout=15s max_fails=3;
    server 172.25.254.20:80 weight=1 fail_timeout=15s max_fails=3;
    server 172.25.254.100:8888 backup;

}
server {
    listen 80;
    server_name www.fjw.org;

    location ~ / {
        proxy_pass http://webserver;	#反向代理负载均衡集群
    }
}

[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
    listen 8888;
    root /usr/local/nginx/errorpage;
    index errormessage;
}

[root@nginx ~]# nginx -s reload

测试

bash 复制代码
#停止后端RS服务使其访问备用网页
[root@RS1 ~]# systemctl stop httpd.service
[root@RS2 ~]# systemctl stop httpd.service

 03/02/2026   18:46.50   /home/mobaxterm  curl www.fjw.org
太不巧了,你要访问的页面辞职了!!

算法

负载均衡算法(调度策略 + 适用场景)

算法语法 核心规则 适用场景 补充特性
默认轮询(无显式配置) 按节点顺序依次分配请求,结合weight实现加权轮询 后端节点性能一致、无会话保持需求 配置最简单,无需额外声明
ip_hash; 基于客户端remote_addr(IPv4 前 24 位 / 完整 IPv6)哈希,固定请求到同一节点 需会话保持(如后端本地 Session、无分布式缓存) 实现会话绑定,同一局域网 IP 可能集中到同一节点
hash KEY [consistent]; 基于指定 KEY(如$request_uri/$cookie_sessionid)哈希,固定请求到同一节点;加consistent启用 ketama 一致性哈希 1. 自定义会话保持(如按 URI/Cookie 绑定);2. 后端为缓存服务器(如 varnish) 一致性哈希可减少节点变化时的请求重分配,降低缓存失效概率
least_conn; 优先将请求分配给当前并发连接数最少的后端服务器 后端请求处理时间差异大(如长连接、慢查询场景) 负载更均衡,避免单节点过载,类似 LVS 的 WLC 算法

以下为算法的实验

ip_hash

bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf.d/up.conf
upstream webserver {
    ip_hash;
    server 172.25.254.10:80 weight=1 fail_timeout=15s max_fails=3;
    server 172.25.254.20:80 weight=1 fail_timeout=15s max_fails=3;
    #server 172.25.254.100:8888 backup;

}
server {
    listen 80;
    server_name www.fjw.org;

    location ~ / {
        proxy_pass http://webserver;
    }
}

[root@nginx ~]# nginx -s reload

#测试
[root@nginx ~]# curl www.fjw.org
RS1 - 172.25.254.10
[root@nginx ~]# curl www.fjw.org
RS1 - 172.25.254.10
[root@nginx ~]# curl www.fjw.org
RS1 - 172.25.254.10
[root@nginx ~]# curl www.fjw.org
RS1 - 172.25.254.10

hash $request_uri consistent;

复制代码
[root@nginx ~]# vim /usr/local/nginx/conf.d/up.conf
upstream webserver {
    #ip_hash;
    hash $request_uri consistent;
    server 172.25.254.10:80 weight=1 fail_timeout=15s max_fails=3;
    server 172.25.254.20:80 weight=1 fail_timeout=15s max_fails=3;
    #server 172.25.254.100:8888 backup;

}
server {
    listen 80;
    server_name www.fjw.org;

    location ~ / {
        proxy_pass http://webserver;
    }
}

[root@nginx ~]# nginx -s reload

#测试
[root@nginx ~]# curl www.fjw.org/web1/index.html
RS1
[root@nginx ~]# curl www.fjw.org/web2/index.html
RS2
[root@nginx ~]# curl www.fjw.org/web3/index.html
RS2

least_conn;

bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf.d/up.conf
upstream webserver {
    #ip_hash;
    #hash $request_uri consistent;
    least_conn;
    server 172.25.254.10:80 weight=1 fail_timeout=15s max_fails=3;
    server 172.25.254.20:80 weight=1 fail_timeout=15s max_fails=3;
    #server 172.25.254.100:8888 backup;

}
server {
    listen 80;
    server_name www.fjw.org;

    location ~ / {
        proxy_pass http://webserver;
    }
}

[root@nginx ~]# nginx -s reload

#测试
[root@nginx ~]# curl www.fjw.org
RS1 - 172.25.254.10
[root@nginx ~]# curl www.fjw.org
RS2 - 172.25.254.20
[root@nginx ~]# curl www.fjw.org
RS1 - 172.25.254.10
[root@nginx ~]# curl www.fjw.org
RS2 - 172.25.254.20

hash $cookie_value;

bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf.d/up.conf
upstream webserver {
    #ip_hash;
    #hash $request_uri consistent;
    #least_conn;
    hash $cookie_fjw;
    server 172.25.254.10:80 weight=1 fail_timeout=15s max_fails=3;
    server 172.25.254.20:80 weight=1 fail_timeout=15s max_fails=3;
    #server 172.25.254.100:8888 backup;

}
server {
    listen 80;
    server_name www.fjw.org;

    location ~ / {
        proxy_pass http://webserver;
    }
}

[root@nginx ~]# nginx -s reload

#测试
[root@nginx ~]# curl -b fjw=1 www.fjw.org
RS1 - 172.25.254.10
[root@nginx ~]# curl -b fjw=2 www.fjw.org
RS2 - 172.25.254.20
[root@nginx ~]# curl -b fjw=3 www.fjw.org
RS1 - 172.25.254.10
[root@nginx ~]# curl -b fjw=4 www.fjw.org
RS1 - 172.25.254.10
[root@nginx ~]# curl -b fjw=5 www.fjw.org
RS2 - 172.25.254.20

七层与四层的参数对比

配置维度 七层反向代理(HTTP/HTTPS) 四层反向代理(TCP/UDP)
核心配置块 ✅ 放在 http {} 内部 ✅ 放在 stream {} 内部(与http平级)
内部配置结构 ✅ 有 server {}location {}(多层嵌套) ✅ 只有 server {}无location(关键差异)
依赖模块 ✅ ngx_http_proxy_module、ngx_http_upstream_module ✅ ngx_stream_proxy_module
监听指令(listen) ✅ 支持:listen 80;listen 443 ssl;http2;支持多域名区分 ✅ 支持:listen 3306;listen 6379 udp;;❌ 不支持ssl、server_name
转发指令(proxy_pass) ✅ 支持:加/不加 /(路径替换/追加);支持代理到http/https;可配合location路由 ✅ 仅支持:IP:端口 或 upstream集群名;❌ 不能带路径、不能加/;只做透传
upstream集群(共有参数) ✅ 支持:server、weight、max_fails、fail_timeout、backup、down、least_conn、hash $remote_addr ✅ 支持:与七层完全一致(上述共有参数)
upstream集群(独有参数) ✅ 独有:ip_hash;hash $cookie_xxx;hash $request_uri;(依赖HTTP解析) ❌ 无独有参数;❌ 不支持ip_hash、cookie/URI哈希(无法解析HTTP)
请求头/响应头操作 ✅ 独有:proxy_set_header、proxy_hide_header、proxy_pass_header、proxy_pass_request_headers/body ❌ 完全不支持(无法解析HTTP头信息)
超时参数 ✅ 支持:proxy_connect_timeout、proxy_read_timeout、proxy_send_timeout、proxy_http_version(独有) ✅ 支持:proxy_connect_timeout、proxy_read_timeout、proxy_send_timeout、proxy_timeout(独有,会话空闲超时);❌ 无proxy_http_version
SSL卸载(解密) ✅ 支持:可配置ssl_certificate、ssl_certificate_key,实现HTTPS解密 ❌ 不支持(仅透传TCP流,不解密SSL)
路由能力 ✅ 支持:按路径(/api)、后缀(.php)、正则路由(location匹配) ❌ 不支持路由;一个server对应一个端口,无法按路径拆分
支持协议 ✅ 仅支持:HTTP、HTTPS ✅ 支持:所有TCP、UDP协议(MySQL、Redis、SSH等)

四层反向代理

基于ngx_stream_proxy_module模块实现

建立子配置文件避免主配置文件杂乱

bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
include "/usr/local/nginx/conf.d/tcp/*.conf";	#与http同级

四层反向代理配置示例

bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf.d/tcp/proxy.conf
# 四层代理需放在stream块中(和http块同级)
stream {
    # MySQL代理
    server {
        listen 3306; # 监听本机3306端口
        # 转发到后端MySQL服务器
        proxy_pass 172.25.254.50:3306;
        # 四层超时配置
        proxy_connect_timeout 5s;
        proxy_timeout 300s;
    }
    
    # Redis代理(UDP示例)
    server {
        listen 6379 udp; # 监听UDP 6379
        proxy_pass 172.25.254.60:6379;
    }
}

四层反向代理负载均衡

基于ngx_stream_proxy_modulengx_http_upstream_module模块实现

bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
include "/usr/local/nginx/conf.d/tcp/*.conf";	#与http同级

tcp四层负载-mysql

配置后端实验环境

bash 复制代码
[root@RS1 ~]# dnf install mariadb-server -y
[root@RS2 ~]# dnf install mariadb-server -y

[root@RS1 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
server-id=10
[root@RS2 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
server-id=20

[root@RS1 ~]# systemctl enable --now mariadb
[root@RS2 ~]# systemctl enable --now mariadb

[root@RS1 ~]# mysql -e "CREATE USER fjw@'%' IDENTIFIED BY 'fjw';"
[root@RS1 ~]# mysql -e "GRANT ALL ON *.* TO fjw@'%';
[root@RS2 ~]# mysql -e "CREATE USER fjw@'%' IDENTIFIED BY 'fjw';"
[root@RS2 ~]# mysql -e "GRANT ALL ON *.* TO fjw@'%';"

配置tcp负载

bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf.d/tcp/up.conf
stream {
  upstream mysql_server {
    server 172.25.254.10:3306  max_fails=3 fail_timeout=30s;
    server 172.25.254.20:3306  max_fails=3 fail_timeout=30s;
  }

  server {
    listen 172.25.254.100:3306;
    proxy_pass mysql_server;				
    proxy_connect_timeout 30s;			# 连接后端超时时间
    proxy_timeout 300s;					# 长连接空闲超时(适配MySQL)
    proxy_socket_keepalive on;    		# 启用TCP keepalive,避免长连接断开
  }
}

[root@nginx ~]# nginx -s reload

在客户端进行测试

udp四层负载-dns

配置后端实验环境

bash 复制代码
[root@RS1 ~]# dnf install bind -y
[root@RS2 ~]# dnf install bind -y

[root@RS1 ~]# vim /etc/named.conf
[root@RS2 ~]# vim /etc/named.conf

options {
//      listen-on port 53 { 127.0.0.1; };			#注释掉使用默认参数
//      listen-on-v6 port 53 { ::1; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        secroots-file   "/var/named/data/named.secroots";
        recursing-file  "/var/named/data/named.recursing";
//      allow-query     { localhost; };
        dnssec-validation no;
   
[root@RS1 ~]# vim /etc/named.rfc1912.zones
[root@RS2 ~]# vim /etc/named.rfc1912.zones
#在末尾添加
zone "fjw.org" IN {
    type master;
    file "fjw.org.zone";
    allow-update { none; };
};

[root@RS1 ~]# cd /var/named/
[root@RS2 ~]# cd /var/named/
[root@RS1 named]# cp -p named.localhost fjw.org.zone
[root@RS2 named]# cp -p named.localhost fjw.org.zone       

[root@RS1 named]# vim fjw.org.zone
$TTL 1D
@   IN SOA  dns.fjw.org rname.invalid. (
                    0   ; serial
                    1D  ; refresh
                    1H  ; retry
                    1W  ; expire
                    3H )    ; minimum
       NS  dns.fjw.org
dns    A   172.25.254.10
test   A   172.25.254.66

[root@RS1 named]# systemctl enable --now named

[root@RS2 named]# vim fjw.org.zone
$TTL 1D
@   IN SOA  dns.fjw.org rname.invalid. (
                    0   ; serial
                    1D  ; refresh
                    1H  ; retry
                    1W  ; expire
                    3H )    ; minimum
       NS  dns.fjw.org
dns    A   172.25.254.20
test   A   172.25.254.66

[root@RS2 named]# systemctl enable --now named

配置udp负载

bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf.d/tcp/up.conf
stream {
  upstream mysql_server {
    server 172.25.254.10:3306  max_fails=3 fail_timeout=30s;
    server 172.25.254.20:3306  max_fails=3 fail_timeout=30s;
  }

  upstream dns_server{
    server 172.25.254.10:53 max_fails=3 fail_timeout=30s;
    server 172.25.254.20:53 max_fails=3 fail_timeout=30s;
  }

  server {
    listen 172.25.254.100:3306;
    proxy_pass mysql_server;
    proxy_connect_timeout 30s;
    proxy_timeout 300s;
    proxy_socket_keepalive on;
  }

  server {
    listen 172.25.254.100:53 udp;
    proxy_pass dns_server;
    proxy_timeout 1s;						# DNS请求超时时间(1s适配DNS快速响应特性)
    proxy_responses 1;						# UDP必配:等待后端1个响应后关闭连接
    error_log logs/dns.log;
  }
}

[root@nginx ~]# nginx -s reload

测试

FastCGI

Nginx基于模块ngx_http_fastcgi_module实现通过fastcgi协议将指定的客户端请求转发至php-fpm处理,其配置指令参数如下:

复制代码
fastcgi_pass address:port;		
#转发请求到后端服务器,address为后端的fastcgi server的地址,可用位置:localhost, if in localhost

fastcgi_index name;
#fastcgi默认的主页资源,示例:fastcgi_index index.php;

fastcgi_param value;
#设置传递给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
#可以通过include fastcgi.conf;参数来作为环境配置参数
#fastcgi.conf此文件都包含了预设的FastCGI环境变量

以下为简洁的默认配置示例

bash 复制代码
server {
        listen 80;
        server_name php.fjw.org;
        root /webdir/fjw.org/php/html;
        location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi.conf;
        }
}

php源码编译安装

1.下载源码包

bash 复制代码
[root@nginx ~]# wget https://www.php.net/distributions/php-8.3.30.tar.gz
[root@nginx ~]# 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     #下载依赖包

2.解压并编译

bash 复制代码
[root@nginx ~]# tar zxf php-8.3.30.tar.gz

#下载依赖包
[root@nginx ~]# dnf install gcc systemd-devel-252-51.el9.x86_64 libxml2-devel.x86_64 sqlite-devel.x86_64  libcurl-devel.x86_64  libpng-devel.x86_64 oniguruma-devel-6.9.6-1.el9.6.x86_64.rpm -y

[root@nginx php-8.3.30]# ./configure \
--prefix=/usr/local/php \		#安装路径
--with-config-file-path=/usr/local/php/etc \	#指定配置路径
--enable-fpm  \			#用cgi方式启动程序
--with-fpm-user=nginx \	#指定运行用户身份
--with-fpm-group=nginx \
--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

[root@nginx php-8.3.30]# make && make instsall

3.配置优化php

bash 复制代码
[root@nginx ~]# cd /usr/local/php/etc
[root@nginx etc]# cp php-fpm.conf.default php-fpm.conf	#复制模板
[root@nginx etc]# vim php-fpm.conf
#去掉注释
pid = run/php-fpm.pid 		#指定pid文件存放位置

[root@nginx etc]# cd php-fpm.d/
[root@nginx php-fpm.d]# cp www.conf.default www.conf
[root@nginx php-fpm.d]# vim www.conf
41 listen = 0.0.0.0:9000	#可以修改端口

#生成主配置文件
[root@nginx php-8.3.30]# cp php.ini-production /usr/local/php/etc/php.ini
[root@nginx ~]# vim /usr/local/php/etc/php.ini
989 date.timezone = Asia/Shanghai #修改时区

#生成启动文件
[root@nginx etc]# cp ~/php-8.3.30/sapi/fpm/php-fpm.service /lib/systemd/system/
[root@nginx etc]# vim /lib/systemd/system/php-fpm.service
#ProtectSystem=full 		#注释该内容
[root@nginx etc]# systemctl daemon-reload
[root@nginx etc]# systemctl enable --now php-fpm.service
[root@nginx etc]# netstat -antlupe | grep php
tcp        0      0 127.0.0.1:9000          0.0.0.0:*               LISTEN      0          120615     147595/php-fpm: mas

Nginx整合php

生成默认发布目录与默认发布文件

bash 复制代码
[root@nginx ~]# mkdir /webdir/fjw.org/php/html -p
[root@nginx ~]# echo php.fjw.org > /webdir/fjw.org/php/html/index.html
[root@nginx ~]# cat > /webdir/fjw.org/php/html/index.php << eof
> <?php
>     phpinfo();
> ?>
> eof

编辑配置文件

bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
server {
......
include "/usr/local/nginx/conf.d/*.conf";
}

[root@nginx ~]# vim /usr/local/nginx/conf.d/php.conf
server {
    listen 80;
    server_name php.fjw.org;
    root /webdir/fjw.org/php/html;
    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi.conf;
    }
}

[root@nginx ~]# nginx -s reload

测试

访问默认静态页面

访问动态php页面

php扩展缓存模块

软件下载:http://pecl.php.net/package/memcache

架构图

原理是利用利用memcache实现php的缓存加速,memcache可替换为任意nosql数据库例如redis

安装php扩展模块memcache

bash 复制代码
#下载软件包后进行解压
[root@nginx ~]# tar zxf memcache-8.2.tgz
#安装php扩展编译软件,生产编译配置
[root@nginx ~]# cd memcache-8.2/
[root@nginx memcache-8.2]# dnf install autoconf -y
[root@nginx memcache-8.2]# phpize
[root@nginx memcache-8.2]# ./configure  && make && make install

#编译完成后查看是否有插件存在
[root@nginx memcache-8.2]# ls /usr/local/php/lib/php/extensions/no-debug-non-zts-20230831/
memcache.so  opcache.so

#编辑php配置文件
[root@nginx memcache-8.2]# vim /usr/local/php/etc/php.ini
939  extension=memcache			#开启支持memcache

#重启服务并查看是否支持memcache模块
[root@Nginx memcache-8.2]# systemctl restart php-fpm.service
[root@Nginx memcache-8.2]# php -m  | grep memcache
memcache

安装memcached

bash 复制代码
[root@nginx ~]# dnf install memcached.x86_64 -y.配置memcache

配置memcached

bash 复制代码
[root@nginx nginx-1.28.1]# cat /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS="-l 127.0.0.1,::1"

[root@nginx ~]# systemctl enable --now memcached.service

[root@nginx ~]# 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

测试缓存

bash 复制代码
[root@nginx memcache-8.2]# vim memcache.php		#memcache缓存状态页
define('ADMIN_USERNAME','admin');   // Admin Username
define('ADMIN_PASSWORD','fjw');     // Admin Password
$MEMCACHE_SERVERS[] = '172.25.254.100:11211'; // add more as an array
#$MEMCACHE_SERVERS[] = 'mymemcache-server2:11211'; // add more as an array

[root@nginx memcache-8.2]# cp -p memcache.php /webdir/fjw.org/php/html/
[root@nginx memcache-8.2]# cp -p example.php /webdir/fjw.org/php/html/	#缓存测试文件

#测试
http://php.fjw.org/memcache.php			#数据页面,在浏览器中可以直接访问
[root@nginx memcache-8.2]# ab -n 1000 -c 300  php.fjw.org/example.php

可以看到被缓存后的文件都是直接走缓存而不会再次处理php文件

测试性能

bash 复制代码
[root@nginx ~]# ab -n 1000 -c 200 php.fjw.org/index.php	#未连接缓存的文件
@@@内容忽略@@@
Complete requests:      1000
Failed requests:        107

[root@nginx ~]# ab -n 1000 -c 200 php.fjw.org/example.php #连接缓存的文件
@@@内容忽略@@@
Complete requests:      1000
Failed requests:        0

php高速缓存

  • 由于php扩展缓存是通过php配置来实现缓存,可以通过nginx直接对接memcache来实现缓存节省开销当有缓存时直接访问memcahe而不走php;
  • 利用memcache实现php的缓存加速;
  • 原理是让nginx直接取访问memcache的缓存如果存在缓存而不去访问php-fpm再访问memcache,当memcache没有缓存才访问php-fpm处理文件后存入缓存返回给nginx。

架构图

实现nginx直接访问memcache需要两个模块

  • srcache-nginx-module 缓存获取
  • memc-nginx-module memcache读写

重新编译nginx添加模块

bash 复制代码
[root@nginx ~]# systemctl stop nginx.service

[root@nginx ~]# tar zxf memc-nginx-module-0.20.tar.gz
[root@nginx ~]# tar zxf srcache-nginx-module-0.33.tar.gz
#切换到nginx源码包清除Makefile
[root@nginx ~]# cd nginx-1.28.1/
[root@nginx nginx-1.28.1]# make clean

#添加模块重新编译
[root@nginx nginx-1.28.1]# ./configure  --prefix=/usr/local/nginx --user=nginx --group=nginx --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/echo-nginx-module-0.64  --add-module=/root/memc-nginx-module-0.20 --add-module=/root/srcache-nginx-module-0.33

#编译但不拷贝文件到系统路径
[root@nginx nginx-1.28.1]# make

更换二进制文件

bash 复制代码
[root@nginx nginx-1.28.1]# rm -rf /usr/local/nginx/sbin/nginx
[root@nginx nginx-1.28.1]# cp -p objs/nginx /usr/local/nginx/sbin/

#查看是否添加成功

编辑nginx整合memcache

bash 复制代码
[root@nginx ~]# vim /usr/local/nginx/conf.d/php.conf
upstream memcache {
   server 127.0.0.1:11211;
   keepalive 512;
}

server {
        listen 80;
        server_name php.fjw.org;
        root /webdir/fjw.org/php/html;

        location /memc {
        	internal;			# 标记该 location 仅能被 Nginx 内部调用,不接受外部直接访问
        	# Memcache 连接/读写超时时间(均为 100 毫秒)
        	memc_connect_timeout 100ms;
       	 	memc_send_timeout 100ms;
        	memc_read_timeout 100ms;
        	# 设置 Memcache 的缓存键:值为请求的查询字符串(如 ?id=1 的部分)
        	set $memc_key $query_string;
        	# 设置缓存过期时间:300 秒(5 分钟)
        	set $memc_exptime 300;
         	# 将请求转发到上面定义的 memcache 上游服务
        	memc_pass memcache;
        }

        location ~ \.php$ {
        	 # 定义缓存键:URL 路径 + 查询参数(比如 /index.php?id=1)
        	set $key $uri$args;
        	# 读取缓存:从 /memc 接口获取 $key 对应的缓存数据
        	srcache_fetch GET /memc $key;
        	# 写入缓存:将 PHP 解析后的响应结果通过 /memc 接口存入 $key
        	srcache_store PUT /memc $key;
        	fastcgi_pass 127.0.0.1:9000;
        	fastcgi_index index.php;
        	include fastcgi.conf;
        }
}

[root@nginx ~]# nginx -s reload

参数详解

bash 复制代码
set $key $uri$args:定义最终的缓存键 = 访问路径($uri,如 /index.php) + 查询参数($args,如 id=1),确保不同页面 / 参数的缓存唯一。

srcache_fetch GET /memc $key:读取缓存:请求 PHP 文件时,先通过 /memc 接口从 Memcache 读取 $key 对应的缓存,如果缓存存在,直接返回缓存内容,不走 PHP-FPM 解析。

srcache_store PUT /memc $key:写入缓存:如果缓存不存在,Nginx 会先让 PHP-FPM 解析 PHP 文件,然后将解析后的响应结果通过 /memc 接口存入 Memcache,供后续请求使用。

测试

bash 复制代码
#重启memcache并访问没有缓存的php文件查看缓存命中
[root@nginx ~]# systemctl restart memcached.service
[root@nginx ~]# ab -n 1000 -c 100 php.fjw.org/index.php

如图所示只有第一次访问未命中缓存后续缓存后都走缓存

Nginx二开版本openresty

OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方 模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服 务和动态网关。

官网: http://openresty.org/cn/

nginx的其它的二次发行版:

Tengine:由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加 了很多高级功能和特性。Tengine的性能和稳定性已经在大型的网站如淘宝网,天猫商城等得到了 很好的检验。它的最终目标是打造一个高效、稳定、安全、易用的Web平台。从2011年12月开始, Tengine成为一个开源项目官网: http://tengine.taobao.org/

编译安装openresty

安装依赖

bash 复制代码
[root@webserver ~]# dnf install gcc pcre-devel openssl-devel perl zlib-devel -y

编译安装

bash 复制代码
[root@webserver ~]# wget https://openresty.org/download/openresty-1.27.1.2.tar.gz
[root@webserver ~]# tar zxf openresty-1.27.1.2.tar.gz
[root@webserver ~]# cd openresty-1.27.1.2/
[root@webserver ~]# useradd -r -s /sbin/nologin nginx

#检查环境
[root@webserver openresty-1.27.1.2]# ./configure --prefix=/usr/local/openresty --user=nginx --group=nginx --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

[root@webserver openresty-1.27.1.2]# gmake && gmake install

添加PATH环境变量

bash 复制代码
[root@webserver openresty-1.27.1.2]# vim ~/.bash_profile
export PATH=$PATH:/usr/local/openresty/bin

[root@webserver openresty-1.27.1.2]# source  ~/.bash_profile

[root@webserver openresty-1.27.1.2]# openresty -v
nginx version: openresty/1.27.1.2

发布测试页面

bash 复制代码
[root@webserver openresty-1.27.1.2]# echo hello openresty > /usr/local/openresty/nginx/html/index.html
[root@webserver openresty-1.27.1.2]# curl 172.25.254.200
hello openresty

默认测试页

相关推荐
荣--4 小时前
一键部署不是为了省时间 —— 它是把"买来的 PaaS"变成"自己的平台"的拐点
运维·zabbix·工程化·一键部署·平台化·边界设计
江华森5 小时前
动手实战学 Docker — 从零到集群编排完全指南
运维
Avan_菜菜21 小时前
FRP 内网穿透完整实战:从 HTTP 映射到 HTTPS 自签代理
运维·nginx·https
SelectDB2 天前
Litefuse 开源并推出单进程轻量模式,25 秒就能跑起来的 Agent 可观测与评估平台
运维·后端·自动化运维
XIAOHEZIcode3 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户0328472220704 天前
如何搭建本地yum源(上)
运维
ping某5 天前
为什么 Nginx 明明监听了 80,转发后端时却用了 4xxxx 端口?
后端·nginx
大树887 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠7 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质7 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务