企业高性能web服务器

目录

1、实验-编译安装nginx

2、平滑升级和回滚

1.平滑升级

2.回滚

3、Nginx 核心配置详解

3.1 新建一个web站点

3.2 root 与 alias

3.3 location

3.4nginx的用户认证

3.5 自定义错误页面

3.6自定义错误日志

3.7检测文件是否存在

3.8长链接

4、Nginx变量的使用

4.1 变量示例

五、Nginx Rewrite相关功能

1、if 指令

2、示例-if指令

3、示例-break

4、示例-return

5、rewrite指令

5.1 域名永久与临时重定向

5.2 永久重定向301

5.3临时重定向302

6、rewrite案例-last与break

7、自动跳转https

8、防盗链

8.1 实现盗链

8.2 实现防盗链

六、 Nginx 反向代理功能

1、实现http反向代理

2、示例-动静分离

3、反向代理示例-缓存功能

http 反向代理负载均衡

4、反向代理示例:后端多台web服务器

5、实现Nginx四层负载均衡

6、负载均衡实例-MySQL

7、udp负载均衡实例-NDS

七、实现FastCGI

案例 - Nginx与php-fpm在同一服务器

1. 源码编译nginx、php

2. php相关配置优化

3. 准备php测试页面

php的动态扩展模块(php的缓存模块)

1.安装memcache模块

2.复制测试文件到nginx发布目录中

3.配置php加载memcache模块

4.部署memcached

5.查看性能

6.php高速缓存

八、nginx 二次开发版本

1、openresty


1.1 互联网发展历程回顾

1993年3月2日,中国科学院高能物理研究所租用AT&T公司的国际卫星信道建立的接入美国SLAC国家实验室的64K专线正式开通,成为我国连入Internet的第一根专线。

1995年马云开始创业并推出了一个web网站 中国黄页

1999年创建阿里巴巴www.alibabagroup.com

2003年5月10日创立淘宝网

2004年12月,马云创立第三方网上支付平台支付宝(蚂蚁金服旗下,共有蚂蚁金服支付宝、余额宝、招财宝、蚂蚁聚宝、网商银行、蚂蚁花呗、芝麻信用等子业务板块)

2009年开始举办双十一购物狂欢节,以下是历年交易成交额:

2009年双十一:5000万元
2010年双十一:9.36亿元
2011年双十一:33.6亿元
2012年双十一:191亿元
2013年双十一:350亿元
2014年双十一:571亿元
2015年双十一:912.17亿元
2016年双十一:1207亿元
2017年双十一:1682.69亿元
2018年双十一:2135亿元
2019年双十一:2684亿元
2020年双十一:4982亿元
2021年双十一:5403亿元
2022年双十一:5571亿元

2022年双十一:5571亿元2012年1月11日淘宝商城正式更名为“天猫”

2014年9月19日里巴巴集团于纽约证券交易所正式挂牌上市

1.2 Web 服务介绍

1.2.1 Apache 经典的 Web 服务端

Apache起初由美国的伊利诺伊大学香槟分校的国家超级计算机应用中心开发

目前经历了两大版本分别是1.X和2.X其可以通过编译安装实现特定的功能

1.2.1.1 Apache prefork 模型

预派生模式,有一个主控制进程,然后生成多个子进程,使用select模型,最大并发1024
每个子进程有一个独立的线程响应用户请求
相对比较占用内存,但是比较稳定,可以设置最大和最小进程数
是最古老的一种模式,也是最稳定的模式,适用于访问量不是很大的场景
优点:稳定
缺点:每个用户请求需要对应开启一个进程,占用资源较多,并发性差,不适用于高并发场景

1.2.1.2 Apache worker 模型

一种多进程和多线程混合的模型
有一个控制进程,启动多个子进程
每个子进程里面包含固定的线程
使用线程程来处理请求
当线程不够使用的时候会再启动一个新的子进程,然后在进程里面再启动线程处理请求,
由于其使用了线程处理请求,因此可以承受更高的并发
优点:相比prefork 占用的内存较少,可以同时处理更多的请求
缺点:使用keepalive的长连接方式,某个线程会一直被占据,即使没有传输数据,也需要一直等待到超时才会被释放。如果过多的线程,被这样占据,也会导致在高并发场景下的无服务线程可用(该问题在prefork模式下,同样会发生)

1.2.1.3 Apache event模型

Apache中最新的模式,2012年发布的apache 2.4.X系列正式支持event 模型,属于事件驱动模型(epoll)
每个进程响应多个请求,在现在版本里的已经是稳定可用的模式
它和worker模式很像,最大的区别在于,它解决了keepalive场景下长期被占用的线程的资源浪费问题
(某些线程因为被keepalive,空挂在哪里等待,中间几乎没有请求过来,甚至等到超时)event MPM中,会有一个专门的线程来管理这些keepalive类型的线程
当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样增强了高并发场景下的请求处理能力
优点:单线程响应多请求,占据更少的内存,高并发下表现更优秀,会有一个专门的线程来管理keepalive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放
缺点:没有线程安全控制

主流的web服务器

1.2.2 Nginx-高性能的 Web 服务端

