Nginx 是一个高性能的HTTP反向代理服务器,及电子邮件(IMAP/POP3)代理服务器可以支持5万个并发请求。其特点占用内存少,并发能力强,在同类型的网页服务器中表现较好。
一、Nginx基础
1. Linux环境安装Nginx
这里主要记录Nginx 环境安装,windows 环境只要下载安装包解压即可使用。
nginx下载地址:https://nginx.org/en/download.html
1. 安装Nginx相关依赖
yum install -y gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel
2. 下载Nginx并安装
2.1 新建一个目录,将压缩包放到Linux中并解压 nginx-xx.tar.gz 包
mkdir /usr/nginx
解压
tar -zxvf nginx-1.26.1.tar.gz
2.2 进入解压缩目录,执行 ./configure 命令
cd nginx-1.26.1
./configure --prefix=/usr/nginx
2.3 编译和安装,执行 make && make install 命令即可安装成功。
nginx make install
启动nginx,启动后是一闪而过的。
nginx // 启动
nginx -s stop // 关闭
nginx -s reload // 重新加载配置文件
访问 nginx
http://ip:nginx的端口
2. Nginx常用命令
nginx -v // 查看nginx版本号
nginx // 启动
nginx -s stop // 关闭
nginx -s reload // 重新加载配置文件
ngins -t // 测试文件是否语法错误
3. nginx 配置文件
nginx配置文件由全局块、events块、http块三部分组成。配置文件默认放在 /usr/local/nginx/conf/nginx.conf 中。结构图如下所示
一般情况下,高一级块中的指令可以作用于自身所在的块和此块包含的所有低层级块。如果某个指令在两个不同层级的块中同时出现,则采用“就近原则”,即以较低层级块中的配置为准。比如,某指令同时出现在 http 全局块中和 server 块中,并且配置不同,则应该以 server 块中的配置为准。
第一部分:全局块
从配置文件开始到events块之间的内容,主要设置一些影响nginx服务器整体运行的配置命令。比如worker_processes,它的值越大,可以支持的并发处理数量也越多。
# user [user] [group]
# 指定可以运行nginx服务的用户和用户组
# 将user指令注释掉,或者配置成nobody 的话所有用户都可以运行
# user nobody nobody;
# user 指令在 Windows 上不生效,如果指定具体用户和用户组会报警告。nginx: [warn]"user" is not supported, ignored in D:\software\nginx-1.18.0/conf/nginx.conf:2 user root;
# 指定并发工作的进程数,可以配置具体数字,也可使用自动模式
# worker_processes number / auto;
# 如下配置:指定4个工作进程,此时会生成一个master进程和4个工作进程,总共五个。因此,可以配置工作进程数为本机CPU核心数n-1
worker_processes 4;
#指定包含 nginx 主进程的 PID 数值的文件路径
# 用途:进程管理、监控与诊断、方便进行自动化脚本控制
pid logs/nginx.pid;
#指定错误日志的路径和日志级别
#error_log [path] [debug | info | notice | warn | error | crit | alert | emerg]
# 其中debug级别的日志需要编译时使用--with-debug开启debug开关
error log logs/error.loginfo;
# 此指令可以在(全局块 〈 http 块 < server 块<location 块)中配置,下面简单介绍下区别:
#首先就是,配置在越低级的块中优先级越高;
#各个级别的配置块中设置的日志指令,将应用于各自所有下级;
# server 块的配置,目的是不同的服务器配置不同的日志文件或日志级别;
# location 块是最具体的配置级别,它可为特定的 URI 路径或模式设置专门的日志指令。
第二部分:events 块
events 块涉及的指令主要影响Nginx服务器与用户的网络连接。比如work_connections 1024,表示支持最大连接数。
- 理论最大并发连接数:
worker_processes * worker_connections
,即此处为1×1024=1024
。- 生产环境建议:根据内存调整,通常设为
10240
或更高(如worker_connections 8192;
)。
events {
worker_connections 1024; # 每个Worker进程最大并发连接数
use epoll; # 指定事件驱动模型(Linux推荐epoll,FreeBSD用kqueue)
mulit_accept on | off(默认) #是否允许同时接收多个网络连接
##设置网络连接序列化,用于解决”惊群“,即客户端发起一个请求,nginx 一多进程的工作模式,也就是会有多个worker 进程会被唤醒,但最终只有要给 worker 进程可以获取连接, 如果每次唤醒数目太多,会影响nginx整体性能。如果将上述值设置为on(开启状态),会对多个nginx进程接收连接进行序列化,排队一个个唤醒接收。
accept_mutex on | off
}
第三部分:http块
Nginx 配置最频繁的一部分。http块内又包含多个 server块,每个server块可以配置多个location块。可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。
http {
include mime.types; #引入配置(conf/mime.types) 文件扩展名与文件类型映射表
default_type application/octet-stream; #默认文件类型,默认为text/plain
#access_log off; #取消服务日志
log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定义格式
access_log log/access.log myFormat; #combined为日志格式的默认值
sendfile on; #允许sendfile方式传输文件,默认为off,可以在http块,server块,location块。
sendfile_max_chunk 100k; #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。
keepalive_timeout 65; #连接超时时间,默认为75s,可以在http,server,location块。
upstream mysvr {
server 127.0.0.1:7878;
server 192.168.10.121:3333 backup; #热备
}
error_page 404 https://www.baidu.com; #错误页
server {
keepalive_requests 120; #单连接请求上限次数。
listen 4545; #监听端口
server_name 127.0.0.1; #监听地址
location ~*^.+$ { #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。
#root path; #根目录
#index vv.txt; #设置默认页
proxy_pass http://mysvr; #请求转向mysvr 定义的服务器列表
deny 127.0.0.1; #拒绝的ip
allow 172.18.5.54; #允许的ip
}
}
}
全局跨域配置
# 全局跨域头(开发环境可用 *,生产环境需限制具体域名,否则权限太高有风险)
# 如 add_header 'Access-Control-Allow-Origin' 'https://www.example.com';
add_header 'Access-Control-Allow-Origin' '*';
# OPTIONS 请求处理:前端发送跨域请求时会先发送 OPTIONS 预检请求,需允许 OPTIONS 方法
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
3.1 server块
server也叫虚拟主机,配置虚拟主机的相关参数,一个http中可以有多个server。一个 server 可以有多个location 。
server {
listen 80;
server_name localhost;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location / {
}
location /api {
}
}
server_name 匹配规则
- 完整匹配
在同一server_name中匹配多个域名,如 server_name www.example1.com www.xox.org
- 通配符匹配
头部匹配:server_name *.exmaple.com
尾部匹配:server_name xhi.*
- 正则匹配
server_name ^[0-9]+\.ample\.com$
error_page
error_page资源错误页面,一旦访问的资源不存在或者程序错误500, 502 , 503 ,504,就会跳转到 50.html页面
例如访问 https://example.com/xoxo/index.html, 如果index.html 不存在,或者出现500, 502 503,504,就会将 50.html 替换原有的资源,即 https://example.com/xoxo/50.html,而这个资源不是我们写的,当然不存在,于是在location中又定义了匹配50.html资源的路径,当匹配到了50.html, 就会在root定义的路径中找这个资源(即在html目录下找)。
3.2 location 块
配置请求的资源,以及各种页面的处理情况。
这里扩展以下url 和 uri 的区别:
url 就是一个完整的域名地址,如 https://example.com/xxoo/index.html 。 而 uri 是也叫资源,是值域名之后的一段地址,拿上面的地址举例就是 /xxoo/index.html 这一部分。
而 location 就是匹配资源的。
rewrite
# 反向代理,处理管理端发送的请求
location /api/ {
# rewrite 正则 地址 转发形式(last、break、redirect、permanent)
rewrite ^/([0-9]+).html$ /index.jsp?pageNum=$1 break;
proxy_pass http://localhost:8080/admin/;
}
转发形式的可选参数
- last: 继续匹配新的 location uri 规则
- break: 不再匹配任何规则
- redirect: 返回302临时重定向,浏览器会显示重定向后的地址
- permanent: 返回301永久重定向,浏览器会显示重定向后的地址
location 匹配顺序
模板
location [ = | ~ | ~* ] /uri/ { … }
规则
- ~ 波浪线表示执行一个正则匹配,区分大小写
- ~* 表示执行一个正则匹配,不区分大小写
- = 进行普通字符精确匹配
location = /exact/path { ... }:精确匹配这个路径。如果请求的 URI 完全等于/exact/path ,则使用这个块的配置处理此请求。这具有最高的优先级。
优先级:精准匹配 > 正则匹配 > 普通匹配 > 默认匹配
- 精准匹配 location =/api, 表示只匹配 /api 的请求
- 多个正则location直接按书写顺序匹配,成功后就不会继续往后面匹配
- 普通(非正则)location会一直往下,直到找到匹配度最高的(最大前缀匹配,长度最长的)
- 当普通location与正则location同时存在,如果正则匹配成功,则不会再执行普通匹配
- 默认匹配 location \
- 所有类型location存在时,“=”匹配 > “^~”匹配 > 正则匹配 > 普通(最大前缀匹配)
二、代理
1. 正向代理
代理的是客户端,对于服务端来说,不知道用户的信息。客户端明确要访问某个服务端地址,而服务端不清楚具体的客户端。如翻墙软件。客户端将请求给代理服务器,由代理服务器转发请求给目标服务,目标服务将结果返回给代理服务器, 然后由代理服务器将数据给客户端。
2. 反向代理
代理的是服务端,客户端不知道服务端。客户端向服务器发送一个请求,由代理服务器把请求转到到目标服务器中,服务器将数据给代理,由代理将数据转发给客户端。至于中间是如何操作的,客户端不管,只要能拿到数据即可。如 nginx。
反向代理案例:在浏览器地址栏输入 http:// localhost:9090/api/hello/ ,请求后端的 http://localhost:8080服务。
当nginx监测到资源中携带 /api 的路径时,就会请求转发到 proxy_pass 中定义的地址中。
踩坑记录: localtion 后面的资源路径与目标地址带斜杠和不带斜杠的区别,即 location /api/ 和 location /api 的区别。
资源后面带/: 会将拦截到的资源去掉匹配上的部分,再将资源拼接目标地址上。如请求地址为http:// localhost:9090/api/hello/say ,目标地址为 http://192.168.30.130:8080/,nginx 匹配到 /api, 截取资源路径,即域名之后的路径 ( /api/hello/say ),去掉匹配上的部分后(/hello/say), 那转发后的地址为:http://192.168.30.130:8080/hello/say
资源后面不带/: 将拦截到的资源直接拼接在目标地址上。如请求地址为http:// localhost:9090/api/hello/say ,目标地址为 http://192.168.30.130:8080/,nginx 匹配到 /api, 截取资源路径,即域名之后的路径 ( /api/hello/say ), 那转发后的地址为:http://192.168.30.130:8080/api/hello/say
三、负载均衡
负载均衡是Nginx一个常见的功能,有2台及以上的服务对外服务,用户每次i请求时,根据特定的规则转发到众多服务的其中一个服务中。这样做可以减轻服务器的压力。
1. 负载均衡基本配置案例
如下图所示,负载均衡基本配置,在upstream 定义服务地址, 然后在目标地址上引用pstream的名称。
注意:upstream 和 server 是同级的关系。
http {
upstream webservers{
server 192.168.30.130:8080;
server 192.168.30.131:8080;
}
server {
listen 80;
server_name localhost;
location / {
root html/sky;
index index.html index.htm;
}
# 反向代理,处理用户端发送的请求
location /user/ {
proxy_pass http://webservers/user/;
}
}
}
2. 负载均衡参数
- weight:权重,权重越大,被访问的几率越大。
- down : 当前server不参与负载均衡,
- backup : 预留的备份服务器; 其它所有的非backup机器down或者忙的时候,请求backup机器。即没有机器可用了才会启用。
- max_fails : 请求失败次数限制
- fail_timeout : 经过max_fails后服务暂停时间
- max_conns : 限制最大的连接数
upstrem weiyigeek {
server 192.168.30.130:8080 down;
server 192.168.30.130:8081 backup;
server 192.168.30.130:8082 max_fails=1 fail_timeout=10s max_conns=1024;
server 192.168.30.130:8083 weight=1
server 192.168.30.130:8084 weight=2
}
3. 负载均衡策略
- 轮询:默认算法,按时间顺序逐一分配,如果后端服务器down掉能自动剔除;
- 加权轮询: weight值越大,分配到访问几率越高;
- ip_hash: 按照请求ip的hash结果分配,可以将来自一个IP的固定访问一个后端服务器;
- url_hash: 需要安装模块,按照访问的URL的hash结果来分配,这样每个URL定向到同一个后端服务器
- least_conn: 按照某台机器最少连接数的进行分配访问;
- hash关键数值: hash 自定义 key
1. 轮询
按时间顺序逐一分配,如果后端服务器down掉能自动剔除
upstream test {
server 192.168.30.130:8080;
server 192.168.30.130:8081;
}
server {
listen 81;
server_name localhost;
client_max_body_size 1024M;
location / {
proxy_pass http://test;
proxy_set_header Host $host:$server_port;
}
}
2. 权重
weight值越大,分配到访问几率越高
upstream test {
server 192.168.30.130:8080 weigth=2; #10次访问只有2次机会被访问到
server 192.168.30.130:8081 weigth=8;
}
server {
listen 81;
server_name localhost;
client_max_body_size 1024M;
location / {
proxy_pass http://test;
proxy_set_header Host $host:$server_port;
}
}
3.ip_hash
ip_hash 会话粘连, 上面的2种方式都有一个问题,那就是下一个请求来的时候请求可能分发到另外一个服务器,当我们的程序不是无状态的时候(采用了session保存数据),这时候就有一个很大的很问题了,比如把登录信息保存到了session中,那么跳转到另外一台服务器的时候就需要重新登录了,所以很多时候我们需要一个客户只访问一个服务器,那么就需要用iphash了,iphash的每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
# 会话粘粘可以理解为用户持续访问一个后端机器
upstream test {
ip_hash;
server 192.168.30.130:8080;
server 192.168.30.130:8081;
}
server {
listen 81;
server_name localhost;
client_max_body_size 1024M;
location / {
proxy_pass http://test;
proxy_set_header Host $host:$server_port;
}
}
4. fair
fair(第三方)按后端服务器 的响应时间来分配请求,响应时间短的优先分配。
upstream test {
fair;
server 192.168.30.130:8080;
server 192.168.30.130:8081;
}
server {
listen 81;
server_name localhost;
client_max_body_size 1024M;
location / {
proxy_pass http://test;
proxy_set_header Host $host:$server_port;
}
}
5. url_hash
url_hash(第三方):按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法
upstream test{
hash $request_uri;
hash_method crc32;
server 192.168.30.130:8080;
server 192.168.30.130:8081;
}
server {
listen 81;
server_name localhost;
client_max_body_size 1024M;
location / {
proxy_pass http://test;
proxy_set_header Host $host:$server_port;
}
}
6. url_hash
将请求分配到连接数最少的服务上
upstream test{
least_conn;
server 192.168.30.130:8080;
server 192.168.30.130:8081;
}
server {
listen 81;
server_name localhost;
client_max_body_size 1024M;
location / {
proxy_pass http://test;
proxy_set_header Host $host:$server_port;
}
}
四、动静分离
动静分离就是将动态资源和静态资源分开。所谓静态资源就是不会随着用户的请求而变化的内容,通常是静态网页(HTML、CSS、JS)、图片资源、字体文件、多媒体文件(视频、音频)等。而动态资源就是通过用户发起请求生成的数据,如数据库查询出来的数据,或者实时的数据。
1. 动静分离原理
动静分离原理简单来说,就是使用正则表达式匹配过滤,然后交个不同的服务器,动态资源交给动态服务器,静态资源交给Nginx直接托管,减少应用服务器压力。
2. 案例
下面是一个简单的动静分离示例
server {
listen 80;
server_name localhost;
# 静态资源规则(正则匹配)
location ~* \.(html|js|css|png|jpg|jpeg|gif|ico|woff2)$ {
root /opt/static;
expires 30d; # 浏览器缓存30天
access_log off;
}
# 动态请求转发
location /api {
proxy_pass http://backend_server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 动态页面转发(如SSR)
location / {
proxy_pass http://backend_server;
}
}
五、Nginx性能优化
Worker 进程数:设置为 CPU 核心数(worker_processes auto),避免进程竞争。
连接数优化:worker_connections设为 10240(根据内存调整),配合multi_accept on(允许 Worker 进程一次性接受多个连接)。
静态资源缓存:通过expires指令设置客户端缓存时间(如图片 / JS/CSS 缓存 30 天)。
压缩配置:启用gzip或brotli压缩,减少传输流量(仅对文本类文件有效)。
日志优化:对静态资源关闭访问日志(access_log off;),减少 I/O 消耗。