一、web服务的常用种类
-
Apache HTTP Server
- 简介:Apache是一款广泛使用的Web服务器软件,支持多种操作系统,包括Linux。
- 特点:
支持多个虚拟主机。
模块化架构,可以根据需要加载不同的模块。
强大的安全性配置选项。
-
Nginx(公司常用)
- 简介:Nginx是一个高性能的HTTP和反向代理Web服务器,同时也提供了IMAP/POP3/SMTP服务。
- 特点:
高并发连接处理能力。
反向代理和负载均衡。
优秀的稳定性。
对比总结:
- 性能和资源消耗:Nginx在处理静态文件和高并发连接方面优于Apache,而Apache在处理动态内容方面更加强大。
- 配置复杂度:Nginx的配置通常比Apache更加简单直观。
- 功能丰富度:Apache提供了更多的内置功能和模块,而Nginx则更加专注于高性能和轻量级的服务。
二、Nginx 概述
Nginx:engine X ,2002年开发,分为社区版和商业版(nginx plus )
2019年3月11日 F5 Networks 6.7亿美元的价格收购
Nginx是免费的、开源的、高性能的HTTP和反向代理服务器、邮件代理服务器、以及TCP/UDP代理服务 器
解决C10K问题(10K Connections)
Nginx官网:http://nginx.org
nginx的其它的二次发行版:
Tengine:由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加 了很多高级功能和特性。Tengine的性能和稳定性已经在大型的网站如淘宝网,天猫商城等得到了 很好的检验。它的最终目标是打造一个高效、稳定、安全、易用的Web平台。从2011年12月开始, Tengine成为一个开源项目官网: http://tengine.taobao.org/
OpenResty:基于 Nginx 与 Lua 语言的高性能 Web 平台, 章亦春团队开发,官网:http://openr esty.org/cn/
Nginx 功能介绍
静态的web资源服务器html,图片,js,css,txt等静态资源
http/https协议的反向代理
结合FastCGI/uWSGI/SCGI等协议反向代理动态资源请求
tcp/udp协议的请求转发(反向代理)
imap4/pop3协议的反向代理
基础特性
模块化设计,较好的扩展性
高可靠性
支持热部署:不停机更新配置文件,升级版本,更换日志文件
低内存消耗:10000个keep-alive连接模式下的非活动连接,仅需2.5M内存
event-driven,aio,mmap,sendfile
Web 服务相关的功能
虚拟主机(server)
支持 keep-alive 和管道连接(利用一个连接做多次请求)
访问日志(支持基于日志缓冲提高其性能)
url rewirte
路径别名
基于IP及用户的访问控制
支持速率限制及并发数限制
重新配置和在线升级而无须中断客户的工作进程
三、Nginx源码安装
直接下载压缩包到/home家目录进行操作
3.1 下载所需环境
dnf install gcc pcre-devel zlib-devel openssl-devel -y
源码安装需要提前准备标准的编译器,GCC的全称是(GNU Compiler collection),其有GNU开发,并以GPL即LGPL许可,是自由的类UNIX即苹果电脑Mac OS X操作系统的标准编译器,因为GCC原本只能处理C语言,所以原名为GNU C语言编译器,后来得到快速发展,可以处理C++,Fortran,pascal,objective,java以及Ada等其他语言,此外还需要Automake工具,以完成自动创建Makefile的工作,Nginx的一些模块需要依赖第三方库,比如: pcre(支持rewrite),zlib(支持gzip模块)和openssl(支持ssl模块)等。
3.2 下载官方源码包
tar zxf nginx-1.24.0.tar.gz
解压
tar zxf nginx-1.24.0.tar.gz
解压完成后进入目录
cd nginx-1.24.0
创建Nginx源码安装的用户
useradd -s /sbin/nologin -M nginx
3.3 源码安装
1.编译
./configure --prefix=/usr/local/nginx --add-module=/root/echo-nginx-module-0.63 --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
没有erroe错误提示则表示成功,错误多半是上面的环境没有准备
安装完成后nginx-1.24.0目录下会多出Makefile和objs两个文件目录
可以使用./configure --help命令查看命令帮助
参数解释:
./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
2.安装
make && make install
make -j2 源文件与系统C语言文件开始对接,可以使用-j指定编译时的CUP内核
make install 将objs目录中的东西拷贝到指定的目录/usr/local/nginx/
3 启动Nginx
进入Nginx配置目录
cd /usr/local/nginx/
找到Nginx的启动程序
sbin/下有一个名叫nginx的可执行程序,这就是nginx的启动程序
cd sbin/
ll
执行/usr/local/nginx/sbin/nginx启动nginx
/usr/local/nginx/sbin/nginx
4.查看nginx是否启动
ps aux |grep nginx 查看进程
netstat -antlupe | grep nginx 查看端口号
netstat不存在时安装whatprovides包
dnf whatprovides */netstat
5.访问
curl 172.25.254.130 #本机的ip地址
第三行看到Welcome to nginx!表示成功
6.nginx相关配置目录
/usr/local/nginx/conf
/usr/local/nginx/conf/nginx.conf 配置文件
7.查看版本
dnf list nginx
curl -I 172.25.254.130
8. 关闭nginx程序
/usr/local/nginx/sbin/nginx -s stop
如果关闭不了
ps aux |grep nginx查看进程号,然后使用kill -9 进程 杀死进程
9.启动Nginx
nginx 已经写入环境变量文件vim ~/.bash_profile
或
/usr/local/nginx/sbin/nginx
或者
/usr/local/nginx/sbin/nginx -s restart
10. 如果有问题直接卸载
rm -rf /usr/local/nginx/ #相对于取消make && make install
make clean #清除第1步编译./configure --prefix.....产生的配置文件
或者直接删除解压nginx压缩包的目录nginx-1.24.0/
从第一步开始重新安装,可以是某个地方做错
3.4 Nginx配置调优
1. 关闭debug功能
查看/usr/local/nginx/sbin/nginx的大小,内存比较大,因为有debug模式,可以关掉
[root@localhost sbin]# du -sh nginx
5.5M nginx
vim nginx-1.24.0/auto/cc/gcc 找到debug将下面一行注释 ,关闭debug
#debug
#CFLAGS="$CFLAGS -g"
2. 添加环境变量
将/usr/local/nginx/sbin写入环境变量文件vim ~/.bash_profile ,这样以后在任何地方直接执行nginx可以启动nginx程序
[root@localhost ~]# vim ~/.bash_profile
export PATH=$PATH:/usr/local/nginx/sbin
[root@localhost ~]# source ~/.bash_profile
添加到环境变量中以后,nginx==/usr/local/nginx/sbin/nginx
3. 启动脚本编写
vim /lib/systemd/system/nginx.service
[Unit]Description=The NGINX HTTP and reverse proxy serverAfter=syslog.target network-online.target remote-fs.target nss-lookup.targetWants=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@localhost sbin]# systemctl daemon-reload
[root@localhost sbin]# nginx -s stop
[root@localhost sbin]# ps aux | grep nginx
root 21627 0.0 0.0 6408 2296 pts/0 S+ 01:53 0:00 grep --color=auto nginx
[root@localhost sbin]# systemctl enable --now nginx.service
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
[root@localhost sbin]# ps aux | grep nginx
root 21665 0.0 0.0 9920 940 ? Ss 01:54 0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 21666 0.0 0.0 13760 4792 ? S 01:54 0:00 nginx: worker process
root 21668 0.0 0.0 6408 2300 pts/0 S+ 01:54 0:00 grep --color=auto nginx
[root@localhost sbin]#
4. 在系统中设置nginx的最大链接数
vim /etc/security/limits.conf 在最下面添加以下内容
nginx - nofile 100000
5. 更改nginx配置文件
添加的内容是汉字注释下面的,如:#参数优化1,用户
vim /usr/local/nginx/conf/nginx.conf
#参数优化1,用户
user nginx;
#参数优化2,内核
worker_processes auto;
#四核
worker_cpu_affinity 0001 0010 0100 1000;#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;#pid logs/nginx.pid;
#参数优化3,系统支持nginx打开的最大链接数量
events {
worker_connections 100000;
}
http {
include mime.types;
default_type application/octet-stream;#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';#access_log logs/access.log main;
...................................下面不用改,省略
nginx -s reload 重启nginx
查看
ps aux | grep nginx 查看内核数量
sudo -u nginx ulimit -a 下的open files 后的数量
3.5 平滑升级与版本回滚
3.5.1 平滑升级
有时候我们需要对 Nginx 版本进行升级以满足对其功能的需求,例如添加新模块,需要新功能,而此时Nginx有业务无法停掉,这时我们就可以选择平滑升级。
步骤:
- 将旧 Nginx 二进制文件换成新 Nginx 程序文件(注意先备份 )
- 向 master 进程发送 USR2 信号
- master 进程修改 pid 文件名加上后缀 .oldbin, 成为 nginx.pid.oldbin
- master 进程用新 Nginx 文件启动新 master 进程成为旧 master 的子进程 , 系统中将有新旧两个 Nginx 主
- 进程共同提供 Web 服务 , 当前新的请求仍然由旧 Nginx 的 worker 进程进行处理 , 将新生成的 master 进程的 PID 存放至新生成的 pid 文件 nginx.pid
- 向旧的 Nginx 服务进程发送 WINCH 信号,使旧的 Nginx worker 进程平滑停止
- 向旧 master 进程发送 QUIT 信号,关闭老 master ,并删除 Nginx.pid.oldbin 文件
- 如果发现升级有问题 , 可以回滚∶向老 master 发送 HUP ,向新 master 发送 QUIT
配置:
1.下载新版本并解压编译
[root@Nginx nginx]# tar zxf nginx-1.26.1.tar.gz
[root@Nginx nginx]# cd nginx-1.26.1/
[root@Nginx nginx-1.26.1]# ./configure --with-http_ssl_module --withhttp_v2_module --with-http_realip_module --with-http_stub_status_module --withhttp_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --
with-stream_realip_module
[root@Nginx nginx-1.26.1]# make
2.此时可以查看到两个版本
[root@Nginx nginx-1.26.1]# ll objs/nginx /usr/local/nginx/sbin/nginx
-rwxr-xr-x 1 root root 1239416 Jul 18 15:08 objs/nginx
-rwxr-xr-x 1 root root 5671488 Jul 18 11:41 /usr/local/nginx/sbin/nginx
3.将旧版本的nginx命令备份并将新版本的nginx命令复制过去
[root@Nginx ~]# cd /usr/local/nginx/sbin/
[root@Nginx sbin]# cp nginx nginx.24
[root@Nginx sbin]# \cp -f /root/nginx/nginx-1.26.1/objs/nginx /usr/local/nginx/sbin
USR2 平滑升级可执行程序,将存储有旧版本主进程PID的文件重命名为nginx.pid.oldbin,并启动新的nginx,此时两个master的进程都在运行,只是旧的master不在监听,由新的master监听80,此时Nginx开启一个新的master进程,这个master进程会生成新的worker进程,这就是升级后的Nginx进程,此时老的进程不会自动退出,但是当接收到新的请求不作处理而是交给新的进程处理。
[root@Nginx sbin]# ps aux | grep nginx
[root@Nginx sbin]# kill -USR2 46548
5.回收旧版本
[root@Nginx sbin]# kill -WINCH 46548
6.检测版本信息
[root@Nginx sbin]# curl -I localhost
3.5.2 版本回滚
如果升级的版本有问题可以回滚
1.重新拉起旧版本的worker
[root@Nginx sbin]# cp nginx nginx.26
[root@Nginx sbin]# ls
nginx nginx.24 nginx.26
[root@Nginx sbin]# mv nginx.24 nginx
mv: overwrite 'nginx'? y
2.重新加载旧版本进程
[root@Nginx sbin]# kill -HUP 48732
3.回收新版本进程
[root@Nginx sbin]# kill -WINCH 52075
6.检测版本信息
[root@Nginx sbin]# curl -I localhost
四、Nginx相关实验配置
4.1 Nginx配置文件说明
配置文件位置:
·主配置文件:/usr/local/nginx/conf/nginx.conf
·子配置文件:/usr/local/nginx/conf.d/*.conf
子配置文件格式说明:
- 配置文件由指令与指令块构成
- 每条指令以;分号结尾,指令与值之间以空格符号分隔
- 可以将多条指令放在同一行,用分号分隔即可,但可读性差,不推荐
- 指令块以{ }大括号将多条指令组织在一起,且可以嵌套指令块
- include语句允许组合多个配置文件以提升可维护性
- 使用#符号添加注释,提高可读性
- 使用$符号使用变量
- 部分指令的参数支持正则表达式
主配置文件结构:
共四部分
main block:主配置段,即全局配置段,对http,mail都有效
#事件驱动相关的配置
event {
...
}
#http/https 协议相关配置段
http {
...
}
#默认配置文件不包括下面两个块
#mail 协议相关配置段
mail {
...
}
#stream 服务器相关配置段
stream {
...
}
主配置文件命令解释
[root@nginx-node1 ~]# vim /usr/local/nginx/conf/nginx.conf
#全局配置或默认配置,设置nginx的启动用户/组,启动的工作进程数量,工作模式,Nginx的PID路径,日志路径等。
#user nobody;
worker_processes 1; #启动工作进程数数量#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;#pid logs/nginx.pid;events { #设置块,主要影响nginx服务器与用户的网络连接,比如是否允许同时接受多个网络连接,使用哪种事件驱动模型#处理请求,每个工作进程可以同时支持的最大连接数,是否开启对多工作进程下的网络连接进行序列化等。worker_connections 1024; #设置单个nginx工作进程可以接受的最大并发,作为web服务器的时候最大并发数为worker_connections *worker_processes,#作为反向代理的时候为(worker_connections * worker_processes)/2
}http { ##http块是Nginx服务器配置中的重要部分,缓存、代理和日志格式定义等绝大多数功能和第三方模块都可以在这设置,#http块可以包含多个server块,而一个server块中又可以包含多个location块,#server块可以配置文件引入、MIME-Type定义、日志自定义、是否启用sendfile、连接超时时间和单个链接的请求上限等。include mime.types;default_type application/octet-stream;#log_format main '$remote_addr - $remote_user [$time_local] "$request" '# '$status $body_bytes_sent "$http_referer" '# '"$http_user_agent" "$http_x_forwarded_for"';#access_log logs/access.log main;sendfile on; #作为web服务器的时候打开sendfile加快静态文件传输,指定是否使用sendfile系统调用来传输文件#sendfile系统调用在两个文件描述符之间直接传递数据(完全在内核中操作)从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,操作效率很高,被称之为零拷贝,#硬盘 >> kernel buffer (快速拷贝到kernelsocketbuffer) >>协议栈。#tcp_nopush on;#keepalive_timeout 0;keepalive_timeout 65; #长连接超时时间,单位是秒#gzip on;server { #设置一个虚拟机主机,可以包含自己的全局块,同时也可以包含多个location模块##比如本虚拟机监听的端口、本虚拟机的名称和IP配置,多个server可以使用一个端口比如都使用80端口提供web服务listen 80; #配置server监听的端口server_name localhost; #本server的名称,当访问此名称的时候nginx会调用当前serevr内部的配置进程匹配。#charset koi8-r;#access_log logs/host.access.log main;location / { #location其实是server的一个指令,为nginx服务器提供比较多而且灵活的指令都是在location中体现的,#主要是基于nginx接受到的请求字符串对用户请求的UIL进行匹配,并对特定的指令进行处理#包括地址重定向、数据缓存和应答控制等功能都是在这部分实现,另外很多第三方模块的配置也是在location模块中配置。root html; #相当于默认页面的目录名称,默认是安装目录的相对路径,可以使用绝对路径配置。index index.html index.htm; #默认的页面文件名称}#error_page 404 /404.html; #错误页面的文件名称# redirect server error pages to the static page /50x.html#error_page 500 502 503 504 /50x.html;location = /50x.html { #location处理对应的不同错误码的页面定义到/50x.html,这个跟对应其server中定义的目录下。root html; #定义默认页面所在的目录} # proxy the PHP scripts to Apache listening on 127.0.0.1:80##location ~ \.php$ {# proxy_pass http://127.0.0.1;#}# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000##location ~ \.php$ {# root html;# fastcgi_pass 127.0.0.1:9000;# fastcgi_index index.php;# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;# include fastcgi_params;#}# deny access to .htaccess files, if Apache's document root# concurs with nginx's one##location ~ /\.ht {# deny all;#}}# another virtual host using mix of IP-, name-, and port-based configuration##server {# listen 8000;# listen somename:8080;# server_name somename alias another.alias;# location / {# root html;# index index.html index.htm;# }#}# HTTPS server##server {# listen 443 ssl;# server_name localhost;# ssl_certificate cert.pem;# ssl_certificate_key cert.key;# ssl_session_cache shared:SSL:1m;# ssl_session_timeout 5m;# ssl_ciphers HIGH:!aNULL:!MD5;# ssl_prefer_server_ciphers on;# location / {# root html;# index index.html index.htm;# }#}}#和邮件相关的配置
#mail {
# ...
# } mail 协议相关配置段#tcp代理配置,1.9版本以上支持
#stream {
# ...
# } stream 服务器相关配置段
#导入其他路径的配置文件
#include /apps/nginx/conf.d/*.conf
}
4.2 root和alias
root:指定web的家目录,在定义location的时候,文件的绝对路径等于 root+location
alias:定义路径别名,会把访问的路径重新定义到其指定的路径,文档映射的另一种机制;仅能用于
location上下文,此指令使用较少。
注意: root, 给定的路径对应于 location 中的 /uri 左侧的 /
alias , 给定的路径对应于 location 中的 /uri 的完整路径
1.使用epoll事件驱动并将子配置文件目录映射到主配置文件中,重载文件
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
events {
worker_connections 100000;
use epoll; #使用epoll事件驱动
}
http {
######
include "/usr/local/nginx/conf.d/*.conf"; #在响应报文中将指定的文件扩展名映射至MIME对应的类型
######
}
nginx -s reload 重启服务
2.创建子配置文件并写入规则,重载文件
[root@nginx ~]# mkdir -p /usr/local/nginx/conf.d
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
server_name www.rhel9.org;
root /data/web/html;
index index.html;
}
nginx -s reload 重启
3.写入测试文字
echo www.rhel9.org > /data/web/html/index.html
4.测试
记得做本地解析
server {
listen 80;
server_name web.rhel9.org;
location /dirtest { #必须建立/mnt/dirtest才能访问
root /mnt;
}
location /alias { #使用alias的时候uri后面如果加了斜杠,则下面的路径配置
必须加斜杠,否则403
alias /mnt/dirtest; #当访问alias的时候,会显示alias定义的/mnt/dirtest
里面的内容
}
4.3 location
在一个 server 中 location 配置段可存在多个,用于实现从 uri到文件系统的路径映射, ngnix 会根据用户请求的 URI 来检查定义的所有 location ,按一定的优先级找出一个最佳匹配, 而后应用其配置在没有使用正则表达式的时候, nginx 会先在 server 中的多个 location 选取匹配度最 高的一个 uri, uri 是用户请求的字符串,即域名后面的 web 文件路径, 然后使用该 location 模块中的正则 url 和字符串,如果匹配成功就结束搜索,并使用此 location 处理 此请求。
匹配优先级: =, ^~, ~ / ~ * , /
location 优先级: (location =) > (location ^~ 路径 ) > (location ~,~* 正则顺序 ) > (location 完整路径 ) > (location 部分起始路径 ) > (/)
匹配符号 | 说明 |
= | 用于标准 uri 前,需要请求字串与 uri 精确匹配,大小敏感 , 如果匹配成功就停止向下匹配并立即处理请求 |
^~ | 用于标准 uri 前,表示包含正则表达式 ,并且匹配以指定的正则表达式开头,对 uri 的最左边部分做匹配检查,不区分字符大小写 |
~ | 用于标准 uri 前,表示包含正则表达式 , 并且区分大小写 |
~* | 用于标准 uri 前,表示包含正则表达式 , 并且不区分大写 |
不带符号 | 匹配起始于此 uri 的所有的 uri |
\ | 用于标准 uri 前,表示包含正则表达式并且转义字符。可以将 . * ? 等转义为普通符号 |
示例配置:
server {
listen 80;
server_name www.rhel9.org;
location / {
root /data/web/html/ccc;
}
location ^~ /images {
root /data/web/html/ccc;
index index.html;
}
location /images1 {
root /data/web/html/ccc;
}
location ~* \.(gif|jpg|jpeg|bmp|png|tiff|tif|ico|wmf|js)$ {
root /data/web/html/ccc;
index index.html;
}
}
4.4 用户认证功能
1.创建用户,完成后可查看信息
[root@nginx ~]# htpasswd -cm /usr/local/nginx/.htpasswd admin
New password:
Re-type new password:
Adding password for user admim
[root@nginx ~]# htpasswd -m /usr/local/nginx/.htpasswd ccc
New password:
Re-type new password:
Adding password for user ccc
[root@nginx ~]# cat /usr/local/nginx/.htpasswd
admin:$apr1$okMzYJLu$Sk/0N1AUZoDjgpldJUi2a0
ccc:$apr1$DMbv5BB8$HbeB4TMW9UZfAScnzjkq.1
2.创建文件并写入测试文字
[root@nginx ~]# mkdir /data/web/ccc
[root@nginx ~]# echo ccc > /data/web/ccc/index.html
3.子配置文件中写入规则并重启
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhost.conf
location /ccc {
root /data/web;
auth_basic "login password !!!"; #用户在浏览器看到的认证信息提示
auth_basic_user_file "/usr/local/nginx/.htpasswd"; #http认证文件路径
}
nginx -s reload 重启服务配置
访问,去Windows浏览器访问,输入创建的用户名和密码
4.5 自定义错误日志
自 定义错误页,同时也可以用指定的响应状态码进行响应
可用位置: http, server, location, if in location
error_page code ... [=[response]] uri;
示例:
listen 80;
server_name www.timinglee.org;
error_page 500 502 503 504 /error.html;
location = /error.html {
root /data/nginx/html;
}
重启 nginx 并访问不存在的页面进行测试
示例:自定义错误页面
[root@nginx ~]# mkdir /webdata/nginx/timinglee/lee/errors -p
[root@nginx ~]# echo error page > /webdata/nginx/timinglee/lee/errors/40x.html
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
error_page 404 /40x.html;
location = /40x.html {
root /webdata/nginx/timinglee/lee/errors;
}
}
测试:
[root@nginx ~]# nginx -s reload
[root@nginx ~]#[root@nginx ~]# curl www.timinglee.org/40x.html/
error page
4.6 自定义错误日志
可以自定义错误日志
Syntax: error_log file [level];
Default:
error_log logs/error.log error;
Context: main, http, mail, stream, server, location
level: debug, info, notice, warn, error, crit, alert, emerg
示例:
[root@nginx ~]# mkdir "/var/log/nginx" -p
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.confserver {
listen 80;
server_name www.timinglee.org;
error_page 404 /40x.html;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location = /40x.html {
root /webdata/nginx/timinglee/lee/errors;
}
}
重启nginx并访问不存在的页面进行测试并验证是在指定目录生成新的日志文件
[root@nginx ~]# nginx -s reload
[root@nginx ~]# curl www.timinglee.org/40x.html/
error page
[root@nginx ~]# cd /var/log/nginx/
[root@nginx nginx]# ls
access.log error.log
4.7 检测文件是否存在
try_files 会按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如果所有文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部URI 的指向。最后一个参数是回退 URI 且必须存在,否则会出现内部500 错误
语法格式
Syntax: try_files file ... uri;
try_files file ... =code;
Default: —
Context: server, location
示例 : 如果不存在页面 , 就转到 default.html 页面
[root@nginx nginx]# mkdir -p /webdata/nginx/timinglee.org/lee/error/
[root@nginx nginx]# echo "index.html is not exist" > /webdata/nginx/timinglee.org/lee/error/default.html
[root@nginx nginx]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;#location /login {
# root /webdata/nginx/timinglee.org/lee;
# index index.html;
# auth_basic "login password";
# auth_basic_user_file "/usr/local/nginx/conf/.htpasswd";
#}
root /webdata/nginx/timinglee.org/lee;
error_page 404 /40x.html;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
try_files $uri $uri.html $uri/index.html /error/default.html;
location = /40x.html {
root /webdata/nginx/timinglee/lee/errors;
}
}
测试:
[root@nginx ~]# nginx -s reload
[root@nginx ~]# curl www.timinglee.org/40x.html/
index.html is not exist
4.8 长连接配置
keepalive_timeout timeout [header_timeout]; #设定保持连接超时时长, 0 表示禁止长连接,默认为75s
#通常配置在http字段作为站点全局配置
keepalive_requests 数字; #在一次长连接上所允许请求的资源的最大数量
#默认为100次,建议适当调大,比如:500
示例:
keepalive_requests 3;
keepalive_timeout 65 60;
# 开启长连接后,返回客户端的会话保持时间为 60s ,单次长连接累计请求达到指定次数请求或 65 秒就会被断
开,第二个数字 60 为发送给客户端应答报文头部中显示的超时时间设置为 60s :如不设置客户端将不显示超时时间。
Keep-Alive:timeout=60 #浏览器收到的服务器返回的报文
#如果设置为0表示关闭会话保持功能,将如下显示:
#Connection:close 浏览器收到的服务器返回的报文
# 使用命令测试:
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
keepalive_timeout 65 60;
keepalive_requests 500;
[root@nginx ~]# telnet www.timinglee.org 80
Trying 192.168.10.140...
Connected to www.timinglee.org.
Escape character is '^]'.
GET / HTTP/1.1 ##输入动作
HOST: www.timinglee.org ##输入访问HOST##输入回车
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Tue, 20 Aug 2024 14:51:18 GMT
Content-Type: text/html
Content-Length: 24
Last-Modified: Tue, 20 Aug 2024 14:36:54 GMT
Connection: keep-alive
Keep-Alive: timeout=60
ETag: "66c4aa06-18"
Accept-Ranges: bytesindex.html is not exist
Trying 192.168.10.140...
Connected to www.timinglee.org.
Escape character is '^]'.
GET / HTTP/1.1 #第一次操作
HOST: www.timinglee.org #第二次操作#第三次操作
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Tue, 20 Aug 2024 14:51:18 GMT
Content-Type: text/html
Content-Length: 24
Last-Modified: Tue, 20 Aug 2024 14:36:54 GMT
Connection: keep-alive
Keep-Alive: timeout=60
ETag: "66c4aa06-18"
Accept-Ranges: bytesindex.html is not exist
Connection closed by foreign host. # 自动断开链接
4.9 作为下载服务器配置
ngx_http_autoindex_module 模块处理以斜杠字符 "/" 结尾的请求,并生成目录列表 , 可以做为下载服务配置使用
相关指令:
autoindex on | off; # 自动文件索引功能,默为 off
autoindex_exact_size on | off; # 计算文件确切大小(单位 bytes ), off 显示大概大小(单位 K、 M),默认 on
autoindex_localtime on | off ; # 显示本机时间而非 GMT( 格林威治 ) 时间,默认 off
autoindex_format html | xml | json | jsonp; # 显示索引的页面文件风格,默认 html
limit_rate rate; # 限制响应客户端传输速率 ( 除 GET 和 HEAD 以外的所有方法 ) ,单位
B/s,bytes/second , # 默认值 0, 表示无限制 , 此指令由ngx_http_core_module提供
set $limit_rate 4k; # 也可以通变量限速 , 单位 B/s, 同时设置 , 此项优级高 .
示例:实现下载站点
注意 :download 不需要 index.html 文件
location /download {
autoindex on; #自动索引功能
autoindex_exact_size on; #计算文件确切大小(单位bytes),此为默认值,off只显示大概大小(单位 kb 、 mb 、 g[root@nginx ~]# mkdir -p /webdata/nginx/timinglee.org/lee/download
[root@nginx ~]# cp /root/anaconda-ks.cfg /webdata/nginx/timinglee.org/lee/download
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
error_page 404 /40x.html;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
try_files $uri $uri.html $uri/index.html /error/default.html;
location = /40x.html {
root /webdata/nginx/timinglee/lee/errors;
}b)autoindex_localtime on; #on表示显示本机时间而非GMT(格林威治)时间,默为为off显示GMT时间
limit_rate 1024k; #限速,默认不限速
}
}
重启 Nginx 并访问测试下载页面
五、高级配置
5.1 状态页
- 基于nginx 模块 ngx_http_stub_status_module 实现,
- 在编译安装nginx的时候需要添加编译参数 --with-http_stub_status_module
- 否则配置完成之后监测会是提示法错误
配置:
location /nginx_status {
stub_status;
auth_basic "auth login";
auth_basic_user_file /apps/nginx/conf/.htpasswd;
allow 192.168.0.0/16;
allow 127.0.0.1;
deny all;
}
# 状态页用于输出 nginx 的基本状态信息:
# 输出信息示例:
Active connections: 291
server accepts handled requests
16630948 16630948 31070465
上面三个数字分别对应 accepts,handled,requests 三个值
Reading: 6 Writing: 179 Waiting: 106
Active connections: #当前处于活动状态的客户端连接数
#包括连接等待空闲连接数=reading+writing+waiting
accepts: #统计总值,Nginx 自启动后已经接受的客户端请求连接的总数。
handled: #统计总值,Nginx自启动后已经处理完成的客户端请求连接总数
#通常等于accepts,除非有因worker_connections限制等被拒绝的
连接
requests: #统计总值,Nginx自启动后客户端发来的总的请求数
Reading: #当前状态,正在读取客户端请求报文首部的连接的连接数
#数值越大,说明排队现象严重,性能不足
Writing: #当前状态,正在向客户端发送响应报文过程中的连接数,数值越大, 说明访问量很大
Waiting: #当前状态,正在等待客户端发出请求的空闲连接数
开启 keep-alive的情况下,这个值等于active –(reading+writing)
5.2 压缩功能
Nginx 支持对指定类型的文件进行压缩然后再传输给客户端,而且压缩还可以设置压缩比例,压缩后的文件大小将比源文件显著变小,样有助于降低出口带宽的利用率,降低企业的IT 支出,不过会占用相应的CPU 资源。
Nginx 对文件的压缩功能是依赖于模块 ngx_http_gzip_module, 默认是内置模
指令说明:
gzip on | off; | 启用或禁用 gzip 压缩,默认关闭 |
gzip_comp_level 4; | 压缩比由低到高从 1 到 9 ,默认为 1 ,值越高压缩后文件越小,但是消耗 cpu 比较高。基本设定未 4 或者 5 |
gzip_disable "MSIE [1-6]\."; | 禁用 IE6 gzip 功能,早期的 IE6 之前的版本不支持压缩 |
gzip_min_length 1k; | gzip 压缩的最小文件,小于设置值的文件将不会压缩 |
gzip_http_version 1.0 | 1.1; | 启用压缩功能时,协议的最小版本,默认 HTTP/1.1 |
gzip_buffers number size; | 指定 Nginx 服务需要向服务器申请的缓存空间的个数和大小 , 平台不同 , 默认 :32 4k 或者 16 8k; |
gzip_types mime-type ...; | 指明仅对哪些类型的资源执行压缩操作 ; 默认为 gzip_types text/html ,不用显示指定,否则出错 |
gzip_vary on | off; | 如果启用压缩,是否在响应报文首部插入 “Vary: Accept-Encoding”, 一般建议打开 |
gzip_static on | off; | 预压缩,即直接从磁盘找到对应文件的 gz 后缀的式的压缩文件返回给用户,无需消耗服务器 CPU 注意 : 来自于 ngx_http_gzip_static_module 模块 |
配置:
[root@nginx ~]# mkdir /webdata/nginx/timinglee.org/lee/data -p
[root@nginx ~]# cp /usr/local/nginx/logs/access.log /webdata/nginx/timinglee.org/lee/data/data.txt
[root@nginx ~]# ll /webdata/nginx/timinglee.org/lee/data/data.txt
-rw-r--r-- 1 root root 2494866 Aug 20 23:18 /webdata/nginx/timinglee.org/lee/data/data.txt
[root@nginx ~]# echo test > /webdata/nginx/timinglee.org/lee/data/test.html #小于1k 的文件测试是否会压缩
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
gzip on;
gzip_comp_level 5;
gzip_min_length 1k;
gzip_types text/plain application/javascript application/x-javascript text/css
application/xml text/javascript application/x-httpd-php image/gif image/png;
gzip_vary on;
# 重启 Nginx 并访问测试:
[root@nginx ~]# nginx -s reload
[root@nginx ~]#[root@nginx ~]# curl --head --compressed www.timinglee.org/data/test.html
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Tue, 20 Aug 2024 15:25:51 GMT
Content-Type: text/html
Content-Length: 5
Last-Modified: Tue, 20 Aug 2024 15:18:58 GMT
Connection: keep-alive
Keep-Alive: timeout=60
ETag: "66c4b3e2-5"
Accept-Ranges: bytes[root@nginx ~]# curl --head --compressed www.timinglee.org/data/data.txt
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Tue, 20 Aug 2024 15:26:08 GMT
Content-Type: text/plain
Last-Modified: Tue, 20 Aug 2024 15:18:05 GMT
Connection: keep-alive
Keep-Alive: timeout=60
Vary: Accept-Encoding
ETag: W/"66c4b3ad-261192"
Content-Encoding: gzip
5.3 变量
- nginx的变量可以在配置文件中引用,作为功能判断或者日志等场景使用
- 变量可以分为内置变量和自定义变量
- 内置变量是由nginx模块自带,通过变量可以获取到众多的与客户端访问相关的值。
5.3.1 内置变量
常用内置变量
$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;
示例:
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
location /var {
default_type text/html;
echo $remote_addr;
echo $args;
echo $document_root;
echo $document_uri;
echo $host;
echo $http_user_agent;
echo $request_filename;
echo $scheme;
echo $scheme://$host$document_uri?$args;
echo $http_cookie;
echo $cookie_key2;
echo $http_Accept;
}
}
测试
[root@nginx ~]# nginx -s reload
[root@nginx ~]#
[root@nginx ~]# curl -b "title=lee;key1=lee,key2=timinglee" "www.timinglee.org/var?search=lee&&id=666666"192.168.10.140
search=lee&&id=666666
/webdata/nginx/timinglee.org/lee
/var
lee.timinglee.org
curl/7.29.0
/webdata/nginx/timinglee.org/lee/var
http
http://lee.timinglee.org/var?search=lee&&id=666666
title=lee;key1=lee,key2=timinglee
timinglee
*/*
5.3.2 自定义变量
假如需要自定义变量名称和值,使用指令 set $variable value;
语法格式:
Syntax: set $variable value;
Default: —
Context: server, location, if
示例 :
set $name timinglee;
echo $name;
set $my_port $server_port;
echo $my_port;
echo "$server_name:$server_port";
[root@nginx ~]# mkdir -p /webdata/nginx/timinglee.org/lee/var
[root@nginx ~]# echo xixi > /webdata/nginx/timinglee.org/lee/var/index.html
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
location /var {
default_type text/html;
set $name timinglee;
echo $name;
set $web_port $server_port;
echo $web_port;
}
}
#测试输出
[root@nginx ~]# nginx -s reload
[root@nginx ~]#
[root@nginx ~]# curl www.timinglee.org/var
timinglee
80
5.4 模块指令
官方文档 : https://nginx.org/en/docs/http/ngx_http_rewrite_module.html
5.4.1 if 指令
官方文档:
https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#if
用于条件匹配判断,并根据条件判断结果选择不同的 Nginx 配置,可以配置在 server 或 location 块中进行配置,Nginx 的 if 语法仅能使用 if 做单次判断,不支持使用 if else 或者 if elif 这样的多重判断,用法如下:
if (条件匹配) {
action
}
使用正则表达式对变量进行匹配,匹配成功时 if 指令认为条件为 true ,否则认为 false ,变量与表达式之间使用以下符号链接:
= #比较变量和字符串是否相等,相等时 if 指令认为该条件为 true ,反之为 false
!= #比较变量和字符串是否不相等,不相等时 if 指令认为条件为 true ,反之为 false
~ #区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~ #区分大小写字符 , 判断是否匹配,不满足匹配条件为真,满足匹配条件为假
~* #不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~* #不区分大小字符 , 判断是否匹配,满足匹配条件为假,不满足匹配条件为真
-f 和 !-f #判断请求的文件是否存在和是否不存在
-d 和 !-d #判断请求的目录是否存在和是否不存在
-x 和 !-x #判断文件是否可执行和是否不可执行
-e 和 !-e #判断请求的文件或目录是否存在和是否不存在 ( 包括文件,目录,软链接 )
#注意:
#如果$变量的值为空字符串或0,则if指令认为该条件为false,其他条件为true。
#nginx 1.0.1之前$变量的值如果以0开头的任意字符串会返回false
示例:
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
location /test {
index index.html;
default_type text/html;
if ( $scheme = http ){
echo "if ---------> $scheme";
}
if ( $scheme = https ){
echo "if ---------> $scheme";
}
}
location /test2 {
if ( !-e $request_filename ){
echo "$request_filename is not exist";
return 409;
}
}
测试:
[root@nginx ~]# curl www.timinglee.org/test/
if ---------> http
[root@nginx ~]# curl www.timinglee.org/test2/test
/webdata/nginx/timinglee.org/lee/test2/test is not exist
5.4.2 set 指令
指定 key 并给其定义一个变量,变量可以调用 Nginx 内置变量赋值给 key
另外 set 定义格式为 set $key value , value 可以是 text, variables 和两者的组合。
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
location /test3{
set $name lee;
echo $name;
}
}
#测试:
[root@nginx ~]# curl www.timinglee.org/test3/
lee
5.4.3 break 指令
用于中断当前相同作用域 (location) 中的其他 Nginx 配置
与该指令处于同一作用域的 Nginx 配置中,位于它前面的配置生效
位于后面的 ngx_http_rewrite_module 模块中指令就不再执行
Nginx 服务器在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置,、
该指令可以在 server 块和 locationif 块中使用
注意: 如果break指令在location块中后续指令还会继续执行,只是不执行 ngx_http_rewrite_module
模块的指令,其它指令还会执行
使用语法如下:
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
location /break{
default_type text/html;
set $name lee;
echo $name;
break;
set $port $server_port;
echo $port;
}
}
#测试:
[root@nginx ~]# curl www.timinglee.org/break/ # 当未添加 break 时
lee
80
[root@nginx ~]# curl www.timinglee.org/break/ # 添加 break 后
lee
5.4.4 return 指令
return 用于完成对请求的处理,并直接向客户端返回响应状态码,比如 : 可以指定重定向 URL( 对于特殊重定向状态码,301/302 等 ) 或者是指定提示文本内容 ( 对于特殊状态码 403/500 等 ) ,处于此指令后的所有配置都将不被执行,return 可以在 server 、 if 和 location 块进行配置
语法格式:
return code; # 返回给客户端指定的 HTTP 状态码
return code [text]; # 返回给客户端的状态码及响应报文的实体内容
# 可以调用变量 , 其中 text 如果有空格 , 需要用单或双引号
return code URL; # 返回给客户端的 URL 地址
示例:
server {
listen 80;
server_name www.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
location /return {
default_type text/html;
if ( !-e $request_filename){
return 301 http://www.baidu.com;
#return 666 "$request_filename is not exist";
}
echo "$request_filename is exist";
}
}
测试:
[root@client ~]# curl www.timinglee.org/return
/webdata/nginx/timinglee.org/lee/return is exist
[root@client ~]# curl www.timinglee.org/return1
/webdata/nginx/timinglee.org/lee/return1 is not exist
# 测试 return 301 http://www.baidu.com;
可在浏览器直接访问 lee.timinglee.org/return1
return 示例:
location /test {
default_type application/json;
return 200 '{"status:"success"}';
}
5.4.5 rewrite 指令
通过正则表达式的匹配来改变 URI ,可以同时存在一个或多个指令,按照顺序依次对 URI 进行匹配,rewrite主要是针对用户请求的 URL 或者是 URI 做具体处理
官方文档:
https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite
语法格式 :
rewrite regex replacement [flag];
rewrite将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为表达式指定的新的URI
注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,隐含有循环机制,但不超过10次;如果超过,提示500响应码,[flag]所表示的标志位用于控制此循环机制
如果替换后的URL是以http://或https://开头,则替换结果会直接以重定向返回给客户端, 即永久重定向301
正则表达式格式
# 匹配除换行符以外的任意字符
\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 这几个字母以外的任意字符
5.4.5.1 rewrite flag
利用 nginx 的 rewrite 的指令,可以实现 url 的重新跳转, rewrite 有四种不同的 flag ,分别是 redirect( 临时重定向302) 、 permanent( 永久重定向 301) 、 break 和 last 。其中前两种是跳转型的 flag ,后两种是代理型
跳转型指由客户端浏览器重新对新地址进行请求
代理型是在WEB服务器内部实现跳转
rewrite 格式
Syntax: rewrite regex replacement [flag]; # 通过正则表达式处理用户请求并返回替换后的数据包。
Default: —
Context: server, location, if
flag 说明
redirect;
# 临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新 URL 给客户端
# 由客户端重新发起请求 ; 使用相对路径 , 或者 http:// 或 https:// 开头,状态码: 302
permanent;
# 重写完成后以永久重定向方式直接返回重写后生成的新 URL 给客户端
# 由客户端重新发起请求,状态码: 301
break;
# 重写完成后 , 停止对当前 URL 在当前 location 中后续的其它重写操作
# 而后直接跳转至重写规则配置块之后的其它配置,结束循环,建议在 location 中使用
# 适用于一个 URL 一次重写
last;
# 重写完成后 , 停止对当前 URI 在当前 location 中后续的其它重写操作,
# 而后对新的 URL 启动新一轮重写检查,不建议在 location 中使用
# 适用于一个 URL 多次重写,要注意避免出现超过十次以及 URL 重写后返回错误的给用户
5.4.5.2 rewrite案例: 域名永久与临时重定向
域名的临时的调整,后期可能会变,之前的域名或者 URL 可能还用、或者跳转的目的域名和 URL 还会跳转,这种情况浏览器不会缓存跳转, 临时重定向不会缓存域名解析记录 (A 记录 ) ,但是永久重定向会缓存。
示例: 因业务需要,将访问源域名 www.timinglee.org 的请求永久重定向到 www.timinglee.com
location / {
root /data/nginx/html/pc;
index index.html;
rewrite / http://www.timinglee.com permanent;
#rewrite / http://www.timinglee.com redirect;
}
# 重启 Nginx 并访问域名 http://www.timinglee.org 进行测试
永久重定向304
域名永久型调整,即域名永远跳转至另外一个新的域名,之前的域名再也不使用,跳转记录可以缓存到客户端浏览器
永久重定向会缓存DNS解析记录, 浏览器中有 from disk cache 信息,即使nginx服务器无法访问,浏览器也会利用缓存进行重定向
比如: 京东早期的域名 www.360buy.com 由于与360公司类似,于是后期永久重定向到了 www.jd.com
示例
[root@nginx lee]# echo 123456 > /webdata/nginx/timinglee.org/lee/index.html
[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 / {
#rewrite / http://lee.timinglee.com redirect;
rewrite / http://lee.timinglee.com permanent;
}
}
server {
listen 80;
server_name lee.timinglee.com;
root /webdata/nginx/timinglee.com/lee;
}
#测试:
[root@nginx ~]# nginx -s reload
[root@nginx ~]#
临时重定向301
域名临时重定向,告诉浏览器域名不是固定重定向到当前目标域名,后期可能随时会更改,因此浏览器不会缓存当前域名的解析记录,而浏览器会缓存永久重定向的DNS 解析记录,这也是临时重定向与永久
重定向最大的本质区别。
即当 nginx 服务器无法访问时 , 浏览器不能利用缓存 , 而导致重定向失败
示例
[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 / {
rewrite / http://lee.timinglee.com redirect;
#rewrite / http://lee.timinglee.com permanent;
}
}
server {
listen 80;
server_name lee.timinglee.com;
root /webdata/nginx/timinglee.com/lee;
}
5.4.5.3 rewrite 案例: break 与 last
[root@nginx ~]# mkdir /webdata/nginx/timinglee.org/lee/{test1,test2,break}
[root@nginx ~]# echo test1 > /webdata/nginx/timinglee.org/lee/test1/index.html
[root@nginx ~]# echo test2 > /webdata/nginx/timinglee.org/lee/test2/index.html
[root@nginx ~]# echo break > /webdata/nginx/timinglee.org/lee/break/index.html
[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 /break {
root /webdata/nginx/timinglee.org/lee;
rewrite ^/break/(.*) /test1/$1 last;
rewrite ^/test1/(.*) /test2/$1 break;
}
location /last {
root /webdata/nginx/timinglee.org/lee;
rewrite ^/last/(.*) /test1/$1 last;
rewrite ^/test1/(.*) /test2/$1 last;
}
location /test1 {
default_type text/html;
return 666 "new test1";
}
location /test2 {
root /webdata/nginx/timinglee.org/lee;
}
}
[root@nginx ~]# curl -L lee.timinglee.org/break/index.html
test1
[root@nginx ~]#curl -L lee.timinglee.org/last/index.html
new test1
5.4.5.4 rewrite案例: 自动跳转 https
案例:基于通信安全考虑公司网站要求全站 https ,因此要求将在不影响用户请求的情况下将 http 请求全部自动跳转至 https ,另外也可以实现部分 location 跳转
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 443 ssl;
listen 80;
ssl_certificate /apps/nginx/certs/www.timinglee.org.crt;
ssl_certificate_key /apps/nginx/certs/www.timinglee.org.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.timniglee.org;
location / { #针对全站跳转
root /data/nginx/html/pc;
index index.html;
if ($scheme = http ){ #如果没有加条件判断,会导致死循环
rewrite / https://$host redirect;
}
}
location /login { #针对特定的URL 进行跳转 https
if ($scheme = http ){ #如果没有加条件判断,会导致死循环
rewrite / https://$host/login redirect;
}
}
}
# 重启 Nginx 并访问测试
[root@nginx ~]#curl -ikL www.timinglee.org
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.18.0
Date: Thu, 08 Oct 2020 15:23:48 GMT
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Location: https://www.magedu.org
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Thu, 08 Oct 2020 15:23:48 GMT
Content-Type: text/html
Content-Length: 7
Last-Modified: Sat, 26 Sep 2020 01:18:32 GMT
Connection: keep-alive
ETag: "5f6e96e8-7"
Accept-Ranges: bytes
pc web
2.2.5 rewrite 案例: 判断文件是否存在
案例:当用户访问到公司网站的时输入了一个错误的 URL ,可以将用户重定向至官网首页
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
location / {
root /data/nginx/html/pc;
index index.html;
if (!-e $request_filename) {
rewrite .* http://www.timinglee.org/index.html; #实现客户端浏览器的302 跳转
#rewrite .* /index.html; #web服务器内部跳转
}
}
# 重启 Nginx 并访问测试
5.5 Nginx 防盗链
防盗链基于客户端携带的 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
正常通过搜索引擎搜索 web 网站并访问该网站的 referer 信息如下:
172.25.254.1 - - [22/Jul/2024:09:27:36 +0800] "GET /favicon.ico HTTP/1.1" 404 149
"http://lee.timinglee.org/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0)
Gecko/20100101 Firefox/115.0"
2024/07/22 09:27:36 [error] 34596#0: *205 open()
"/webdata/nginx/timinglee.org/lee/favicon.ico" failed (2: No such file or
directory), client: 172.25.254.1, server: lee.timinglee.org, request: "GET
/favicon.ico HTTP/1.1", host: "lee.timinglee.org", referrer:
"http://lee.timinglee.org/"
5.5.1 实现盗链
在一个 web 站点盗链另一个站点的资源信息,比如 : 图片、视频等
# 新建一个主机 192.168.10.141, 盗取另一台主机 lee.timinglee.org/images/logo.png 的图片
[root@client ~]# yum install httpd -y
[root@client html]# vim /var/www/html/index.html
# 准备盗链 web 页面:
<html>
<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://192.168.10.140 测试
# 验证两个域名的日志,是否会在被盗连的 web 站点的日志中出现以下盗链日志信息:
[root@Nginx ~]# cat /usr/local/nginx/logs/access.log
192.168.10.1 - - [22/Jul/2024:09:50:01 +0800] "GET /images/logo.png HTTP/1.1" 304
0 "http:/192.168.10.140/" "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"
192.168.10.1 - - [22/Jul/2024:09:50:18 +0800] "GET / HTTP/1.1" 304 0
"http://192.168.10.140/" "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"
5.5.2 实现防盗链
基于访问安全考虑, nginx 支持通过 ngx_http_referer_module 模块 , 检查访问请求的 referer 信息是否有效实现防盗链功能
官方文档 :
https://nginx.org/en/docs/http/ngx_http_referer_module.html
示例 : 定义防盗链:
[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://192.168.10.140
5.6 反向代理
反向代理:reverse proxy,指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户的一种方式,这是用的比较多的一种方式。
Nginx 除了可以在企业提供高性能的web服务之外,另外还可以将 nginx 本身不具备的请求通过某种预定义的协议转发至其它服务器处理,不同的协议就是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 协议转发至指定服务器处理
5.6.1 反向代理单台 web 服务器
要求:将用户对域 www.timinglee.org 的请求转发给后端服务器处理
[root@nginx ~]# cat /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
location / {
proxy_pass http://192.168.10.141;
}
}
# 重启 Nginx 并访问测试
5.6.2 针对指定的 location
server {
listen 80;
server_name www.timinglee.org;
location / {
proxy_pass http://192.168.10.141;
}
location ~ /static {
proxy_pass http://192.168.10.140:8080;
}
}
# 后端 web 服务器必须要有相对于的访问 URL
[root@nginx ~]## mkdir /var/www/html/static
[root@nginx ~]## echo static 192.168.10.140 > /var/www/html/static/index.html
[root@nginx2 ~]#]# echo 192.168.10.141 > /var/www/html/index.html
# 重启 Nginx 并访问测试:
[root@nginx ~]# curl www.timinglee.org/static/
static 192.168.10.140
[root@nginx ~]# curl www.timinglee.org
192.168.10.141
5.6.3 针对特定的资源实现代理
静态分离
[root@Nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
location / {
proxy_pass http://192.168.10.141;
}
location ~ \.(png|jpg|gif) {
proxy_pass http://192.168.10.140:8080;
}
}
5.6.4 缓存功能
缓存功能默认关闭状态 , 需要先动配置才能启用
proxy_cache zone_name | off; 默认 off
# 指明调用的缓存,或关闭缓存机制 ;Context:http, server, location
#zone_name 表示缓存的名称 . 需要由 proxy_cache_path 事先定义
proxy_cache_key string;
# 缓存中用于 “ 键 ” 的内容,默认值: proxy_cache_key $scheme$proxy_host$request_uri;
proxy_cache_valid [code ...] time;
# 定义对特定响应码的响应内容的缓存时长,定义在 http{...} 中
示例 :
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_path;
# 定义可用于 proxy 功能的缓存 ;Context:http
proxy_cache_path path [levels=levels] [use_temp_path=on|off]
keys_zone=zone_name:size [inactive=time] [max_size=size] [manager_files=number]
[manager_sleep=time] [manager_threshold=time] [loader_files=number]
[loader_sleep=time] [loader_threshold=time] [purger=on|off]
[purger_files=number] [purger_sleep=time] [purger_threshold=time];
示例:在 http 配置定义缓存信息
proxy_cache_path /var/cache/nginx/proxy_cache # 定义缓存保存路径, proxy_cache 会自动创建
levels=1:2:2 # 定义缓存目录结构层次
#1:2:2 可以生成
2^4x2^8x2^8=2^20=1048576 个目录
keys_zone=proxycache:20m # 指内存中缓存的大小,主要用于存放 key 和 metadata
(如:使用次数)
# 一般 1M 可存放 8000 个左右的 key
inactive=120s # 缓存有效时间
max_size=10g; # 最大磁盘占用空间,磁盘存入文件内容的缓存空间最大值
# 调用缓存功能,需要定义在相应的配置段,如 server{...}; 或者 location 等
proxy_cache proxycache;
proxy_cache_key $request_uri; # 对指定的数据进行 MD5 的运算做为缓存的 key
proxy_cache_valid 200 302 301 10m; # 指定的状态码返回的数据缓存多长时间
proxy_cache_valid any 1m; # 除指定的状态码返回的数据以外的缓存多长时间 , 必须设置 ,
否则不会缓存
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 |
http_502 | http_503 | http_504 | http_403 | http_404 | off ; # 默认是 off