往期推荐
亲爱的读者朋友:本文内容有点多,可能需要花费您多一点时间阅读,如果时间不够没有关系,可以把本文收藏起来,以备后面可以用的上,作为工作中的一个手册,时常读读。
-----------------------------------------------------------------------------
在疫情期间在家里整理的一篇配置手册,笑纳!!!
-----------------------------------------------------------------------------
回归正题:
相信Nginx对于大家都不陌生,而且也是在项目中经常用到,听的很多的一个词语就是”负载均衡“,”反向代理“等等,也是面试中基本上都会被问到的吧!
这里先上一个架构图,让大家看看Nginx处于架构中的哪个位置,如下图:

在大型分布式架构中,负责负载均衡的有很多种,而且是逐层进行压力均衡,从上图中可以看到ospf(开放式最短路径优先)负载均衡,LVS负载均衡,Nginx负载均衡,还有后面的服务层的软负载均衡算法等等。咱们这次不探讨Nginx的原理,我先从配置入手,主要重点在于如何能用正确的姿势来使用好我们的Nginx。

一、Nginx能做什么?
1.1、反向代理
接受外部请求,然后把请求转发到内部服务器,并将从服务器上得到的结果返回给客户端,下图为简易图:

1.2、负载均衡
当有2台或以上服务器时,根据均衡策略将请求分发到指定的服务器上处理
均衡策略:
轮询(RR) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,故障系 统被自动剔除,使用户访问不受影响;
权重 指定轮询权值,Weight值越大,分配到的访问机率越高,主要用于后端每个服务器性能不均的情况下
ip_hash 每个请求按访问IP的hash结果分配,这样来自同一个IP的访客固定访问一个后端服务 器,有效解决了动态网页存在的session共享问题;
fair(第三方) 此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务 器的响应时间来分配请求,响应时间短的优先分配 注意:Nginx本身不支持fair,必须下载Nginx的upstream_fair模块;
url_hash(第三方) 按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,可以进一步提 高后端缓存服务器的效率注意:Nginx本身不支持url_hash,必须安装Nginx 的hash软件包;
1.3、HTTP服务器(动静分离)
Nginx本身也是一个静态资源的服务器,当只有静态资源的时候,就可以使用Nginx来做服务 器,同时现在也很流行动静分离,就可以通过Nginx来实现,现在前后端分离的项目,类似 DCIM,充电桩系统的前端代码都可以直接部署到Nginx下面。
示例
server {#监听端口listen 80;server_name localhost;client_max_body_size 1024M;location / {#指定静态资源的目录root e:\wwwroot;index index.html;}}动静分离
动静分离是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来, 说白了就是把api请求接口通过反向代理把请求分配到对应的后台服务器上,静态资源 (html,image,js,css)这些就由Nginx的静态资源服务器的功能来处理
示例
upstream zuul_server{server localhost:8080;server localhost:8081;}server {listen 80;server_name localhost;# 所有静态请求都由nginx处理,存放目录为htmllocation /report {alias D:/nginx-1.15.2/html/report-app/;}# 所有静态请求都由nginx处理,存放目录为htmllocation ~ \.(gif|jpg|jpeg|png|bmp|swf|css|js)$ {root D:/nginx-1.15.2/html/report-app/;}# 所有动态请求都转发给网关处理location /api/ {proxy_pass http://zuul_server/;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header REMOTE-HOST $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}error_page 500 502 503 504 /50x.html;location = /50x.html {root D:/nginx-1.15.2/html;}}
1.4、正向代理(使用较少)
概述
正向代理最大的特点是客户端非常明确要访问的服务器地址;服务器只清楚请求来自哪个代理服务器,而不清楚来自哪个具体的客户端;正向代理模式屏蔽或者隐藏了真实客户端信息,如下图:

举例
我们常常用的翻墙代理,就是很典型的正向代理的行为,我们很清楚需要访问哪个网址,但是国内又访问不了,只能找一台代理服务器来帮忙访问,由这台代理服务器与目标服务器进行通讯交互, 并把结果返回给到我们。配置如下:
server {listen 80;server_name localhost nginx.tangll.cn;#指定DNS服务器IP地址resolver 8.8.8.8;location / {#设定代理服务器的协议和地址proxy_pass http://$http_host$request_uri;}error_page 500 502 503 504 /50x.html;location = /50x.html {root /usr/share/nginx/html;}}

二、配置详解
2.1、整体结构


2.2 、main全局块
2.2.1、全局配置示例
#main # 全局配置user nobody nobody;pid logs/nginx.pid;worker_processes 2;worker_rlimit_nofile 1024;error_log logs/error.log infoevents { # nginx工作模式配置....}http { # http设置....server { # 服务器主机配置....location { # 路由配置....}}upstream name { # 负载均衡配置....}}
2.2.2、user
配置运行Nginx服务器用户(组),指定Nginx Worker进程运行用户,默认是nobody帐号。
指令格式:user user [group];
user:指定可以运行Nginx服务器的用户;group:可选项,可以运行Nginx服务器的用户组
示例
user tony users;
2.2.3、pid
用来指定进程id的存储文件的位置
指令格式:pid file;
file: 指定nginx进程id的存储文件的位置
示例
pid logs/nginx.pid
2.2.4、worker_processes
指定nginx要开启的子进程数量,运行过程中监控每个进程消耗内存(一般几M~几十M不等)根据实 际情况进行调整,通常数量是CPU内核数量的整数倍.
指令格式:worker_processes number
number:通常数量是CPU内核数量的整数倍
示例
worker_processes 2;
2.2.5、worker_rlimit_nofile
用于指定一个进程可以打开最多文件数量的描述,设置了这个nginx就不会有“too many open files”问题。
指令格式:worker_rlimit_nofile limit
limit :最大值65535
示例
worker_rlimit_nofile 1024;
2.2.6、error_log
定义错误日志文件的位置及输出级别,支持级别:debug / info / notice / warn / error / crit
指令格式:error_log file [ debug | info | notice | warn | error | crit ]
file: 日志文件保存位置,info: 日志级别
示例
error_log logs/error.log info
2.3、events块
2.3.1、events配置示例
# main 全局配置....event {worker_connections 1024;multi_accept on;use epoll;}http { # http设置....server { # 服务器主机配置....location { # 路由配置....}}upstream name { # 负载均衡配置....}}
2.3.2、worker_connections
指定最大可以同时接收的连接数量,这里一定要注意,最大连接数量是和worker processes共同 决定的 作为反向代理,max_clients为:max_clients = worker_processes * worker_connections/4
指令格式:worker_connections number
number: 指定最大可以同时接收的连接数量
示例
worker_connections 1024;
2.3.3、multi_accept
配置指定nginx在收到一个新连接通知后尽可能多的接受更多的连接
指令格式:multi_accept [on|off]
on|off: 默认of
示例
multi_accept on;
2.3.4、use
Nginx使用I/O 模型的指定 配置指定了线程轮询的方法,如果是linux2.6+,使用epoll,如果是BSD如Mac请使用Kqueue.
指令格式:use [ kqueue | rtsig | epoll | /dev/poll | select | poll | eventport ]
select/poll:属于标准事件模型,如果不存在更有效的方法,nginx会
选择select或poll
kqueue: 使用于FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和
MacOS X. /dev/poll:使用于Solaris 7 11/99+, HP/UX
11.22+ (eventport), IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+
eventport:使用于Solaris 10. 为了防止出现内核崩溃的问题, 有必要
安装安全补丁
示例
use epoll;
2.4、http块
2.4.1、http配置示例
# main 全局配置....event {.... #nginx工作模式配置}http { # http设置### 基础配置##sendfile on;tcp_nopush on;tcp_nodelay on;keepalive_timeout 65;send_timeout 50;client_max_body_size: 10m;client_body_buffer_size: 128k;types_hash_max_size 2048;include mime.types;default_type application/octet-stream;### 日志配置##access_log logs/access.log main;error_log logs/error.log;### Gzip 压缩配置##gzip on;gzip_disable "msie6";### 开启参数中包含"_"##underscores_in_headers on;##cache##proxy_connect_timeout 500;#跟后端服务器连接的超时时间_发起握手等候响应超时时间proxy_read_timeout 600;#连接成功后_等候后端服务器响应的时间_其实已经进入后端的排队之中等候处理proxy_send_timeout 500;#后端服务器数据回传时间_就是在规定时间内后端服务器必须传完所有数据proxy_buffer_size 128k;#代理请求缓存区_这个缓存区间会保存用户的头信息以供Nginx进行规则处理_一般只要能保存下头信息即可proxy_buffers 4 128k;#同上 告诉Nginx保存单个用的几个Buffer最大用多大空间proxy_busy_buffers_size 256k;#如果系统很忙的时候可以申请更大的proxy_buffers 官方推荐*2proxy_temp_file_write_size 128k;#proxy缓存临时文件的大小proxy_temp_path d:/nginx-1.15.2/temp;#用于指定本地目录来缓冲较大的代理请求proxy_cache_path d:/nginx-1.15.2/cache levels=1:2 keys_zone=cache_one:200minactive=1d max_size=30g;#设置web缓存区名为cache_one,内存缓存空间大小为12000M,自动清除超过15天没有被访问过的缓存数据,硬盘缓存空间大小200gupstream zuul_server {server 192.168.9.51:8000;}server {listen 8001;server_name localhost;#charset koi8-r;access_log logs/host.access.log;# proxy the PHP scripts to Apache listening on 127.0.0.1:80location /report {alias D:/nginx-1.15.2/html/report-app/;}location /{alias D:/nginx-1.15.2/html/master-app/;}location /api/ {#proxy_pass http://zuul_server/;proxy_pass http://192.168.9.51:8057/;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header REMOTE-HOST $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}}
2.4.2、基础配置
sendfile
配置on让sendfile发挥作用,将文件的回写过程交给数据缓冲去去完成,而不是放在应用中 完成,这样的话在性能提升有有好处
指令格式:sendfile [on|off]
示例:
sendfile on;tcp_nopush
让nginx在一个数据包中发送所有的头文件,而不是一个一个单独发
指令格式:tcp_nopush [on|off]
示例:
tcp_nopush on;keepalive_timeout
给客户端分配连接超时时间,服务器会在这个时间过后关闭连接。一般设置时间较短,可以 让nginx工作持续性更好
指令格式:keepalive_timeout second
second: 默认75秒
示例:
keepalive_timeout 20;send_timeout
用于指定响应客户端的超时时间。这个超时仅限于两个连接活动之间的时间,如果超过这个 时间,客户端没有任何活动,Nginx将会关闭连接
指令格式:send_timeout second
second: 默认60秒
示例:
send_timeout 50client_max_body_size
指令格式:client_max_body_size size
size: 默认1m,可自定义
示例:
client_max_body_size: 10m;client_body_buffer_size
缓冲区代理缓冲用户端请求的最大字节数
指令格式:client_body_buffer_size the_size
the_size: 默认8k/16k
示例:
client_body_buffer_size 128k;types_hash_max_size
混淆数据,影响三列冲突率,值越大消耗内存越多,散列key冲突率会降低,检索速度更 快;值越小key,占用内存较少,冲突率越高,检索速度变慢
指令格式:types_hash_max_size 2048
default_type
指定默认处理的文件类型可以是二进制
示例
default_type application/octet-stream;
允许客户端请求的最大单文件字节数。如果有上传较大文件,请设置它的限制值
2.4.3、upstream
upstream模块主要负责负载均衡的配置,通过默认的轮询调度方式来分发请求到后端服务器
指令格式:
server host:port [weight/down/max_fails/fail_timeout/backup];
down: 表示该主机暂停服务
max_fails:表示失败最大次数,超过失败最大次数暂停服务
fail_timeout:表示如果请求受理失败,暂停指定的时间之后重新发起请求
backup:其它所有的非backup机器down或者忙的时候,请求backup机器,所以这台机器 压力会最轻
默认轮询
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除
示例:
upstream backend {server 192.168.1.10:8001;server 192.168.1.11:8001;}权重
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况
示例:
upstream backend {server 192.168.1.10:8001 weight=1;server 192.168.1.11:8001 weight=1;}
ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决 session的问题
示例:
upstream name {ip_hash;server 192.168.1.101:8000;server 192.168.1.102:8000 down;server 192.168.1.103:8000 max_fails=3;server 192.168.1.104:8000 fail_timeout=20s;server 192.168.1.105:8000 max_fails=3 fail_timeout=20s;server 192.168.1.106:8000 backup;}
fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配
示例
upstream backserver {server 192.168.1.101:8000;server 192.168.1.102:8000;fair;}url_hash(第三方)
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存 时比较有效
示例:
upstream backserver {server 192.168.1.101:3128;server 192.168.1.102:3128;hash $request_uri;hash_method crc32;}
2.4.4、server
2.4.4.1 公共配置
listen
监听端口,默认80,小于1024的要以root启动。可以为listen *:80、listen 127.0.0.1:80等 形式
`指令格式:listen address:port [ default [ backlog=num |
rcvbuf=size | sndbuf=size | accept_filter=filter | deferred |
bind | ssl ] ]
示例
listen 127.0.0.1:8000;listen 127.0.0.1;listen 8000;listen *:8000;listen localhost:8000;listen 443 default ssl;listen 127.0.0.1 default accept_filter=dataready backlog=1024;server_name
服务器名,如localhost、www.example.com,可以通过正则匹配
示例
server_name localhost 192.168.1.100;root
表示整个server虚拟主机内的根目录,所有当前主机中web项目的根目录
index
用户访问web网站时的全局首页
access_log
用于指定该虚拟主机服务器中的访问记录日志存放路径
error_log
用于指定该虚拟主机服务器中访问错误日志的存放路径
2.4.4.2、location模块
location模块是nginx配置中出现最多的一个配置,主要用于配置路由访问信息
location匹配规则
location 的匹配顺序:先进行“精准匹配”匹配成功则执行相应操作并结束,匹配失败则进行 普通匹配,匹配成功记录路径最长的那个(就是有多个普通location时记录匹配的路径最长 那个),再继续按顺序进行正则匹配,直到正则匹配成功则结束匹配执行正则对应的操作, 若正则全部匹配失败则执行之前的普通匹配中最长匹配的操作
语法:location [=|~|~*|^~] /uri/ { ... }
普通匹配(/)
location / { #所有以“/”开头的路径都匹配,/aa/h.html 或 / 都匹配return 401;#配置A}精准匹配(=)
#路径只能是/ ,http://localhost/则匹配,http://localhost/a.html 则不匹配location =/ {return 402;#配置B}前缀正则匹配(^~)
#依然遵循最长路径匹配,普通匹配之前如果匹配成功则不继续执行下面的正则匹配(也就是优先于正则匹配)location ^~ /images/ {return 404;#配置C}正则匹配,区分大小写(~)
#匹配任何以gif,jpg或jpeg结尾的请求,大小写严格区分location ~ \.(gif|jpg|jpeg)$ {return 500;#配置D}正则匹配,不区分大小写(~*)
#匹配任何以gif,jpg或jpeg结尾的请求。但是对/images/ 的请求优先【#配置C】先匹配location ~* \.(gif|jpg|jpeg)$ {return 500;#配置E}root
指定请求的文档根 最终访问路径:root路径+location路径
指令格式:root path
path: 默认html
示例
location /i/{root /spool/w3;}注意:"/i/top.gif" 最终会转换成 "/spool/w3/i/top.gif"
alias
别名的方式,使用alias路径替换location路径 使用alias时,目录名后面一定要加"/",alias只能位于location块中
指令格式:alias file-path|directory-path;
示例
location /i/ {alias /spool/w3/images/;}注意:"/i/top.gif" 最终会转换成 "/spool/w3/images/top.gif"
proxy_pass
反向代理请求转发,格式:proxy_pass URL; 其中URL包含:传输协议(http://, https://等)、主机名(域名或者IP:PORT)、uri
对于proxy_pass的配置有几种情况需要注意:
#假设server_name为www.xxx.com#当请求http://www.xxx.com/test/a.html的时候,以上示例分别访问的结果是#示例1:location /test/{proxy_pass http://192.168.1.10;...}#结果1:http://192.168.1.10/test/a.html#示例2:location /test/{proxy_pass http://192.168.1.10/;...}#结果2:http://192.168.1.10/a.html#示例3:location /test/{proxy_pass http://192.168.1.10/linux/;...}#结果3:http://192.168.1.10/linux/a.html#示例4:location /test/{proxy_pass http://192.168.1.10/linux;...}#结果4:http://192.168.1.10/linuxa.html总结:
#为了方便记忆和规范配置,建议所有的 proxy_pass 后的url都以“/”结尾。proxy_pass http://192.168.1.10/linux/;proxy_set_header
反向代理时在请求头中设置相应的值
proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header REMOTE-HOST $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
携带主机名,远程ip等
2.5、stream块
TCP 代理配置模块,1.9.0之后安装后自带了该模块
#stream段的配置要与http段在同级目录。此处引用的为官方nginx说明配置。stream {upstream backend {hash $remote_addr consistent;server 192.168.9.51:8888 weight=5;server 192.168.8.230:8888 max_fails=3 fail_timeout=30s;}server {# 需要修改数据库的通用访问接口为这个listen *:9999 so_keepalive=on;proxy_connect_timeout 1s;proxy_timeout 20s;proxy_pass backend;proxy_protocol on;}}
2.6、变量参数
常见的nginx 变量
| 变量 | 作用 |
| $arg_参数名 | URL 中某个具体参数的值 |
| $query_string | 与args变量完全相同 |
| $args | 全部URL参数 |
| $is_args | 如果请求的URL中有参数则返回?否则返回空 |
| $content_length | HTTP 请求中标识包体长度的Content-Length头部的值,头部没有这个则 为空 |
| $content_type | 标识请求包体类型的Content-Type 头部的值 |
| $uri | 请求的URI(不包含,不包含?后的参数) |
| $document_uri | 与uri完全相同 |
$request_uri | 这个变量等于包含一些客户端请求参数的原始URI,它无法修改,请查看 $uri更改或重写URI,不包含主机名,例如:"/cnphp/test.php? arg=freemouse" |
| $scheme | 请求使用的Web协议,"http" 或 "https" |
| $request_method | 请求的方法GET 或者 POST |
| $request_length | 所有请求内容的大小,包括请求行,头部,包体等 |
| $remote_user | 有HTTP Basic Authentication 协议传入的用户名 |
| $request | 原始的url请求,含有方法和协议版本 |
TCP相关的变量
| 变量 | 作用 |
| $binary_remote_addr | 客户端地质的整型格式,对于IPv4是4字节 |
| $remote_addr | 客户端地址 |
| $remote_port | 客户端端口 |
| $connection | 递增的连接序号 |
| $connection_requests | 当前连接上执行过的请求数,对keepalive 有意义 |
| $proxy_protocol_addr | 若使用了proxy_protocol 协议则返回协议中的地址 |
| $proxy_protocol_port | 若使用了proxy_protocol 协议则返回协议中的端口 |
| $server_addr | 服务器端地址(本端地址) |
| $server_port | 服务器端端口 |
| $server_protocol | 服务端协议,例如 HTTP |
Nginx 处理请求过程中产生的变量
| 变量 | 作用 |
| $request_time | 请求处理到现在的耗时 |
| $server_name | 匹配上的请求server_name |
| $request_completion | 若请求处理完则返回OK,否则为空 |
| $request_id | 以16禁止输出的请求标识id,随即生成 |
Nginx系统变量
| 变量 | 作用 |
| $time_local | 以本地时间的标准输出 |
| $pid | 所属worker进程的id |
| $hostname | 与系统上输出hostname 一致 |

公众号:架构工匠(ID: gh_e3ddf5fb9980)
CSDN博客:架构工匠
长按二维码关注
愿一个热爱技术的灵魂,给你带来更多共鸣与激情碰撞。

感谢您的阅读!常来哦




