Nginx
Nginx是一个WEB服务
【1】、安装nginx
1.官网安装 2.使用默认的仓库安装,版本较低 3.编译方式安装,需要其他功能模块的时候 自定义安装
# 基于官网仓库的安装方式,版本较新,配置易读 # 准备软件仓库 [root@web01 ~]# cat /etc/yum.repos.d/nginx.repo [nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/7/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true # 安装nginx [root@web01 ~]# yum install -y nginx [root@web01 ~]# nginx -v nginx version: nginx/1.26.1
源码编译安装nginx
作用: 根据需求自定义nginx的安装配置及所需要的模块
作用: 根据需求自定义nginx的安装配置及所需要的模块 1.安装依赖 [root@lb01 ~]# yum install -y gcc glibc gcc-c++ pcre-devel openssl-devel patch 2.下载Nginx源码包(要和当前nginx版本号一致) 解压 [root@lb01 ~]# wget http://nginx.org/download/nginx-1.26.1.tar.gz [root@lb01 ~]# tar xf nginx-1.26.1.tar.gz 3.下载第三方模块 解压 [root@lb01 ~]# wget https://github.com/yaoweibin/nginx_upstream_check_module/archive/master.zip [root@lb01 ~]# unzip master.zip 4.将新的模块添加进默认的模版中 [root@lb01 nginx-1.26.1]# patch -p1 < ../nginx_upstream_check_module-master/check_1.20.1+.patch 5.添加模块的位置到默认的配置中 --add-module=/root/nginx_upstream_check_module-master ############################# --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --add-module=/root/nginx_upstream_check_module-master --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' 完成后复制上面的模块信息,进入第6步 6.配置安装 [root@lb01 nginx-1.26.1]# ./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --add-module=/root/nginx_upstream_check_module-master --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' 7.make编译 [root@lb01 nginx-1.26.1]# make 8.安装 [root@lb01 nginx-1.26.1]# make install 9.检查模块 [root@lb01 ~]# nginx -V nginx version: nginx/1.26.1 built by gcc 7.3.0 (GCC) built with OpenSSL 1.1.1f 31 Mar 2020 TLS SNI support enabled configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --add-module=/root/nginx_upstream_check_module-master --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' [root@lb01 conf.d]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
【2】、nginx配置文件解析
/etc/nginx/nginx.conf [root@web01 nginx]# cat nginx.conf # 核心区块 user nginx; # 运行nginx的用户 安装nginx自动创建此用户 worker_processes auto; # nginx启动进程数量 以核心为准 error_log /var/log/nginx/error.log notice; # 错误日志的位置 pid /var/run/nginx.pid; # nginx的pid号写入到此文件中 #事件模块 events { worker_connections 25532; # 每个进程最大的连接数 } # http区块 接收浏览器请求 并且响应浏览器请求 http { charset utf-8,gbk; # 支持的编码格式 include /etc/nginx/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 /var/log/nginx/access.log main; # 访问日志的位置 sendfile on; # 文件传输 #tcp_nopush on; keepalive_timeout 65; # 长连接 65秒自动和浏览器断开 #gzip on; # 是否资源压缩 include /etc/nginx/conf.d/*.conf; # 将conf.d下的*.conf引入到当前的文件 } server区块,网站的配置。server区块是包含在http区块中。 [root@web01 ~]# cat /etc/nginx/conf.d/default.conf [root@web01 ~]# > /etc/nginx/conf.d/default.conf [root@web01 conf.d]# cat default.conf server { listen 80; # 监听的端口 server_name www.xu.com; # 自己购买的域名 hosts解析 location / { # 路径匹配 www.xu.com/ root /code; # 让用户去/code目录获取网站信息 index index.html; # 默认给浏览器返回的文件 index.html } }
# 创建代码目录 mkdir /code # 上传网站代码,解压到代码目录 [root@web01 ~]# unzip xiaobawang.zip -d /code/ [root@web01 ~]# ll /code/ total 48 -rw-r--r-- 1 root root 28032 May 24 2021 bgm.mp3 drwxr-xr-x 2 root root 23 May 24 2021 css drwxr-xr-x 2 root root 23 May 24 2021 images -rw-r--r-- 1 root root 8956 May 24 2021 index.html drwxr-xr-x 2 root root 213 May 24 2021 js drwxr-xr-x 2 root root 4096 May 24 2021 roms -rw-r--r-- 1 root root 811 May 24 2021 shuoming.html # 客户端访问
HTTP 404 # 代码目录不存在
HTTP 403 # 有代码目录但是没有文件
日志文件:
/var/log/nginx/access.log
/var/log/nginx/error.log2024/12/06 18:55:40 [error] 147450#147450: *14 open() "/code/aasdsadsa" failed (2: No such file or directory), client: 192.168.121.1, server: www.xu.com, request: "GET /aasdsadsa HTTP/1.1", host: "www.xu.com" 2024/12/06 18:55:41 [error] 147450#147450: *14 open() "/code/aasdsadsa" failed (2: No such file or directory), client: 192.168.121.1, server: www.xu.com, request: "GET /aasdsadsa HTTP/1.1", host: "www.xu.com"
【3】、nginx配置多业务
基于多IP地址 了解 10.0.0.7----------->忍者 10.0.0.8----------->小霸王 1.配置一个ip地址 [root@web01 ~]# ip add add 10.0.0.8/24 dev ens33 2.配置文件修改为 10.0.0.7对应的是忍者业务 [root@web01 conf.d]# cat default.conf server { listen 10.0.0.7:80; # 监听的端口 server_name _; # 自己购买的域名 hosts解析 location / { # 路径匹配 www.oldboy.com/ root /code; # 让用户去/code目录获取网站信息 index index.html; # 默认给浏览器返回的文件 index.html } } [root@web01 conf.d]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [root@web01 conf.d]# systemctl restart nginx 3.检查当前的监听端口 [root@web01 conf.d]# netstat -tnulp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 10.0.0.7:80 0.0.0.0:* LISTEN 32133/nginx: master 增加小霸王业务 通过10.0.0.8IP访问 1.增加server配置 [root@web01 conf.d]# cat game.conf server { listen 10.0.0.8:80; server_name _; location / { root /game; index index.html; } } 2.创建代码目录 [root@web01 conf.d]# mkdir /game [root@web01 conf.d]# cd /game/ 3.上传小霸王游戏包 [root@web01 game]# ll total 7708 -rw-r--r-- 1 root root 7890373 Dec 6 11:34 game.zip [root@web01 game]# unzip game.zip 4.检测配置文件 [root@web01 game]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful 5.重启nginx [root@web01 game]# systemctl restart nginx 浏览器访问: 10.0.0.7--->忍者 10.0.0.8--->小霸王 [root@web01 game]# netstat -tnulp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 10.0.0.8:80 0.0.0.0:* LISTEN 32233/nginx: master tcp 0 0 10.0.0.7:80 0.0.0.0:* LISTEN 32233/nginx: master 为什么基于IP的用的少? 因为现在的带宽大部分都是BGP多线路。而不是单线 基于多端口 常用 80是给用户用的,自己的业务的后台不能让用户访问。自定义后台的端口 10.0.0.7:80------>忍者 10.0.0.7:81------>小霸王 忍者配置文件 [root@web01 conf.d]# cat default.conf server { listen 80; # 监听的端口 server_name _; # 自己购买的域名 hosts解析 location / { # 路径匹配 www.oldboy.com/ root /code; # 让用户去/code目录获取网站信息 index index.html; # 默认给浏览器返回的文件 index.html } } 小霸王配置文件 [root@web01 conf.d]# cat game.conf server { listen 81; server_name _; location / { root /game; index index.html; } } [root@web01 conf.d]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [root@web01 conf.d]# systemctl restart nginx 访问测试: 10.0.0.7:80 10.0.0.7:81 基于多域名 常用 www.oldboy.com-------->忍者 www.game.com-------->小霸王 配置忍者业务 [root@web01 conf.d]# cat default.conf server { listen 80; # 监听的端口 server_name www.oldboy.com; # 自己购买的域名 hosts解析 location / { # 路径匹配 www.oldboy.com/ root /code; # 让用户去/code目录获取网站信息 index index.html; # 默认给浏览器返回的文件 index.html } } 配置小霸王游戏业务 [root@web01 conf.d]# cat game.conf server { listen 80; server_name www.game.com; location / { root /game; index index.html; } } [root@web01 conf.d]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [root@web01 conf.d]# systemctl restart nginx 测试访问: www.oldboy.com 对应的忍者 www.game.com 对应的小霸王
❓reload和restart的区别
一般来说我们如果是对原有配置文件做出了修改,使用reload生效
如果创建了新的配置文件就是用restart生效
【4】、nginx常用模块
nginx配置文件分区
http区
server区
location区
1、auto_index索引模块
autoindex on:表示开启索引模块 off:关闭索引模块 autoindex_localtime on:显示文件时间为文件服务器的时间 off:显示文件时间试GMT时间 autoindex_exact_size on:显示文件确切大小,单位是bytes off:显示出文件的大概大小,单位是KB、GB或MB
# 创建索引模块的配置文件 [root@web01 ~]# cat /etc/nginx/conf.d/www.index.com.conf server { listen 80; server_name www.index.com; autoindex on; autoindex_localtime on; autoindex_exact_size off; location / { root /code/index; index index.html; } } # 创建对应的目录 [root@web01 ~]# mkdir /code/index/{01..10} -p # 进行hosts解析 192.168.121.7 www.index.html
访问测试
[root@web01 ~]# cd /code/index/01 [root@web01 01]# echo `pwd` > index.html
[root@web01 01]# cd /code/index/ [root@web01 index]# echo `pwd` > /code/index/aaa.html
我们就可以在页面中通过目录的方式来访问内容
2、下载限制模块
默认不限速,限制下载速度
limit_rate 0 limit_rate_after 50M # 下50M;不限速,后面开始限速
[root@web01 ~]# cat /etc/nginx/conf.d/www.index.com.conf server { listen 80; server_name www.index.com; autoindex on; autoindex_localtime on; autoindex_exact_size off; limit_rate 1M; location / { root /code/index; index index.html; } }
[root@web01 ~]# cat /etc/nginx/conf.d/www.index.com.conf server { listen 80; server_name www.index.com; autoindex on; autoindex_localtime on; autoindex_exact_size off; limit_rate 1M; limit_rate_after 10M; location / { root /code/index; index index.html; } }
3、基于用户登录认证模块
作用: 登录网站的时候需要提供用户名和密码 auth_basic off|string auth_basic_user_file auth_conf
1.htpasswd生成密码文件 # -b 免交互直接在命令行输入密码 -c 创建文件的意思 htpasswd -c -b /etc/nginx/auth.conf xu xu [root@web01 ~]# cat /etc/nginx/auth.conf xu:$apr1$8k9aXaPG$JC2DrQ3C/Bsv9qPErDQaf/ 2.配置文件 [root@web01 ~]# cat /etc/nginx/conf.d/www.index.com.conf server { listen 80; server_name www.index.com; autoindex on; autoindex_localtime on; autoindex_exact_size off; limit_rate 1M; limit_rate_after 10M; auth_basic "hahah"; auth_basic_user_file auth.conf; location / { root /code/index; index index.html; } } [root@web01 ~]# systemctl reload nginx.service [root@web01 ~]# tail -1 /var/log/nginx/access.log 192.168.121.1 - xu [09/Dec/2024:15:04:38 +0800] "GET / HTTP/1.1" 200 1309 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36" "-"
在输入密码时如果验证错误,状态码是401
192.168.121.1 - xu [09/Dec/2024:15:07:18 +0800] "GET / HTTP/1.1" 401 581 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0" "-"
4、nginx状态模块
作用: 显示用户访问nginx的连接信息 stub_status # 只能放在server和location中
[root@web01 ~]# cat /etc/nginx/conf.d/www.index.com.conf server { listen 80; server_name www.index.com; autoindex on; autoindex_localtime on; autoindex_exact_size off; limit_rate 1M; limit_rate_after 10M; auth_basic "hahah"; auth_basic_user_file auth.conf; location / { root /code/index; index index.html; } location /nginx_status { stub_status; } }
# 当前TCP连接数 Active connections: 2 # accept:已经接收了多少个 # handled:已经处理的 # request:http请求数 server accepts handled requests 27 27 40 # Reading:当前读取请求头数量 # Writing:当前响应的请求头数量 # Waiting:等待的请求数,开启了keepalived Reading: 0 Writing: 1 Waiting: 1
5、IP访问控制模块
# 允许哪些 allow address|CIDR|all # 拒绝哪些 deny address|CIDR|all
[root@backup ~]# curl 192.168.121.7/nginx_status Active connections: 1 server accepts handled requests 46 46 59 Reading: 0 Writing: 1 Waiting: 0 # 不允许192.168.121.41访问nginx_status [root@web01 ~]# cat /etc/nginx/conf.d/www.index.com.conf server { listen 80; server_name www.index.com; autoindex on; autoindex_localtime on; autoindex_exact_size off; limit_rate 1M; limit_rate_after 10M; location / { root /code/index; index index.html; } location /nginx_status { stub_status; allow 192.168.121.7; # 只限制/nginx_status页面,别的都能访问 deny all; } } [root@web01 ~]# curl 192.168.121.7/nginx_status Active connections: 1 server accepts handled requests 47 47 60 Reading: 0 Writing: 1 Waiting: 0 [root@backup ~]# curl 192.168.121.7/nginx_status <html> <head><title>403 Forbidden</title></head> <body> <center><h1>403 Forbidden</h1></center> <hr><center>nginx/1.26.1</center> </body> </html>
6、Nginx访问限制
在企业中经常会遇到这种情况,服务器流量异常,负载过大等等。对于大流量恶意的攻击访问,会带来带宽的浪费,服务器压力,影响业务,这时往往会考虑对同一个IP的请求数和连接数进行限制。
ngx_http_limit_conn_module 模块可以根据定义的key来限制每个键值的连接数,如同一个IP来源的连接数。
limit_conn_module 连接频率限制
limit_req_module 请求频率限制
(1)、TCP连接数限制
limit_conn_module key zone=name:size http
[root@web01 ~]# cat /etc/nginx/conf.d/www.index.com.conf - limit_conn_zone $remote_addr zone=conn_zone:10m; #限制模块名称 客户端IP 开辟内存空间名称叫 conn_zone 空间大小10m server { listen 80; server_name www.index.com; autoindex on; autoindex_localtime on; autoindex_exact_size off; limit_rate 1M; limit_rate_after 10M; location / { limit_conn conn_zone 1; # 限制limit_conn_zone空间里的所有IP 同一时间只有1个TCP连接 root /code/index; index index.html; } location /nginx_status { stub_status; allow 192.168.121.7; deny all; } }
(2)、请求数限制
limit_req_zone $remote_addr zone=req_zone:10m rate=20r/s; # 每秒最多20个请求
[root@web01 ~]# cat /etc/nginx/conf.d/www.index.com.conf limit_req_zone $remote_addr zone=req_zone:10m rate=20r/s; # 每秒最多20个请求 server { listen 80; server_name www.index.com; autoindex on; autoindex_localtime on; autoindex_exact_size off; limit_rate 1M; limit_rate_after 10M; location / { limit_req zone=req_zone burst=5 nodelay; # 限制延时处理5个,剩余的返回503 root /code/index; index index.html; } location /nginx_status { stub_status; allow 192.168.121.7; deny all; } }
【5】、location匹配规则优先级
匹配符 匹配规则 优先级 = 精确匹配 1 ^~ 以某个字符串开头 2 ~ 区分大小写的正则匹配 3 ~* 不区分大小写的正则匹配 4 / 通用匹配,任何请求都会匹配到 5
server { listen 80; server_name www.youxianji.com; default_type text/html; location ~ /haha { return 200 "configuration E"; } location / { return 200 "configuration A"; } location = / { return 200 "configuration B"; } location ^~ /document { return 200 "configuration C"; } location ~* .(jpg|gif)$ { return 200 "configuration D"; } }
【6】、rewrite
Rewrite主要实现url地址重写,以及重定向,就是把传入 web 的请求重定向到其他 url 的过程。
1、地址跳转,用户访问www.lzy.com这个URL时,将其定向至一个新的域名mobile.lzy.com
2、协议跳转,用户通过http协议请求网站时,将其重新跳转至https协议方式
3、伪静态,将动态页面显示为静态页面方式的一种技术,便于搜索引擎的录入,同时减少动态URL地址对外暴露过多的参数,提升更高的安全性。
4、搜索引擎,SEO优化依赖于url路径,好记的url便于支持搜索引擎录入
1、rewrite配置
句法:Syntax: rewrite regex replacement [flag] 默认:Default: -- 语境:Context: server,location,if [root@web01 conf.d]# cat rewrite.conf server { listen 80; server_name www.rew.com; root /code/test; location / { rewrite /1.html /2.html; #rewrite /2.html /3.html; } }
2、flag设置
rewrite 指令根据表达式来重定向 URL ,或者修改字符串,可以应用于 server,location,if 环境下,每行 rewrite 指令最后跟一个 flag 标记,支持的 flag 标记有如下表格所示:
flag | 作用 |
---|---|
break | 本条规则匹配完成后,停止匹配,不在匹配后面的规则 |
last | 本条规则匹配完成后,停止匹配,不在匹配后面的规则,但是会重新发起请求 |
redirect | 返回302临时重定向,地址栏显示跳转后的地址 |
permanent | 返回301永久重定向,地址栏显示跳转后的地址 |
[root@web01 conf.d]# cat re.conf server { listen 80; server_name test.oldboy.com; root /code/test/; location / { rewrite /1.html /2.html; rewrite /2.html /3.html; } location /2.html { rewrite /2.html /a.html; } location /3.html { rewrite /3.html /b.html; } } [root@web01 conf.d]# echo 3.html > /code/test/3.html [root@web01 conf.d]# echo a.html > /code/test/a.html [root@web01 conf.d]# echo b.html > /code/test/b.html [root@web01 conf.d]# echo 2.html > /code/test/2.html
# break 停止向后匹配,返回2.html中的资源 [root@web01 conf.d]# cat re.conf server { listen 80; server_name test.oldboy.com; root /code/test/; location / { rewrite /1.html /2.html break; rewrite /2.html /3.html; } location /2.html { rewrite /2.html /a.html; } location /3.html { rewrite /3.html /b.html; } }
# last: 停止向后匹配,但是浏览器会重新对服务器发起请求。第一次匹配到了/2.html,然后就再次发起/2.html的请求,因此就会匹配到/a.html [root@web01 conf.d]# cat re.conf server { listen 80; server_name test.oldboy.com; root /code/test/; location / { rewrite /1.html /2.html last; rewrite /2.html /3.html; } location /2.html { rewrite /2.html /a.html; } location /3.html { rewrite /3.html /b.html; } }
# redirect 302临时重定向 [root@web01 conf.d]# cat re.conf server { listen 80; server_name www.rew.com; root /code; location /test { rewrite ^(.*)$ http://www.baidu.com redirect; #rewrite ^(.*)$ http://www.oldboy.com permanent; #return 301 http://www.oldboy.com; #return 302 http://www.oldboy.com; } }
# permanent 301永久重定向 [root@web01 conf.d]# cat re.conf server { listen 80; server_name www.rew.com; root /code; location /test { #rewrite ^(.*)$ http://www.baidu.com redirect; #return 302 http://www.baidu.com; rewrite ^(.*)$ http://www.baidu.com permanent; #return 301 http://www.oldboy.com; } } # 测试直接访问和关闭nginx后访问,都可以访问到百度
redirect: 每次请求都会询问服务器,如果当服务器不可用时,则会跳转失败。
permanent: 第一次请求会询问,浏览器会记录跳转的地址,第二次则不再询问服务器,直接通过浏览器缓存的地址跳转。
在写rewrite规则之前,我们需要开启rewrite日志对规则的匹配进行调试。
http { rewrite_log on; }
案例1:用户访问 /abc/1.html 实际上真实访问的是 /ccc/bbb/2.html
[root@web01 conf.d]# cat re.conf server { listen 80; server_name test.oldboy.com; root /code; location / { root /code; index index.html; } location /abc { rewrite (.*) /ccc/bbb/2.html redirect; #return 302 /ccc/bbb/2.html; } } 正则匹配方式 [root@web01 conf.d]# cat re.conf server { listen 80; server_name test.oldboy.com; root /code; location / { root /code; index index.html; } location ~ abc$ { # 匹配以abc结尾的url rewrite (.*) /ccc/bbb/2.html redirect; #return 302 /ccc/bbb/2.html; } } [root@web01 conf.d]# cat re.conf server { listen 80; server_name test.oldboy.com; root /code; location / { root /code; index index.html; } location ~ ^/abc$ { # 必须为abc rewrite (.*) /ccc/bbb/2.html redirect; #return 302 /ccc/bbb/2.html; } } [root@web01 conf.d]# mkdir /code/ccc/bbb -p [root@web01 conf.d]# echo 2.html > /code/ccc/bbb/2.html [root@web01 conf.d]# cat /code/ccc/bbb/2.html 2.html
用户访问 /2018/ccc/2.html 实际上真实访问的是 /2014/ccc/2.html
[root@web01 conf.d]# cat rewrite.conf server { listen 80; server_name www.rew.com; root /code; location /2018 { rewrite ^/2018/(.*)$ /2014/$1 redirect; } }
[root@web01 conf.d]# vim re.conf server { listen 80; server_name test.oldboy.com; root /code; location / { root /code; index index.html; } location /2024 { rewrite ^/2024/(.*)-(.*).html$ /2018/$1/$2/index.html redirect; } } "re.conf" 13L, 275C written [root@web01 conf.d]# ll /code/2018/ total 0 drwxr-xr-x 3 root root 16 Dec 16 10:00 11 [root@web01 conf.d]# ll /code/2018/11/22/ total 4 -rw-r--r-- 1 root root 22 Dec 16 10:00 3.html [root@web01 conf.d]# echo hehe > /code/2018/11/22/index.html [root@web01 conf.d]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [root@web01 conf.d]# systemctl restart nginx
3、错误页面跳转
[root@web01 conf.d]# cat rewrite.conf server { listen 80; server_name www.rew.com; root /code; location /2018 { rewrite ^/2018/(.*)-(.*).html /2014/$1/$2/index.html redirect; } error_page 403 404 500 501 502 @error_test; location @error_test { rewrite ^(.*)$ /404.html break; } }
4、使用变量判断跳转
# $args是nginx中的默认变量,默认是是空值,通过set指令去赋值 [root@web01 conf.d]# cat rewrite.conf server { listen 80; server_name www.rew.com; set $args "&showoffline=1"; location / { root /code; index index.html; } if ($remote_addr = 192.168.121.1 ){ # 判断如果客户端是192.168.121.1 才执行下面的rewrite rewrite (.*) http://www.rew.com$1; } } [root@web01 conf.d]# systemctl restart nginx [root@web01 conf.d]# curl www.rew.com xixi
跳转维护页面,指定IP正常访问 [root@web01 conf.d]# cat re.conf server { listen 80; server_name www.rew.com; root /code; index index.html; location / { set $ip 0; # 设置变量为0 if ($remote_addr = "192.168.121.1"){ set $ip 1; # 如果来源IP为0.1则设置为1 } if ($ip = 0){ # 判断如果变量为0 则跳转维护页面 rewrite ^(.*)$ /wh.html break; } } } [root@web01 conf.d]# echo "目前网站正在维护中...." > /code/wh.html
【8】、DNS劫持
[root@web01 conf.d]# cat test.conf server { listen 80; server_name www.jiechi.com; root /code/test; index index.html; } [root@web01 conf.d]# ll /code/test/ [root@web01 conf.d]# cat /code/test/index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>我是title</title> </head> <body> <article> <header> <h1>我是妹妹</h1> <p>创建时间:<time pubdate="pubdate">2025/5/20</time></p> </header> <p> <b>Aticle</b>第一次用h5写文章,好他*的紧张... </p> <footer> <p><small>版权所有!</small></p> </footer> </article> </body> </html>
web02配置劫持test.oldboy.com [root@web02 conf.d]# cat jc.conf upstream jiechi { server 192.168.121.7:80; } server { listen 80; server_name www.jiechi.com; location / { proxy_pass http://jiechi; proxy_set_header Host $http_host; } }
# 直接修改网站内容 [root@web02 conf.d]# cat jc.conf upstream jiechi { server 192.168.121.7:80; } server { listen 80; server_name www.jiechi.com; location / { proxy_pass http://jiechi; proxy_set_header Host $http_host; sub_filter '<h1>我是妹妹' '<h1>哈哈哈 '; sub_filter '<b>Aticle</b>第一次用h5写文章,好他*的紧张...' '<img src="https://p2.itc.cn/q_70/images03/20230828/b88f3181994f45c3b9d0b86d9cc449ba.jpeg">'; sub_filter '<small>版权所有' ' <small>开源'; } }
【9】、nginx性能优化
1、压力测试工具
在系统业务量没有增长之前,我们就要做好相应的准备工作,以防患业务量突增带来的接口压力,所以对于接口压力测试就显得非常重要了,我们首先要评估好系统压力,然后使用工具检测当前系统情况,是否能满足对应压力的需求。
1.安装压力测试工具 [root@lb01 ~]# yum -y install httpd-tools 2.使用压力测试命令 ab [root@web01 ~]# ab -n 200 -c 2 http://127.0.0.1/ #-n 要执行的请求数 #-c 请求的并发数 #-k 是否开启长连接,默认不是长连接 # -p 指定测试的动作,是get还是post。。。。 [root@web01 ~]# ab -n20000 -c200 http://127.0.0.1/index.html This is ApacheBench, Version 2.3 <$Revision: 1874286 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient) Completed 2000 requests Completed 4000 requests Completed 6000 requests Completed 8000 requests Completed 10000 requests Completed 12000 requests Completed 14000 requests Completed 16000 requests Completed 18000 requests Completed 20000 requests Finished 20000 requests Server Software: nginx/1.26.1 # Nginx版本号 Server Hostname: 127.0.0.1 # 压测的主机名称 Server Port: 80 # 网站的端口号 Document Path: /index.html # 压测的具体资源 Document Length: 9 bytes # 页面总大小 Concurrency Level: 200 # 并发数 Time taken for tests: 1.498 seconds # 处理完成的时间 Complete requests: 20000 # 总共的请求数量 Failed requests: 0 # 失败 Total transferred: 5140000 bytes # 总页面的大小 包含头部数据 HTML transferred: 180000 bytes # 页面的大小 Requests per second: 13352.94 [#/sec] (mean) # 吞吐量 Time per request: 14.978 [ms] (mean) # 用户平均请求等待时间 Time per request: 0.075 [ms] (mean, across all concurrent requests) Transfer rate: 3351.28 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 7 25.0 3 1050 Processing: 0 6 13.6 4 216 Waiting: 0 5 12.6 3 215 Total: 0 14 28.8 8 1061 Percentage of the requests served within a certain time (ms) 50% 8 66% 11 75% 12 80% 14 90% 19 95% 37 98% 108 99% 119 100% 1061 (longest request)
2、文件句柄
也叫做文件描述符(文件最大打开数)
文件句柄,Linux一切皆文件,文件句柄可以理解为就是一个索引,文件句柄会随着我们进程的调用频繁增加,系统默认文件句柄是有限制的,不能让一个进程无限的调用,所以我们需要限制每个 进程和每个服务使用多大的文件句柄,文件句柄也是必须要调整的优化参数。
[root@web01 conf.d]# ulimit -n 65535 [root@web01 conf.d]# tail -1 /etc/security/limits.conf * - nofile 65535 1、系统全局性修改。 # * 代表所有用户 * soft nofile 25535 * hard nofile 25535 2.用户局部性修改 #针对root用户,soft仅提醒,hard限制,nofile打开最大文件数 root soft nofile 65535 root hard nofile 65535 3.进程局部性修改 #针对nginx进程,nginx自带配置 /etc/nginx.conf worker_rlimit_nofile 30000
# 调整内核参数,让time_wait状态重用 [root@web01 ROOT]# vim /etc/sysctl.conf net.ipv4.tcp_tw_reuse = 1 # 开启端口复用 net.ipv4.tcp_timestamps = 0 # 禁用时间戳 [root@web01 ROOT]# sysctl -p #可以查看我们添加的内核参数 [root@web01 ROOT]# sysctl -a #可以查看所有内核参数
在高并发短连接的TCP服务器上,当服务器处理完请求后立刻主动正常关闭连接。这个场景下会出现大量socket处于TIME_WAIT状态。如果客户端的并发量持续很高,此时部分客户端就会显示连接不上。 我来解释下这个场景。主动正常关闭TCP连接,都会出现TIM_EWAIT。
为什么我们要关注这个高并发短连接呢?有两个方面需要注意:
- 高并发可以让服务器在短时间范围内同时占用大量端口,而端口有个0~65535的范围,并不是很多,刨除系统和其他这里有个相对长短的概念,比如取一个web页面,1秒钟的http短连接处理完业务,在关闭连接之后,这个业务用过的端口会停留在TIMEWAIT状态几分钟,而这几分钟,其他HTTP请求来临的时候是无法占用此端口的(占着茅坑不拉翔)。单用这个业务计算服务器的利用率会发现,服务器干正经事的时间和端口(资源)被挂着无法被使用的时间的比例是 1:几百,服务器资源严重浪费。(说个题外话,从这个意义出发来考虑服务器性能调优的话,长连接业务的服务就不需要考虑TIMEWAIT状态。同时,假如你对服务器业务场景非常熟悉,你会发现,在实际业务场景中,一般长连接对应的业务的并发量并不会很高。
3、代理服务器使用长连接
通常nginx作为代理服务,负责转发用户的请求,那么在转发的过程中建议开启HTTP长连接,用于减少握手次数,降低服务器损耗
[root@lb01 conf.d]# vim wp.conf upstream wp { server 172.16.1.7:80; server 172.16.1.8:80; keepalive 16; } server { }
4、配置静态页面缓存
浏览器缓存设置用于提高网站性能,尤其是新闻网站,图片一旦发布,改动的可能是非常小的,所以我们希望能否用户访问一次后,图片缓存在用户的浏览器长时间缓存。 浏览器是有自己的缓存机制,他是基于HTTP协议缓存机制来实现的,在HTTP协议中有很多头信息,那么实现浏览器的缓存就需要依赖特殊的头信息来与服务器进行特殊的验证,如Expires(http/1.0);Cache-control(http/1.1)。
浏览器缓存过期校验机制
Last-Modified:服务器上文件的最后修改时间
Etag:文件标识
Expires:本地缓存目录中,文件过期的时间(由服务器指定具体的时间)
Cache-control:本地缓存目录中,文件过期的时间(由服务器指定过期的间隔时间,由浏览器根据间隔生成具体的时间)
[root@web01 conf.d]# cat test.conf server { listen 80; server_name test.oldboy.com; root /code; location / { index index.html; } location ~ .*.(jpg|gif|png)$ { expires 7d; } }
新配置的页面不希望被用户缓存,希望用户每次请求都到源站
location ~ .*.(js|css|html)$ { add_header Cache-Control no-store; add_header Pragma no-cache; }
5、文件高效传输
sendfile 参数 vim nginx.conf ... sendfile on; tcp_nopush on; # 大文件开启此配置 tcp_nodelay on; # 小文件开启此位置 ...
如果传输的有大文件
打开 sendfile on
tcp_nopush on
如果小文件个数很多
打开 tcpnodelay on
6、静态资源压缩
Nginx将响应报文发送至客户端之前启用压缩功能,然后进行传输,这能够有效地节约带宽,并提高响应至客户端的速度
但是如果进行压缩会消耗CPU,因此我们需要考虑是不是进行压缩传输
[root@web01 conf.d]# cat test.conf server { listen 80; server_name test.oldboy.com; root /code; location / { index index.html; } location ~ .*.(txt|xml|html|json|js|css)$ { gzip on; # 开启gzip传输 gzip_http_version 1.1; # gzip版本 gzip_comp_level 5; # 压缩等级,1为最低 gzip_types text/plain application/json application/x-javascript application/css application/xml text/javascript; } }
7、防盗链
1.准备盗链的服务器 WEB01 [root@web01 conf.d]# cat test.conf server { listen 80; server_name test.oldboy.com; root /code; location / { index index.html; } location ~ .*.(jpg|png|gif) { gzip on; gzip_types image/jpeg image/gif image/png; gzip_comp_level 9; gzip_http_version 1.1; } } [root@web01 conf.d]# cat /code/index.html <html> <head> <meta charset="utf-8"> <title>oldboy.com</title> </head> <body style="background-color:pink;"> <center><img src="http://web.oldboy.com/daolian.jpg"/></center> </body> </html> 2.准备源站WEB02 [root@web02 conf.d]# cat d.conf server { listen 80; server_name web.oldboy.com; root /code; location / { index index.html; } } [root@web02 conf.d]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [root@web02 conf.d]# systemctl restart nginx 上传一张图片到/code [root@web02 code]# ll daolian.jpg -rw-r--r-- 1 root root 438692 Dec 19 11:33 daolian.jpg windows hosts解析 192.168.121.7 test.oldboy.com 192.168.121.8 web.oldboy.com 3.访问网站
4.在web02上配置防止盗链 [root@web02 conf.d]# cat d.conf server { listen 80; server_name web.oldboy.com; root /code; location / { index index.html; } location ~ .*.(jpg|png|gif) { valid_referers none blocked *.baidu.com; if ( $invalid_referer ) { return 403; } } } [root@web02 conf.d]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [root@web02 conf.d]# systemctl restart nginx # 指定返回页面或者图片 或者html页面 [root@web02 conf.d]# cat d.conf server { listen 80; server_name web.oldboy.com; root /code; location / { index index.html; } location ~ .*.(jpg|png|gif) { valid_referers none blocked *.baidu.com; if ( $invalid_referer ) { #return 403; rewrite ^(.*)$ /d.png break; # 在/code/下准备d.png的图片 } } }
8、跨域请求
什么是跨域访问,当我们通过浏览器访问a网站时,同时会利用到ajax或其他方式,同时也请求b网站,这样的话就出现了请求一个页面,使用了两个域名,这种方式对浏览器来说默认是禁止的。
那Nginx语序跨站访问与浏览器有什么关系呢,因为浏览器会读取Access-Control-Allow-Origin的头信息,如果服务端允许,则浏览器不会进行拦截。
1.配置跨域文件 [root@web02 conf.d]# cat s.conf server { listen 80; server_name s.oldboy.com; location / { root /code; index index.html; } } [root@web02 conf.d]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [root@web02 conf.d]# systemctl restart nginx [root@web02 conf.d]# cat /code/index.html <html lang="en"> <head> <meta charset="UTF-8" /> <title>测试ajax和跨域访问</title> <script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script> </head> <script type="text/javascript"> $(document).ready(function(){ $.ajax({ type: "GET", url: "http://test.oldboy.com", success: function(data) { alert("sucess 成功了!!!"); }, error: function() { alert("fail!!,跨不过去啊,不让进去啊,只能...!"); } }); }); </script> <body> <h1>跨域访问测试</h1> </body> </html> windows 解析 192.168.121.8 s.oldboy.com 192.168.121.7 test.oldboy.com 直接访问测试 s.oldboy.com
在web01配置允许跨域请求 [root@web01 conf.d]# cat test.conf server { listen 80; server_name test.oldboy.com; root /code; location / { index index.html; } location ~ .*.(html|htm)$ { add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS; } } nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [root@web01 conf.d]# systemctl restart nginx
9、cpu亲和
CPU亲和(affinity)减少进程之间不断频繁切换,减少性能损耗,其实现原理是建CPU核心和Nginx工作进程绑定方式,把每个worker进程固定到对应的cpu上执行,减少切换CPU的cache miss,获得更好的性能。
/etc/nginx/nginx.conf ... worker_cpu_affinity auto; ...
10、nginx优化总结
面试题: Nginx优化过哪些内容 1、CPU亲和、worker进程数、调整每个worker进程打开的文件数 # 必做 worker_cpu_affinity auto; worker_processes auto; ulimit -n 2、使用epool网络模型、调整每个worker进程的最大连接数 默认是1024 # 必做 event { use epool; worker_connections 10240; } 3、文件的高效读取sendfile、nopush # 看需求 # 传输大文件时最好打开 sendfile on; tcp_nopush on; # 小文件数量多的建议打开 tcp_nodelay on; 4、文件的传输实时性、nodealy # 看需求 5、开启tcp长连接,以及长连接超时时间keepalived # 配置如果有负载均衡 keepalived 16; 6、开启文件传输压缩gzip # 看需求 gzip on gzip_http_version 1.1; gzip_comp_level 5; gzip_types text/plain application/json application/x-javascript application/css application/xml text/javascript; 7、开启静态文件expires缓存 # 看需求 静态文件缓存天数 N年 expires 7d 8、隐藏nginx版本号 # 必做 server_token off; 9、禁止通过ip地址访问,禁止恶意域名解析,只允许域名访问 # 必做 空的主机头部 用IP地址访问业务 10、配置防盗链、以及跨域访问 # 看需求 11、防DDOS、cc攻击,限制单IP并发连接,以及http请求 # 看需求 limit_conn_zone $remote_addr zone=conn_zone:10m; #限制模块名称 客户端IP 开辟内存空间名称叫 conn_zone 空间大小10m location / { limit_conn conn_zone 1; # 限制limit_conn_zone空间里的所有IP 同一时间只有1个TCP连接 root /code/index; index index.html; } limit_req_zone $remote_addr zone=req_zone:10m rate=20r/s; # 每秒最多20个请求 location / { limit_req zone=req_zone burst=5 nodelay; # 限制延时处理5个,剩余的返回503 root /code/index; index index.html; } 12、优雅显示nginx错误页面 # 看需求 error_page 403 404 500 501 502 @error_test; location @error_test { rewrite ^(.*)$ /404.html break; } 13、nginx加密传输https优化 # 必做 ssl_certificate ssl_key/server.crt; ssl_certificate_key ssl_key/server.key;