Nginx是由1994年毕业于俄罗斯国立莫斯科鲍曼科技大学的同学为俄罗斯rambler.ru公司开发的,开发工作最早从2002年开始,第一次公开发布时间是2004年10月4日,版本号是0.1.0
2019年3月11日F5 与 NGINX达成协议,F5 将收购 NGINX 的所有已发行股票,总价值约为 6.7 亿美元。
6.7亿美金约合44.97亿人民币,nginx核心模块代码长度198430(包括空格、注释),所以一行代码约为2.2万人民币
官网地址 www.nginx.org
Nginx历经十几年的迭代更新(https://nginx.org/en/CHANGES), 目前功能已经非常完善且运行稳定,另外Nginx的版本分为开发版、稳定版和过期版,nginx以功能丰富著称,它即可以作为http服务器,也可以作为反向代理服务器或者邮件服务器能够快速的响应静态网页的请求
支持FastCGI/SSL/Virtual Host/URL Rwrite /Gzip / HTTP Basic Auth/http或者TCP的负载均衡(1.9版本以上且开启stream模块)等功能,并且支持第三方的功能扩展。
天猫 淘宝 京东 小米 163 新浪等一线互联网公司都在用Nginx或者进行二次开发

基于Nginx的工作场景:

左边椭圆为一个请求,到了nginx,动态的访问动态的,静态的访问静态的。

1、实验-编译安装nginx

直接安装dnf install nginx,在企业中并不常见,因为一般都是使用的定制的nginx。
实验准备:
克隆rhel9 名为nginx 172.25.254.100
vmset.sh eth0 172.25.254.100 nginx.jingwen.org
#下载-安装
[root@Nginx ~]# dnf install gcc pcre-devel zlib-devel openssl-devel -y
[root@nginx ~]# tar zxf nginx-1.24.0.tar.gz 
[root@Nginx nginx-1.24.0]# useradd -s /sbin/nologin -M nginx
[root@nginx nginx-1.24.0]# ./configure --prefix=/usr/local/nginx \
--user=nginx \            # 指定nginx运行用户
--group=nginx \           # 指定nginx运行组
--with-http_ssl_module \  # 支持https://
--with-http_v2_module \   # 支持http版本2
--with-http_realip_module \ # 支持ip透传
--with-http_stub_status_module \ # 支持状态页面
--with-http_gzip_static_module \ # 支持压缩
--with-pcre \              # 支持正则
--with-stream \            # 支持tcp反向代理
--with-stream_ssl_module \ # 支持tcp的ssl加密
--with-stream_realip_module # 支持tcp的透传ip


./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

#检测成功则Makefile出现
[root@nginx nginx-1.24.0]# ls
auto     CHANGES.ru  configure  html     Makefile  objs    src
CHANGES  conf        contrib    LICENSE  man       README
[root@nginx nginx-1.24.0]# make && make install
#nginx完成安装以后,有四个主要的目录

[root@nginx nginx-1.24.0]# ls /usr/local/nginx/
conf  html  logs  sbin
conf:保存nginx所有的配置文件,其中nginx.conf是nginx服务器的最核心最主要的配置文件,其他的.conf则是用来配置nginx相关的功能的,例如fastcgi功能使用的是fastcgi.conf和fastcgi_params两个文件,配置文件一般都有一个样板配置文件,是以.default为后缀,使用时可将其复制并将default后缀去掉即可。
html目录中保存了nginx服务器的web文件,但是可以更改为其他目录保存web文件,另外还有一个50x的web文件是默认的错误页面提示页面。
logs:用来保存nginx服务器的访问日志错误日志等日志,logs目录可以放在其他路径,比
如/var/logs/nginx里面。
sbin:保存nginx二进制启动脚本,可以接受不同的参数以实现不同的功能。

[root@nginx nginx-1.24.0]# cd /usr/local/nginx/
[root@nginx nginx]# cd sbin/
[root@nginx sbin]# ls
nginx

#验证版本及编译参数
#不想写这么长的路径,把nginx软件的命令执行路径添加到环境变量中
[root@nginx nginx]# vi ~/.bash_profile
export PATH=$PATH:/usr/local/nginx/sbin
[root@nginx nginx]# source ~/.bash_profile

#显示 /usr/local/nginx/sbin/nginx 这个文件的磁盘使用量为 5.5MB
[root@nginx nginx]# du -sh /usr/local/nginx/sbin/nginx 
5.5M	/usr/local/nginx/sbin/nginx

[root@nginx nginx]# nginx
[root@nginx nginx]# curl 172.25.254.100
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
[root@nginx sbin]# id nginx 
uid=1000(nginx) gid=1000(nginx) groups=1000(nginx)
[root@nginx sbin]# ll
total 5548
-rwxr-xr-x 1 root root 5679504 Aug 15 11:01 nginx

2、平滑升级和回滚

1.平滑升级

平滑升级客户感受不到任何变化,我们就能升级成功

[root@nginx ~]# ls
anaconda-ks.cfg  echo-nginx-module-0.63.tar.gz  nginx-1.24.0  nginx-1.24.0.tar.gz  nginx-1.26.1  nginx-1.26.1.tar.gz
[root@nginx ~]# tar zxf nginx-1.26.1.tar.gz 
[root@nginx ~]# tar zxf echo-nginx-module-0.63.tar.gz 
[root@nginx ~]# ls
anaconda-ks.cfg                nginx-1.24.0         nginx-1.26.1.tar.gz
echo-nginx-module-0.63         nginx-1.24.0.tar.gz
echo-nginx-module-0.63.tar.gz  nginx-1.26.1

[root@nginx ~]# cd nginx-1.26.1
[root@nginx nginx-1.26.1]# ls
auto     CHANGES.ru  configure  html     man     src
CHANGES  conf        contrib    LICENSE  README

#检测,但是需要加一个模板参数
[root@nginx nginx-1.26.1]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --add-module=/root/echo-nginx-module-0.63 --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
#检测,出现makefile文件
#这里不能使用make&&make install

[root@nginx nginx-1.26.1]# ls
auto     CHANGES.ru  configure  html     Makefile  objs    src
CHANGES  conf        contrib    LICENSE  man       README
[root@nginx nginx-1.26.1]# make
[root@nginx nginx-1.26.1]# cd objs/
[root@nginx objs]# ls
autoconf.err  nginx    ngx_auto_config.h   ngx_modules.c  src
Makefile      nginx.8  ngx_auto_headers.h  ngx_modules.o
[root@nginx objs]# cd /usr/local/nginx/sbin/
[root@nginx sbin]# ls
nginx

#先把nginx备份
[root@nginx sbin]# cp nginx nginx.bak
[root@nginx sbin]# ls
nginx  nginx.bak

#把新版本的nginx命令复制过去
[root@nginx sbin]# \cp -f /root/nginx-1.26.1/objs/nginx /usr/local/nginx/sbin
[root@nginx sbin]# ps aux | grep nginx
root        7353  0.0  0.0   9888   936 ?        Ss   16:17   0:00 nginx: master process nginx
nginx       7354  0.0  0.2  13720  5208 ?        S    16:17   0:00 nginx: worker process
root       10686  0.0  0.1   6408  2212 pts/0    S+   16:22   0:00 grep --color=auto nginx
[root@nginx sbin]# pidof nginx
46163 16790

#把旧的work回收,使用新的进程。
#USR2信号通常用于优雅地重启服务,即启动一个新的工作进程来处理新的请求,同时旧的进程继续处理当前的请求,直到它们完成。
[root@nginx sbin]# kill -USR2 7353
[root@nginx sbin]# ps aux | grep nginx
root        7353  0.0  0.1   9888  2576 ?        Ss   16:17   0:00 nginx: master process nginx
nginx       7354  0.0  0.2  13720  5208 ?        S    16:17   0:00 nginx: worker process
root       10689  0.0  0.3   9916  6360 ?        S    16:23   0:00 nginx: master process nginx
nginx      10690  0.0  0.2  13748  4756 ?        S    16:23   0:00 nginx: worker process
root       10692  0.0  0.1   6408  2132 pts/0    T    16:23   0:00 grep --color=auto nginx
root       10694  0.0  0.1   6408  2144 pts/0    S+   16:23   0:00 grep --color=auto nginx

[root@nginx sbin]# curl -I 172.25.254.101
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Thu, 15 Aug 2024 08:24:58 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Thu, 15 Aug 2024 08:14:26 GMT
Connection: keep-alive
ETag: "66bdb8e2-267"
Accept-Ranges: bytes

#WINCH信号通常用于请求旧的工作进程(在USR2信号触发的重启过程中)优雅地退出,以便新的工作进程可以接管所有的请求处理。
[root@nginx sbin]# kill -WINCH 7353
[root@nginx sbin]# ps aux | grep nginx
root        7353  0.0  0.1   9888  2576 ?        Ss   16:17   0:00 nginx: master process nginx
root       10689  0.0  0.3   9916  6360 ?        S    16:23   0:00 nginx: master process nginx
nginx      10690  0.0  0.2  13748  4756 ?        S    16:23   0:00 nginx: worker process
root       10692  0.0  0.1   6408  2132 pts/0    T    16:23   0:00 grep --color=auto nginx
root       10816  0.0  0.1   6408  2148 pts/0    S+   16:25   0:00 grep --color=auto nginx

#此时可以看见版本已经升级成功为1.26.1
[root@nginx sbin]# curl -I 172.25.254.101
HTTP/1.1 200 OK
Server: nginx/1.26.1
Date: Thu, 15 Aug 2024 08:25:56 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Thu, 15 Aug 2024 08:14:26 GMT
Connection: keep-alive
ETag: "66bdb8e2-267"
Accept-Ranges: bytes

2.回滚

假设新版本效果一般,我们需要回到老版本。

[root@nginx sbin]# kill -HUP 16790
[root@nginx sbin]# ps aux | grep nginx
root       16790  0.0  0.1   9892  3324 ?        Ss   11:06   0:00 nginx: master process nginx
nginx      46163  3.7  0.2  13736  4852 ?        S    11:53   0:00 nginx: worker process
root       48875  0.0  0.1   6408  2160 pts/0    S+   11:54   0:00 grep --color=auto nginx

#回收之前新的
[root@nginx sbin]# kill -WINCH  ********
[root@nginx sbin]# ps aux | grep nginx
************
[root@nginx sbin]# curl -I 172.25.254.100
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Thu, 15 Aug 2024 03:55:19 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Thu, 15 Aug 2024 03:01:44 GMT
Connection: keep-alive
ETag: "66bd6f98-267"
Accept-Ranges: bytes
[root@nginx sbin]# kill -HUP 7353
[root@nginx sbin]# ps aux | grep nginx
root        7353  0.0  0.1   9888  2576 ?        Ss   16:17   0:00 nginx: master process nginx
root       10689  0.0  0.3   9916  6360 ?        S    16:23   0:00 nginx: master process nginx
nginx      10690  0.0  0.2  13748  5228 ?        S    16:23   0:00 nginx: worker process
root       10692  0.0  0.1   6408  2132 pts/0    T    16:23   0:00 grep --color=auto nginx
nginx      11295  0.0  0.2  13720  4728 ?        S    16:29   0:00 nginx: worker process
root       11383  0.0  0.1   6408  2080 pts/0    S+   16:30   0:00 grep --color=auto nginx

#回收之前新的
[root@nginx sbin]# kill -WINCH 10689

#此时已经回滚成功
[root@nginx sbin]# curl -I 172.25.254.100
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Thu, 15 Aug 2024 08:31:59 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Thu, 15 Aug 2024 03:01:44 GMT
Connection: keep-alive
ETag: "66bd6f98-267"
Accept-Ranges: bytes

options:

[root@Nginx ~]# nginx -v
nginx version: nginx/1.18.0
Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]
Options:
-?,-h : this help
-v : show version and exit
-V : show version and configure options then exit #显示版本和编译参数
-t : test configuration and exit #测试配置文件是否异
-T : test configuration, dump it and exit #测试并打印
-q : suppress non-error messages during configuration testing #静默
模式
-s signal : send signal to a master process: stop, quit, reopen, reload #
发送信号,reload信号 会生成新的worker,但master不会重新生成
-p prefix : set prefix path (default: /etc/nginx/) #指定Nginx 目录
-c filename : set configuration file (default: /etc/nginx/nginx.conf) #
配置文件路径
-g directives : set global directives out of configuration file #设置全局指令,注意和配置文件不要同时配置,否则冲突

