一、概述
Nginx一个具有高性能的【HTTP】和【反向代理】的【WEB服务器】,同时也是一个电子邮件代理服务器。正向代理服务的是客户端(比如VPN),反向代理服务的是服务端。Nginx是多进程的,有一个Master进程控制多个Worker进程。速度快、并发高、热部署。
1、优点
- 速度快,并发高,在5万左右。采用多进程,io多路复用技术。像Tomcat是一个重量级的服务器,并发在200左右
- 配置简单,扩展性强
- 高可靠性,有master进程和worker进程,其中master进行单独用于管理worker进程
- 热部署
- 成本低,BSD许可证(可以修改源码并且可以用来赚钱)
2、常用模块
- 静态资源部署
- Rewrite地址重写,使用正则表达式
- 反向代理
- 负载均衡
- web缓存
- 用户认证模块
3、核心组成
- nginx:二进制可执行文件
- nginx.conf:核心配置文件
- error.log:错误的日志记录
- access.log:访问日志记录
- nginx.pid:记录nginx的Master进程id
二、配置
# nginx.config文件
# 全局配置部分
#-----------------------------# 定义工作进程数量(建议设置为CPU核心数或自动检测)
# 值:数字 或 auto
worker_processes 4; # user指令:用于配置运行Nginx服务器的worker进程的用户和用户组。使用user指令启动的时候,可以指定Linux系统的用户和用户组,然后访问Nginx的时候,只能访问到该用户拥有权限的目录,进行权限访问控制。# daemon:是否已守护进程运行,默认为on# pid:用于指定存放master进程id的文件路径# error_log:用于配置Nginx错误日志存放的路径# include:可以引入其他的配置文件,可以放在任何位置,放在全局块中可以引入全局块指令# 事件模块配置(控制连接处理模型)
#-----------------------------
events {# 每个Worker进程允许的最大并发连接数(包含活动连接和空闲连接)。默认 512。设置值不能超过操作系统支持打开的最大句柄数量# 总最大连接数 = worker_processes * worker_connectionsworker_connections 40960; # accept_mutex:用来设置Nginx网络连接序列化,默认为on。用来解决惊群问题,就是一个请求发送过来,所有的worker进程都会唤醒来抢夺这个请求,设置为on开启序列化,意为每次来请求,只会唤醒一个worker进程来处理请求。根据实际需求来配置,因为可能会同时发送过来多个请求# muli accept:用来设置是否允许woker进行同时接受多个网络连接。默认为off,可以打开提高速度# use:设置Nginx服务器使用哪种事件驱动来处理网络消息。默认值根据操作系统来确定。推荐使用epoll使用io多路复用。
}# HTTP核心模块配置
#-----------------------------
http {# 根据User-Agent判断设备类型(用于后续条件判断)# 定义变量 $device_type,默认值为desktop,匹配移动设备则设为mobilemap $http_user_agent $device_type {default desktop; # 默认值~*android|iphone|ipad|ipod mobile; # 正则匹配(不区分大小写)}# 包含MIME类型定义文件(默认路径为nginx目录下的conf/mime.types)# 我们都知道浏览器中可以显示的内容有HTML、XML、GIF等种类繁多的文件、媒体等资源,浏览器为了区分这些资源,就需要使用MIME Type。所以说MIME Type是网络资源的媒体类型。Nginx作为web服务器,也需要能够识别前端请求的资源类型。default_type 来指定相应给前端的类型, application/octet-stream会下载下来响应include mime.types; # access_log:用来设置用户访问日志的目录、格式等相关属性# log_format:用来指定日志的输出格式# 默认响应类型(当无法识别文件类型时使用)# 注意:application/wasm 是WebAssembly的MIME类型,需确认是否需要此设置default_type application/wasm; # 启用高效文件传输模式(零拷贝技术)。用来设置Nginx服务器是否使用Linux操作系统的sendfile()传输文件,该属性可以大大提高Nginx处理静态资源的性能。默认off# 读取文件流程是客户端请求,用户区、内核区、磁盘、网卡中进行多次拷贝,效率较低,四次拷贝,sendfile是操作系统底层函数。开启可以提升效率,不需要多次拷贝,可以指定读取到哪个socket,直接响应给客户端。服务端的数据要返回给客户端。那么有两种模式,一种是实时发送,即`tcp_nodelay`,默认on,来了一个数据就直接发送给客户端,这样实时性很高,但是消耗性能。第二种就是开辟一个缓冲区,即`tcp_nopush`,默认off,依赖sendfile,数据将缓冲区填满之后再一起发送,实时性弱一点,但是性能高。两个配置看起来是互斥的,但是Linux2.5.9之后进行了优化,所有建议三者都打开,配置在http块。sendfile on; # 客户端保持连接的超时时间(单位:秒)。用来设置长连接的超时时间。如何客户端向服务端发送多个请求,每个请求都需要重新创建一次连接,效率相对来说比较多,使用keepalive模式,可以告诉服务器端在处理完一个请求后保持这个TCP连接的打开状态,若接收到来自这个客户端的其他请求,服务端就会利用这个未被关闭的连接,而不需要重新创建一个新连接,提升效率,但是这个连接也不能一直保持,这样的话,连接如果过多,也会是服务端的性能下降,这个时候就需要我们进行设置其的超时时间。默75秒keepalive_timeout 65; # keepalive_requests:用来设置一个keep-alive连接使用的次数,达到次数就关闭这个连接# 从ISO8601时间格式中提取日期(用于日志文件名)map $time_iso8601 $logdate {'~^(?<ymd>\d{4}-\d{2}-\d{2})' $ymd; # 正则捕获年月日default 'date-not-found'; # 匹配失败时的默认值}# 访问日志配置(按日期分割日志)access_log logs/access-$logdate.log; # 客户端请求相关配置#-----------------------------client_max_body_size 50m; # 允许客户端上传的最大文件大小(重要!涉及文件上传需设置)client_body_buffer_size 60k; # 客户端请求体缓冲区大小client_body_timeout 60; # 客户端请求体读取超时时间(秒)client_header_buffer_size 64k; # 客户端请求头缓冲区大小client_header_timeout 60; # 客户端请求头读取超时时间(秒)# 错误页面配置#-----------------------------error_page 400 /error/400.html; # 错误码映射到指定URIerror_page 403 /error/403.html;error_page 404 /error/404.html;error_page 500 /error/500.html;# ...(其他错误码配置,需确保/error目录下存在对应HTML文件)# 高级连接配置#-----------------------------keepalive_requests 1000; # 单个Keep-Alive连接允许的最大请求数large_client_header_buffers 4 64k; # 大型请求头的缓冲区数量和大小reset_timedout_connection on; # 关闭超时未响应的连接以释放资源send_timeout 60; # 响应发送超时时间(秒)# 文件传输优化sendfile_max_chunk 512k; # 单次sendfile调用的最大传输量(避免Worker进程阻塞)# 服务器名哈希表优化server_names_hash_bucket_size 256; # 服务器名哈希表桶大小(域名较长时需要增加)# 包含虚拟主机配置文件(通常用于分站点管理)include vhosts/*.conf;
}# 系统资源限制(需放在全局块,不能放在http块内)
#-----------------------------
worker_rlimit_nofile 100000; # Worker进程能打开的最大文件描述符数量(需配合系统ulimit设置)
# includ.config文件
# ======================================================
# Nginx Server 块配置详解
# 此配置用于处理域名为 dbgmarkets.co 的 HTTP/HTTPS 请求
# 实现功能:SSL 加密、动静分离、API 代理、设备类型适配、Gzip 压缩
# ======================================================# server块的匹配优先级是:准确匹配、通配符在前的匹配、通配符在后的匹配、正则表达式的匹配、默认的server匹配
server {# --------------------------# 监听端口与协议配置# --------------------------listen 80; # 监听 IPv4 的 HTTP 80 端口listen 443 ssl http2 default_server; # 监听 IPv4 的 HTTPS 443 端口,启用 HTTP/2,设为默认主机listen [::]:443 ssl http2 default_server; # 监听 IPv6 的 HTTPS 443 端口# 说明:# - default_server: 当请求未匹配其他 server_name 时,并且请求的为指定监听的端口,则由此块处理。没有指定默认server,第一个server就是默认的server# - http2: 启用 HTTP/2 协议提升性能# - ssl: 启用 SSL/TLS 加密# --------------------------# 域名与基础设置# --------------------------server_name dbgmarkets.co; # 匹配的域名(精确匹配,不含 www 等子域名)。用于指定访问的ip或域名。多个域名间用空格分隔。有三种模式,精确匹配,通配符*匹配(不能写在中间,只能出现在首段和尾端,否者会失效),正则表达式匹配(必须使用~作为开始标识)。其中正则表达式,可以使用括号和$N方式在return中获取对应访问的值absolute_redirect off; # 关闭绝对路径重定向(返回相对路径,适用于反向代理后方场景)# --------------------------# Gzip 压缩配置(优化传输效率)# --------------------------# 在http块中。gzip设置为on。gzip_types 设置要压缩的类型,默认只会压缩text/html类型。# gzip_comp_level:有1到9个级别。1压缩最快,压缩程度低,建议设置为6,基本已经极限。# gzip_vary:默认off。开启之后,会在响应头上面添加Vary:Accept-Encoding# gzip_buffers number size:设置压缩时缓冲区的数量和大小。默认即可# gzip_disable "正则表达式" : 会匹配浏览器的user-agnet,匹配到的就不进行压缩# gzip_min_length:当资源小于这个指定大小后,就不进行压缩了。默认20b# gzip_proxied:默认off。指的是作为反向代理服务器,对于后端返回的数据是否进行压缩。# gzip_static:默认off这个是在还没有读取时就压缩文件,然后直接读取对应文件的.gz文件,有的话就直接使用这个文件,没有的话在读取源文件,使用头信息Content-Encoding:gzip和Vary:Accept-Encoding告诉浏览器进行了文件压缩。gzip on; # 启用 Gzip 压缩gzip_min_length 1k; # 只压缩大于 1KB 的文件gzip_comp_level 9; # 压缩级别 1-9(9 最高压缩率,CPU 消耗较大)gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml; # 压缩指定 MIME 类型gzip_vary on; # 添加 "Vary: Accept-Encoding" 头gzip_disable "MSIE [1-6]\."; # 为旧版 IE 浏览器禁用压缩# --------------------------# SSL/TLS 安全配置# --------------------------ssl_certificate C:/crm/nginx-1.20.2/ssl/dbgmarkets_co/dbgmarkets_co.crt; # SSL 证书路径(Windows 格式)ssl_certificate_key C:/crm/nginx-1.20.2/ssl/dbgmarkets_co/dbgmarkets_co.key; # SSL 私钥路径ssl_session_cache shared:SSL:1m; # SSL 会话缓存(1MB 内存,减少握手开销)ssl_session_timeout 10m; # SSL 会话超时时间(10 分钟)ssl_ciphers HIGH:!aNULL:!MD5; # 加密套件配置(HIGH 安全级别,禁用 aNULL/MD5)ssl_prefer_server_ciphers on; # 优先使用服务端加密套件# 注意:建议添加 ssl_protocols TLSv1.2 TLSv1.3; 以禁用老旧协议# --------------------------# 静态资源服务配置# --------------------------# root 实际返回的资源是root路径+location路径# alias 实际返回的资源只是alias的路径root C:/crm/web/dist; # 静态文件根目录(前端构建产物存放路径)# 示例:请求 /css/style.css 将映射到 C:/crm/web/dist/css/style.css# --------------------------# 公共代理头设置# --------------------------proxy_set_header X-Forwarded-Proto $scheme; # 传递客户端协议(http/https)proxy_set_header X-Real-IP $remote_addr; # 传递客户端真实 IPclient_max_body_size 15M; # 允许客户端上传最大 15MB 文件(如文件上传功能)# --------------------------# 路由处理:根路径(/)# --------------------------location / {# 设备类型判断(根据全局 map 映射的 $device_type 变量)if ($device_type = mobile) { # 如果是移动设备proxy_pass http://127.0.0.1:3001; # 代理到本地的 3001 端口(移动端服务)break; # 终止后续处理}index index.html; # 默认访问文件try_files $uri $uri/ /index.html; # 前端 SPA 路由支持(找不到文件时返回 index.html)# 流程:尝试访问真实文件 → 查找目录 → 回退到 index.html}# --------------------------# 路由处理:API 接口(/api)# --------------------------# location /api 匹配所有以/api开头的请求# =/api 精确匹配,只匹配/api的请求# ~^/api\w$ 正则表达式匹配,~标识使用正则表达式,^开头,$结尾。其中使用~*标识正则表达式不区分大小写# ^~/api 匹配第一个以/api开头的请求。默认的匹配顺序是匹配所有的条件,返回最后一个匹配到的,这个^~标识表示匹配到这个表达式之后,就不再向后匹配,直接返回结果location /api {# 解决跨域问题# add_header Access-Control-Allow-Origin 访问的ip地址端口号# add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE# 代理到本地的 81 端口(后端 API 服务)proxy_pass http://127.0.0.1:81; # 关键代理头设置# WebSocket 协议升级支持proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; # 传递原始域名# 补充:通常还需添加 X-Forwarded-For 头记录客户端 IP 链}# --------------------------# 错误页面配置# --------------------------# 5xx 错误统一返回 50x.html。error_page 500 =200 /error.html 使用=可以将返回的状态码500改为200error_page 500 502 503 504 /50x.html; # 注意:需确保 root 目录存在 50x.html 文件
}# rewrit 指令
# set指令。`set $key value`。设置变量键值对。$key可以直接使用。Nginx有预定的变量,如$args就是所有请求参数,$host获取到的是访问的服务器地址
# `if (){}`指令。条件如果是一个变量,不为空或0就是true。也可以使用=和!=判断,不需要引号。也可以使用正则表达式判断,变量和表达式之间用空格和~隔开,然后匹配上为true,其中~区分大小写,~*不区分大小写,!~表示取反。还可以使用内置参数和变量结合判断,如`-f $request_filename`用来判断这个文件是否存在。
# break;指令,终止当前作用域,并且会重定向到当前indx文件。
# `rewrite 正则表达式 地址 [命令]`。命令:last:匹配到后会拿这个地址去所有块中寻找,然后转发;break:匹配到后,会拿这个地址去本块中寻找;redirect:重定向到指定地址,临时重定向302;permanent:永久重定向,301
# `rewrite_log on;`开启后,会以notice级别输出到error日志中。所以需要 `error_log error.log notice;`
# `return code url`:直接返回指定的code,跳转到对应的url上。