文章目录
- 1、nginx编译安装
- 2、nginx核心配置详解
-
- 2.1、配置文件说明
- 2.2、全局配置
- 2.3、http配置块
- 2.4、核心配置示例
-
- [2.4.1、新建一个PC web站点(109节点)](#2.4.1、新建一个PC web站点(109节点))
- 2.4.2、root与alias
- 2.4.3、location的详细使用
- 3、nginx四层访问控制
- 4、nginx账务认证功能
- 5、自定义错误页面
- 6、检测文件是否存在
- 7、长连接配置
- 8、作为下载服务器配置
- 9、其他配置
- 10、nginx高级配置
- 11、nginx变量
- [12、Nginx 自定义访问日志](#12、Nginx 自定义访问日志)
- 13、nginx压缩功能
1、nginx编译安装
nginx官网:https://nginx.org/
1.1、下载源码包
进入官网后点击download,找到要下载的版本右击复制地址,进入服务器使用wget进行下载,以1.24.0版本为例。
bash
# 下载
[root@109 ~]#wget https://nginx.org/download/nginx-1.24.0.tar.gz
# 解压
[root@109 ~]#tar -xf nginx-1.24.0.tar.gz
# 创建nginx账号
[root@109 ~/nginx-1.24.0]#useradd -r -s /sbin/nologin nginx
1.2、安装依赖
bash
[root@109 ~/nginx-1.24.0]#yum -y install gcc pcre-devel openssl-devel zlib-devel
1.3、编译安装
bash
[root@109 ~/nginx-1.24.0]#./configure --prefix=/apps/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module
[root@109 ~/nginx-1.24.0]# make -j 2 && make install
# 创建nginx用户
root@109:~/nginx-1.24.0$ useradd -s /sbin/nologin nginx
# 修改/apps/nginx的属主与属组
root@109:~/nginx-1.24.0$ chown -R nginx.nginx /apps/nginx
查看目录结构
bash
root@109:/apps$ tree nginx/
nginx/
├── conf
│ ├── fastcgi.conf
│ ├── fastcgi.conf.default
│ ├── fastcgi_params
│ ├── fastcgi_params.default
│ ├── koi-utf
│ ├── koi-win
│ ├── mime.types
│ ├── mime.types.default
│ ├── nginx.conf
│ ├── nginx.conf.default
│ ├── scgi_params
│ ├── scgi_params.default
│ ├── uwsgi_params
│ ├── uwsgi_params.default
│ └── win-utf
├── html
│ ├── 50x.html
│ └── index.html
├── logs
└── sbin
└── nginx
4 directories, 18 files
做启动程序软连接到/usr/sbin/下
bash
root@109:/apps$ ln -s /apps/nginx/sbin/nginx /usr/sbin/
查看编译内容
bash
# -V 参数(大写)
root@109:/apps$ nginx -V
nginx version: nginx/1.24.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --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
1.4、设置开机自启
bash
# 编辑自启配置文件
root@109:/apps$ vim /usr/lib/systemd/system/nginx.service
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/apps/nginx/run/nginx.pid
ExecStart=/apps/nginx/sbin/nginx -c /apps/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
# 注意,除了上述nginx.service需要编辑外,还需要修改nginx.conf配置文件,因为两个地方都定义了pid的路径
root@109:/apps/nginx/conf$ vim /apps/nginx/conf/nginx.conf
#pid logs/nginx.pid;
# 原来的是注释掉的,需放开注释改为nginx.service中pid设置的路径
pid /apps/nginx/run/nginx.pid;
# 创建run目录,因为nginx目录中默认是没有这个目录的
root@109:~$ mkdir /apps/nginx/run/
# 重新加载systemd守护进程配置
root@109:~$ systemctl daemon-reload
# kill掉nginx重启一下
root@109:~$ kill -9 12858
# 启动下nginx
root@109:~$ systemctl enable --now nginx
# 查看状态
root@109:~$ systemctl status nginx
● nginx.service - nginx - high performance web server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; static; vendor preset: disabled)
Active: active (running) since Sun 2024-04-07 10:23:02 CST; 17s ago
Docs: http://nginx.org/en/docs/
Process: 12957 ExecStart=/apps/nginx/sbin/nginx -c /apps/nginx/conf/nginx.conf (code=exited, status=0/SUCCESS)
Main PID: 12958 (nginx)
CGroup: /system.slice/nginx.service
├─12958 nginx: master process /apps/nginx/sbin/nginx -c /apps/nginx/conf/nginx.conf
└─12959 nginx: worker process
Apr 07 10:23:02 109 systemd[1]: Starting nginx - high performance web server...
Apr 07 10:23:02 109 systemd[1]: Started nginx - high performance web server.
**注意:**如果用systemctl启动的nginx,一定要用systemctl进行停止,如果用nginx -s start命令启动的需要用nginx -s stop进行停止,必须成对的,否则有时候查询状态不一样或者出现其他的各种问题。
2、nginx核心配置详解
2.1、配置文件说明
nginx官方帮助文档
bash
http://nginx.org/en/docs/
tengine 帮助文档
bash
http://tengine.taobao.org/nginx_docs/cn/docs/
自定义配置路径
bash
# 编译的nginx最后没有include内容,我们可以手动添加下,这样以后就不用一直改主配置文件了
root@109:/apps/nginx/conf$ vim nginx.conf
......
# location / {
# root html;
# index index.html index.htm;
# }
#}
# 在最后一个大括号前添加include选项,是放在http语句块里了,注意,如果conf.d中还有目录,如vhosts,vhosts目录下的*.conf文件是不会生效的,如果有vhosts需要在加一条,如第二条
include /apps/nginx/conf/conf.d/*.conf;
include /apps/nginx/conf/conf.d/vhosts/*.conf;
}
# 因conf.d目录不存在,需要手动创建
root@109:~$ cd /apps/nginx/conf/
root@109:/apps/nginx/conf$ mkdir conf.d
Nginx的配置文件的组成部分:
- 主配置文件:nginx.conf
- 子配置文件: include conf.d/*.conf
- fastcgi, uwsgi,scgi 等协议相关的配置文件
- mime.types:支持的mime类型,MIME(Multipurpose Internet Mail Extensions)多用途互联网
邮件扩展类型,MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据,是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
MIME参考文档:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME
_Types
Nginx 主配置文件的配置指令方式:
bash
directive value [value2 ...];
注意
(1) 指令必须以分号结尾
(2) 支持使用配置变量
内建变量:由Nginx模块引入,可直接引用
自定义变量:由用户使用set命令定义,格式: set variable_name value;
引用变量:$variable_name
主配置文件结构:四部分
bash
main block:主配置段,即全局配置段,对http,mail都有效
#事件驱动相关的配置
event {
...
}
#http/https 协议相关配置段
http {
...
}
#默认配置文件不包括下面两个块
#mail 协议相关配置段
mail {
...
}
#stream 服务器相关配置段
stream {
...
}
默认的nginx.conf 配置文件格式说明
bash
#全局配置端,对全局生效,主要设置nginx的启动用户/组,启动的工作进程数量,工作模式,Nginx的PID
路径,日志路径等。
user nginx nginx; # 这个地方执行了worker进程的用户,master的启动用户永远是root,是不能指定的,因为master默认监听的端口是80,低于1023的,必须是特权用户才能使用,worker的用户是可以修改的
worker_processes 1; #启动工作进程数数量,一般CPU的核心数,每次查后在修改太麻烦,直接设置成auto即可。修改完记得reload
events { #events设置块,主要影响nginx服务器与用户的是网络连接,比如是否允许同时接受多个网络连接,使用哪种事件驱动模型处理请求,每个工作进程可以同时支持的最大连接数,是否开启对多工作进程下的网络连接进行序列化等。
worker_connections 1024; #设置单个nginx worker工作进程可以接受的最大并发,作为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;
sendfile on; #作为web服务器的时候打开sendfile加快静态文件传输,指定是否使用
sendfile系统调用来传输文件,sendfile系统调用在两个文件描述符之间直接传递数据(完全在内核中操
作),从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,操作效率很高,被称之为零拷贝,硬盘 >>
kernel buffer (快速拷贝到kernelsocket buffer) >>协议栈。
keepalive_timeout 65; #长连接超时时间,单位是秒
server { #设置一个虚拟机主机,可以包含自己的全局快,同时也可以包含多个location模块。比如
本虚拟机监听的端口、本虚拟机的名称和IP配置,多个server 可以使用一个端口,比如都使用80端口提供
web服务
listen 80; #配置server监听的端口
server_name localhost; #本server的名称,当访问此名称的时候nginx会调用当前
serevr内部的配置进程匹配。
location / { #location其实是server的一个指令,为nginx服务器提供比较多而且灵活的
指令,都是在location中体现的,主要是基于nginx接受到的请求字符串,对用户请求的URL进行匹配,并
对特定的指令进行处理,包括地址重定向、数据缓存和应答控制等功能都是在这部分实现,另外很多第三方模
块的配置也是在location模块中配置。
root html; #相当于默认页面的目录名称,默认是安装目录的相对路径,可以使用绝对
路径配置。
index index.html index.htm; #默认的页面文件名称
}
error_page 500 502 503 504 /50x.html; #错误页面的文件名称
location = /50x.html { #location处理对应的不同错误码的页面定义到/50x.html,这
个跟对应其server中定义的目录下。
root html; #定义默认页面所在的目录
}
}
#和邮件相关的配置
#mail {
# ...
# } mail 协议相关配置段
#tcp代理配置,1.9版本以上支持
#stream {
# ...
# } stream 服务器相关配置段
#导入其他路径的配置文件
#include /apps/nginx/conf.d/*.conf
}
2.2、全局配置
Main 全局配置段常见的配置指令分类
- 正常运行必备的配置
- 优化性能相关的配置
- 用于调试及定位问题相关的配置
- 事件驱动相关的配置
全局配置说明:
bash
user nginx nginx; #启动Nginx工作进程的用户和组
worker_processes [number | auto]; #启动Nginx工作进程的数量,一般设为和CPU核心数相同
worker_cpu_affinity 00000001 00000010 00000100 00001000; #将Nginx工作进程绑定到指定
的CPU核心,默认Nginx是不进行进程绑定的,绑定并不是意味着当前nginx进程独占以一核心CPU,但是可
以保证此进程不会运行在其他核心上,这就极大减少了nginx的工作进程在不同的cpu核心上的来回跳转,减
少了CPU对进程的资源分配与回收以及内存管理等,因此可以有效的提升nginx服务器的性能。
CPU MASK: 00000001:0号CPU
00000010:1号CPU
10000000:7号CPU
#示例:
worker_cpu_affinity 0001 0010 0100 1000;第0号---第3号CPU
worker_cpu_affinity 0101 1010;
#示例
worker_processes 4;
worker_cpu_affinity 00000010 00001000 00100000 10000000;
[root@centos8 ~]# ps axo pid,cmd,psr | grep nginx
31093 nginx: master process /apps 1
34474 nginx: worker process 1
34475 nginx: worker process 3
34476 nginx: worker process 5
34477 nginx: worker process 7
35751 grep nginx
# 如果CPU是16颗,都需要绑定的话,可以这样写:0000000000000001,0000000000000010
#错误日志记录配置,语法:error_log file [debug | info | notice | warn | error |
crit | alert | emerg]
#error_log logs/error.log;
#error_log logs/error.log notice;
error_log /apps/nginx/logs/error.log error;
#pid文件保存路径,上文中我们已经将目录修改为了:/apps/nginx/run/nginx.pid;了
pid /apps/nginx/logs/nginx.pid;
worker_priority 0; #工作进程优先级,-20~20(19)
worker_rlimit_nofile 65536; #**所有worker进程能打开的文件数量上限**,包括:Nginx的所有连接(例
如与代理服务器的连接等),而不仅仅是与客户端的连接,另一个考虑因素是实际的并发连接数不能超过系统
级别的最大打开文件数的限制.最好与ulimit -n 或者limits.conf的值保持一致,
#修改pam限制,跳转到最后,在最后添加这两行
[root@centos8 ~]#vim /etc/security/limits.conf
* soft nofile 1000000
* hard nofile 1000000
# 修改完成后重启系统reboot,重启后查看ulimit -n或者ulimit -a
root@109:~$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 15064
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1000000 # 已不再是1024了
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 15064
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
root@109:~$ ulimit -n
1000000
# 验证进程优先级
watch -n1 'ps -axo pid,cmd,nice | grep nginx'
# 前台运行nginx服务,用于测试、docker等环境
daemon off;
master_process off|on; #是否开启Nginx的master-worker工作模式,仅用于开发调试场景,默认为
on
events {
worker_connections 65536; #设置单个工作进程的最大并发连接数
use epoll; #使用epoll事件驱动,默认使用的是epoll,如果不更该事件驱动,这个地方可以不写,Nginx支持众多的事件驱动,比如:select、poll、epoll,只能设置在events模块中设置。
accept_mutex on; #on为同一时刻一个请求轮流由work进程处理,而防止被同时唤醒所有worker,
避免多个睡眠进程被唤醒的设置,默认为off,新请求会唤醒所有worker进程,此过程也称为"惊群",因此
nginx刚安装完以后要进行适当的优化。建议设置为on
multi_accept on; #ON时Nginx服务器的每个工作进程可以同时接受多个新的网络连接,此指令默
认为off,即默认为一个工作进程只能一次接受一个新的网络连接,打开后几个同时接受多个。建议设置为on
}
范例: 实现 nginx 的高并发配置
bash
# 临时调整下ulimit值,永久调整需要修改/etc/security/limits.conf,可参考上边,上文内容有修改过
[root@centos7 ~]#ulimit -n 102400
# 以下命令用于进行 HTTP 压力测试,while true是无限循环的开始,该命令将一直循环执行直到被手动中断。-c指定并发连接数为 5000,即同时向目标地址发起 5000 个连接,指定总请求数为 10000,即每个连接将发送 10000 个请求。
[root@centos7 ~]#while true;do ab -c 5000 -n 10000 http://10.0.0.8/;sleep
0.5;done
#默认配置不支持高并发,会出现以下错误日志
[root@centos8 conf]#tail /apps/nginx/logs/error.log
2020/09/24 21:19:33 [crit] 41006#0: *1105860 open() "/apps/nginx/html/50x.html"
failed (24: Too many open files), client: 10.0.0.7, server: localhost, request:
"GET / HTTP/1.0", host: "10.0.0.8"
2020/09/24 21:19:33 [crit] 41006#0: accept4() failed (24: Too many open files)
2020/09/24 21:19:33 [crit] 41006#0: *1114177 open()
"/apps/nginx/html/index.html" failed (24: Too many open files), client:
10.0.0.7, server: localhost, request: "GET / HTTP/1.0", host: "10.0.0.8"
2.3、http配置块
http 协议相关的配置结构
bash
http {
...
... #各server的公共配置
server { #每个server用于定义一个虚拟主机,第一个server为默认虚拟服务器
...
}
server {
...
server_name #虚拟主机名
root #主目录
alias #路径别名
location [OPERATOR] URL { #指定URL的特性
...
if CONDITION {
...
}
}
}
}
http 协议配置说明
bash
http {
include mime.types; #导入支持的文件类型,是相对于/apps/nginx/conf的目录
default_type application/octet-stream; #除mime.types中文件类型外,设置其它文件默
认类型,访问其它类型时会提示下载不匹配的类型文件
#日志配置部分
#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;
#tcp_nopush on; #在开启了sendfile的情况下,合并请求后统一发送给客户端。
#tcp_nodelay off; #在开启了keepalived模式下的连接是否启用TCP_NODELAY选项,当为
off时,延迟0.2s发送,默认On时,不延迟发送,立即发送用户响应报文。
#keepalive_timeout 0;
keepalive_timeout 65 65; #设置会话保持时间,第二个值为响应首部:keepAlived:timeout=65,可以和第一个值不同
#gzip on; #开启文件压缩
server {
listen 80; #设置监听地址和端口
server_name localhost; #设置server name,可以以空格隔开写多个并支持正则表达
式,如:*.magedu.com www.magedu.* ~^www\d+\.magedu\.com$ default_server
#charset koi8-r; #设置编码格式,默认是俄语格式,建议改为utf-8
#access_log logs/host.access.log main;
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 {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ { #以http的方式转发php请求到指定web服务器
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ { #以fastcgi的方式转发php请求到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 { #拒绝web形式访问指定文件,如很多的网站都是通过.htaccess文件
来改变自己的重定向等功能。
# deny all;
#}
location ~ /passwd.html {
deny all;
}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server { #自定义虚拟server
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm; #指定默认网页文件,此指令由
ngx_http_index_module模块提供
# }
#}
# HTTPS server
#
#server { #https服务器配置
# 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;
# }
#}
2.3.1、mime
bash
# 在响应报文中将指定的文件扩展名映射至MIME对应的类型
include /etc/nginx/mime.types;
default_type application/octet-stream;#除mime.types中的类型外,指定其它文件的默
认MIME类型,浏览器一般会提示下载
types {
text/html html;
image/gif gif;
image/jpeg jpg;
}
# MIME参考文档:
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_Types
范例: 识别php文件为text/html
bash
[root@109 ~]#cat /apps/nginx/html/test.php
<?php
phpinfo();
?>
访问发现直接下载了test.php文件
通过106主机访问109节点nginx
bash
[root@106 ~]#curl 192.168.31.109/test.php -I
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Tue, 09 Apr 2024 02:52:15 GMT
Content-Type: application/octet-stream
Content-Length: 20
Last-Modified: Tue, 09 Apr 2024 02:44:48 GMT
Connection: keep-alive
ETag: "6614aba0-14"
Accept-Ranges: bytes
root@109:~$ vim /apps/nginx/conf/nginx.conf
http {
include mime.types;
#default_type application/octet-stream;
default_type test/html; # 修改成test/html
root@109:~$ nginx -s reload
# 从106节点重新查看
[root@106 ~]#curl 192.168.31.109/test.php -I
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Tue, 09 Apr 2024 03:01:00 GMT
**Content-Type: text/html # 已经变成变成了text了**
Content-Length: 20
Last-Modified: Tue, 09 Apr 2024 02:44:48 GMT
Connection: keep-alive
ETag: "6614aba0-14"
Accept-Ranges: bytes
查看所有的mime类型
bash
cat /apps/nginx/conf/mime.tpyes
types {
text/html html htm shtml;
text/css css;
text/xml xml;
image/gif gif;
image/jpeg jpeg jpg;
application/javascript js;
application/atom+xml atom;
application/rss+xml rss;
text/mathml mml;
text/plain txt;
text/vnd.sun.j2me.app-descriptor jad;
text/vnd.wap.wml wml;
text/x-component htc;
image/avif avif;
image/png png;
image/svg+xml svg svgz;
image/tiff tif tiff;
......
2.3.2、指定响应报文server首部
bash
# 是否在响应报文中的Content-Type显示指定的字符集,默认off不显示
charset charset | off;
# 示例
charset utf-8;
# 是否在响应报文的Server首部显示nginx版本
server_tokens on | off | build | string;
显示utf-8字符集
bash
# 添加字符集显示,默认是不显示的
root@109:~$ vim /apps/nginx/conf/nginx.conf
http {
include mime.types;
#default_type application/octet-stream;
default_type text/plain;
charset utf-8; # 添加此行
# 从106访问可以看到字符集是utf-8了
[root@106 ~]#curl 192.168.31.109/test.php -I
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Tue, 09 Apr 2024 03:16:02 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 20
Last-Modified: Tue, 09 Apr 2024 02:44:48 GMT
Connection: keep-alive
ETag: "6614aba0-14"
Accept-Ranges: bytes
隐藏版本号
bash
# 默认是显示版本号的,显示版本号是很不安全的,如下
[root@106 ~]#curl 192.168.31.109/test.php -I
HTTP/1.1 200 OK
Server: nginx/1.24.0 # nginx版本号为1.24.0
Date: Tue, 09 Apr 2024 03:16:02 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 20
Last-Modified: Tue, 09 Apr 2024 02:44:48 GMT
Connection: keep-alive
ETag: "6614aba0-14"
Accept-Ranges: bytes
# 设置隐匿版本号
root@109:~$ vim /apps/nginx/conf/nginx.conf
http {
include mime.types;
#default_type application/octet-stream;
default_type text/plain;
charset utf-8;
server_tokens off; # 添加此行
注意:隐藏后版本还是会显示服务是nginx服务的。
修改版本号
bash
# 停止服务
root@109:~$ systemctl stop nginx
# 操作前备份
root@109:~$ cp /apps/nginx/sbin/nginx /root/
# 需要修改两个地方,第一个需要修改/root/nginx-1.24.0/src/core/nginx.h的第13、14两行中的版本号和服务名称,nginx-1.24.0是下载源码包解压后的目录
vim /root/nginx-1.24.0/src/core/nginx.h
...
13 #define NGINX_VERSION "1.24.0"
14 #define NGINX_VER "nginx/" NGINX_VERSION
...
# 第二处修改/root/nginx-1.24.0/src/http/ngx_http_header_filter_module.c,修改第49行的"Server: nginx"改为自己想要显示的名称,如:gxy,只修改49行,其他行不用修改
vim /root/nginx-1.24.0/src/http/ngx_http_header_filter_module.c
49 static u_char ngx_http_server_string[] = "Server: nginx" CRLF;
50 static u_char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
51 static u_char ngx_http_server_build_string[] = "Server: " NGINX_VER_BUILD CRLF;
# 修改后需要重新编译,商业版在特定的版本是可以进行修改的,不需要编译,开源版本必须重新编译才行
# 查看编译选项
root@109:~$ cd nginx-1.24.0
root@109:~/nginx-1.24.0$ nginx -V
nginx version: nginx/1.24.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --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@109:~/nginx-1.24.0$ ./configure --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --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
# make
root@109:~/nginx-1.24.0$ make && make install
# 启动nginx
root@109:~$ systemctl start nginx
# 通过106访问验证
[root@106 ~]#curl 192.168.31.109/test.php -I
HTTP/1.1 200 OK
gxy # 发现已经变了
Date: Tue, 09 Apr 2024 04:03:54 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 20
Last-Modified: Tue, 09 Apr 2024 02:44:48 GMT
Connection: keep-alive
ETag: "6614aba0-14"
Accept-Ranges: bytes
nginx默认自带的web页面
bash
# nginx默认的页面html根目录是相对nginx的,nginx目录下有html目录
root@109:~$ vim /apps/nginx/conf/nginx.conf
# location / {
root html;
index index.html index.htm;
}
# 访问的时候只需要输入IP地址就可以访问默认页面,默认页面存放在/apps/nginx/html下
2.4、核心配置示例
基于不同的IP、不同的端口以及不用得域名实现不同的虚拟主机,依赖于核心模块
ngx_http_core_module实现。
2.4.1、新建一个PC web站点(109节点)
bash
# 创建html目录
root@109:~$ mkdir -p /data/nginx/html/{mobile,pc}
root@109:~$ echo pc-web > /data/nginx/html/mobile/index.html
root@109:~$ echo phone-web > /data/nginx/html/pc/index.html
# 创建vhosts目录
root@109:~$ cd /apps/nginx/conf/conf.d/
root@109:~$ mkdir vhosts
# 创建配置文件
root@109:~$ cd /apps/nginx/conf/conf.d/vhosts
root@109:/apps/nginx/conf/conf.d/vhosts$ vim mobile.conf
server {
listen 80;
server_name www.gxy.mobile.com;
root /data/nginx/html/mobile;
}
root@109:/apps/nginx/conf/conf.d/vhosts$ vim pc.conf
server {
listen 80;
server_name www.gxy.pc.com;
root /data/nginx/html/pc;
}
# 或者这样写也是可以的
server {
listen 80;
server_name www.gxy.pc.com;
location / {
root /data/nginx/html/mobile;
}
}
# 添加vhosts目录到nginx.conf中,在最后一个大括号前添加一行
root@109:/apps/nginx/conf$ vim nginx.conf
...
# }
#}
include /apps/nginx/conf/conf.d/*.conf;
include /apps/nginx/conf/conf.d/vhosts/*.conf; # 添加此行
}
# 检查nginx配置文件语法是否有误
root@109:/apps/nginx/conf$ nginx -t
# 重新加载nginx
root@109:/apps/nginx/conf$ nginx -s reload
访问验证(106节点)
bash
# 修改/etc/hosts文件,在最后添加一行
[root@106 ~]# vim /etc/hosts
192.168.31.109 www.gxy.mobile.com www.gxy.pc.com
# 访问域名进行验证
[root@106 ~]# curl www.gxy.mobile.com
phone-web
[root@106 ~]# curl www.gxy.pc.com
pc-web
2.4.2、root与alias
上文vhosts中pc.conf的写法也可以改成如下写法:
bash
# root可以写在location模块内
root@109:/apps/nginx/conf/conf.d/vhosts$ cat pc.conf
server {
listen 80;
server_name www.gxy.pc.com;
location / {
root /data/nginx/html/pc;
}
}
# 在106节点验证
[root@106 ~]# curl www.gxy.pc.com
pc-web
root:指定web的家目录,在定义location的时候,文件的绝对路径等于 root+location
bash
# server下有两个location模块,一个根,一个about
root@109:/apps/nginx/conf/conf.d/vhosts$ cat pc.conf
server {
listen 80;
server_name www.gxy.pc.com;
location / {
root /data/nginx/html/pc;
}
location /about { # 必须要在html目录中创建一个about目录才可以访问,否则报错。
root /opt/nginx/html; # 这个路径**不用**修改成/opt/nginx/html/about,当访问about的时候是把/opt/nginx/html目录作为根目录
}
}
# 上文中第二个location模块地址改成了/opt/nginx/html,将该目录建起来
root@109:~$ mkdir -p /opt/nginx/html
root@109:~$ echo opt-web > /opt/nginx/html/index.html
# 重载nginx
root@109:~$ nginx -s reload
# 106访问测试,发现无法访问
[root@106 ~]#curl www.gxy.pc.com/about
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
# 原因是因为访问about是访问不是/opt/nginx/html下的index.html文件,而是访问的/opt/nginx/html/目录下about目录下的index.html,对其进行改造
root@109:~$ cd /opt/nginx/html
root@109:/opt/nginx/html$ mkdir about
root@109:/opt/nginx/html$ mv index.html about/
# 重载nginx
root@109:~$ nginx -s reload
# 106仍然访问不到,301,重定向了
[root@192 ~]#curl www.gxy.pc.com/about
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>
# 注意:路径一定要写对,about后边一定要加 "/",否则访问不到
[root@106 ~]#curl www.gxy.pc.com/about/
opt-web
# 如果about后不加"/",也可以在访问的时候加上 "-L" 参数
[root@106 ~]#curl -L www.gxy.pc.com/about/
opt-web
# 如果加参数它会把你访问重定向到about内
[root@192 ~]#curl www.gxy.pc.com/about -I
HTTP/1.1 301 Moved Permanently
gxy
Date: Wed, 10 Apr 2024 06:21:46 GMT
Content-Type: text/html
Content-Length: 162
Location: http://www.gxy.pc.com/about/
Connection: keep-alive
注意:第二个location后跟的路径是/opt/nginx/html,为什么不用改成/opt/nginx/html/about呢?因为这个路径是拼接的,是root + about拼接的。
alias:定义路径别名,会把访问的路径重新定义到其指定的路径,文档映射的另一种机制;仅能用于
location上下文,此指令使用较少
上个例子中about是root+about,如果将root换成alias呢?
bash
# 将root换成alias
root@109:/apps/nginx/conf/conf.d/vhosts$ cat pc.conf
server {
listen 80;
server_name www.gxy.pc.com;
location / {
root /data/nginx/html/pc;
}
location /about {
alias /opt/nginx/html; # 将root换成alias,访问的是html下的index.html,一一映射
}
}
# 在/opt/nginx/html下创建index.html页面
root@109:/opt/nginx/html$ echo /opt/nginx/html >index.html
# 在106节点测试发现访问about访问的是/opt/nginx/html下的index.html,而非about下的index.html
[root@192 ~]# curl www.gxy.pc.com/about/
/opt/nginx/html
2.4.3、location的详细使用
在一个server中location配置段可存在多个,用于实现从uri到文件系统的路径映射;ngnix会根据用户请求的URI来检查定义的所有location,按一定的优化级找出一个最佳匹配,而后应用其配置在没有使用正则表达式的时候,nginx会先在server中的多个location选取匹配度最高的一个uri,uri是用户请求的字符串,即域名后面的web文件路径,然后使用该location模块中的正则url和字符串,如果
匹配成功就结束搜索,并使用此location处理此请求。
location 官方帮助:
bash
http://nginx.org/en/docs/http/ngx_http_core_module.html#location
语法规则
bash
#语法规则:
location [ = | ~ | ~* | ^~ ] uri { ... }
= #用于标准uri前,需要请求字串与uri精确匹配,大小敏感,如果匹配成功就停止向下匹配并立即处理请
求
^~ #用于标准uri前,表示包含正则表达式,并且匹配以指定的正则表达式开头,对URI的最左边部分做匹配
检查,不区分字符大小写
~ #用于标准uri前,表示包含正则表达式,并且区分大小写
~* #用于标准uri前,表示包含正则表达式,并且不区分大写
不带符号 #匹配起始于此uri的所有的uri
\ #用于标准uri前,表示包含正则表达式并且转义字符。可以将 . * ?等转义为普通符号
#匹配优先级从高到低:
**=, ^~, ~/~*, 不带符号**
官方范例
bash
location = / {
[ configuration A ]
}
location / {
[ configuration B ]
}
location /documents/ {
[ configuration C ]
}
location ^~ /images/ {
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
[ configuration E ]
}
The "/" request will match configuration A(?), the "/index.html" request will
match configuration B,
the "/documents/document.html" request will match configuration C, the
"/images/1.gif" request will match configuration D, and the "/documents/1.jpg"
request will match configuration E.
例1:
bash
# 例如访问百度
https://www.baidu.com/
# 上边的域名是以根"/"结尾的,根据官方范例,A、B都匹配,那谁去处理呢,按照官方优先级顺序A "= /"的优先级高,因此A生效的,A是严格匹配,B是以"/"开头的,但优先级不如A的高,因此A生效了
例2:
bash
# 访问
https://www.baidu.com/index.html
# 先查看匹配项,在看谁生效,A不匹配,因为A是精确匹配,必须是以"/"结尾的才匹配,所以A不匹配,B是以"/"开头的,是匹配的, C、D、E均不匹配,所有B匹配了
例3:
bash
# 访问
https://www.baidu.com/documents/index.html
# A不匹配,B匹配,C匹配,因C匹配的更精确,所以C生效
例4:
bash
# 访问
https://www.baidu.com/images/test.gif
# B、D、E都匹配,按照"=, ^~, ~/~*, 不带符号"优先级,D是最高的,因此D生效,E的优先级不如D高,B的优先级是最低的,因为B就不带符号,优先级最低
例5:
bash
# 访问
https://www.baidu.com/documents/test.gif
# A不匹配,B、E匹配,按照例4中的优先级,E生效
2.4.3.1、配案例-精确匹配
在server部分使用location配置一个web界面,例如:当访问nginx 服务器的/logo.jpg的时候要显示指
定html文件的内容
精确匹配一般用于匹配组织的logo等相对固定的URL,匹配优先级最高
范例: 精确匹配 logo
bash
root@109:/apps/nginx/conf/conf.d/vhosts$ cat pc.conf
server {
listen 80;
server_name www.gxy.pc.com;
location / {
root /data/nginx/html/pc;
}
location /about {
alias /opt/nginx/html;
}
# 添加下面location块,这里边logo用了精确匹配
location = /logo.png {
root /data/nginx/html;
}
}
# 创建index.html文件
root@109:/data/nginx/html$ echo /data/nginx/html > index.html
# 下载jd logo
root@109:/data/nginx/html$ wget https://img10.360buyimg.com/img/jfs/t1/192028/25/33459/5661/63fc2af2F1f6ae1b6/d0e4fdc2f126cbf5.png
root@109:/data/nginx/html$ mv d0e4fdc2f126cbf5.png logo.png
# 修改windows hosts文件,添加下边一行
192.168.31.109 www.gxy.pc.com
# 通过浏览器访问,浏览器输入http://www.gxy.pc.com/logo.png
可以正常访问到jd logo
:
#用于标准uri前,表示包含正则表达式,并且区分大小写
bash
root@109:/apps/nginx/conf/conf.d/vhosts$ vim pc.conf
server {
listen 80;
server_name www.gxy.pc.com;
location / {
root /data/nginx/html/pc;
}
# 匹配字母L开头的jpg图片,后面?表示L后面零次或一个字符,如:图片名为Lg.jpg
location ~ /L.?\.jpg {
index index.html;
root /data/nginx/html/images;
}
}
创建images目录
bash
mkdir -p /data/nginx/html/images
下载测试图片
bash
# 切换到图片的存储路径
root@109:~$ cd /data/nginx/html/images
# 下载图片
root@109:/data/nginx/html/images$ wget https://imgcps.jd.com/img-cubic/creative_server_cia_jdcloud/v2/2000366/26357985294/FocusFullshop/CkRqZnMvdDEvMTkxMDg0LzM4LzQ0Mjk4LzE1MjMyNi82NjFkODIzMkY3NGMxZWY4ZS84MTM5MGVkMDdhMTExNDA5LnBuZxIJMy10eV8wXzU0MAI47ot6QhMKD-WPo-WtkOeqlueZvemFkhABQhAKDOebm-aDoOeLrOS6qxACQhAKDOeri-WNs-aKoui0rRAGQgoKBuS8mOi0qBAHWI7gu5hi/cr/s/q.jpg
# 重名了
root@109:/data/nginx/html/images$ mv q.jpg Lg.jpg
重载nginx
bash
root@109:/apps/nginx/conf/conf.d/vhosts$ nginx -s reload
测试访问
浏览器访问:http://www.gxy.pc.com/Lg.jpg
访问成功!
浏览器访问:http://www.gxy.pc.com/lg.jpg,访问不到,因为:\~ 表示包含正则表达式,并且区分大小写,是区分大小写的,所以小写的"l"是访问不到的。
浏览器访问:http://www.gxy.pc.com/Lo.jpg,访问不到,因为:L后边的字符必须和文件中的一致。
浏览器访问:http://www.gxy.pc.com/Lgo.jpg,访问不到,因为:?可以是0个和1个,本例中是三个,所以不匹配。
2.4.3.3、匹配案例-不区分大小写
~* #用于标准uri前,表示包含正则表达式,并且不区分大写。
~* 用来对用户请求的uri做模糊匹配,uri中无论都是大写、都是小写或者大小写混合,此模式也都会匹配,通常使用此模式匹配用户request中的静态资源并继续做下一步操作,此方式使用较多。
注意: 此方式中,对于Linux文件系统上的文件仍然是区分大小写的,如果磁盘文件不存在,仍会提示404
bash
# 将上述例子中的 ~ 改成 ~* 这样就不在区分大小写了
root@109:/apps/nginx/conf/conf.d/vhosts$ vim pc.conf
server {
listen 80;
server_name www.gxy.pc.com;
location / {
root /data/nginx/html/pc;
}
# ~*不区分大小写,如:图片名为Lg.jpg,当访问Lg.jpg和lg.jpg均能正常访问到图片
location ~* /L.?\.jpg {
index index.html;
root /data/nginx/html/images;
}
}
nginx重载后访问测试
浏览器输入:http://www.gxy.pc.com/lg.jpg,"l" 是小写
对于不区分大小写的location,则可以访问任意大小写结尾的图片文件,如区分大小写则只能访问Lg.jpg此类文件,不区分大小写则可以访问lg.jpg以外的资源比如lG.JPG、lG.jPG这样的混合名称文件,但是要求nginx服务器的资源目录有相应的文件,比如有Lg.JPG有lG.jPG。
**注意:**linux文件默认是区分大小的。
2.4.3.4、匹配案例-URI开始
bash
# ^~表示以什么什么开头,这里表示以images开头
location ^~ /images {
root /data/nginx/;
index index.html;
}
location /api {
alias /data/nginx/api;
index index.html;
}
#重启Nginx并访问测试,实现效果是访问/images和/app返回不同的结果
[root@centos8 ~]# curl http://www.magedu.org/images/
images
[root@centos8 ~]# curl http://www.magedu.org/api/
api web
2.4.3.4、匹配案例-文件名后缀
bash
# 修改配置文件,将精确匹配注释掉
root@109:/apps/nginx/conf/conf.d/vhosts$ vim pc.conf
server {
listen 80;
server_name www.gxy.pc.com;
location / {
root /data/nginx/html/pc;
}
# location = /csdn.png {
# index index.html;
# root /data/nginx/html/images;
# }
location ~* \.(gif|jpg|jpeg|bmp|png|tiff|tif|ico|wmf|js|css)$ {
root /data/nginx/static;
index index.html;
}
}
创建/data/nginx/static目录
bash
# 创建static目录
root@109:/apps/nginx$ mkdir -p /data/nginx/statics
# 上传测试图片
root@109:/data/nginx/static$ ll
total 8
-rw-r--r--. 1 root root 7932 Nov 24 2020 csdn.png
重载nginx进行测试
2.4.3.5、匹配案例-文件名后缀
bash
# 优先级最高
location = /1.jpg {
root /data/nginx/static1;
index index.html;
}
location /1.jpg { # 优先级最后
root /data/nginx/static2;
index index.html;
}
location ~* \.(gif|jpg|jpeg|bmp|png|tiff|tif|ico|wmf|js)$ { # 优先级第二
root /data/nginx/static3;
index index.html;
}
root@109: mkdir -p /data/nginx/static{1,2,3}
#上传图片到 /data/nginx/static{1,2,3} 并重启nginx访问测试
#匹配优先级:=, ^~, ~/~*,/
location优先级:(location =) > (location ^~ 路径) > (location ~,~* 正则顺序) >
(location 完整路径) > (location 部分起始路径) > (/)
3、nginx四层访问控制
访问控制基于模块ngx_http_access_module实现,可以通过匹配客户端源IP地址进行限制。
注意: 如果能在防火墙设备控制,最好就不要在nginx上配置,可以更好的节约资源。
官方帮助:http://nginx.org/en/docs/http/ngx_http_access_module.html
设置IP限制(黑白名单)
bash
root@109:/apps/nginx/conf/conf.d$ vim pc.conf
server {
listen 80;
server_name www.gxy.pc.com;
deny 192.168.31.106; # 限制106访问
allow 192.168.31.107; # 允许107访问
allow 192.168.31.0/24; # 允许31段的访问,范围是从小到大
location / {
root /data/nginx/html/pc;
}
}
# 重载nginx
nginx -s reload
访问测试
bash
# 106限制之前访问
[root@106-server ~]# curl www.gxy.pc.com
pc web
# 107限制之后访问
[root@106-server ~]# curl www.gxy.pc.com
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>
# 107限制之前访问
[root@107 ~]# curl www.gxy.pc.com
pc web
# 107限制之后访问
[root@107 ~]# curl www.gxy.pc.com
pc web
如果将上边三行调换顺序,结果会不一样
bash
root@109:/apps/nginx/conf/conf.d$ cat pc.conf
server {
listen 80;
server_name www.gxy.pc.com;
allow 192.168.31.0/24; # 将范围大的放在最前边,范围小的放到最后边
deny 192.168.31.106;
allow 192.168.31.107;
location / {
root /data/nginx/html/pc;
}
}
# 重载nginx
nginx -s reload
访问测试
bash
# 106是可以正常访问的
[root@106 ~]# curl www.gxy.pc.com
pc web
# 107可以正常访问
[root@107 ~]# curl www.gxy.pc.com
pc web
解释为什么106是可以正常访问:在配置中106已经是设置的deny,为什么还可以正常访问,因为allow 31段的在deny 106前边,31段的范围更大,如果范围大的在前,后边的小范围的是不生效的。
4、nginx账务认证功能
由 ngx_http_auth_basic_module 模块提供此功能
官方帮助:
bash
http://nginx.org/en/docs/http/ngx_http_auth_basic_module.html
范例:
bash
root@109:~$ yum -y install httpd-tools
# 创建用户
#-b 非交互式方式提交密码
root@109:~$ htpasswd -cb /apps/nginx/conf/conf.d/.htpasswd user1 123456
root@109:~$ htpasswd -b /apps/nginx/conf/conf.d/.htpasswd user2 123456
root@109:~$ cd /apps/nginx/conf/conf.d
root@109:/apps/nginx/conf/conf.d$ ll -a
total 16
drwxr-xr-x. 3 root root 71 May 6 20:09 .
drwxr-xr-x. 3 nginx nginx 4096 Apr 9 16:16 ..
-rw-r--r--. 1 root root 88 May 6 16:10 .htpasswd
-rw-r--r--. 1 root root 840 May 6 20:09 pc.conf
-rw-r--r--. 1 root root 266 May 6 15:04 pc.conf.bak
drwxr-xr-x. 2 root root 40 Apr 23 22:02 vhosts
# 查看生成的用户及密码
root@109:/apps/nginx/conf/conf.d$ cat .htpasswd
user1:$apr1$RfZd2ZDN$uDLzDgftPso6uxq5Z67Pg0
user2:$apr1$F1Us34yb$GUnNNa9mmb3Urg3NRO9X40
修改配置文件
bash
root@109:/apps/nginx/conf/conf.d$ vim pc.conf
server {
listen 80;
server_name www.gxy.pc.com;
# root /data/nginx/html/pc;
location /admin {
auth_basic "login password"; #添加这两行
auth_basic_user_file /apps/nginx/conf/conf.d/.htpasswd; #添加这两行
}
}
重载nginx后访问测试
bash
# 106节点访问报错
[root@106 ~]# curl http://www.gxy.pc.com/admin/
<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx</center>
</body>
</html>
# 加上用户名密码再次访问,404了,说明登录是成功的,因为上边没有写admin对应的路径
[root@106 ~]# curl http://user1:123456@www.gxy.pc.com/admin/
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
# 再次访问查看日志,发现它去/apps/nginx/html/admin/找了,需要把sever下的root /data/nginx/html/pc;路径写上,从日志看它去默认的网站去找了
root@109:/apps/nginx/logs$ tail -f error.log
2024/05/06 22:29:15 [error] 23759#0: *46 "/apps/nginx/html/admin/index.html" is not found (2: No such file or directory), client: 192.168.31.106, server: www.gxy.pc.com, request: "GET /admin/ HTTP/1.1", host: "www.gxy.pc.com"
# 查看该文件不存在
root@109:/apps/nginx/conf/conf.d$ ll /apps/nginx/html/admin/index.html
ls: cannot access /apps/nginx/html/admin/index.html: No such file or directory
重新修改配置文件
bash
# 将注释行取消掉
root@109:/apps/nginx/conf/conf.d$ vim pc.conf
server {
listen 80;
server_name www.gxy.pc.com;
root /data/nginx/html/pc; # 将该行的注释去掉
location /admin {
auth_basic "login password"; #添加这两行
auth_basic_user_file /apps/nginx/conf/conf.d/.htpasswd; #添加这两行
}
}
重载后再次访问查看日志
bash
# 发现它到我们设置的路径(/data/nginx/html/pc)去找文件了
root@109:/apps/nginx/logs$ tail -f error.log
2024/05/06 22:43:14 [error] 28626#0: *51 "/data/nginx/html/pc/admin/index.html" is not found (2: No such file or directory), client: 192.168.31.106, server: www.gxy.pc.com, request: "GET /admin/ HTTP/1.1", host: "www.gxy.pc.com"
创建对应的目录及文件
bash
# 创建admin目录
root@109: mkdir /data/nginx/html/pc/admin
root@109: echo /data/nginx/html/pc/admin >/data/nginx/html/pc/admin/index.html
再次访问正常
bash
[root@106 ~]# curl http://user1:123456@www.gxy.pc.com/admin/
/data/nginx/html/pc/admin
# 也可以通过-u参数访问
[root@106 ~]# curl -u user2:123456 http://www.gxy.pc.com/admin/
/data/nginx/html/pc/admin
通过浏览器访问
输入账号密码后访问
5、自定义错误页面
定义错误页,以指定的响应状态码进行响应, 可用位置:http, server, location, if in location
bash
error_page code ... [=[response]] uri;
范例:
bash
vim /apps/nginx/conf/conf.d/pc.conf
server {
listen 80;
server_name www.gxy.pc.com;
root /data/nginx/html/pc;
# 定义错误页面
error_page 404 /40x.html;
location /40x.html {
root /data/html/error;
}
}
# 创建错误目录
root@109:~$ mkdir -pv /data/html/error
mkdir: created directory '/data/html'
mkdir: created directory '/data/html/error'
# 新建错误文件
root@109:~$ wget https://h5static.m.jd.com/returncode/error.html -P /data/html/error/
root@109:/data/html/error$ mv error.html 40x.html
# 重载nginx
nginx -s reload
浏览器访问一个不存在的页面,如:http://www.gxy.pc.com/sdfbsdf
范例: 浏览器"截胡"
使用360浏览器访问基于IP的不存在页面时会自动用广告页面代替错误页面,本来是自己设定的错误页面,结果在用360浏览器访问的时候自己的错误页面没展示出来,而是被360的"截胡"后用自己的错误页面替代掉了,只真流氓,自己实测没复现出来(哈哈)
该图来自于马哥教育
解决办法:
bash
#404转为302,302是临时重定向,这里将404重定向到了302,并且转到了主页面,当访问错误状态吗直接跳转主页面
error_page 404 =302 /index.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
实际上好多网站在访问不存在的页面的时候都设置重定向,如京东:
bash
[root@106 ~]# curl www.jd.com/xxx/xx.html -I
HTTP/1.1 302 Moved Temporarily
Server: nginx
Date: Sun, 12 May 2024 09:54:35 GMT
Content-Type: text/html
Content-Length: 138
Connection: keep-alive
Location: https://www.jd.com/xxx/xx.html
Timing-Allow-Origin: *
X-Trace: 302-1715507675988-0-0-0-0-0
Strict-Transport-Security: max-age=3600
定义不同虚拟主机的日志路径
bash
# 针对pc虚机的日志定义
root@109:/apps/nginx/conf/conf.d/vhosts$ vim pc.conf
server {
listen 80;
server_name www.gxy.pc.com;
location / {
root /data/nginx/html/pc;
}
access_log /data/nginx/html/pc/log/pc_log;
error_log /data/nginx/html/pc/log/error_log;
location = /error.html {
root /data/nginx/html/pc;
}
}
# 针对mobile虚机的日志定义
root@109:/apps/nginx/conf/conf.d/vhosts$ vim mobile.conf
server {
listen 80;
server_name www.gxy.mobile.com;
root /data/nginx/html/mobile;
access_log /data/nginx/html/mobile/logs/mobile_log;
error_log /data/nginx/html/mobile/logs/error_mobile_log;
location /error.html {
root /data/nginx/html/mobile;
}
}
重载nginx后查看日志是否生成
bash
# mobile的日志已生成
root@109:~$ ll /data/nginx/html/mobile/logs/
total 0
-rw-r--r--. 1 root root 0 May 12 18:57 error_mobile_log
-rw-r--r--. 1 root root 0 May 12 18:57 mobile_log
# pc的日志已生成
root@109:~$ ll /data/nginx/html/pc/log/
total 0
-rw-r--r--. 1 root root 0 May 12 18:57 error_log
-rw-r--r--. 1 root root 0 May 12 19:04 pc_log
6、检测文件是否存在
try_files会按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如果所有文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部URI的指向。最后一个参数是回退URI且必须存在,否则会出现内部500错误。
场景: 如果访问了网站的一个不存在的页面,则会报错404,如下图:
有时候为了美观或者其他因素考虑,当访问一个不存在的页面是会让他重定向到首页。
例如:当访问一个不存在页面的时,让它访问我们指定的页面。
修改配置
bash
# 加上最后一行
root@109:/apps/nginx/conf/conf.d/vhosts$ vim mobile.conf
server {
listen 80;
server_name www.gxy.mobile.com;
root /data/nginx/html/mobile;
try_files $uri ?$uri.html $uri/index.html /about/default.html;
# 创建目录和文件
mkdir -p /data/nginx/html/mobile/about
echo default-web > default.html
重载nginx进行访问测试,访问一个不存在的页面如:http://www.gxy.mobile.com/test/test.html
发现已经重定向到了我们指定的web页面了
也可以将不存在的页面让其返回错误码,如访问不存在的页面返回489状态码
bash
# 增加红色行
root@109:/apps/nginx/conf/conf.d/vhosts$ vim mobile.conf
server {
listen 80;
server_name www.gxy.mobile.com;
root /data/nginx/html/mobile;
# try_files $uri $uri.html $uri/index.html /about/default.html;
try_files $uri $uri.html $uri/index.html =489;
access_log /data/nginx/html/mobile/logs/mobile_log;
error_log /data/nginx/html/mobile/logs/error_mobile_log;
location /error.html {
root /data/nginx/html/mobile;
}
}
# 重载nginx
root@109:/apps/nginx/conf/conf.d/vhosts$ nginx -t
root@109:/apps/nginx/conf/conf.d/vhosts$ nginx -s reload
访问测试
bash
# 106节点访问109节点,返回定义的489
[root@106 ~]# curl www.gxy.mobile.com/abc/a.html -I
HTTP/1.1 489
gxy
Date: Tue, 21 May 2024 12:06:32 GMT
Content-Length: 0
Connection: keep-alive
浏览器访问不存在的页面如:http://www.gxy.mobile.com/test/test.html,返回定义的状态吗489
7、长连接配置
bash
keepalive_timeout timeout [header_timeout]; #设定保持连接超时时长,0表示禁止长连接,默
认为75s,通常配置在http字段作为站点全局配置
keepalive_requests number; #在一次长连接上所允许请求的资源的最大数量,默认为100次,建议适
当调大,比如:500
范例:
bash
root@109:/apps/nginx/conf/conf.d/vhosts$ vim mobile.conf
server {
listen 80;
server_name www.gxy.mobile.com;
root /data/nginx/html/mobile;
keepalive_requests 3;
keepalive_timeout 65 60;
# try_files $uri $uri.html $uri/index.html /about/default.html;
try_files $uri $uri.html $uri/index.html =489;
access_log /data/nginx/html/mobile/logs/mobile_log;
error_log /data/nginx/html/mobile/logs/error_mobile_log;
location /error.html {
root /data/nginx/html/mobile;
}
}
keepalive_requests 3;
keepalive_timeout 65 60;
#开启长连接后,返回客户端的会话保持时间为60s,单次长连接累计请求达到指定次数请求或65秒就会被断
开,后面的60为发送给客户端应答报文头部中显示的超时时间设置为60s:如不设置客户端将不显示超时时
间。
# 重载nginx
nginx -t
nginx -s reload
106访问109节点
bash
# timeout已经变成了60
[root@106 ~]# curl www.gxy.mobile.com -I
HTTP/1.1 200 OK
gxy
Date: Tue, 21 May 2024 12:32:13 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 11
Last-Modified: Mon, 13 May 2024 06:06:29 GMT
Connection: keep-alive
Keep-Alive: timeout=60 # 该值已变成了60
ETag: "6641ade5-b"
Accept-Ranges: bytes
将keepalive_timeout值改为0
bash
root@109:/apps/nginx/conf/conf.d/vhosts$ vim mobile.conf
server {
listen 80;
server_name www.gxy.mobile.com;
root /data/nginx/html/mobile;
keepalive_requests 3;
**keepalive_timeout 0;**
# try_files $uri $uri.html $uri/index.html /about/default.html;
try_files $uri $uri.html $uri/index.html =489;
access_log /data/nginx/html/mobile/logs/mobile_log;
error_log /data/nginx/html/mobile/logs/error_mobile_log;
location /error.html {
root /data/nginx/html/mobile;
}
}
# 重载nginx
nginx -t
nginx -s reload
测试,106访问109
bash
# connection已变成close状态
[root@106 ~]# curl www.gxy.mobile.com -I
HTTP/1.1 200 OK
gxy
Date: Tue, 21 May 2024 12:40:55 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 11
Last-Modified: Mon, 13 May 2024 06:06:29 GMT
**Connection: close**
ETag: "6641ade5-b"
Accept-Ranges: bytes
8、作为下载服务器配置
ngx_http_autoindex_module 模块处理以斜杠字符 "/" 结尾的请求,并生成目录列表,可以做为下载服务配置使用。
相关指令:
bash
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提供
例如:当前访问192.168.31.109(默认页面)
修改配置
bash
#
[root@109 ~]# cd /data/nginx/html/mobile
[root@109 mobile]# mkdir download/{6,7,8} -pv
mkdir: created directory 'download'
mkdir: created directory 'download/6'
mkdir: created directory 'download/7'
mkdir: created directory 'download/8'
# 创建几个测试文件放在对应目录下
[root@109 mobile]# tree centos
download
├── 6
│ └── centos6
├── 7
│ └── centos7
└── 8
└── centos8
3 directories, 3 files
访问192.168.31.109/download发现无法访问
调整配置,是其作为下载目录
bash
[root@109 vhosts]# pwd
/apps/nginx/conf/conf.d/vhosts
[root@109 vhosts]# ll
total 12
-rw-r--r--. 1 root root 607 Jun 26 22:50 mobile.conf
-rw-r--r--. 1 root root 266 May 13 14:07 pc.conf
-rw-r--r--. 1 root root 266 Jun 25 16:26 zabbix.conf_bak
[root@109 vhosts]# vim mobile.conf
server {
listen 80;
server_name www.gxy.mobile.com;
root /data/nginx/html/mobile;
keepalive_requests 3;
keepalive_timeout 0;
# try_files $uri $uri.html $uri/index.html /about/default.html;
try_files $uri $uri.html $uri/index.html =489;
access_log /data/nginx/html/mobile/logs/mobile_log;
error_log /data/nginx/html/mobile/logs/error_mobile_log;
location /error.html {
root /data/nginx/html/mobile;
}
# 添加此location块
location /download {
autoindex on; # 自动索引功能
autoindex_exact_size on; # 计算文件确切大小(单位bytes),此为默认值,off只显示大小(单位kb、mb、gb)
autoindex_localtime on; # on表示用本机时间,默认是off,off是GMT时间(格林威治)
limit_rate 1024k; # 限速,默认是不限速
root /data/nginx/html/mobile;
}
}
重载nginx
bash
[root@109 mobile]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@109 mobile]# nginx -s reload
再次访问192.168.31.109/download,发现可以正常访问了
测试限速下载速度
bash
[root@109 mobile]# cd download/
[root@109 download]# ll
total 0
drwxr-xr-x. 2 root root 21 Jun 26 22:30 6
drwxr-xr-x. 2 root root 21 Jun 26 22:31 7
drwxr-xr-x. 2 root root 21 Jun 26 22:31 8
# 生成1G大小的文件
[root@109 download]# dd if=/dev/zero of=6/test.img bs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 2.85831 s, 376 MB/s
[root@109 download]# ll -h 6/
total 1.1G
-rw-r--r--. 1 root root 8 Jun 26 22:30 centos6
-rw-r--r--. 1 root root 1.0G Jun 26 23:08 test.img
通过上述配置查看限速是1M( limit_rate 1024k; ),通过下载发现速度最大为1M,限速成功。
9、其他配置
bash
keepalive_disable none | browser ...;
#对哪种浏览器禁用长连接
9.1、客户端请求方法控制
bash
limit_except method ... { ... },仅用于location
#限制客户端使用除了指定的请求方法之外的其它方法
method:GET, HEAD, POST, PUT, DELETE,MKCOL, COPY, MOVE, OPTIONS, PROPFIND,
PROPPATCH, LOCK, UNLOCK, PATCH
# 除了192.168.0.0段、10.0.0.1可以使用GET方法,其他主机全部禁用该方法访问
limit_except GET {
allow 192.168.0.0/24;
allow 10.0.0.1;
deny all;
}
重载nginx后测试
bash
# 通过本机访问报403,因为只有107节点允许,其他的都拒绝
[root@109 mobile]# curl -XOPTIONS 192.168.31.109/upload
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>
# 登录107节点访问报405,405说明网站是不允许的,但是权限是允许的,-X是提交一些方法,options就是查我支持的方法
[root@107 ~]# curl -XOPTIONS 192.168.31.109/upload
<html>
<head><title>405 Not Allowed</title></head>
<body>
<center><h1>405 Not Allowed</h1></center>
<hr><center>nginx</center>
</body>
</html>
9.2、开启异步IO
bash
aio on | off #是否启用asynchronous file I/O(AIO)功能,需要编译开启 --with-file-aio
#linux 2.6以上内核提供以下几个系统调用来支持aio:
1、SYS_io_setup:建立aio 的context
2、SYS_io_submit: 提交I/O操作请求
3、SYS_io_getevents:获取已完成的I/O事件
4、SYS_io_cancel:取消I/O操作请求
5、SYS_io_destroy:毁销aio的context
# 该参数在server下配置
这个需要在编辑nginx的时候加上--with-file-aio,否则会报错,如:
bash
# 查看nginx编译参数
[root@109 vhosts]# nginx -V
nginx version: gxy/1.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --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
开启异步IO如下
bash
[root@109 vhosts]# vim mobile.conf
1 server {
2 listen 80;
3 server_name www.gxy.mobile.com;
4 root /data/nginx/html/mobile;
5 keepalive_requests 3;
6 keepalive_timeout 0;
7 # try_files $uri $uri.html $uri/index.html /about/default.html;
8 try_files $uri $uri.html $uri/index.html =489;
9 aio on; # 开启异步IO
10
11 access_log /data/nginx/html/mobile/logs/mobile_log;
12 error_log /data/nginx/html/mobile/logs/error_mobile_log;
13 location /error.html {
14 root /data/nginx/html/mobile;
15 }
16
17 location /download {
18 autoindex on;
检查nginx语法报错,如想让该参数生效,需要重新编译添加此参数
bash
# 报错是第9行
[root@109 vhosts]# nginx -t
nginx: [emerg] "aio on" is unsupported on this platform in /apps/nginx/conf/conf.d/vhosts/mobile.conf:9
nginx: configuration file /apps/nginx/conf/nginx.conf test failed
写文件到磁盘
bash
directio size | off; #操作完全和aio相反,aio是读取文件而directio是写文件到磁盘,启用直接
I/O,默认为关闭,当文件大于等于给定大小时,例如:directio 4m,同步(直接)写磁盘,而非写缓存。
9.3、打开文件进行缓存
bash
# 打开后的优点就是第一打开磁盘的上文件后第二次就不需要在去读取磁盘了,从而提高效率
open_file_cache off; #是否缓存打开过的文件信息,默认是禁用的
open_file_cache max=N [inactive=time];
max=N:#可缓存的缓存项上限数量;达到上限后会使用LRU(Least recently used,最近最少使用)算法
实现管理
inactive=time:#缓存项的非活动时长,在此处指定的时长内未被命中的或命中的次数少于
open_file_cache_min_uses指令所指定的次数的缓存项即为非活动项,将被删除
open_file_cache_valid time; #缓存项有效性的检查验证频率,默认值为60s
open_file_cache_errors on | off; #是否缓存查找时发生错误的文件一类的信息,默认值为off,如从磁盘查到的文件不存在,可以记录到缓存中,下次在有相同的查找就不用到磁盘上去找了
open_file_cache_min_uses number; #open_file_cache指令的inactive参数指定的时长内,至少
被命中此处指定的次数方可被归类为活动项,默认值为1
nginx可以缓存打开的文件有哪些?如下:
bash
#nginx可以缓存以下三种信息:
(1) 文件元数据:文件的描述符、文件大小和最近一次的修改时间
(2) 打开的目录结构
(3) 没有找到的或者没有权限访问的文件的相关信息
范例:
bash
open_file_cache max=10000 inactive=60s; #最大缓存10000个文件,非活动数据超时时长60s
open_file_cache_valid 60s; #每间隔60s检查一下缓存数据有效性
open_file_cache_min_uses 5; #60秒内至少被命中访问5次才被标记为活动数据
open_file_cache_errors on; #缓存错误信息
添加缓存配置
bash
[root@109 vhosts]# vim mobile.conf
server {
listen 80;
server_name www.gxy.mobile.com;
root /data/nginx/html/mobile;
access_log /data/nginx/html/mobile/logs/mobile_log;
error_log /data/nginx/html/mobile/logs/error_mobile_log;
location /error.html {
root /data/nginx/html/mobile;
}
# 添加location块
location /nginx_status {
stub_status;
}
}
# 重载nginx
[root@109 vhosts]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@109 vhosts]# nginx -s reload
浏览器访问:http://192.168.31.109/nginx_status
解释打印信息
bash
Active connections: 1 # 这是活动链接数,当前值是1
server accepts handled requests # 这一行是显示接收、处理、请求的连接数,此行为累计数据,服务重启会重新计数
3 3 3 # 分别对应上述三个状态的数(接受、处理、请求)
Reading: 0 Writing: 1 Waiting: 0 # 目前读的有0个,写的有1个,等的有0个
#状态页用于输出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)
为了安全可对上文配置进行改造
bash
[root@109 vhosts]# vim mobile.conf
server {
listen 80;
server_name www.gxy.mobile.com;
root /data/nginx/html/mobile;
access_log /data/nginx/html/mobile/logs/mobile_log;
error_log /data/nginx/html/mobile/logs/error_mobile_log;
location /error.html {
root /data/nginx/html/mobile;
}
# 修改内容如下,增加了验证功能,对IP进行了限制
location /nginx_status {
stub_status;
auth_basic "login password";
auth_basic_user_file /apps/nginx/conf/conf.d/.htpasswd;
allow 192.168.31.0/24;
allow 127.0.0.1;
deny all;
}
}
# 重载nginx
[root@109 vhosts]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@109 vhosts]# nginx -s reload
浏览器访问:http://192.168.31.109/nginx_status
10、nginx高级配置
10.1、nginx状态页
基于nginx 模块 ngx_http_stub_status_module 实现,在编译安装nginx的时候需要添加编译参数 --
with-http_stub_status_module,否则配置完成之后监测会是提示语法错误
注意: 状态页显示的是整个服务器的状态,而非虚拟主机的状态
11、nginx变量
nginx的变量可以在配置文件中引用,作为功能判断或者日志等场景使用。
变量可以分为内置变量和自定义变量。
内置变量是由nginx模块自带,通过变量可以获取到众多的与客户端访问相关的值。
11.1、内置变量
jsx
http://nginx.org/en/docs/varindex.html
常用内置变量
jsx
$remote_addr;
#存放了客户端的地址,注意是客户端的公网IP
$proxy_add_x_forwarded_for
#此变量表示将客户端IP追加请求报文中X-Forwarded-For首部字段,多个IP之间用逗号分隔,如果请求中没
有X-Forwarded-For,就使用$remote_addr
the "X-Forwarded-For" client request header field with the $remote_addr variable
appended to it, separated by a comma. If the "X-Forwarded-For" field is not
present in the client request header, the $proxy_add_x_forwarded_for variable is
equal to the $remote_addr variable.
$args;
#变量中存放了URL中的参数,例如:http://www.magedu.org/main/index.do?
id=20190221&partner=search
#返回结果为: id=20190221&partner=search
$document_root;
#保存了针对当前资源的请求的系统根目录,例如:/apps/nginx/html。
$document_uri;
#保存了当前请求中不包含参数的URI,注意是不包含请求的指令,比如:
http://www.magedu.org/main/index.do?id=20190221&partner=search会被定义
为/main/index.do
#返回结果为:/main/index.do
$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请求生成的文件绝对路径,
如:/apps/nginx/html/main/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_<name>
#name为任意请求报文首部字段,表示记录请求报文的首部字段
arbitrary request header field; the last part of a variable name is the field
name converted to lower case with dashes replaced by underscores #用下划线代替横线
#示例: echo $http_User_Agent;
$http_user_agent;
#客户端浏览器的详细信息
$http_cookie;
#客户端的cookie信息
$cookie_<name>
#name为任意请求报文首部字部cookie的key名
$http_referer
# 这个是跳转的链接,如从百度跳转到你的网站,这个referer就是百度的地址,自定义日志格式部分的范例
会提到,这个地方可以统计防掉链的数据
范例:
jsx
[root@centos8 ~]#vi /apps/nginx/conf/conf.d/pc.conf
location /main {
index index.html;
default_type text/html;
echo "hello world,main-->";
echo $remote_addr ;
echo $args ;
echo $document_root;
echo $document_uri;
echo $host;
echo $http_user_agent;
echo $http_cookie;
echo $request_filename;
echo $scheme;
echo $scheme://$host$document_uri?$args;
}
[root@centos6 ~]#curl -b title=ceo 'http://www.magedu.org/main/index.do?
id=20190221&partner=search'
hello world,main-->
10.0.0.6
id=20190221&partner=search
/apps/nginx/html
/main/index.do
www.magedu.org
curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3
libidn/1.18 libssh2/1.4.2
title=ceo
/apps/nginx/html/main/index.do
http
http://www.magedu.org/main/index.do?id=20190221&partner=search
范例:
jsx
[root@centos8 conf.d]#vim www.conf
.....
location /echo {
echo $request;
echo $proxy_add_x_forwarded_for;
echo $args;
echo $document_uri;
echo $request_uri;
echo $document_root;
echo $host;
echo $request_method;
echo $request_filename;
echo $scheme;
set $test $http_host;
echo $test;
echo $http_User_Agent;
echo $http_cookie;
echo $cookie_key1;
}
}
[root@centos7 ~]#curl -b 'key1=v1;key2=v2'
"http://www.magedu.org/echo/index.html?id=123456&partner=search"
GET /echo/index.html?id=123456&partner=search HTTP/1.1
10.0.0.7
id=123456&partner=search
/echo/index.html
/echo/index.html?id=123456&partner=search
/data/nginx/html/pc
www.magedu.org
GET
/data/nginx/html/pc/echo/index.html
http
www.magedu.org
curl/7.29.0
key1=v1;key2=v2
v1
11.2、自定义变量
假如需要自定义变量名称和值,使用指令set $variable value;
语法格式:
jsx
Syntax: set $variable value;
Default: ---
Context: server, location, if
范例:
jsx
set $name magedu;
echo $name;
set $my_port $server_port;
echo $my_port;
echo "$server_name:$server_port";
#输出信息如下
[root@centos6 ~]#curl www.magedu.org/main
magedu
80
www.magedu.org:80
12、Nginx 自定义访问日志
访问日志是记录客户端即用户的具体请求内容信息,全局配置模块中的error_log是记录nginx服务器运行时的日志保存路径和记录日志的level,因此有着本质的区别,而且Nginx的错误日志一般只有一个,但是访问日志可以在不同server中定义多个,定义一个日志需要使用access_log指定日志的保存路径,使用log_format指定日志的格式,格式中定义要保存的具体日志内容。
访问日志由 ngx_http_log_module 模块实现
官方帮助文档:
jsx
http://nginx.org/en/docs/http/ngx_http_log_module.html
语法格式
jsx
Syntax: access_log path [format [buffer=size] [gzip[=level]] [flush=time]
[if=condition]];
access_log off;
Default:
access_log logs/access.log combined;
Context: http, server, location, if in location, limit_except
12.1、自定义默认格式日志
主配置文件定义日志格式,其他server块中可以引用定义的log_format名
查看log_format可以在那些语句块中使用:
jsx
# 找到log_format模块,我发现只能用在http语句块中,所以就只能改nginx.conf配置文件
https://nginx.org/en/docs/dirindex.html
主配置文件定义日志格式:
如果是要保留日志的源格式,只是添加相应的日志内容,则配置如下:
jsx
[root@VM-20-17-centos ~]# cd /apps/nginx/conf
# 添加或者修改都可以,如果不想用默认的可以添加,默认的是注释掉的,我这里是直接添加的
[root@VM-20-17-centos conf]# vim nginx.conf
...
log_format nginx_format1 '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'$server_name:$server_port';
...
server块引用日志格式名:
jsx
[root@VM-20-17-centos ~]# vim /apps/nginx/conf/conf.d/vhosts/pc.conf
server {
listen 80;
server_name www.gxy.pc.com;
error_log /apps/nginx/logs/www_error.log error;
# error_page 404 /40x.html;
**# 添加此行,固定格式:access_log + 日志文件名 + 主配置定义的日志格式名字,这里www_access.log是自定义的日志文件名**
**access_log /apps/nginx/logs/www_access.log nginx_format1;**
location = /40x.html {
root /data/html/error;
}
location / {
root /data/nginx/html/pc;
}
}
重载nginx后查看已经有对应的日志文件了:
jsx
[root@VM-20-17-centos vhosts]# ll /apps/nginx/logs/
total 180
-rw-r--r-- 1 root root 115911 Dec 8 14:35 access.log
-rw-r--r-- 1 root root 54528 Dec 8 14:38 error.log
-rw-r--r-- 1 root root 0 Dec 7 18:13 m_error.log
-rw-r--r-- 1 root root 0 Dec 3 22:31 nginx.pid
-rw-r--r-- 1 root root 0 Dec 8 14:38 **www_access.log**
-rw-r--r-- 1 root root 0 Dec 7 18:13 www_error.log
本机访问测试:
jsx
[root@VM-20-17-centos ~]# curl www.gxy.pc.com
pc-web
# 查看实时日志,发现已经是我们定义的日志了
[root@VM-20-17-centos logs]# tail -f www_access.log
127.0.0.1 - - [08/Dec/2024:14:39:05 +0800] "GET / HTTP/1.1" 200 7 "-" "curl/7.29.0" "-" www.gxy.pc.com:80
主配置文件提到了$http_referer这个变量,这个就是从哪个地方跳转过来的,如从百度跳转到你的网站。可以使用curl命令模拟,如:
jsx
# 查看curl那个参数是加referer的,发现是-e参数
[root@VM-20-17-centos ~]# curl --help |grep ref
-e, --referer Referer URL (H)
# 本地模拟
[root@VM-20-17-centos ~]# curl -e 'https://www.baidu.com' http://www.gxy.pc.com
pc-web
# 查看日志,发现referer是百度的网址
[root@VM-20-17-centos logs]# tail -f www_access.log
127.0.0.1 - - [08/Dec/2024:14:39:05 +0800] "GET / HTTP/1.1" 200 7 "-" "curl/7.29.0" "-" www.gxy.pc.com:80
127.0.0.1 - - [08/Dec/2024:15:03:28 +0800] "GET / HTTP/1.1" 200 7 "https://www.baidu.com" "curl/7.29.0" "-" www.gxy.pc.com:80
12.2、自定义json格式日志
修改nginx.conf主配置文件,添加自定义日志格式:
jsx
#
[root@VM-20-17-centos ~]# **vim /apps/nginx/conf/nginx.conf**
log_format nginx_format1 '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'$server_name:$server_port';
# access_log logs/access.log nginx_format1;
# 自定义日志格式,在nginx.conf中添加以下行
**log_format access_json '{"@timestamp":"$time_iso8601",'
'"host":"$server_addr",'
'"clientip":"$remote_addr",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,'
# 以下两行是反向代理会用到的
'"upstreamtime":"$upstream_response_time",'
'"upstreamhost":"$upstream_addr",'
'"http_host":"$host",'
'"uri":"$uri",'
'"xff":"$http_x_forwarded_for",'
'"referer":"$http_referer",'
'"tcp_xff":"$proxy_protocol_addr",'
'"http_user_agent":"$http_user_agent",'
'"status":"$status"}';**
修改server块,引用自定义日志格式
jsx
# 在pc.conf中修改引用的日志名
[root@VM-20-17-centos ~]# **vim /apps/nginx/conf/conf.d/vhosts/pc.conf**
server {
listen 80;
server_name www.gxy.pc.com;
error_log /apps/nginx/logs/www_error.log error;
# error_page 404 /40x.html;
# 将此行的**nginx_format1改成我们定义的json日志格式名**
access_log /apps/nginx/logs/www_access_json.log **access_json**;
location = /40x.html {
root /data/html/error;
}
location / {
root /data/nginx/html/pc;
}
}
检查配置文件语法并重载nginx
jsx
[root@VM-20-17-centos ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@VM-20-17-centos ~]# nginx -s reload
# 查看文件**www_access_json.log**已生成
[root@VM-20-17-centos ~]# ll /apps/nginx/logs/
total 188
-rw-r--r-- 1 root root 118112 Dec 8 16:09 access.log
-rw-r--r-- 1 root root 54910 Dec 8 16:21 error.log 6,43 All
-rw-r--r-- 1 root root 0 Dec 7 18:13 m_error.log
-rw-r--r-- 1 root root 0 Dec 3 22:31 nginx.pid
-rw-r--r-- 1 root root 417 Dec 8 16:14 **www_access_json.log**
-rw-r--r-- 1 root root 232 Dec 8 15:03 www_access.log
-rw-r--r-- 1 root root 0 Dec 7 18:13 www_error.log
本机访问测试
jsx
[root@VM-20-17-centos conf]# curl http://www.gxy.pc.com
pc-web
查看日志格式
bash
[root@VM-20-17-centos logs]# tail -f www_access_json.log
{"@timestamp":"2024-12-08T16:14:43+08:00", '"host":"127.0.0.1",' '"clientip":"127.0.0.1",' '"size":7,' '"responsetime":0.000,' '"upstreamtime":"-",' '"upstreamhost":"-",' '"http_host":"www.gxy.pc.com",' '"uri":"/index.html",' '"xff":"-",' '"referer":"-",' '"tcp_xff":"-",' '"http_user_agent":"curl/7.29.0",' '"status":"200"}'
有了以上日志格式,我们就可以分析日志了,如果项目用了ELK日志分析系统,我们可以更好分析日志,ELK分析的也是json格式的日志。
我们也可以使用脚本去分析日志:
范例:
我们使用shell脚本去分析日志中的200和40X、50X的数据。
bash
[root@VM-20-17-centos shell]# vim nginx_log.sh
#!/bin/bash
# 定义日志文件路径
log_file="/apps/nginx/logs/www_access_json.log"
# 检查日志文件是否存在
if [ ! -f "$log_file" ]; then
echo "日志文件不存在:$log_file"
exit 1
fi
# 初始化计数器
status_200=0
status_4xx=0
status_5xx=0
# 逐行读取日志文件
while read -r line; do
# 提取状态码
status_code=$(echo "$line" | grep -oP '"status":"\K[0-9]{3}')
# 根据状态码分类
if [[ "$status_code" == "200" ]]; then
((status_200++))
elif [[ "$status_code" =~ ^4 ]]; then
((status_4xx++))
elif [[ "$status_code" =~ ^5 ]]; then
((status_5xx++))
fi
done < "$log_file"
# 输出结果
echo "状态码200的记录数:$status_200"
echo "状态码4xx的记录数:$status_4xx"
echo "状态码5xx的记录数:$status_5xx"
执行测试
bash
[root@VM-20-17-centos shell]# ./nginx_log.sh
状态码200的记录数:4
状态码4xx的记录数:2
状态码5xx的记录数:0
13、nginx压缩功能
Nginx支持对指定类型的文件进行压缩然后再传输给客户端,而且压缩还可以设置压缩比例,压缩后的文件大小将比源文件显著变小,这样有助于降低出口带宽的利用率,降低企业的IT支出,不过会占用相应的CPU资源。
Nginx对文件的压缩功能是依赖于模块 ngx_http_gzip_module
官方文档: https://nginx.org/en/docs/http/ngx_http_gzip_module.html
配置指令如下:
bash
#启用或禁用gzip压缩,默认关闭
gzip on | off;
#压缩比由低到高从1到9,默认为1,9的压缩比最高,但它会消耗更多的CPU
gzip_comp_level level;
#禁用IE6 gzip功能
gzip_disable "MSIE [1-6]\.";
#gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
#启用压缩功能时,协议的最小版本,默认HTTP/1.1
gzip_http_version 1.0 | 1.1;
#指定Nginx服务需要向服务器申请的缓存空间的个数和大小,平台不同,默认:32 4k或者16 8k;
gzip_buffers number size;
#指明仅对哪些类型的资源执行压缩操作;默认为gzip_types text/html,不用显示指定,否则出错
gzip_types mime-type ...;
#如果启用压缩,是否在响应报文首部插入"Vary: Accept-Encoding",一般建议打开
gzip_vary on | off;
我们先将之前的日志格式恢复成原来的默认的,不使用json格式的
bash
[root@VM-20-17-centos vhosts]# vim pc.conf
server {
listen 80;
server_name www.gxy.pc.com;
error_log /apps/nginx/logs/www_error.log error;
# error_page 404 /40x.html;
# 我们将www_access_json.log换成**www_access.log**,将**access_json**换成**nginx_format1**,日志名字无所谓,
# 也可以不改,只不过不想让两种格式的日志写到一个日志文件中,所以做了修改
access_log /apps/nginx/logs/**www_access.log nginx_format1**;
location = /40x.html {
root /data/html/error;
}
location / {
root /data/nginx/html/pc;
}
}
# 修改完成后重载nginx
[root@VM-20-17-centos vhosts]# nginx -s reload
找一个大的测试文件
bash
[root@VM-20-17-centos pc]# cd /data/nginx/html/pc
[root@VM-20-17-centos pc]# ll
total 4
-rw-r--r-- 1 root root 7 Dec 7 10:02 index.html
# m.txt文件13M
[root@VM-20-17-centos pc]# cat /var/log/messages > m.txt
[root@VM-20-17-centos pc]# ll -h
total 13M
-rw-r--r-- 1 root root 7 Dec 7 10:02 index.html
-rw-r--r-- 1 root root 13M Dec 8 17:47 m.txt
# 测试
[root@VM-20-17-centos ~]# curl http://www.gxy.pc.com/m.txt -I
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Sun, 08 Dec 2024 09:49:18 GMT
Content-Type: text/plain
**Content-Length: 12692363 # 返回的字节很大,为了节省带宽,需要启动压缩功能**
Last-Modified: Sun, 08 Dec 2024 09:47:24 GMT
Connection: keep-alive
ETag: "67556b2c-c1ab8b"
Accept-Ranges: bytes
# 通过日志也可以看出了
[root@VM-20-17-centos logs]# tail -f www_access.log
127.0.0.1 - - [08/Dec/2024:14:39:05 +0800] "GET / HTTP/1.1" 200 7 "-" "curl/7.29.0" "-" www.gxy.pc.com:80
127.0.0.1 - - [08/Dec/2024:15:03:28 +0800] "GET / HTTP/1.1" 200 7 "https://www.baidu.com" "curl/7.29.0" "-" www.gxy.pc.com:80
127.0.0.1 - - [08/Dec/2024:17:41:32 +0800] "GET / HTTP/1.1" 200 7 "-" "curl/7.29.0" "-" www.gxy.pc.com:80
127.0.0.1 - - [08/Dec/2024:17:49:18 +0800] "HEAD /m.txt HTTP/1.1" 200 0 "-" "curl/7.29.0" "-" www.gxy.pc.com:80
# 这里也可以看出日志**12692363**
127.0.0.1 - - [08/Dec/2024:18:00:48 +0800] "GET /m.txt HTTP/1.1" 200 12692363 "-" "curl/7.29.0" "-" www.gxy.pc.com:80
启动压缩功能
bash
[root@VM-20-17-centos vhosts]# vim pc.conf
server {
listen 80;
server_name www.gxy.pc.com;
error_log /apps/nginx/logs/www_error.log error;
# error_page 404 /40x.html;
access_log /apps/nginx/logs/www_access.log nginx_format1;
# 添加以下几行
gzip on;
gzip_comp_level 9; **# 9的压缩率最高,我们测试可以用9进行测试,实际需要根据项目情况决定**
gzip_min_length 1k; **# 小于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; **# 在响应报文首部插入"Vary: Accept-Encoding",一般建议打开**
location = /40x.html {
root /data/html/error;
}
location / {
root /data/nginx/html/pc;
}
}
重载nginx
bash
[root@VM-20-17-centos vhosts]# nginx -s reload
测试查看压缩情况
bash