Nginx 启动文件:

[root@Nginx ~]# vim /lib/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
[root@Nginx ~]# systemctl daemon-reload
[root@Nginx ~]# systemctl start nginx

1.2.4 服务端 I/O 流程

I/O在计算机中指Input/Output, IOPS (Input/Output Per Second)即每秒的输入输出量(或读写次数),是衡量磁盘性能的主要指标之一。IOPS是指单位时间内系统能处理的I/O请求数量,一般以每秒处理的I/O请求数量为单位,I/O请求通常为读或写数据操作请求。

一次完整的I/O是用户空间的进程数据与内核空间的内核数据的报文的完整交换,但是由于内核空间与用户空间是严格隔离的,所以其数据交换过程中不能由用户空间的进程直接调用内核空间的内存数据,而是需要经历一次从内核空间中的内存数据copy到用户空间的进程内存当中,所以简单说I/O就是把数据从内核空间中的内存数据复制到用户空间中进程的内存当中。

服务器的I/O
磁盘I/O
网络I/O : 一切皆文件,本质为对socket文件的读写

1.3.2 网络 I/O 模型

阻塞型、非阻塞型、复用型、信号驱动型、异步

信号驱动I/O的意思就是进程现在不用傻等着,也不用去轮询。而是让内核在数据就绪时,发送信号通知进程。
调用的步骤是,通过系统调用 sigaction ,并注册一个信号处理的回调函数,该调用会立即返回,然后主程序可以继续向下执行,当有I/O操作准备就绪,即内核数据就绪时,内核会为该进程产生一个 SIGIO信号,并回调注册的信号回调函数,这样就可以在信号回调函数中系统调用 recvfrom 获取数据,将用户进程所需要的数据从内核空间拷贝到用户空间
此模型的优势在于等待数据报到达期间进程不被阻塞。用户主程序可以继续执行,只要等待来自信号处
理函数的通知。
在信号驱动式 I/O 模型中,应用程序使用套接口进行信号驱动 I/O,并安装一个信号处理函数,进程继续运行并不阻塞
在信号驱动式 I/O 模型中,应用程序使用套接口进行信号驱动 I/O,并安装一个信号处理函数,进程继续运行并不阻塞
当数据准备好时,进程会收到一个 SIGIO 信号,可以在信号处理函数中调用 I/O 操作函数处理数据。优点:线程并没有在等待数据时被阻塞,内核直接返回调用接收信号,不影响进程继续处理其他请求因此可以提高资源的利用率
缺点:信号 I/O 在大量 IO 操作时可能会因为信号队列溢出导致没法通知
异步阻塞:程序进程向内核发送IO调用后,不用等待内核响应,可以继续接受其他请求,内核收到进程请求后进行的IO如果不能立即返回,就由内核等待结果,直到IO完成后内核再通知进程。

3、Nginx 核心配置详解

