一、Nginx配置文件
1.1 主配置文件
主配置文件位置:nginx.conf
tip:安装方式不同,路径不同
#主配置文件格式 main block:主配置段,即全局配置段,对http,mail都有效 #配置Nginx服务器的事件模块相关参数 events { ... } #http/https 协议相关配置段 http { ... } #默认配置文件不包括下面两个模块 #mail 协议相关配置段 mail { ... } #stream 服务器相关配置段 stream {负载均衡 ... }
[root@localhost ~]# vim /apps/nginx/conf/nginx.conf #编译安装nginx后,nginx.conf为例
1.2 子配置文件
子配置文件位置:conf.d/*.conf
tip:须在http模块下添加include 子配置文件位置
http块中可以包含多个子配置文件,常见的子配置文件
server块:用于配置HTTP服务器的具体行为,包括监听的端口、虚拟主机的配置、请求处理逻辑等。
location块:用于指定不同URL请求的处理方式,例如静态文件的服务、反向代理等。
upstream块:用于配置反向代理的目标服务器列表。
include指令:用于引入其他的子配置文件,可以将一些通用的配置项单独放在一个文件中,然后通过include指令引入。
二、全局配置部分(调优)
2.1 修改启动的工作进程数
通过使用 auto 参数,Nginx 可以根据系统的负载情况智能地分配工作进程,以提供更好的性能和资源利用率。
#修改主配置文件中的work_processes项 vim /apps/nginx/conf/nginx.conf
[root@localhost ~]# nginx -s reload #重新加载配置文件 [root@localhost ~]# ps axo pid,cmd,psr,ni|grep nginx 13013 nginx: master process /apps 1 0 13019 nginx: worker process 0 0 13020 nginx: worker process 0 0 13021 nginx: worker process 0 0 13022 nginx: worker process 1 0 13035 grep --color=auto nginx 0 0
2.2 cpu与worker process绑定
在 Nginx 配置文件中,worker_cpu_affinity
指令用于控制 worker 进程与 CPU 的亲缘性(affinity)关系
[root@localhost ~]# vim /apps/nginx/conf/nginx.conf user nginx; worker_processes auto; worker_cpu_affinity 00000001 00000010; #绑定到 第一 和 第二块cpu上 error_log /var/log/nginx/error.log; #指定错误日志的路径和文件名
[root@localhost ~]# 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
2.3PID路径修改
2.4 修改工作进程的优先级
工作进程优先级,-20~19
[root@localhost ~]# nginx -s reload [root@localhost ~]# ps axo pid,cmd,psr,ni|grep nginx|sort -n 13501 nginx: master process /apps 2 0 14025 nginx: worker process 2 -20 14026 nginx: worker process 3 -20 14027 nginx: worker process 1 -20 14028 nginx: worker process 0 -20 14038 grep --color=auto nginx 3 0
2.5 调试工作进程打开文件的数量
2.5.1 基本原理
所有worker进程能打开的文件数量上限,包括:Nginx的所有连接(例如与代理服务器的连接等),而不仅仅是与客户端的连接,另一个考虑因素是实际的并发连接数不能超过系统级别的最大打开文件数的限制.最好与ulimit -n 或者limits.conf的值保持一致,
2.5.2 配置过程
先修改主配置文件
vim /apps/nginx/conf/nginx.conf #添加 worker_rlimit_nofile 65536
再修改系统默认项
临时修改:
ulimit -n 70000 #修改单个进程能打开的最大文件数为 70000 #仅应用于当前会话即不会永久修改限制 ulimit -a #显示当前用户的所有资源限制信息
[root@localhost ~]# ulimit -n 70000 [root@localhost ~]# 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) 7168 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 70000 #默认值为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) 7168 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
永久修改:
vim /etc/security/limits.conf #在最后加入 * soft core unlimited * hard core unlimited * soft nproc 1000000 * hard nproc 1000000 * soft nofile 1000000 * hard nofile 1000000 * soft memlock 32000 * hard memlock 32000 * soft msgqueue 8192000 * hard msgqueue 8192000 `nproc`(最大进程数限制)的软限制和硬限制都设置为 1000000,当前用户在单个会话中可以创建的最大进程数为 1000000 `nofile`(打开文件描述符限制)的软限制和硬限制都设置为 1000000,这意味着当前用户在单个会话中可以使用的最大文件描述符数将被限制为 1000000。软限制是软性限制,用户可以根据需要进行调整,而硬限制是硬性限制,一旦设定,用户无法超过该限制 `memlock`(锁定内存限制)的软限制和硬限制都设置为 32000,这意味着当前用户在单个会话中可以锁定的最大内存量为 32000KB `msgqueue`(消息队列限制)的软限制和硬限制都设置为 8192000,这意味着当前用户在单个会话中可以使用的最大消息队列大小为 8192000字节
2.6 关闭master-worker工作模式(仅测试用)
master_process off|on; #是否开启Nginx的master-worker工作模式,仅用于开发调试场景,默认为on
三、events部分
在Nginx的主配置文件中,events部分用于配置Nginx服务器的事件模块相关参数,控制Nginx服务器在处理连接请求时的行为。
常见的events配置参数:
worker_connections:指定每个工作进程可以同时处理的最大连接数。
multi_accept:指定是否一次接受多个连接。默认情况下,Nginx在每个循环中只接受一个连接,但设置multi_accept为"on"后可以同时接受多个连接。
use:指定Nginx使用的事件模块。常见的事件模块有"epoll"、"kqueue"和"eventport"等。
#举个例子 events { worker_connections 1024; multi_accept on; use epoll; } #指定了每个工作进程可以处理的最大连接数为1024,启用了多个连接同时接受,以及使用了epoll事件模块
四、http设置 (重要)
4.1http部分详解
include:引入其他配置文件,通常用于加载 MIME 类型配置文件。
default_type:指定默认的 MIME 类型。
server:定义一个或多个虚拟主机。
listen:指定该虚拟主机监听的端口。
server_name:指定域名,用于匹配请求的主机头。
root:指定虚拟主机的根目录。
location:用于匹配不同的 URL,并定义相关配置规则。
#基本格式 http { ... ... #各server的公共配置 server { #每个server用于定义一个虚拟主机,第一个server为默认虚拟服务器 ... } server { ... server_name #虚拟主机名 root #主目录 alias #路径别名 location [OPERATOR] URL { #指定URL的特性 ... if CONDITION { ... } } } }
#详解 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" ' refer是跳转的源地址,如果没有跳转 没有refer # '"$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,可以以空格隔开写多个并支持正则表达式,如:*.kgc.com www.kgc.* ~^www\d+\.kgc\.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
4.2 mime
在Nginx中,“mime” 是一种配置指令,用于设置 MIME 类型与文件扩展名的映射关系。
vim /apps/nginx/conf/mime.types #查看当前Nginx服务器配置的MIME类型列表
4.3 server 下的 root指令
在Nginx配置中,"root"指令用于设置服务器块(server block)的根目录,即指明软件的根目录。
通常,"root"指令位于Nginx配置文件中的服务器块(server block)中。
server { listen 80; server_name example.com; root /var/www/html; location / { ... } ... } #指定了服务器块的根目录为"/var/www/html" #访问该服务器的网站时,Nginx会在"/var/www/html"文件夹中查找并提供相应的静态文件
4.4 构建虚拟主机
4.4.1 基于域名的虚拟主机
以手机端和电脑端为例
mkdir -p /apps/nginx/conf.d/#建立虚拟主机配置文件目录 cd /apps/nginx/conf #主配置文件所在目录 #添加到http模块中 vim nginx.conf include /apps/nginx/conf.d/*.conf; #声明子配置文件的位置,需要写在最上面 nginx -t #保存后检查语法
cd /apps/nginx/conf.d/ #编写电脑端的配置文件 vim computer.conf server{ listen 192.168.10.10:80; server_name www.computer.com; location / { root /data/nginx/html/pc; } } #编写手机端的配置文件 vim mobile.conf server { listen 192.168.10.10:80; server_name www.mobile.com; root /data/nginx/html/mobile/; } [root@localhost logs]# 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@localhost logs]# nginx -s reload
#构建数据文件夹 mkdir /apps/nginx/html/pc -pv mkdir /apps/nginx/html/mobile -pv
#构建数据文件 echo This is computer > /apps/nginx/html/pc/index.html echo This is mobile > /apps/nginx/html/mobile/index.html
#切换到测试机 #修改本地hosts文件 添加对应映射 vim /etc/hosts 192.168.10.10 www.computer.com 192.168.10.10 www.mobile.com
#测试 curl www.mobile.com This is mobile curl www.computer.com This is computer
4.4.2 基于端口
服务端 #编辑子配置文件 mobile.conf,修改端口号 server{ listen 192.168.10.10:8080; server_name www.mobile.com; root /data/nginx/html/moblie; } #computer.conf 不变 server{ listen 192.168.10.10:80; server_name www.computer.com; root /data/nginx/html/pc; }
切换到客户端 curl 192.168.10.10:8080 This is mobile curl 192.168.10.10:80 This is computer
4.4.3 基于ip地址
服务端 添加新网卡并配置
#编辑子配置文件mobile.conf,修改IP地址 cd /apps/nginx/conf.d/ vim mobile.conf server{ listen 192.168.10.11:80; server_name www.mobile.com; root /data/nginx/html/mobile; } #computer.conf不变 server{ listen 192.168.10.10:80; server_name www.computer.com; root /data/nginx/html/pc; }
修改客户端hosts文件 vim /etc/hosts 192.168.10.10 www.computer.com 192.168.10.11 www.mobile.com
curl 192.168.10.11 This is mobile curl 192.168.10.10 This is computer
4.5 路径别名-----alias
在 Nginx 中,alias 用于创建一个路径别名的指令。
别名可以用于将文件或目录从一个位置映射到另一个位置,提供更灵活的访问控制。
服务端 #编辑子配置文件cxk.conf,使用alias server { listen 80; location /test{ alias /apps/nginx/html/pc; #相当于替换,访问/test/就是访问/apps/nginx/html/pc; } }
4.6 location模块
在Nginx中,location
是一个用于匹配请求 URL 路径的指令。它在 Nginx 配置文件中使用,在不同的 location
块中定义不同的行为或处理规则。
#官方帮助文档 http://nginx.org/en/docs/http/ngx_http_core_module.html#location
#基本语法 location [修饰符] 匹配的路径 { ... 配置指令 ... } ```
修饰符 | 功能 |
---|---|
= | 精确字符串匹配 |
^~ | 前缀匹配,如果URL路径以指定的字符串开始,则停止查找其他匹配。 |
~ | 使用正则表达式进行匹配,区分大小写 |
~* | 使用正则表达式进行匹配,不区分大小写 |
不带符号 | 匹配起始于此uri的所有的uri |
\ | 表示包含正则表达式并且转义字符 |
优先级
4.7 基于四层的访问控制-----access模块
Nginx的access
模块允许用户定义基于IP地址、请求方法、URI等条件的访问规则,以控制客户端对NGINX服务器上特定资源的访问。
1)IP地址访问控制:允许或拒绝特定IP地址或IP地址范围的访问。
拒绝特定IP地址的访问 location / { deny 192.168.10.10; #默认允许所有 }
允许特定IP地址段的访问 location / { allow 192.168.2.0/24; deny all; }
2)请求方法访问控制:允许或拒绝特定HTTP请求方法(如GET、POST等)的访问。
仅允许GET请求 if ($request_method != GET) { return 403; }
3)URI访问控制:允许或拒绝特定URI或URI模式的访问。
拒绝特定URI的访问 location /cxk { deny all; }
允许特定URI模式的访问 location ~ ^/api/ { allow all; }
4)条件组合访问控制:根据多个条件的组合来实施访问控制策略。
仅允许特定IP地址段的GET请求访问特定URI模式 #举个例子 location ~ ^/api/ { if ($request_method != GET) { return 403; } allow 192.168.1.0/24; deny all; }
4.8 验证模块
4.8.1 htpasswd命令
安装 yum install httpd-tools -y
常用命令 #第一次生成文件 htpasswd -c 文件路径 姓名 交互式生成密码 htpasswd -bc 文件路径 姓名 密码 直接将密码跟在 -c 代表新建用户名和密码对应的文件 -b 将密码跟在用户名后
#非第一次生成文件 htpasswd 文件路径 姓名 交互式生成密码 htpasswd -b 文件路径 姓名 密码 直接将密码跟在后面
4.8.2 配置验证模块
#编辑配置文件 vim cxk.conf server { listen 80; location /test{ alias /apps/nginx/html/pc; } location /admin{ root /data/nginx/html/pc; auth_basic "admin site"; #提示信息,不是所有浏览器都有用 auth_basic_user_file /apps/nginx/conf.d/.httpuser; #密码文件存放位置 } }
使用 Basic 认证(基本认证)对用户进行身份验证
htpasswd -bc /apps/nginx/conf.d/.httpuser byyd 123456 #创建一个.htpasswd文件,并添加一个使用Basic认证的用户名和密码
使用主机浏览器
访问192.168.10.10/admin
4.9 关闭或修改版本信息
4.9.1 关闭版本信息显示
Syntax: server_tokens on | off | build | string; Default: server_tokens on; Context: http, server, location #修改配置文件 放在 http语句中 http { server_tokens off; [root@localhost nginx]#nginx -s reload #重新加载 验证 [root@localhost sbin]#curl -I http://192.168.10.10/ HTTP/1.1 200 OK Server: nginx/1.18.0 Date: Thu, 21 Apr 2022 03:34:51 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Tue, 19 Apr 2022 02:43:17 GMT Connection: keep-alive ETag: "625e21c5-264" Accept-Ranges: bytes [root@localhost sbin]#curl -I http://192.168.10.10/ HTTP/1.1 200 OK Server: nginx Date: Thu, 21 Apr 2022 04:04:23 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Tue, 19 Apr 2022 02:43:17 GMT Connection: keep-alive ETag: "625e21c5-264" Accept-Ranges: bytes
4.9.2 修改nginx 版本信息 优化
思路: 修改安装包里源码, 再重新编译 源码路径 /nginx-1.18.0/src/core/nginx.h
cd /opt vim./nginx-1.18.0/src/core/nginx.h #修改前 #define nginx_version 1018000 #define NGINX_VERSION "1.18.0" #define NGINX_VER "nginx/" NGINX_VERSION #修改后 #define nginx_version 1018000 #define NGINX_VERSION "cxk" #define NGINX_VER "nginx/" NGINX_VERSION vim ./nginx-1.18.0/src/http/ngx_http_header_filter_module.c #修改模块的源代码文件 #修改前 static u_char ngx_http_server_string[] = "Server: nginx" CRLF; static u_char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF; static u_char ngx_http_server_build_string[] = "Server: " NGINX_VER_BUILD CRLF; #修改后 static u_char ngx_http_server_string[] = "Server: cxk" CRLF; static u_char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF; static u_char ngx_http_server_build_string[] = "Server: " NGINX_VER_BUILD CRLF;
##然后重新编译安装 ./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 make -j2 && make install 编译安装完成后,重启 nginx -v #查看版本信息 curl -I 192.168.2.100
4.10 自定义 错误页面
#error_page 404 /404.html; #默认错误页面
修改错误页面的主要目的是为了提供更友好的用户体验和品牌一致性。
也可以用指定的响应状态码进行响应。
#部分响应状态码 400 Bad Request:请求不正确或无效的错误页面。 401 Unauthorized:未授权访问的错误页面。 403 Forbidden:禁止访问的错误页面。 404 Not Found:页面未找到的错误页面。 500 Internal Server Error:服务器内部错误的错误页面。 502 Bad Gateway:错误的网关请求的错误页面。 503 Service Unavailable:服务不可用的错误页面
配置文件中的可用位置:http, server, location, if in location。
#基本格式 error_page code ... [=[response]] uri; #构成详解 error_page 固定写法 code 响应码 = 可以将响应码转换 uri 访问连接
新建错误页面和错误页面目录 mkdir /apps/nginx/html/pc/error/ cd /appsnginx/html/pc/error/ vim 40x.html #错误页面 在子配置文件的sever语块下 error_page 404 =302 /40x.html; location = /40x.html { root /apps/nginx/html/pc/error/; }
4.11 修改日志的位置
通过修改日志的路径,可以实现日志分离,即不同网站的日志单独存放。
mkdir /data/logs #新建存放日志的目录 #编辑子配置文件,指定日志存放位置 在server语块下添加 error_log /data/logs/m_error.log; access_log /data/logs/m_access.log; nginx -t nginx -s reload #语法检查无误后重载
4.13 长连接相关-----keepalive指令
4.13.1 原理
HTTP Keep-Alive 功能用于实现长连接,允许客户端和服务器之间的 TCP 连接在发送完一个请求后保持打开状态,以便在同一连接上发送多个请求和响应。
可以加在全局或者 server 。
keepalive 配置指令仅对 HTTP/1.0 和 HTTP/1.1 版本的连接有效。
对于 HTTP/2 连接,keepalive 功能是默认启用的,并且无需额外配置。
4.13.2 keepalive_timeout
keepalive_timeout timeout [header_timeout]; #设定保持连接超时时长
keepalive_timeout
用于定义长连接超时时间。
当一个客户端与服务器之间的连接完成一个请求后的等待时间。 如果在这个时间内没有收到新的请求,服务器会关闭连接。 这个时间是以秒为单位的,默认值是 75 秒。
4.13.3 keepalive_requests
keepalive_requests number; #在一次长连接上所允许请求的资源的最大数量
keepalive_requests 用于设置一个连接上可以处理的最大请求数量。
当达到指定数量后,服务器会关闭该连接并且客户端需要重新建立新连接。
默认情况下,keepalive_requests 的值是 100。
如果将 keepalive_requests 设置为 0,则表示在完成每个请求后立即关闭连接,禁用了 Keep-Alive 功能。
4.14 用户上传资料
client_max_body_size 1m; #设置允许客户端上传单个文件的最大值,默认值为1m,上传文件超过此值会出413错误 client_body_buffer_size size; #用于接收每个客户端请求报文的body部分的缓冲区大小;默认16k;超出此大小时,其将被暂存到磁盘上的由下面client_body_temp_path指令所定义的位置 client_body_temp_path path [level1 [level2 [level3]]]; #设定存储客户端请求报文的body部分的临时存储路径及子目录结构和数量,目录名为16进制的数字,使用hash之后的值从后往前截取1位、2位、2位作为目录名 上传文件大于限制 错误代码413
4.15 其他设置
directio size | off; #操作完全和aio相反,aio是读取文件而directio是写文件到磁盘,启用直接I/O,默认为关闭,当文件大于等于给定大小时,例如:directio 4m;同步(直接)写磁盘,而非写缓存。 直接 写入 磁盘 还是等待一定数据量写入磁盘
open_file_cache off; #是否缓存打开过的文件信息 open_file_cache max=N [inactive=time]; #nginx可以缓存以下三种信息: (1) 文件元数据:文件的描述符、文件大小和最近一次的修改时间 (2) 打开的目录结构 (3) 没有找到的或者没有权限访问的文件的相关信息 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 范例: 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; #缓存错误信息 limit_except method ... { ... },仅用于location #限制客户端使用除了指定的请求方法之外的其它方法 method:GET, HEAD, POST, PUT, DELETE,MKCOL, COPY, MOVE, OPTIONS, PROPFIND, PROPPATCH, LOCK, UNLOCK, PATCH limit_except GET { allow 192.168.91.101; deny all; } #除了GET和HEAD 之外其它方法仅允许192.168.1.0/24网段主机使用
五、变量
在NGINX中,变量是一种用于存储和检索HTTP请求和响应中的数据的机制。
变量可以包含请求头、请求方法、请求参数、时间戳等信息。
http://nginx.org/en/docs/varindex.html 官方文档
5.1 内置变量
5.1.1 常用内置变量
当NGINX作为反向代理服务器时,它将接收到的客户端请求转发给后端服务器。为了保持请求的来源信息,NGINX可以在转发请求时设置X-Forwarded-For头部,以便后端服务器知道真实的客户端IP地址。
内置变量 | 功能 |
---|---|
$remote_addr | 客户端的地址,注意是客户端的公网IP |
$proxy_add_x_forwarded_for | 在反向代理服务器中设置X-Forwarded-For请求头 |
$args | 请求的查询参数 |
$arg_ | 输出名为的查询参数的值 |
$document_root | 当前请求的根目录路径 |
$document_uri | 当前请求的URI,不包括查询字符串部分 |
$host | 存放了请求的主机名 |
limit_rate | 如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置, 则显示0 |
$remote_port | 客户端请求Nginx服务器时随机打开的端口,这是每个客户端自己的端口 |
$remote_user | 已经经过Auth Basic Module验证的用户名 |
$request_body_file | 做反向代理时发给后端服务器的本地资源的名称 |
$request_method | 请求资源的方式,GET/PUT/DELETE等 |
$request_filename | 当前请求的文件路径 |
$request_uri | 包含请求参数的原始URI,不包含主机名 |
$scheme | 请求使用的协议(http或https) |
$server_protocol | 保存了客户端请求资源使用的协议的版本 |
$server_addr | 保存了服务器的IP地址 |
$server_name | 请求的服务器的主机名 |
$server_port | 请求的服务器的端口号 |
$http_ | 记录请求报文的首部字段 |
$http_user_agent | 客户端使用的用户代理 |
$http_cookie | 请求中的Cookie |
$cookie_ | name为任意请求报文首部字部cookie的key名 |
$sent_http_ | name为响应报文的首部字段 |
5.1.2自定义变量
假如需要自定义变量名称和值,使用指令set $variable value;
语法格式:
Syntax: set $variable value; Default: — Context: server, location, if
范例:
set $name kgc; echo $name; set $my_port $server_port; echo $my_port; echo "$server_name:$server_port"; #输出信息如下 [root@centos6 ~]#curl www.kgc.org/main kgc 80 www.kgc.org:80 ###################################################### 实际例子: location /test { set $name kgc; echo $name; set $my_port $server_port; echo $my_port; }
六、自定义访问日志 (优化)
自定义访问日志可以提供更灵活和定制化的日志记录方式。
1.满足特定需求:通过自定义访问日志,你可以选择记录特定的访问信息,如客户端IP地址、访问时间、请求内容、状态码、传输字节数、引用页面、用户代理等。这些信息可以根据你的需求进行自定义,以满足特定的分析、监控或统计需求。
2.减少日志量:默认情况下,Nginx 记录的访问日志较为详细,包含了大量的信息。而自定义访问日志可以让你只记录感兴趣的信息,避免产生过多的日志数据,减少磁盘空间和读写开销。
3.提高性能:自定义访问日志可以减少磁盘的写入操作,从而减小对系统性能的影响。尤其在高访问量的情况下,减少日志量可以提高系统的处理能力和响应速度。
4.日志分析与监控:自定义访问日志可以使日志数据更易于分析和监控。你可以根据自定义的格式,使用各种日志分析工具或脚本,提取有用的信息,进行访问分析、安全审计、性能优化等工作。
6.1自定义访问日志的格式
要自定义 Nginx 的访问日志,你需要编辑 Nginx 的配置文件,并修改 http
部分的日志格式。
以下是一个简单的例子,展示了如何在 Nginx 配置文件中定义一个自定义的访问日志格式:
http { # 定义自定义访问日志格式 log_format my_custom_log '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent"'; # 配置使用自定义访问日志格式的访问日志文件 access_log /path/to/custom_access.log my_custom_log; # 其他配置项... } 在上述例子中,我们使用 `log_format` 指令定义了一个名为 `my_custom_log` 的自定义日志格式,该格式包含了 IP 地址、用户名、访问时间、请求内容、状态码、传输字节数、引用页面和用户代理等信息。 然后,在 `access_log` 指令中指定了一个自定义访问日志文件的路径 `/path/to/custom_access.log`,并且将之前定义的 `my_custom_log` 格式应用于该日志文件。 请注意,修改完配置文件之后,记得重新加载 Nginx 配置使改动生效,使用命令 `nginx -s reload` 可以实现配置文件的热重载。
6.2 自定义json 格式日志
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"}'; location / { root /data/nginx/pc/; access_log logs/access.log access_json; } '"http_user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTMLe/101.0.4951.54 Safari/537.36",' '"status":"304"}'
七、Nginx压缩功能(重要)
Nginx通过在服务器上启用gzip模块来提供压缩功能。
启用gzip后,Nginx会自动检测客户端的浏览器支持情况,然后在服务器和客户端之间压缩和解压缩文件。
太小的文件没必要压缩,压缩说不定变大了。
官方文档: Module ngx_http_gzip_module
参数项 | 释义 | 参数值 |
---|---|---|
gzip | 开启或关闭压缩机制 | on/off; |
gzip_types | 根据文件类型选择性开启压缩机制 | image/png、text/css… |
gzip_comp_level | 用于设置压缩级别,级别越高越耗时 | 1~9(越高压缩效果越好) |
gzip_vary | 设置是否携带Vary:Accept-Encoding头域的响应头部 | on/off |
gzip_buffers | 设置处理压缩请求的缓冲区数量和大小 数量 大小 | 如16 8k |
gzip_disable | 针对不同客户端的请求来设置是否开启压缩 | 如 .Chrome. |
gzip_http_version | 指定压缩响应所需要的最低HTTP请求版本 | 如1.1 |
gzip_min_length | 设置触发压缩的文件最低大小 | 如512k |
gzip_proxied | 对于后端服务器的响应结果是否开启压缩 | off、expired、no-cache… |
http{ # 开启压缩机制 gzip on; # 指定会被压缩的文件类型(也可自己配置其他类型) gzip_types text/plain application/javascript text/css application/xml text/javascript image/jpeg image/gif image/png; # 设置压缩级别,越高资源消耗越大,但压缩效果越好 gzip_comp_level 5; # 在头部中添加Vary: Accept-Encoding(建议开启) gzip_vary on; # 处理压缩请求的缓冲区数量和大小 gzip_buffers 16 8k; # 对于不支持压缩功能的客户端请求不开启压缩机制 gzip_disable "MSIE [1-6]\."; # 低版本的IE浏览器不支持压缩 # 设置压缩响应所支持的HTTP最低版本 gzip_http_version 1.1; # 设置触发压缩的最小阈值 gzip_min_length 2k; # 关闭对后端服务器的响应结果进行压缩 gzip_proxied off; }
八、HTTPS 功能
8.1 Nginx的HTTPS工作原理的详解
1)客户端发送HTTPS请求:客户端(例如Web浏览器)通过HTTPS协议向Nginx服务器发送加密的HTTP请求。默认情况下,HTTPS使用443端口进行通信。
2)服务器证书握手:Nginx服务器接收到HTTPS请求后,会向客户端发送已经配置好的SSL证书。该证书包含了服务器的公钥以及其他相关信息,例如服务器的域名。
3)客户端验证证书:客户端接收到服务器发送的证书后,会使用预置的受信任证书颁发机构(CA)根证书列表来验证详细的服务器证书链。客户端会检查证书是否由受信任的CA签发,并验证证书的有效性和真实性。如果证书通过验证,客户端可以确认服务器的身份。
4)密钥交换:如果服务器的证书被成功验证,客户端会生成一个随机的对称密钥,称为“会话密钥”。然后,客户端使用服务器的公钥来加密该会话密钥,并将其发送给服务器。
5)数据加密:Nginx服务器接收到客户端发送的加密的会话密钥后,使用服务器的私钥解密该会话密钥。此后,Nginx服务器和客户端使用会话密钥来进行对称加密和解密,以加密和解密数据的传输。
6)安全数据传输:一旦会话密钥被交换并使用,Nginx服务器和客户端之间的通信将通过使用会话密钥进行加密和解密来保证安全性。所有通过HTTPS协议传输的数据,包括HTTP请求和响应内容,都将被加密。
客户端和服务器之间的加密通道建立后,数据在传输过程中将经过加密,从而提供了更高的安全性。
8.2 启用功能模块的配置过程
Nginx的HTTPS功能通过ngx_http_ssl_module模块来实现的。
ngx_http_ssl_module模块为Nginx添加了对SSL/TLS协议的支持,使其能够提供HTTPS服务。
ngx_http_ssl_module模块提供了一组配置项,用于指定SSL证书、私钥、加密算法、协议版本以及其他与SSL/TLS相关的设置。
配置步骤:
1)获取SSL证书和私钥:从证书颁发机构(CA)或自签名证书颁发机构获取有效的SSL证书和对应的私钥文件。证书用于验证服务器的身份,私钥用于解密SSL连接。
2)配置Nginx:编辑主配置文件nginx.conf
ssl_certificate:指定SSL证书文件的路径。 ssl_certificate_key:指定SSL私钥文件的路径。 ssl_protocols:指定支持的TLS协议版本,例如TLSv1.2、TLSv1.3。 ssl_ciphers:指定加密算法套件,例如AES128-GCM-SHA256、ECDHE-RSA-AES256-GCM-SHA384。 其他可选的SSL配置项:ssl_prefer_server_ciphers、ssl_session_timeout等。
#举例子 server { listen 443 ssl; server_name example.com; ssl_certificate /path/to/certificate.crt; ssl_certificate_key /path/to/private/key.key; # SSL配置项 ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; }
3)重启Nginx:保存配置文件,并重新加载或重启Nginx服务。
nginx -s reload
九、自定义图标
favicon.ico
文件是浏览器收藏网址时显示的图标。
当客户端使用浏览器问页面时,浏览器会自己主动发起请求获取页面的favicon.ico文件。 当浏览器请求的favicon.ico
文件不存在时,服务器会记录404日志
,而浏览器会显示404
报错。
#方法一:服务器不记录访问日志: location = /favicon.ico { log_not_found off; access_log off; } #方法二:将图标保存到指定目录访问: #location ~ ^/favicon\.ico$ { location = /favicon.ico { root /data/nginx/html/pc/images; expires 365d; #设置文件过期时间 }
十、重写功能 rewrite
Nginx服务器利用 ngx_http_rewrite_module
模块解析和处理rewrite请求。
Nginx 的重写功能是指通过修改请求 URL 的方式来实现URL重定向或者路由转发的功能。
通过使用重写规则,可以对访问的URL进行匹配和替换,以达到用户期望的效果。
#举个例子 location /old-url { rewrite ^/old-url/(.*)$ /new-url/$1 permanent; } 匹配以 "/old-url/" 开头的请求,并将其重定向到 "/new-url/"。
10.1 if指令
基本原理
官方文档 Module ngx_http_rewrite_module
if指令用于条件匹配判断,并根据条件判断结果选择不同的Nginx配置,可以配置在server或location块中。
Nginx的if语法仅能使用if做单次判断,不支持使用if else或者if elif这样的多重判断。
基本语法
if (条件匹配) { action }
使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,否则认为false。
变量与表达式之间使用以下符号链接
= #比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false != #比较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false ~ #区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假 !~ #区分大小写字符,判断是否匹配,不满足匹配条件为真,满足匹配条件为假 ~* #不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假 !~* #不区分大小字符,判断是否匹配,满足匹配条件为假,不满足匹配条件为真
-f 和 !-f #判断请求的文件是否存在和是否不存在 -d 和 !-d #判断请求的目录是否存在和是否不存在 -x 和 !-x #判断文件是否可执行和是否不可执行 -e 和 !-e #判断请求的文件或目录是否存在和是否不存在(包括文件,目录,软链接)
如果$ 变量的值为空字符串或0,则if指令认为该条件为false,其他条件为true。
$变量的值如果以0开头的任意字符串会返回false
location /main { index index.html; default_type text/html; if ( $scheme = http ){ echo "if-----> $scheme"; } if ( $scheme = https ){ echo "if ----> $scheme"; } #if (-f $request_filename) { # echo "$request_filename is exist"; #} if (!-e $request_filename) { echo "$request_filename is not exist"; #return ; } } 【用户访问的文件不存在 直接返回主页】 server { listen 80; server_name www.kgc.com; root /data/nginx/pc/; location / { root /data/nginx/pc/; } location /test { default_type text/plain; return 301 http://www.baidu.com; } location /main { index index.html; default_type text/html; if ( $scheme = http ){ return 666 "if-----> $scheme"; } if (!-e $request_filename){ return 302 /index.html; #如果用户不存在直接跳转到主页面 } } } www.kgc.com/main/xxxxx #注意访问的main下的不存在 目录 #注意前面的if语句执行后会 停止匹配 【想控制所有网站可以 放到前面】 server { listen 80; server_name www.kgc.com; root /data/nginx/pc/; if (!-e $request_filename){ return 302 /index.html; #如果用户不存在直接跳转到主页面 } location / { root /data/nginx/pc/; } location /test { default_type text/plain; return 301 http://www.baidu.com; } location /main { index index.html; default_type text/html; if ( $scheme = http ){ return 666 "if-----> $scheme"; } } }
10.2 return指令
return用于完成对请求的处理,并直接向客户端返回响应状态码,比如:可以指定重定向URL(对于特殊重定向状态码,301/302等) 或者是指定提示文本内容(对于特殊状态码403/500等),处于此指令后的所有配置都将不被执行,return可以在server、if 和 location块进行配置
语法格式:
www.kgc.com/test/ 404 return code; #返回给客户端指定的HTTP状态码 return code [text]; #返回给客户端的状态码及响应报文的实体内容,可以调用变量,其中text如果有空格,需要用单或双引号 return code url; #返回给客户端的URL地址
范例:
location / { root /data/nginx/html/pc; default_type text/html; index index.html; if ( $scheme = http ){ #return 666; #return 666 "not allow http"; #return 301 http://www.baidu.com; return 500 "service error"; echo "if-----> $scheme"; #return后面的将不再执行 } if ( $scheme = https ){ echo "if ----> $scheme"; } } ############################################################## 例子1: server { listen 80; server_name www.kgc.com; root /data/nginx/pc/; location /{ root /data/nginx/pc/; } location /test { #访问test 直接返回403 return 403; #可以改成666 } } 例子2: location /test { #访问test 直接返回403 return 666 "hello"; #可以改成666自定义,hello是描述 文字可以 图形浏览器不可以 } 例子3: location /test { default_type text/plain; #定义文本格式后图形浏览器可以看见 return 666 "hello"; } 例子4: location /test { default_type text/plain; return 302 http://www.baidu.com; } location /test { default_type text/plain; return 301 /index.html; } 301 缓存在磁盘上,有些 302 没有缓存 , 服务器断开无法重定向 jd
永久重定向
10.3 set 指令
指定key并给其定义一个变量,变量可以调用Nginx内置变量赋值给key,另外set定义格式为set $key value,value可以是text, variables和两者的组合。
location /main { root /data/nginx/html/pc; index index.html; default_type text/html; set $name kgc; echo $name; set $my_port $server_port(nginx 自带的变量 服务端口 一般80); echo $my_port; }
10.4 break指令
用于中断当前相同作用域(location)中的其他Nginx配置,与该指令处于同一作用域的Nginx配置中,位于它前面的配置生效,位于后面的 ngx_http_rewrite_module 模块中指令就不再执行,Nginx服务器在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置,该指令可以在server块和locationif块中使用
注意: 如果break指令在location块中后续指令还会继续执行,只是不执行 ngx_http_rewrite_module 模块的指令,其它指令还会执行
使用语法如下:
if ($slow) { limit_rate 10k; break; } location /main { root /data/nginx/html/pc; index index.html; default_type text/html; set $name kgc; echo $name; break; #location块中break后面指令还会执行 set $my_port $server_port; echo $my_port; }
10.5 rewrite 指令
通过正则表达式的匹配来改变URI,可以同时存在一个或多个指令,按照顺序依次对URI进行匹配,rewrite主要是针对用户请求的URL或者是URI做具体处理
官方文档:
https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite % s/旧的/新的/
rewrite可以配置在 server、location、if
语法格式 :
rewrite可以配置在 server、location、if 语法格式 : rewrite regex replacement(www.baidu.com) [flag]; 正则匹配原始访问url 替代你想让客户访问的 标志 ()premanent301 redirect302 break last
rewrite将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为表达式指定的新的URI
注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,隐含有循环机制,但不超过10次;如果超过,提示500响应码,[flag]所表示的标志位用于控制此循环机制如果替换后的URL是以http://或https://开头,则替换结果会直接以重定向返回给客户端, 即永久重定向 301
正则表达式格式
. #匹配除换行符以外的任意字符 \w #匹配字母或数字或下划线或汉字 \s #匹配任意的空白符 \d #匹配数字 [0-9] \b #匹配单词的开始或结束 ^ #匹配字付串的开始 $ #匹配字符串的结束 * #匹配重复零次或更多次 + #匹配重复一次或更多次 ? #匹配重复零次或一次 (n) #匹配重复n次 {n,} #匹配重复n次或更多次 {n,m} #匹配重复n到m次 *? #匹配重复任意次,但尽可能少重复 +? #匹配重复1次或更多次,但尽可能少重复 ?? #匹配重复0次或1次,但尽可能少重复 {n,m}? #匹配重复n到m次,但尽可能少重复 {n,}? #匹配重复n次以上,但尽可能少重复 \W #匹配任意不是字母,数字,下划线,汉字的字符 \S #匹配任意不是空白符的字符 \D #匹配任意非数字的字符 \B #匹配不是单词开头或结束的位置 [^x] #匹配除了x以外的任意字符 [^kgc] #匹配除了kgc 这几个字母以外的任意字符
rewrite flag 使用介绍
利用nginx的rewrite的指令,可以实现url的重新跳转,rewrtie有四种不同的flag,分别是redirect(临时重定向302)、permanent(永久重定向301)、break和last。其中前两种是跳转型的flag,后两种是代理型
-
跳转型指由客户端浏览器重新对新地址进行请求
-
代理型是在WEB服务器内部实现跳转
rewrite 格式
Syntax: rewrite regex replacement [flag]; #通过正则表达式处理用户请求并返回替换后的数据包。 Default: — Context: server, location, if hn 湖南 海南 河南 hn hainan
flag 说明
redirect;302 #临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求;使用相对路径,或者http://或https://开头,状态码:302 permanent;301 www.bj.com www.beijing.com #重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求,状态码:301 break; www.bj.com #重写完成后,停止对当前URL在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置;结束循环,建议在location中使用 #适用于一个URL一次重写 last; #重写完成后,停止对当前URI在当前location中后续的其它重写操作,而后对新的URL启动新一轮重写检查,不建议在location中使用 #适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户301
例子:
www.haishi.com www.hs.com
#访问 bj 跳转到 beijing location /bj { root /data/nginx/pc; rewrite ^/bj/(.*) /beijing/$1 permanent; } 此处的$1代表后项引用 location / { root /data/nginx/html/pc; index index.html; rewrite / http://www.kgc.com permanent; #rewrite / http://www.kgc.com redirect; } #重启Nginx并访问域名 http://www.kgc.org 进行测试 【rewrite】 rewrite regex replacement [flag]; 指令 正则 替换 标志 【访问bj 等于 访问beijing】 location /bj { rewrite ^/bj/(.*) /beijing/$1 permanent; } mkdir beijing echo beijing > beijing/index.html 整个网页跳转 老域名跳转到新域名 location / { root /data/nginx/pc/; rewrite / http://www.accp.com permanent; } server { listen 80; server_name www.accp.com; root /data/nginx/pc/accp/; } ~ cd /data/nginx/pc/ mkdir accp echo accp > accp/index.html 【break】 server { listen 80; server_name www.kgc.com; root /data/nginx/pc/; if (!-e $request_filename){ return 302 /index.html; } location /test { default_type text/plain; set $name kgc; return 666 $name; } location /main { index index.html; default_type text/html; if ( $scheme = http ){ return 666 "if-----> $scheme"; } } location /bj { rewrite ^/bj/(.*) /beijing/$1 break; } } mkdir beijing echo beijing > beijing/index.html mkdir bj echo bj > bj/index.html 301 302 请求后 告诉你重定向的域名, 让你重新发起请求 break 服务器缓存好网页直接让你访问,直接给你结果
实战案例 http 转https
server { listen 443 ssl; listen 80; ssl_certificate /apps/nginx/certs/www.kgc.org.crt; ssl_certificate_key /apps/nginx/certs/www.kgc.org.key; ssl_session_cache shared:sslcache:20m; ssl_session_timeout 10m; server_name www.kgc.org; location / { #针对全站跳转 root /data/nginx/html/pc; index index.html; if ($scheme = http ){ #如果没有加条件判断,会导致死循环 rewrite / https://$host redirect; } http://www.kgc.com https://www.kgc.com } location /login { #针对特定的URL进行跳转https if ($scheme = http ){ #如果没有加条件判断,会导致死循环 rewrite / https://$host/login redirect; } } }
10.6 防盗链
10.6.1什么是盗链?
盗链(Hotlinking)是指在一个网站上使用或显示其他网站的资源(如图片、视频、音频等)的行为,而不是通过将资源保存到本地服务器来引用这些资源。
盗链者直接链接到原始资源的URL,使得资源消耗原始网站的带宽和服务器资源,会给原始网站带来额外的负担,并且可能导致资源被滥用或不当使用。
10.6.2 防盗链简介
Nginx的防盗链机制实现,跟一个头部字段:Referer有关,该字段主要描述了当前请求是从哪儿发出的,那么在Nginx中就可获取该值,然后判断是否为本站的资源引用请求,如果不是则不允许访问。
基本语法
valid_referers none | blocked | server_names | string ...;
none
:表示接受没有Referer
字段的HTTP
请求访问。
blocked
:表示允许http://
或https//
以外的请求访问。
server_names
:资源的白名单,这里可以指定允许访问的域名。
string
:可自定义字符串,支配通配符、正则表达式写法。
实现防盗链
在第二台机器上: systemctl stop firewalld setenforce 0 yum install epel-release.noarch -y yum install nginx cd /usr/share/nginx/html vim index.html <html> <body> <h1>this is yunjisuan </h1> <img src="http://www.kgc.com/a.jpg"/> </body> </html> systemctl start nginx vim /etc/nginx/nginx.conf 41 server_name www.accp.com; 修改41行如上 真机上 添加dns 解析 C:\Windows\System32\drivers\etc 打开 hosts 文件 第二台机器的IP地址 www.accp.com 真机上测试 www.accp.com 是否可以打开图片 第一台服务器 vim /apps/nginx/conf.d/pc.conf server{ listen 80; server_name www.pc.com; root /data/nginx/pc; location / { root /data/nginx/pc; } location ~* \.(jpg|gif|swf|jpeg|bmp)$ { root /data/nginx/pc; valid_referers none blocked *.pc.com pc.com; if ( $invalid_referer ) { #rewrite ^/ http://www.pc.com/error.png; return 403; } } } } cd /data/nginx/pc/ 拖入两张图片 a.jpg error.png 再次测试www.accp.com 是否可以打开图片 www.kgc.com www.accp.com 80 /data/nginx/kgc /data/nginx/accp server { listen 80; server_name www.kgc.com; root /data/nginx/kgc; } server { listen 80; server_name www.accp.com; root /data/nginx/accp; }
location ~* \.(jpg|gif|swf)$ { root /data/nginx/pc; valid_referers none blocked *.pc.com pc.com; if ( $invalid_referer ) { rewrite ^/ http://www.pc.com/error.png; #return 403 } } ~* \.(jpg|gif|swf)$:这段正则表达式表示匹配不区分大小写,以.jpg 或.gif 或.swf 结尾的文件 Valid_referers:设置信任的网站,可以正常使用图片。 None :浏览器中 referer 为空的情况,就是直接在浏览器访问图片。 Blocked :referer 不为空的情况 ,但是值被代理或防火墙删除了,这些值不以 http://或https://开头。后面的网址或者域名:referer 中包含相关字符串的网址。 If 语句:如果链接的来源域名不在 valid_referers 所列出的列表中,$invalid_referer 为1,则执行后面的操作,即进行重写或返回 403 页面。
十一、正向代理与反向代理
11.1 正向代理简介
正向代理代理的是客户端。
客户端设备要访问局域网以外的 Internet 时,需在客户端浏览器中配置代理服务器,然后通过代理服 务器来进行访问,将访问到的局域网以外的 Internet 网站内容返回给客户端,而不是通过局域网中的客 户端设备直接访问。
正向代理的用途:
访问原来无法访问的资源;
可做缓存,加速访问资源;
对客户端访问授权,上网进行认证;
代理可以记录用户访问记录等,且对外隐藏用户信息。
简单配置:
server { listen 80; server_name ....;#客户端访问的域名或IP地址 location / { proxy_pass http://目标服务器地址; } }
11.2 反向代理简介
反向代理代理的是服务端。
在使用反向代理时,客户端向一个服务器发送请求,而实际上该请求会被转发到后端的多个真实服务器(也称为上游服务器),然后由反向代理服务器来处理请求并将结果返回给客户端。
客户端不直接与后端服务器进行通信,而是与反向代理服务器进行通信,隐藏了后端服务器的 IP 地址。
反向代理能实现的功能
反向代理的主要作用是提供负载均衡和高可用性。
负载均衡:Nginx可以将传入的请求分发给多个后端服务器,以平衡服务器的负载,提高系统性能和可靠性。
缓存功能:Nginx可以缓存静态文件或动态页面,减轻服务器的负载,提高响应速度。
动静分离:将动态生成的内容(如 PHP、Python、Node.js 等)和静态资源(如 HTML、CSS、JavaScript、图片、视频等)分别存放在不同的服务器或路径上。
多站点代理:Nginx可以代理多个域名或虚拟主机,将不同的请求转发到不同的后端服务器上,实现多个站点的共享端口。
反向代理的可用模块
ngx_http_proxy_module #将客户端的请求以http协议转发至指定服务器进行处理 ngx_http_upstream_module #用于定义为proxy_pass,fastcgi_pass,uwsgi_pass等指令引用的后端服务器分组 ngx_stream_proxy_module #将客户端的请求以tcp协议转发至指定服务器处理 ngx_http_fastcgi_module #将客户端对php的请求以fastcgi协议转发至指定服务器助理 ngx_http_uwsgi_module #将客户端对Python的请求以uwsgi协议转发至指定服务器处理
十二、配置反向代理
12.1 反向代理配置参数
12.1.1 proxy_pass
proxy_pass 地址:端口的方式 ; #用来设置将客户端请求转发给的后端服务器的主机,可以是主机名(将转发至后端服务做为主机头首部)、IP #也可以代理到预先设置的主机群组,需要模块ngx_http_upstream_module支持 #如果location定义其uri时使用了正则表达式模式(包括~,~*,但不包括^~),则proxy_pass之后必须不能使用uri; 即不能有/ ,用户请求时传递的uri将直接附加至后端服务器之后 proxy_pass http://10.0.0.18:8080; 和 proxy_pass http://10.0.0.18:8080/;主要有以下区别: 1. 尾部斜杠的处理:在 `proxy_pass` 指令中,尾部斜杠的有无会影响代理的行为。当 `proxy_pass` 后跟一个斜杠 `/` 时,表示将请求的 URI 附加到代理服务器的地址后面。而当 `proxy_pass` 后没有斜杠时,请求的 URI 将被完全忽略,并将直接转发到指定的代理服务器。 - `proxy_pass http://10.0.0.18:8080;`:请求将直接转发到 `http://10.0.0.18:8080`,不附加任何 URI。 - `proxy_pass http://10.0.0.18:8080/;`:请求将被附加上原始 URI,并转发到 `http://10.0.0.18:8080`。 2. 请求路径的保留:当使用 `proxy_pass` 指令时,代理服务器会保留原始请求的路径信息。这意味着,无论使用哪种形式,原始请求的路径将被传递到目标服务器。只是在转发时是否附加原始路径的处理不同。
12.1.2 其余参数
proxy_hide_header field; #用于nginx作为反向代理的时候,在返回给客户端http响应时,隐藏后端服务器相应头部的信息,可以设置 proxy_pass_header field; #默认nginx在响应报文中不传递后端服务器的首部字段Date, Server, X-Pad, X-Accel等参数,如果 要传递的话则要使用 proxy_pass_header field声明将后端服务器返回的值传递给客户端 #field 首部字段大小不敏感 #示例:透传后端服务器的Server和Date首部给客户端,同时不再响应报中显示前端服务器的Server字段` proxy_pass_header Server; proxy_pass_header Date; proxy_pass_request_body on | off; #是否向后端服务器发送HTTP实体部分,可以设置在http,server或location块,默认即为开启 proxy_pass_request_headers on | off; #是否将客户端的请求头部转发给后端服务器,可以设置在http,server或location块,默认即为开启
2.2 配置实例:反向代理单台web服务器
配置部分
7-1 代理服务器 vim /apps/nginx/conf.d/computer.conf #添加 location / { proxy_pass http://192.168.2.102; }
7-2 真实服务器 yum install httpd -y #安装服务 cd /var/www/html echo "Hello World" > index.html #主页内容 systemctl start httpd #开启服务
7-3 客户机 vim /etc/hosts 192.168.2.100 www.byyb.com
测试
7-3(客户端)访问 7-2(代理服务器)
curl 192.168.2.100 Hello World
十三、反向代理实现动静分离
server { listen 80; server_name www.kgc.org; location / { index index.html index.php; root /data/nginx/html/pc; } location /api { #proxy_pass http://10.0.0.18:80/; #注意有后面的/, 表示置换 proxy_pass http://192.168.91.101; #后面没有 / , 表示追加 } } server { ...... location ~* \.(jpe?g|png|bmp|gif)$ { proxy_pass http://192.168.91.103; #如果加/ 语法出错 } } #如果 http://10.0.0.18/ 有 / 语法出错 server{ listen 80; server_name www.pc.com; root /data/nginx/pc; location / { root /data/nginx/pc; } location /api { root /data/nginx/pc; proxy_pass http://192.168.91.101:8080; } location ~* \.(jpg|jpeg|png|gif|bmp)$ { root /data/nginx/pc; proxy_pass http://192.168.91.102; } }
十四、缓存功能
反向代理可以缓存静态资源,如图片、CSS和JavaScript文件等。
当客户端再次请求相同资源时,反向代理可以直接返回缓存中的响应,减少对后端服务器的请求压力,并加快响应速度。
proxy_cache zone_name | off; 默认off #指明调用的缓存,或关闭缓存机制;Context:http, server, location #zone_name 表示缓存的名称.需要由proxy_cache_path事先定义 proxy_cache_key string; #缓存中用于“键”的内容,默认值:proxy_cache_key $scheme$proxy_host$request_uri; proxy_cache_valid [code ...] time; #定义对特定响应码的响应内容的缓存时长,定义在http{...}中 示例: proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; proxy_cache_path; #定义可用于proxy功能的缓存;Context:http proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=zone_name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time]; #示例:在http配置定义缓存信息 proxy_cache_path /var/cache/nginx/proxy_cache #定义缓存保存路径,proxy_cache会自动创建 levels=1:2:2 #定义缓存目录结构层次,1:2:2可以生成2^4x2^8x2^8=2^20=1048576个目录 keys_zone=proxycache:20m #指内存中缓存的大小,主要用于存放key和metadata(如:使用次数),一般1M可存放8000个左右的key inactive=120s #缓存有效时间 max_size=10g; #最大磁盘占用空间,磁盘存入文件内容的缓存空间最大值 #调用缓存功能,需要定义在相应的配置段,如server{...};或者location等 proxy_cache proxycache; proxy_cache_key $request_uri; #对指定的数据进行MD5的运算做为缓存的key proxy_cache_valid 200 302 301 10m; #指定的状态码返回的数据缓存多长时间 proxy_cache_valid any 1m; #除指定的状态码返回的数据以外的缓存多长时间,必须设置,否则不会缓存 proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off ; #默认是off #在被代理的后端服务器出现哪种情况下,可直接使用过期的缓存响应客户端 #示例 proxy_cache_use_stale error http_502 http_503; proxy_cache_methods GET | HEAD | POST ...; #对哪些客户端请求方法对应的响应进行缓存,GET和HEAD方法总是被缓存
proxy_cache_path /data/nginx/proyxcache levels=1:1:1 keys_zone=proxycache:20m inactive=120s max_size=1g; #上面那段写在 http语句 :1:1 16个二进制 server { listen 80; proxy_cache proxycache; proxy_cache_key $request_uri; #proxy_cache_key $host$uri$is_args$args; proxy_cache_valid 200 302 301 10m; proxy_cache_valid any 5m; server_name www.kgc.com; root /data/nginx/pc; location / { root /data/nginx/pc; } location /api { proxy_pass http://192.168.91.101:9527; } location ~* \.(jpg|png|gif|html)$ { proxy_pass http://192.168.91.102; } }
十五、反向代理客户端的IP透传
15.1 原理概述
反向代理客户端IP透传是指在使用反向代理服务器时,将客户端的真实IP地址传递给后端服务器。
这可以通过一些特定的 HTTP 头字段来实现,比如 X-Forwarded-For (XFF) 头字段。
当请求经过反向代理服务器时,代理服务器会将客户端的真实IP地址添加到 XFF 头字段中,然后转发给后端服务器。
15.2 一级代理
配置部分
7-1 代理服务器 #编辑子配置文件 vim /apps/nginx/conf.d/computer.conf #修改location部分 location / { index index.html index.php; root /data/nginx/html/pc; proxy_pass http://192.168.2.102; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } ##### `$proxy_add_x_forwarded_for` 是一个 nginx 变量,用于获取客户端的真实 IP 地址并将其添加到请求中的 `X-Forwarded-For` 头字段中,后端服务器可以通过检查该头字段来获取请求的真实客户端 IP 地址。 `X-Forwarded-For` 头字段是一个常用的 HTTP 请求头,用于指示请求的真实客户端 IP 地址。 7-2 后端服务器 #关闭防火墙和selinux systemctl stop firewalld setenforce 0 #安装服务 yum install -y epel-release #依赖 yum install nginx -y systemctl start nginx
测试部分
7-3客户端,访问代理服务器 curl 192.168.2.100 7-2 后端服务器,查看日志 cat /var/log/nginx/access.log | tail -n -2 #后端服务器可以看到客户端的真实地址
十六、反向代理负载均衡
Nginx 可以基于ngx_http_upstream_module
模块提供服务器分组转发、权重分配、状态监测、调度算法等高级功能。
16.1 工作原理
Nginx负载均衡通过将传入的请求分发到多个后端服务器来实现负载均衡。
它可以根据不同的调度算法(如轮询、IP哈希、最小连接数等)将请求分发到后端服务器。
16.2 部分配置参数
s
erver address [parameters]; #配置一个后端web服务器,配置在upstream内,至少要有一个server服务器配置。 #server支持的parameters如下: weight=number #设置权重,默认为1,实现类似于LVS中的WRR,WLC等 max_conns=number #给当前后端server设置最大活动链接数,默认为0表示没有限制 max_fails=number #后端服务器的下线条件,当客户端访问时,对本次调度选中的后端服务器连续进行检测多少次,如果都失败就标记为不可用,默认为1次,当客户端访问时,才会利用TCP触发对探测后端服务器健康性检查,而非周期性的探测 fail_timeout=time #后端服务器的上线条件,对已经检测到处于不可用的后端服务器,每隔此时间间隔再次进行检测是否恢复可用,如果发现可用,则将后端服务器参与调度,默认为10秒 sorry server 自己不能转自己 down #标记为down状态 resolve #当server定义的是主机名的时候,当A记录发生变化会自动应用新IP而不用重启Nginx
backup #设置为备份服务器,当所有后端服务器不可用时,才会启用此备用服务器 upstream backend { server backend1.example.com; server backend2.example.com backup; server backend3.example.com; }
16.3 调度算法
1)轮询(Round Robin):这是默认的调度算法,Nginx依次分配每个请求给后端服务器,实现简单且公平的请求分发。
http { upstream backend { server backend1.example.com; server backend2.example.com; } server { listen 80; location / { proxy_pass http://backend; } } }
2)加权轮询(Weighted Round Robin):通过为每个后端服务器指定一个权重,根据权重比例来分配请求。具有更高权重的服务器将获得更多的请求。
http { upstream backend { server backend1.example.com weight=3; server backend2.example.com weight=1; } server { listen 80; location / { proxy_pass http://backend; } } }
3)IP Hash:根据客户端的IP地址进行散列,将同一IP的请求分配给同一台后端服务器,实现会话保持。
http { upstream backend { ip_hash; server backend1.example.com; server backend2.example.com; } server { listen 80; location / { proxy_pass http://backend; } } }
4)URL哈希(URL Hash):基于请求的URL进行散列计算,将相同URL的请求分发到同一台后端服务器,用于缓存或会话的需要。
http { upstream backend { hash $request_uri; server backend1.example.com; server backend2.example.com; } server { listen 80; location / { proxy_pass http://backend; } } }
5)参数哈希(Parameter Hash):基于请求的特定参数进行散列计算,将具有相同参数值的请求分发到同一台后端服务器。
6)最小连接数(Least Connections):将请求分发给连接数最少的服务器,以确保服务器的负载尽可能均衡。
http { upstream backend { least_conn; server backend1.example.com; server backend2.example.com; } server { listen 80; location / { proxy_pass http://backend; } } }
7)最少响应时间(Least Time):根据服务器的响应时间进行选择,将请求分配给响应时间最短的服务器。