nginx 官方帮助文档:http://nginx.org/en/docs/
Nginx的配置文件的组成部分:
主配置文件:nginx.conf
子配置文件: include conf.d/*.conf
fastcgi, uwsgi,scgi 等协议相关的配置文件
mime.types:支持的mime类型,MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据,是设定某
种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动
使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
nginx 配置文件格式说明
配置文件由指令与指令块构成
每条指令以;分号结尾,指令与值之间以空格符号分隔
可以将多条指令放在同一行,用分号分隔即可,但可读性差,不推荐指令块以{ }大括号将多条指令组织在一起,且可以嵌套指令块include语句允许组合多个配置文件以提升可维护性
使用#符号添加注释,提高可读性
使用$符号使用变量
部分指令的参数支持正则表达式

主配置文件结构:四部分

main block:主配置段,即全局配置段,对http,mail都有效
#事件驱动相关的配置
event {
...
}
#http/https 协议相关配置段
http {
...
}
#默认配置文件不包括下面两个块
#mail 协议相关配置段
mail {
...
}
#stream 服务器相关配置段
stream {
...
}

3.1 新建一个web站点

[root@nginx ~]# vi /usr/local/nginx/conf/nginx.conf
#gzip  on;
    include "/usr/local/nginx/conf.d/*.conf";

[root@nginx ~]# mkdir -p /usr/local/nginx/conf.d
[root@nginx ~]# vi /usr/local/nginx/conf.d/vhost.conf
server {
    listen 80;
    server_name www.jingwen.org;
    root /data/web/html;
    index index.html;
}

[root@nginx ~]# mkdir -p /data/web/html
[root@nginx ~]# echo www.jingwen.org > /data/web/html/index.html
[root@nginx ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx ~]# nginx -s reload

本地解析C:\Windows\System32\drivers\etc hosts里加入172.25.254.101

3.2 root 与 alias

root:指定web的家目录,在定义location的时候,文件的绝对路径等于 root+location3.2

[root@nginx ~]# mkdir /data/web/test1 -p

#当你去访问/test1的时候 我带你访问 /detaweb/test1
[root@nginx ~]# vi /usr/local/nginx/conf.d/vhost.conf 
server {
    listen 80;
    server_name www.jingwen.org;
    root /data/web/html;
    index index.html;
    location /test1/ {
    	root /data/web;
    }
}
[root@nginx ~]# echo /data/web/test1 > /data/web/test1/index.html
[root@nginx ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx ~]# nginx -s reload

alias:定义路径别名,会把访问的路径重新定义到其指定的路径,文档映射的另一种机制;仅能用于location上下文,此指令使用较少

[root@nginx ~]# cat /usr/local/nginx/conf.d/vhost.conf 
server {
    listen 80;
    server_name www.jingwen.org;
    root /data/web/html;
    index index.html;
    location /test1/ {
    	root /data/web;
    }
    location /test2 {
        alias /data/web/test1;
    }
}
[root@nginx ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx ~]# nginx -s reload

3.3 location

# 语法规则:
location [ = | ~ | ~* | ^~ ] uri { ... }

=       #用于标准uri前,需要请求字串与uri精确匹配,大小敏感,如果匹配成功就停止向下匹配并立即处理请求
^~      #用于标准uri前,表示包含正则表达式,并且匹配以指定的正则表达式开头, #对uri的最左边部分做匹配检查,不区分字符大小写
~       #用于标准uri前,表示包含正则表达式,并且区分大小写
~*      #用于标准uri前,表示包含正则表达式,并且不区分大写
不带符号 #匹配起始于此uri的所有的uri
\       #用于标准uri前,表示包含正则表达式并且转义字符。可以将 . * ?等转义为普通符号

新版本:1.26
#匹配目录优先级从高到低:
(~* = ~)> 不带符号 > ^~ > =
#匹配文件优先级从高到低:
= > (~* = ~) > 不带符号 > ^~ 
#测试简单目录优先级,精确匹配
[root@nginx ~]# mkdir /data/web{1,2}
[root@nginx ~]# mkdir /data/web{1,2}/test
[root@nginx ~]# echo web1 test > /data/web1/test/index.html
[root@nginx ~]# echo web2 test > /data/web2/test/index.html
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhost.conf
server {
    listen 80;
    server_name www.jingwen.org;
    root /data/web/html;
    index index.html;

    location /test {
        root /data/web1;
    }

    location = /test {
        root /data/web2;
    }
}

[root@nginx ~]# nginx -s reload

#测试
访问http://172.25.254.100/test/
出现web1 test
#测试模糊匹配
[root@nginx ~]# mkdir -p /data/web1/{test1,tee}
[root@nginx ~]# echo test1 > /data/web1/test1/index.html
[root@nginx ~]# echo tee > /data/web1/tee/index.html
[root@nginx ~]# mkdir -p /data/web1/lee
[root@nginx ~]# echo lee > /data/web1/lee/index.html
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhost.conf
server {
    listen 80;
    server_name www.jingwen.org;
    root /data/web/html;
    index index.html;

    location ^~ /t {
        root /data/web1;
    }
}

[root@nginx ~]# nginx -s reload

#测试
访问http://172.25.254.100/tee/
显示tee
访问http://172.25.254.100/lee/
显示404

其他的类似。。。。

3.4nginx的用户认证

# 创建默认认证文件
[root@nginx ~]#htpasswd -cm /usr/local/nginx/.htpasswd admin
redhat
[root@nginx ~]#htpasswd -m /usr/local/nginx/.htpasswd lee #有这个文件去掉c选项
redhat

[root@nginx ~]# mkdir /data/web/lee
[root@nginx ~]# echo lee > /data/web/lee/index.html
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhost.conf
server {
    listen 80;
    server_name www.jingwen.org;
    root /data/web/html;
    index index.html;

    location /lee {
        root /data/web;
        auth_basic "login password !!";
        auth_basic_user_file "/usr/local/nginx/.htpasswd";
    }
}
[root@nginx ~]# nginx -s reload

#测试
访问172.25.254.100/lee
输入用户名和密码,显示lee

3.5 自定义错误页面

[root@nginx ~]# mkdir /data/web/errorpage -p
[root@nginx ~]# echo  error page > /data/web/errorpage/40x.html
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhost.conf
server {
	error_page 404 /40x.html;
	
	location = /40x.html {
		root /data/web/errorpage;
	}
}
[root@nginx ~]# nginx -s reload

测试:
[root@node100 ~]# curl www.timinglee.org/testa
error page
或者在浏览器访问www.timinglee.org/testa
出现error page

3.6自定义错误日志

[root@nginx ~]# mkdir /var/log/timinglee.org
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhost.conf
server {
	error_log /var/log/timinglee.org/error.log;
	access_log /var/log/timinglee.org/access.log;
}

[root@nginx ~]# nginx -s reload

#测试
[root@nginx ~]# curl www.timinglee.org
[root@nginx ~]# cat /var/log/timinglee.org/access.log
[root@nginx ~]# curl www.timinglee.org/aaa
[root@nginx ~]# cat /var/log/timinglee.org/error.log

3.7检测文件是否存在

[root@nginx ~]# rm -rf /data/web/html/index.html
[root@nginx ~]# rm -rf /data/web/html/error/
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhost.conf
server {
	error_log /var/log/timinglee.org/error.log;
	access_log /var/log/timinglee.org/access.log;
	try_files $uri $uri.html $uri/index.html /error/default.html;

}
[root@nginx ~]# nginx -s reload;

#测试
[root@nginx ~]# curl www.timinglee.org
500

[root@nginx ~]# mkdir /data/web/html/error
[root@nginx ~]# echo error default > /data/web/html/error/default.html

#测试
[root@nginx ~]# curl www.timinglee.org
error default

3.8长链接

[root@nginx ~]# echo www.timinglee.org > /data/web/html/index.html

[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
http {
	keepalive_timeout 65;
	keepalive_requests 2;
}
[root@nginx ~]# nginx -s reload

# 长链接测试工具
[root@nginx ~]#dnf install telnet -y
# 测试
[root@nginx ~]#telnet www.timinglee.org 80
GET / HTTP/1.1
Host: www.timinglee.org

Server: nginx/1.24.0
Date: Fri, 16 Aug 2024 06:45:42 GMT
Content-Type: text/html
Content-Length: 18
Last-Modified: Fri, 16 Aug 2024 06:45:22 GMT
Connection: keep-alive
ETag: "66bef582-12"
Accept-Ranges: bytes

www.timinglee.org
(做两次后结束)

4、Nginx变量的使用

常用内置变量

$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为任意请求报文首部字段,表示记录请求报文的首部字段,ame的对应的首部字段名需要为小写,如果有横线需要替换为下划线
#示例:
echo $http_user_agent;
echo $http_host;
$sent_http_<name>
#name为响应报文的首部字段,name的对应的首部字段名需要为小写,如果有横线需要替换为下划线,此变量有问题
echo $sent_http_server;
$arg_<name>
#此变量存放了URL中的指定参数,name为请求url中指定的参数
echo $arg_id;

4.1 变量示例

[root@nginx ~]# nginx -V
nginx version: nginx/1.26.1
built by gcc 11.3.1 20220421 (Red Hat 11.3.1-2) (GCC) 
built with OpenSSL 3.0.1 14 Dec 2021
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --add-module=/root/echo-nginx-module-0.63 --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
[root@nginx ~]# nginx -v
nginx version: nginx/1.26.1
[root@nginx ~]# cat /usr/local/nginx/conf.d/vars.conf 
server { 
    listen 80;
    server_name var.jingwen.org;
    root /data/web/html;
    index index.html;
    
    location /var {
        default_type text/html;
        echo "jingwen.org";
    }
} 
[root@nginx ~]# echo var.jingwen.org > /data/web/html/index.html
[root@nginx ~]# echo var.jingwen.org > /data/web/html/var/index.html

[root@nginx ~]# nginx -s reload
[root@nginx ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.254.101	nginx.jingwen.org www.jingwen.org status.jingwen.org var.jingwen.org

#测试
[root@nginx ~]# curl var.jingwen.org
var.jingwen.org

#再添加一个变量
 location /var {
        default_type text/html;
        echo $remote_addr
#测试
[root@nginx ~]# curl var.jingwen.org/var

可以依次尝试

五、Nginx Rewrite相关功能

1、if 指令

用于条件匹配判断,并根据条件判断结果选择不同的Nginx配置,可以配置在server或location块中进行

配置,Nginx的if语法仅能使用if做单次判断,不支持使用if else或者if elif这样的多重判断,用法如下:

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

2、示例-if指令

[root@nginx ~]# cat /usr/local/nginx/conf.d/vars.conf 
server { 
    listen 80;
    server_name var.jingwen.org;
    root /data/web/html;
    index index.html;
    
    location /var {
        default_type text/html;
        echo "jingwen.org";
    }
    location /test2 {
    if ( !-e $request_filename ){
        echo "$request_filename is not exist";
    }
  }
} 
[root@nginx ~]# nginx -s reload
[root@nginx ~]# curl var.jingwen.org/test2/index.html
/data/web/html/test2/index.html is not exist

3、示例-break

用于中断当前相同作用域(location)中的其他Nginx配置
与该指令处于同一作用域的Nginx配置中,位于它前面的配置生效
位于后面的 ngx_http_rewrite_module 模块中指令就不再执行
[root@nginx ~]# cat /usr/local/nginx/conf.d/vars.conf 
server { 
    listen 80;
    server_name var.jingwen.org;
    root /data/web/html;
    index index.html;
    
    location /var {
        default_type text/html;
        echo "jingwen.org";
    }
    location /test2 {
    if ( !-e $request_filename ){
        echo "$request_filename is not exist";
        #return 409
    }
  }
  location /break {
      default_type test/html;
      set $name lee;
      echo $name;
      set $id 666;
      echo $id;
  }
} 
[root@nginx ~]# nginx -s reload
#测试
[root@nginx ~]# curl var.jingwen.org/break
lee
666

#如果在内容中加上break
location /break {
      default_type test/html;
      set $name lee;
      echo $name;
      break;
      set $id 666;
      echo $id;
[root@nginx ~]# nginx -s reload

#测试:看见后面无法看见了
[root@nginx ~]# curl var.jingwen.org/break
lee

[root@nginx ~]# 

4、示例-return

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

#return定向到百度网站

[root@nginx ~]# cat /usr/local/nginx/conf.d/vars.conf 
server { 
    listen 80;
    server_name var.jingwen.org;
    root /data/web/html;
    index index.html;
    
    location /var {
        default_type text/html;
        echo "jingwen.org";
    }
    location /test2 {
    if ( !-e $request_filename ){
        echo "$request_filename is not exist";
        #return 409
    }
  }
  location /break {
      default_type test/html;
      set $name lee;
      echo $name;
      break;
      set $id 666;
      echo $id;
  }
  location /return {
       default_type test/html;
       if ( !-e $request_filename){
           return 301 http://www.baidu.com;
        }
        echo "$request_filename is exist";
   }
} 
[root@nginx ~]# curl -I var.jingwen.org/return
HTTP/1.1 301 Moved Permanently
Server: nginx/1.26.1
Date: Sun, 18 Aug 2024 05:55:48 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: http://www.baidu.com

#创建路径
[root@nginx conf.d]# mkdir -p /data/web/html/return
[root@nginx conf.d]# curl -I var.jingwen.org/return
HTTP/1.1 200 OK
Server: nginx/1.26.1
Date: Sun, 18 Aug 2024 06:02:31 GMT
Content-Type: test/html
Connection: keep-alive
#此时去浏览器访问会显示
/data/web/html/return is exist

5、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以外的任意字符
[^lee] #匹配除了magedu 这几个字母以外的任意字符
rewrite flag 使用介绍
利用nginx的rewrite的指令,可以实现url的重新跳转,rewrite有四种不同的flag,分别是redirect(临时重定向302)、permanent(永久重定向301)、break和last。其中前两种是跳转型的flag,后两种是代理型
跳转型指由客户端浏览器重新对新地址进行请求
代理型是在WEB服务器内部实现跳转
redirect;
#临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端
#由客户端重新发起请求;使用相对路径,或者http://或https://开头,状态码:302
permanent;
#重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端
#由客户端重新发起请求,状态码:301
break;
#重写完成后,停止对当前URL在当前location中后续的其它重写操作
#而后直接跳转至重写规则配置块之后的其它配置,结束循环,建议在location中使用
#适用于一个URL一次重写
last;
#重写完成后,停止对当前URI在当前location中后续的其它重写操作,
#而后对新的URL启动新一轮重写检查,不建议在location中使用
#适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户

5.1 域名永久与临时重定向

[root@nginx conf.d]# cat /usr/local/nginx/conf.d/vars.conf 
server { 
    listen 80;
    server_name var.jingwen.org;
    root /data/web/html;
    index index.html;
    location / {
        root /data/web/var;
        index index.html;
        #rewrite / http://www.jingwen.com permanent;
        #rewrite / http://www.jingwen.com redirect;
    }
} 
[root@nginx conf.d]# nginx
[root@nginx conf.d]# nginx -s reload
[root@nginx conf.d]# mkdir /data/web/var -p
[root@nginx conf.d]# echo var page > /data/web/var/index.html
[root@nginx conf.d]# nginx -s reload
[root@nginx conf.d]# curl var.jingwen.org
var page
[root@nginx conf.d]# curl www.jingwen.org
www.jingwen.org

5.2 永久重定向301

域名永久型调整,即域名永远跳转至另外一个新的域名,之前的域名再也不使用,跳转记录可以缓存到客户端浏览器
永久重定向会缓存DNS解析记录, 浏览器中有 from disk cache 信息,即使nginx服务器无法访问,浏览器也会利用缓存进行重定向
比如: 京东早期的域名 www.360buy.com 由于与360公司类似,于是后期永久重定向到了 www.jd.com
示例:
#将这句注释打开 
rewrite / http://www.jingwen.com permanent;
[root@nginx conf.d]# curl var.jingwen.org
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.26.1</center>
</body>
</html>

#可以看见重定向已经生效了,定向到了http://www.jingwen.org
[root@nginx conf.d]# curl -I var.jingwen.org
HTTP/1.1 301 Moved Permanently
Server: nginx/1.26.1
Date: Sun, 18 Aug 2024 13:01:26 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: http://www.jingwen.com

#此时去浏览器访问var.jingwen.org就会转到www.jingwen.org

5.3临时重定向302

域名临时重定向,告诉浏览器域名不是固定重定向到当前目标域名,后期可能随时会更改,因此浏览器不会缓存当前域名的解析记录,而浏览器会缓存永久重定向的DNS解析记录,这也是临时重定向与永久
重定向最大的本质区别。
即当nginx服务器无法访问时,浏览器不能利用缓存,而导致重定向失败
#将这句注释打开 
#rewrite / http://www.jingwen.com redirect;
[root@nginx conf.d]# curl -I var.jingwen.org
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.26.1
Date: Sun, 18 Aug 2024 13:11:56 GMT
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Location: http://www.jingwen.com

6、rewrite案例-last与break

[root@nginx conf.d]# cat /usr/local/nginx/conf.d/vars.conf 
server { 
    listen 80;
    server_name var.jingwen.org;
    root /data/web/html;
    index index.html;
 
    location /break {
        root /data/web/html;
        rewrite ^/break/(.*) /test1/$1 break;
        rewrite ^/test1/(.*) /test1/$2;
    }    
    location /last {
        root /data/web/html;
        rewrite ^/last/(.*) /test1/$1 last;
        rewrite ^/test1/(.*) /test2/$1;
    }
    location /test1 {
        default_type test/html;
        return 666 "jingwen hahahahahaha ";
    }
    location /test2 {
        root /data/web/html;
    }
} 
[root@nginx conf.d]# mkdir  /data/web/html/{test1,test2,break,last} -p
[root@nginx conf.d]# echo test1 > /data/web/html/test1/index.html
[root@nginx conf.d]# echo test2 > /data/web/html/test2/index.html
[root@nginx conf.d]# echo last > /data/web/html/last/index.html
[root@nginx conf.d]# echo break > /data/web/html/break/index.html
[root@nginx conf.d]# nginx -s reload
[root@nginx conf.d]# curl var.jingwen.org/break/index.html
test1
[root@nginx conf.d]# curl var.jingwen.org/last/index.html
jingwen hahahahahaha [root@nginx conf.d]#

7、自动跳转https

案例:基于通信安全考虑公司网站要求全站 https,因此要求将在不影响用户请求的情况下将http请求全
部自动跳转至 https,另外也可以实现部分 location 跳转
[root@nginx ~]# cd /usr/local/nginx/
[root@nginx nginx]# mkdir certs
[root@nginx nginx]# ls
certs             conf    fastcgi_temp  logs        sbin       uwsgi_temp
client_body_temp  conf.d  html          proxy_temp  scgi_temp
[root@nginx nginx]# openssl req -newkey rsa:2048 -nodes -sha256 -keyout /usr/local/nginx/certs/jingwen.org.key -x509 -days 365 -out /usr/local/nginx/certs/jingwen.org.crt
..+..+.+..+.........+...+..........+...+.........+........+.......+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+...+.+.....+......+....+......+...+..+...+......+....+...+...+.........+..+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Shaanxi
Locality Name (eg, city) [Default City]:Xi'an
Organization Name (eg, company) [Default Company Ltd]:jingwen
Organizational Unit Name (eg, section) []:webserver
Common Name (eg, your name or your server's hostname) []:www.jingwen.org
Email Address []:admin@jingwen.org
[root@nginx nginx]# cd certs/
[root@nginx certs]# ls
jingwen.org.crt  jingwen.org.key
[root@nginx certs]# cd ..
[root@nginx nginx]# cd conf.d/
[root@nginx conf.d]# ls
vars.conf
[root@node1 ~]# ssh -l root 172.25.254.101
[root@nginx conf.d]# cat vhosts.conf
server {
    listen 80;
    listen 443 ssl;
    server_name www.jingwen.org;
    root /data/web/html;
    index index.html;
    ssl_certificate /usr/local/nginx/certs/jingwen.org.crt;
    ssl_certificate_key /usr/local/nginx/certs/jingwen.org.key;
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout 5m;
}
[root@nginx conf.d]# nginx -s reload

#测试:
#去浏览器访问 www.jingwen.org
www.jingwen.org

#去浏览器访问 https://www.jingwen.org
www.jingwen.org

8、防盗链

防盗链基于客户端携带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标记信息,如果别人只链接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是盗链,referer就是之前的那个网站域名,正常的referer信息有以下几种:
none: #请求报文首部没有referer首部,
#比如用户直接在浏览器输入域名访问web网站,就没有referer信息。
blocked: #请求报文有referer首部,但无有效值,比如为空。
server_names: #referer首部中包含本主机名及即nginx 监听的server_name。
arbitrary_string: #自定义指定字符串,但可使用*作通配符。示例: *.timinglee.org
www.timinglee.*
regular expression: #被指定的正则表达式模式匹配到的字符串,要使用~开头,例如:
~.*\.timinglee\.com
[root@nginx ~]# mkdir -p /data/web/html/images

8.1 实现盗链

在一个web 站点盗链另一个站点的资源信息,比如:图片、视频等

#新建一个主机172.25.254.20,盗取另一台主机lee.timinglee.org/images/logo.png的图片
[root@client ~]# yum install httpd -y
[root@client html]# vim /var/www/html/index.html
#准备盗链web页面:
<html>
5.3.2 实现防盗链
基于访问安全考虑,nginx支持通过ngx_http_referer_module模块,检查访问请求的referer信息是否有效
实现防盗链功能
官方文档: 
示例: 定义防盗链:

<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<title>盗链</title>
</head>

<body>
<img src="http://lee.timinglee.org/images/logo.png" >

<h1 style="color:red">欢迎大家</h1>
<p><a href=http://lee.timinglee.org>狂点老李</a>出门见喜</p>

</body>
</html>
#重启apache并访问http://172.25.254.20 测试
#验证两个域名的日志,是否会在被盗连的web站点的日志中出现以下盗链日志信息:
[root@Nginx ~]# cat /usr/local/nginx/logs/access.log
172.25.254.1 - - [22/Jul/2024:09:50:01 +0800] "GET /images/logo.png HTTP/1.1" 304
0 "http://172.25.254.20/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36
Edg/126.0.0.0"
172.25.254.1 - - [22/Jul/2024:09:50:18 +0800] "GET / HTTP/1.1" 304 0
"http://172.25.254.20/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36
Edg/126.0.0.0"

8.2 实现防盗链

基于访问安全考虑,nginx支持通过ngx_http_referer_module模块,检查访问请求的referer信息是否有效实现防盗链功能

[root@Nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
location /images {
valid_referers none blocked server_names *.timinglee.org ~\.baidu\.;
if ($invalid_referer){
#return 403;
rewrite ^/ http://lee.timinglee.org/daolian.png permanent;
}
}
}
#重启Nginx并访问测试
http://172.25.254.20

六、 Nginx 反向代理功能

ngx_http_proxy_module: #将客户端的请求以http协议转发至指定服务器进行处理
ngx_http_upstream_module #用于定义为proxy_pass,fastcgi_pass,uwsgi_pass
#等指令引用的后端服务器分组
ngx_stream_proxy_module: #将客户端的请求以tcp协议转发至指定服务器处理
ngx_http_fastcgi_module: #将客户端对php的请求以fastcgi协议转发至指定服务器助理
ngx_http_uwsgi_module: #将客户端对Python的请求以uwsgi协议转发至指定服务器处

1、实现http反向代理

实验准备
克隆rhel9 名为node1 172.25.254.10
克隆rhel9 名为node2 172.25.254.20
克隆rhel9 名为nginx 172.25.254.101

echo 172.25.254.10 > /var/web/html
[root@node1 ~]# dnf install httpd -y
[root@node1 ~]# echo 172.25.254.10 > /var/www/html/index.html
[root@node1 ~]# systemctl restart httpd
[root@node1 ~]# systemctl enable --now httpd
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.
#里面端口为80
[root@node1 ~]# cat /etc/httpd/conf/httpd.conf
#Listen 12.34.56.78:80
Listen 80

[root@node1 ~]# dnf install httpd -y
[root@node2 ~]# echo 172.25.254.20 > /var/www/html/index.html
[root@node2 ~]# systemctl restart httpd
[root@node2 ~]# systemctl enable --now htttpd
Failed to enable unit: Unit file htttpd.service does not exist.
[root@node2 ~]# systemctl enable --now httpd
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.
[root@node2 ~]# cat /etc/httpd/conf/httpd.conf
#Listen 12.34.56.78:80
Listen 80

#保证在nginx能ping通两台
[root@nginx conf.d]# curl 172.25.254.10
172.25.254.10
[root@nginx conf.d]# curl 172.25.254.20
172.25.254.20

开始实验:

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

    location / {
        proxy_pass http://172.25.254.10:80;
    }
}
[root@nginx conf.d]# nginx -s reload
[root@nginx conf.d]# curl www.jingwen.org
172.25.254.10
#改为端口8080
[root@node2 ~]# cat /etc/httpd/conf/httpd.conf
#Listen 12.34.56.78:80
Listen 8080
[root@nginx conf.d]# cat /usr/local/nginx/conf.d/vhosts.conf
server {
    listen 80;
    server_name www.jingwen.org;

    location / {
        #proxy_pass http://172.25.254.10:80;
        proxy_pass http://172.25.254.20:8080;
    }
}
[root@nginx conf.d]# nginx -s reload
[root@nginx conf.d]# curl www.jingwen.org
172.25.254.20

2、示例-动静分离

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

    location / {
        proxy_pass http://172.25.254.10:80;
    }
    location /static {
        proxy_pass http://172.25.254.20:8080;
    }
}
[root@nginx conf.d]# nginx -s reload

[root@node2 ~]# mkdir -p /var/www/html/static
[root@node2 ~]# echo static 172.25.254.20 > /var/www/html/static/index.html
#测试
[root@nginx conf.d]# curl www.jingwen.org
172.25.254.10
[root@nginx conf.d]# curl www.jingwen.org/static/
static 172.25.254.20

3、反向代理示例-缓存功能

缓存功能默认关闭状态,需要先动配置才能启用

[root@nginx ~]# cat /usr/local/nginx/conf/nginx.conf
http {
#gzip  on;
    proxy_cache_path /apps/nginx/proxy_cache levels=1:2:2 keys_zone=proxycache
inactive=120s max_size=1g;

[root@nginx nginx]# cat /usr/local/nginx/conf.d/vhosts.conf
server {
    listen 80;
    server_name www.jingwen.org;
 
    location ~ \.php$ {
        proxy_pass http://172.25.254.10:8080;
    }
    location /static {
        proxy_pass http://172.25.254.20:8080;
        proxy_cache proxycache;
        proxy_cache_key $request_uri;
        proxy_cache_valid 200 302 301 10m;
        proxy_cache_valid any 1m;
    }
}
[root@nginx ~]# nginx -s reload

http 反向代理负载均衡

在上一个节中Nginx可以将客户端的请求转发至单台后端服务器但是无法转发至特定的一组的服务器,而且不能对后端服务器提供相应的服务器状态监测,Nginx 可以基于ngx_http_upstream_module模块提供服务器分组转发、权重分配、状态监测、调度算法等高级功能

4、反向代理示例:后端多台web服务器

#机器
172.25.254.100 #Nginx 代理服务器
172.25.254.10 #后端web A,Apache部署
172.25.254.20 #后端web B,Apache部署# 部署后端 Apache服务器
[root@node1 ~]# dnf install httpd -y
[root@node1 ~]# echo "172.25.254.10" > /var/www/html/index.html
[root@node1 ~]# systemctl enable --now httpd[root@nginx ~]# vim /usr/local/nginx/conf.d/vhost.conf
upstream webcluster {
    server 172.25.254.10:80 fail_timeout=15s max_fails=3;
    server 172.25.254.20:8080 fail_timeout=15s max_fails=3;
    server 172.25.254.100:80 backup;
}
​
server {
    listen 80;
    server_name www.timinglee.org;
​
    location / {
        proxy_pass http://webcluster;
    }
​
}
​
[root@nginx ~]# nginx -s reload
​
#测试
[root@nginx ~]# curl www.timinglee.org
172.25.254.10
[root@nginx ~]# curl www.timinglee.org
172.25.254.20upstream webcluster {
    ip_hash;
    server 172.25.254.10:80 fail_timeout=15s max_fails=3;
    server 172.25.254.20:8080 fail_timeout=15s max_fails=3;
    #server 172.25.254.100:80 backup;
}
[root@nginx ~]# curl www.timinglee.org
172.25.254.10
[root@nginx ~]# curl www.timinglee.org
172.25.254.10upstream webcluster {
    #ip_hash;
    hash $request_uri consistent;
    server 172.25.254.10:80 fail_timeout=15s max_fails=3;
    server 172.25.254.20:8080 fail_timeout=15s max_fails=3;
    #server 172.25.254.100:80 backup;
}
[root@nginx ~]# curl www.timinglee.org
172.25.254.20
[root@nginx ~]# curl www.timinglee.org
172.25.254.20
​# 基于Cookie 实现会话绑定
upstream webcluster {
    #ip_hash;
    #hash $request_uri consistent;
    hash $cookie_lee;
    server 172.25.254.10:80 fail_timeout=15s max_fails=3;
    server 172.25.254.20:8080 fail_timeout=15s max_fails=3;
    #server 172.25.254.100:80 backup;
}
​
​
[root@nginx ~]# curl www.timinglee.org
172.25.254.10
[root@nginx ~]# curl www.timinglee.org
172.25.254.20
[root@nginx ~]# curl -b "lee=1" www.timinglee.org
172.25.254.10
[root@nginx ~]# curl -b "lee=1" www.timinglee.org
172.25.254.10配置nginx反向

5、实现Nginx四层负载均衡

tcp负载均衡配置参数
stream { #定义stream相关的服务;
Context:main
upstream backend { #定义后端服务器
hash $remote_addr consistent; #定义调度算法
server backend1.example.com:12345 weight=5; #定义具体server
server 127.0.0.1:12345 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
}
upstream dns { #定义后端服务器
server 10.0.0.1:53; #定义具体server
server dns.example.com:53;
}
server { #定义server
listen 12345; #监听IP:PORT
proxy_connect_timeout 1s; #连接超时时间
proxy_timeout 3s; #转发超时时间
proxy_pass backend; #转发到具体服务器组
}
server {
listen 127.0.0.1:53 udp reuseport;
proxy_timeout 20s;
proxy_pass dns;
}
server {
listen [::1]:12345;
proxy_pass unix:/tmp/stream.socket;
}
}

6、负载均衡实例-MySQL

#在apache20中安装mysql
[root@apache20 ~]# yum install mariadb-server -y
[root@apache20 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=20
[root@apache20 ~]# systemctl start mariadb
[root@apache20 ~]# mysql -e "grant all on *.* to lee@'%' identified by 'lee';"
[root@apache30 ~]# mysql -ulee -plee -h172.25.254.20 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
| 20 |
+-------------+
#在apache30重复以上步骤并在apache20上测试
[root@Nginx ~]# vim /apps/nginx/conf/tcp/tcp.conf
stream {
upstream mysql_server {
server 172.25.254.20:3306 max_fails=3 fail_timeout=30s;
server 172.25.254.30:3306 max_fails=3 fail_timeout=30s;
}
server {
listen 172.25.254.10:3306;
proxy_pass mysql_server;
proxy_connect_timeout 30s;
proxy_timeout 300s;
}
}
#重启nginx并访问测试:
[root@Nginx ~]# nginx -s reload
#测试通过nginx负载连接MySQL:
[root@apache30 ~]# mysql -ulee -plee -h172.25.254.10 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
| 20 |
+-------------+
[root@apache30 ~]# mysql -ulee -plee -h172.25.254.10 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
| 30 |
+-------------+
6.2.3 udp 负载均衡实例: DNS 
#在10.0.0.28停止MySQL服务
[root@apache20 ~]# systemctl stop mariadb
#再次测试访问,只会看到mysql-server1.timinglee.org进行响应
[root@apache30 ~]# mysql -ulee -plee -h172.25.254.10 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
| 30 |
+-------------+
[root@apache30 ~]# mysql -ulee -plee -h172.25.254.10 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
| 30 |
+-------------+

7、udp负载均衡实例-NDS

#在apache20中安装mysql
[root@apache20 ~]# yum install mariadb-server -y
[root@apache20 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=20
[root@apache20 ~]# systemctl start mariadb
[root@apache20 ~]# mysql -e "grant all on *.* to lee@'%' identified by 'lee';"
[root@apache30 ~]# mysql -ulee -plee -h172.25.254.20 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
| 20 |
+-------------+
#在apache30重复以上步骤并在apache20上测试
[root@Nginx ~]# vim /apps/nginx/conf/tcp/tcp.conf
stream {
upstream mysql_server {
server 172.25.254.20:3306 max_fails=3 fail_timeout=30s;
server 172.25.254.30:3306 max_fails=3 fail_timeout=30s;
}
server {
listen 172.25.254.10:3306;
proxy_pass mysql_server;
proxy_connect_timeout 30s;
proxy_timeout 300s;
}
}
#重启nginx并访问测试:
[root@Nginx ~]# nginx -s reload
#测试通过nginx负载连接MySQL:
[root@apache30 ~]# mysql -ulee -plee -h172.25.254.10 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
| 20 |
+-------------+
[root@apache30 ~]# mysql -ulee -plee -h172.25.254.10 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
| 30 |
+-------------+
#在10.0.0.28停止MySQL服务
[root@apache20 ~]# systemctl stop mariadb
#再次测试访问,只会看到mysql-server1.timinglee.org进行响应
[root@apache30 ~]# mysql -ulee -plee -h172.25.254.10 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
| 30 |
+-------------+
[root@apache30 ~]# mysql -ulee -plee -h172.25.254.10 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
| 30 |
+-------------+

七、实现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-FPM?

PHP-FPM(FastCGI Process Manager:
FastCGI进程管理器)是一个实现了Fastcgi的程序,并且提供进程管理的功能。
进程包括master进程和worker进程。master进程只有一个,负责监听端口,接受来自web server的请求
worker进程一般会有多个,每个进程中会嵌入一个PHP解析器,进行PHP代码的处理。

案例 - Nginx与php-fpm在同一服务器

实验准备:
需要对nginx重新编译

1. 源码编译nginx、php

[root@nginx ~]# stop nginx
[root@nginx ~]# cd /usr/local
[root@nginx local]# rm -rf /usr/local/nginx/
[root@nginx local]# cd
[root@nginx ~]# dnf install php
#拉入两个压缩包
[root@nginx ~]# tar zxf memc-nginx-module-0.20.tar.gz
[root@nginx ~]# tar zxf srcache-nginx-module-0.33.tar.gz
[root@nginx ~]# cd nginx-1.26.1/
[root@nginx nginx-1.26.1]# ./configure --prefix=/usr/local/nginx --add-module=/root/echo-nginx-module-0.63 --add-module=/root/memc-nginx-module-0.20 --add-module=/root/srcache-nginx-module-0.33 --user=nginx --group=nginx --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-stream --with-stream_ssl_module --with-stream_realip_module --with-pcre

#编译
[root@nginx nginx-1.26.1]# make && make install
[root@nginx nginx-1.26.1]# systemctl start nginx
[root@nginx nginx-1.26.1]# nginx -t

#查看进程,操作见下图,删除正在允许的nginx.
[root@nginx nginx-1.26.1]# ps aux | grep nginx

[root@nginx nginx-1.26.1]# nginx
[root@nginx nginx-1.26.1]# nginx -v

#拉入压缩包php-8.3.9.tar.gz
[root@nginx ~]# tar zxf php-8.3.9.tar.gz
[root@nginx ~]# cd php-8.3.9/
[root@nginx php-8.3.9]# ./configure --prefix=/usr/local/php --enable-fpm --with-fpm-user=nginx --with-fpm-group=nginx --with-curl --with-iconv --with-mhash --with-zlib --with-openssl --enable-mysqlnd --with-mysqli --with-pdo-mysql --disable-debug --enable-soap --enable-sockets --enable-xml --enable-ftp --enable-gd --enable-exif --enable-mbstring --enable-bcmath --with-fpm-systemd

#利用yum解决php依赖,但是还需要oniguruma-devel,去阿里云里wget下来
[root@nginx ~]# yum install -y bzip2 systemd-devel libxml2-devel sqlite-devel libpng-devel libcurl-devel
[root@nginx ~]# cd /mnt
[root@nginx mnt]# wget https://mirrors.aliyun.com/rockylinux/9.4/devel/x86_64/kickstart/Packages/o/oniguruma-devel-6.9.6-1.el9.5.x86_64.rpm   
[root@nginx ~]# dnf install oniguruma-devel-6.9.6-1.el9.5.x86_64.rpm
[root@nginx php-8.3.9]# ./configure --prefix=/usr/local/php --enable-fpm --with-fpm-user=nginx --with-fpm-group=nginx --with-curl --with-iconv --with-mhash --with-zlib --with-openssl --enable-mysqlnd --with-mysqli --with-pdo-mysql --disable-debug --enable-soap --enable-sockets --enable-xml --enable-ftp --enable-gd --enable-exif --enable-mbstring --enable-bcmath --with-fpm-systemd

#此时makefile已经生成
[root@nginx php-8.3.9]# make && make install

2. php相关配置优化

# php相关配置优化
[root@Nginx ~]# cd /usr/local/php/etc
[root@nginx etc]# ls
php-fpm.conf.default  php-fpm.d
[root@Nginx etc]# cp -p 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]# ls
www.conf.default
[root@Nginx php-fpm.d]# cp -p www.conf.default www.conf

#生成主配置文件
[root@Nginx php-fpm.d]# cd /root/php-8.3.9/
[root@Nginx php-8.3.9]# cp php.ini-production /usr/local/php/etc/php.ini
[root@Nginx ~]# vim /usr/local/php/etc/php.ini
[Date]
; Defines the default timezone used by the date functions
; https://php.net/date.timezone
date.timezone = Asia/Shanghai #修改时区

# 查找时区
[root@nginx ~]# timedatectl list-timezones | grep Asia/Shanghai
Asia/Shanghai

#生成启动文件
[root@Nginx ~]# cd /root/php-8.3.9/sapi/fpm
[root@Nginx fpm]# cp php-fpm.service /lib/systemd/system/
[root@nginx fpm]# vim /lib/systemd/system/php-fpm.service 
# Mounts the /usr, /boot, and /etc directories read-only for processes invoked by this unit.
#ProtectSystem=full #注释该内容
[root@Nginx fpm]# systemctl daemon-reload
[root@Nginx fpm]# systemctl start php-fpm.service
[root@Nginx fpm]# netstat -antlupe | grep php
tcp        0      0 127.0.0.1:9000          0.0.0.0:*               LISTEN      0          132259     158979/php-fpm: mas 

3. 准备php测试页面

# php测试页面
[root@nginx ~]# mkdir -p /data/web/php
[root@nginx ~]# cd /usr/local/php/bin/

#添加php环境变量
[root@nginx bin]# vim ~/.bash_
.bash_history  .bash_logout   .bash_profile  
[root@nginx bin]# vim ~/.bash_profile 
export PATH=$PATH:/usr/local/nginx/sbin:/usr/local/php/bin:/usr/local/php/sbin
[root@nginx bin]# source ~/.bash_profile 
[root@nginx bin]# cd /data/web/php/
[root@nginx php]# vim index.php
[root@nginx php]# cat index.php 
<?php
	phpinfo();
?>
[root@nginx conf]# cd /usr/local/nginx/
[root@nginx nginx]# mkdir conf.d
[root@nginx nginx]# vim conf/nginx.conf
include "/usr/local/nginx/conf.d/*.conf";
[root@nginx nginx]# vim conf.d/vhost.conf
server {
    listen 80;
    server_name www.timinglee.org;
    root /data/web/html;
    index index.html;

    location ~\.php$ {
        root /data/web/php;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi.conf;
    }
}
[root@nginx nginx]# nginx -t
[root@nginx nginx]# nginx -s reload

访问验证php测试页面

#更改再测试
[root@nginx ~]# cat /usr/local/nginx/conf.d/vhosts.conf 
fastcgi_pass 172.25.254.101:9000;
       
[root@nginx ~]# vim /usr/local/php/etc/php-fpm.d/www.conf
listen = 0.0.0.0:9000
[root@nginx ~]# cd /root/php-8.3.9/sapi/fpm/
[root@nginx fpm]# systemctl daemon-reload
[root@nginx fpm]# systemctl start php-fpm.service

php的动态扩展模块(php的缓存模块)

访问1000失败了904次,性能低。

Php每次都要去访问,性能低,所以在内存中存放缓存。

增加的东西就叫做内存中的一片区域,使用memcache管理。

1.安装memcache模块

[root@Nginx ~]# tar zxf memcache-8.2.tgz
[root@Nginx ~]# cd memcache-8.2/
[root@Nginx memcache-8.2]# yum install autoconf
[root@Nginx memcache-8.2]# phpize
Configuring for:
PHP Api Version:         20230831
Zend Module Api No:      20230831
Zend Extension Api No:   420230831
[root@Nginx memcache-8.2]# ./configure && make && make install
Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-nonzts-20230831/
[root@Nginx memcache-8.2]# ls /usr/local/php/lib/php/extensions/no-debug-non-zts-
20230831/
memcache.so opcache.so

2.复制测试文件到nginx发布目录中

[root@Nginx ~]# cd memcache-8.2/
[root@Nginx memcache-8.2]# ls
autom4te.cache config.log configure.ac example.php Makefile.fragments
README
build config.m4 config.w32 include Makefile.objects runtests.php
config9.m4 config.nice CREDITS libtool memcache.la src
config.h config.status docker LICENSE memcache.php
tests
config.h.in configure Dockerfile Makefile modules
[root@Nginx memcache-8.2]# cp example.php memcache.php /data/web/php
[root@Nginx ~]# vim /data/web/php/memcache.php
define('ADMIN_USERNAME','admin'); // Admin Username
define('ADMIN_PASSWORD','lee'); // Admin Password
define('DATE_FORMAT','Y/m/d H:i:s');
define('GRAPH_SIZE',200);
define('MAX_ITEM_DUMP',50);
$MEMCACHE_SERVERS[] = '127.0.0.1:11211'; // add more as an array
#$MEMCACHE_SERVERS[] = 'mymemcache-server2:11211'; // add more as an array

3.配置php加载memcache模块

[root@Nginx ~]# vim /usr/local/php/etc/php.ini
;extension=zip
extension=memcache
;zend_extension=opcache

#注意一定要重启
[root@Nginx ~]# systemctl reload php-fpm

# 因为没有指定路劲,所以要移动到默认路径
[root@Nginx ~]# cp /usr/local/php/etc/php.ini /usr/local/php/lib/
[root@Nginx no-debug-non-zts-20230831]# php -m | grep mem
memcache

4.部署memcached

[root@Nginx ~]# yum install memcached -y
[root@Nginx ~]# systemctl enable --now memcached.service
[root@Nginx ~]# netstat -antlupe | grep memcache
tcp 0 0 127.0.0.1:11211 0.0.0.0:* LISTEN
976 1037243 186762/memcached
[root@Nginx ~]# cat /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS="-l 127.0.0.1,::1"

测试:

访问 http://php.timinglee.org/example.php 不断刷新
访问 http://php.timinglee.org/memcache.php 查看命中效果

刷新模拟的是数据的存储,访问其它链接一直访问并不会发生改变

5.查看性能

查看性能是否有提升?

访问1000次失败112次

[root@nginx ~]# ab -n1000 -c10 http://www.jingwen.org/index.php
Complete requests:      1000
Failed requests:        112

在实验之前是访问1000失败了904次。

image-20240819153950857

所以性能有所提升。

#性能对比
[root@apache20 ~]# ab -n500 -c10 http://php.timinglee.org/index.php
@@@内容忽略@@@
Concurrency Level: 10
Time taken for tests: 0.514 seconds
Complete requests: 500
Failed requests: 44
(Connect: 0, Receive: 0, Length: 44, Exceptions: 0)
[root@apache20 ~]# ab -n500 -c10 http://php.timinglee.org/example.php
@@@内容忽略@@@
Concurrency Level: 10
Time taken for tests: 0.452 seconds
Complete requests: 500
Failed requests: 0

memcache缓存的是php从数据库中取出的数据

php大多被用来做网页和数据库的交互

但是nginx并不支持与数据库交互,所以只能通过php。

6.php高速缓存

这样nginx才具备读取php的功能

[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf 
upstream memcache {
   server 127.0.0.1:11211;
   keepalive 512;
}
server {
    listen 80;
    server_name php.timinglee.org;
    root /data/web/html;

    location /memc {
        internal;
        memc_connect_timeout 100ms;
        memc_send_timeout 100ms;
        memc_read_timeout 100ms;
        set $memc_key $query_string; #使用内置变量$query_string来作为key
        set $memc_exptime 300; #缓存失效时间300秒
        memc_pass memcache;
	}
    location ~ \.php$ {
        set $key $uri$args; #设定key的值
        srcache_fetch GET /memc $key; #检测mem中是否有要访问的php
        srcache_store PUT /memc $key; #缓存为加载的php数据
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi.conf;
	}
}
[root@nginx ~]# nginx -s reload
#测试结果 没有访问成功的为0次
[root@nginx ~]# ab -n1000 -c10 http://www.jingwen.org/index.php
Concurrency Level:      10
Time taken for tests:   0.047 seconds
Complete requests:      1000
Failed requests:        0

八、nginx 二次开发版本

1、openresty

Nginx 是俄罗斯人发明的, Lua 是巴西几个教授发明的,中国人章亦春把 LuaJIT VM 嵌入到 Nginx 中,实现了 OpenResty 这个高性能服务端解决方案
OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方
模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。
OpenResty® 通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将Nginx
有效地变成一个强大的通用 Web 应用平台。这样,Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高
性能 Web 应用系统。
OpenResty 由于有功能强大且方便的的API,可扩展性更强,如果需要实现定制功能,OpenResty是个不错的
选择
官网: http://openresty.org/cn/
[root@Nginx ~]#dnf -yq install gcc pcre-devel openssl-devel perl
[root@Nginx ~]#useradd -r -s /sbin/nologin nginx
[root@Nginx ~]#cd /usr/local/src
[root@Nginx src]#wget https://openresty.org/download/openresty-1.17.8.2.tar.gz
[root@Nginx src]#tar xf openresty-1.17.8.2.tar.gz
[root@Nginx src]#cd openresty-1.17.8.2/
[root@Nginx openresty-1.17.8.2]#./configure \
--prefix=/apps/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@Nginx openresty-1.17.8.2]#make && make install
[root@Nginx openresty-1.17.8.2]#ln -s /apps/openresty/bin/* /usr/bin/
[root@Nginx openresty-1.17.8.2]#openresty -v
nginx version: openresty/1.17.8.2
[root@Nginx openresty-1.17.8.2]#openresty
[root@Nginx openresty-1.17.8.2]#ps -ef |grep nginx
[root@Nginx ~]#curl 10.0.0.18
  • 28
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值