Nginx(发音为“engine x”)是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP代理服务器。Nginx以其轻量级、高并发的特性广泛应用于负载均衡、缓存、静态文件服务和反向代理等场景。
Nginx的主配置文件通常位于 /etc/nginx/nginx.conf
。建议的配置文件目录结构如下:
/etc/nginx/ ├── nginx.conf # 主配置文件 ├── conf.d/ # 各站点配置文件 │ ├── default.conf # 默认配置文件 │ ├── siteA.conf # 站点A配置文件 │ ├── siteB.conf # 站点B配置文件 │ └── ... └── cert/ # SSL证书 ├── siteA.key # 站点A私钥 └── siteA.pem # 站点A公钥
相关信息
每个站点配置文件中只允许配置该站点下相关规则,禁止将多个站点配置混在一个配置文件中,或将配置全部放在主配置文件nginx.conf中。
主配置文件参考内容如下:
user nginx; worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; events { worker_connections 1024; } http { 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; #gzip on; include /etc/nginx/conf.d/*.conf; }
相关配置说明如下:
nginx
)来提高安全性。auto
时,Nginx会根据CPU核心数自动决定合适的工作进程数。/var/log/nginx/error.log
是日志文件的路径,notice
是日志级别,表示记录一般的信息,包括重要的运行状态。application/octet-stream
作为默认类型,表示二进制流。main
是日志格式的名称,后面的字符串定义了记录的内容,如客户端IP、请求时间、请求方法、状态码等。main
格式记录日志。/etc/nginx/conf.d/
目录下的所有配置文件。这使得用户可以将不同的虚拟主机或服务配置分散到多个文件中,便于管理和维护。此部分仅供参考,建议以实际站点名称进行配置文件命名
server { listen 443 ssl; server_name siteA; ssl_certificate /etc/nginx/cert/siteA.pem; ssl_certificate_key /etc/nginx/cert/siteA.key; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; location / { proxy_pass http://ip:port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $host; proxy_set_header X-Forwarder-For $remote_addr; proxy_set_header Upgrade $http_upgrade; } } server { listen 80; server_name siteA; # 将所有HTTP请求通过rewrite指令重定向到HTTPS。 rewrite ^(.*)$ https://$host$1; location / { index index.html index.htm; } }
在 Nginx 中,location
指令用于定义请求路径的匹配规则,它可以根据请求的 URI 将请求转发到不同的后端服务器或执行不同的处理逻辑。Nginx 提供了多种匹配方式,可以精确或模糊匹配请求路径。了解 location
的匹配规则有助于优化 Nginx 的配置,以实现高效的路由处理。
location [匹配模式] [URI] { # 配置指令 }
Nginx 中的 location
匹配方式大致可以分为三类:精确匹配、前缀匹配和正则表达式匹配。这些匹配方式的顺序和优先级很重要,因为 Nginx 会按照优先级依次检查每个 location
,并选择最合适的一个。
=
)描述:当 location
以 =
开头时,表示进行精确匹配。如果请求的 URI 与指定的 URI 完全相同,则匹配此 location
。
优先级:最高。
示例:
location = / { # 精确匹配根路径 / }
适用场景:通常用于处理根路径或特定的单一请求。
^~
)描述:当 location
以 ^~
开头时,表示前缀匹配,并且一旦匹配成功,就不再检查正则表达式匹配的 location
。
优先级:比正则表达式匹配高。
示例:
location ^~ /static/ { # 匹配以 /static/ 开头的路径,忽略正则匹配 }
适用场景:适用于静态资源文件夹、图片、CSS、JS 等路径。
~
和 ~*
)描述:~
用于区分大小写的正则表达式匹配,~*
用于不区分大小写的正则表达式匹配。正则表达式匹配的优先级最低,但如果没有匹配到更高优先级的 location
,Nginx 将尝试匹配正则表达式。
优先级:低于精确匹配和前缀匹配。
示例:
location ~ \.php$ { # 匹配所有以 .php 结尾的路径,区分大小写 } location ~* \.(jpg|jpeg|png|gif)$ { # 匹配所有以 .jpg、.jpeg、.png、.gif 结尾的路径,不区分大小写 }
适用场景:适用于需要正则匹配的场景,如根据文件扩展名区分不同类型的请求。
Nginx 按照以下顺序来匹配 location
指令:
location
块都匹配相同的 URI,Nginx 会根据优先级选择最合适的一个。因此,建议先定义优先级较高的规则,如 =
和 ^~
,然后定义常规的匹配。worker_processes
定义Nginx的工作进程数量。设置为auto
时,Nginx会根据CPU核心数自动决定合适的工作进程数。
auto
auto
可以充分利用所有核心,提高并发处理能力,特别适合高流量环境。在无法确定或没有特殊要求的情况下,该值通常设置为auto
以发挥Nginx的最大性能。
worker_connections
是Nginx中用于定义每个工作进程能够同时打开的最大连接数的配置项。合理配置这个参数对于提高服务器的并发处理能力至关重要。
worker_connections
指定的是每个Nginx工作进程可以同时处理的连接数,包括来自客户端的连接和与后端服务器(如数据库或应用服务器)的连接。worker_processes
乘以worker_connections
,即:总连接数 = worker_processes × worker_connections
确定服务器的负载需求:根据网站的访问量和并发用户数估算所需的连接数。例如,如果预计同时在线用户数为1000,并且每个用户打开多个连接(如长连接、HTTP/2等),需要的连接数可能会更高。
评估服务器资源:了解服务器的硬件配置,包括CPU核心数、内存和网络带宽。确保服务器能够承受所配置的连接数。
选择合适的worker_processes值:通常可以设置为CPU核心数的数量或其倍数,以确保充分利用CPU资源。
配置worker_connections:根据需要的并发连接数和worker_processes
来设置。例如,如果设置了4个工作进程,预计的总连接数为4000,那么每个进程的连接数应设置为1000:
worker_connections = 总连接数 / worker_processes = 4000 / 4 = 1000
假设有以下情况:
计算:
2000用户 × 3连接/用户 = 6000连接
。worker_processes
为4(CPU核心数)。worker_connections
:worker_connections = 6000 / 4 = 1500
配置示例:
worker_processes 4; events { worker_connections 1500; }
根据操作系统的不同,Nginx 支持多种事件处理机制,如 select
、poll
、epoll
、kqueue
等。
常用事件模型:
select
更高效,但在连接数增加时性能下降。配置示例:
events { use epoll; # 在 Linux 系统上使用 epoll 事件模型 }
keepalive
是 Nginx 中用于保持客户端与服务器之间持久连接的功能。通过使用 keepalive
,可以减少连接建立和关闭的开销,从而提高性能。
keepalive
允许在同一 TCP 连接上发送多个 HTTP 请求,避免每个请求都重新建立连接。keepalive
可以显著提高响应速度和降低延迟,尤其在高并发环境中。含义:指定服务器在客户端没有发送请求的情况下,保持连接的最大时间(以秒为单位)。
示例:
server { listen 80; server_name example.com; keepalive_timeout 65; # 设置保持连接超时时间为65秒 }
含义:指定每个持久连接允许的最大请求数。达到该请求数后,连接将被关闭。
示例:
server { listen 80; server_name example.com; keepalive_requests 100; # 每个连接最大允许100个请求 }
keepalive
可以减少连接建立的开销,提高请求处理效率。keepalive
可以提高请求的响应速度,尤其是在短时间内发送多个请求的情况下,保持连接可以降低延迟。keepalive
可以减少每次请求时的延迟,提高文件加载速度。注意
过长的 keepalive_timeout
可能会导致服务器资源浪费,尤其是在低流量环境中。
Gzip 是一种常用的压缩技术,能够显著减少 HTTP 响应数据的大小,从而加快页面加载速度和降低带宽使用。
要启用 Gzip 压缩,需要在 Nginx 配置文件的 http
块中添加以下配置:
http { gzip on; # 启用 Gzip 压缩 }
gzip_types:指定哪些 MIME 类型的响应数据将被压缩。默认情况下,只有文本文件类型(如 HTML、CSS、JavaScript 等)会被压缩。
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_min_length:设置压缩的响应数据的最小长度,只有大于该长度的响应才会被压缩。可以减少小文件的处理开销。
gzip_min_length 1000; # 仅压缩大于1000字节的响应
gzip_comp_level:设置压缩级别,范围从 1 到 9。级别越高,压缩率越高,但 CPU 使用率也会增加。通常建议设置为 5。
gzip_comp_level 5; # 设置压缩级别为5
gzip_vary:启用 Vary: Accept-Encoding
头,允许不同的客户端(支持 Gzip 的和不支持的)接收不同的响应,从而实现更好的缓存效果。
gzip_vary on; # 启用 Vary 头
gzip_disable:用于指定不启用 Gzip 压缩的条件。例如,可以根据用户代理(User-Agent)禁用 Gzip。
gzip_disable "MSIE [1-6]\."; # 禁用 IE 6 及以下版本的 Gzip
注意
启用 Gzip 压缩会增加 CPU 使用率,尤其是在压缩级别较高时。应根据服务器性能进行调整。
在 Nginx 中,缓冲区大小的配置是影响性能和响应速度的重要因素,特别是在处理大文件和高并发请求时。合理配置缓冲区可以优化资源使用,提升用户体验。
缓冲区用于临时存储传入和传出的数据,以减少磁盘 I/O 和网络延迟。Nginx 提供多个缓冲区配置选项,主要用于控制请求和响应的数据处理。
含义:指定 Nginx 用于存储客户端请求体的缓冲区大小。对于 POST 请求,Nginx 会将请求体存储在该缓冲区中。
示例:
http { client_body_buffer_size 16k; # 设置为16KB }
适用场景:适用于接收较大的 POST 请求(如文件上传)时,增加该值可以减少磁盘 I/O。
含义:限制客户端请求体的最大大小。如果请求体超过该限制,Nginx 会返回 413 错误。
示例:
http { client_max_body_size 20m; # 最大请求体为20MB }
适用场景:主要用于控制文件上传的大小,防止恶意用户上传过大的文件。
含义:指定用于存储从后端服务器接收的响应头的缓冲区大小。
示例:
http { proxy_buffer_size 8k; # 设置为8KB }
适用场景:适用于需要处理大响应头的 API 或后端服务。
含义:设置用于存储从后端服务器接收的响应数据的缓冲区数量和大小。
示例:
http { proxy_buffers 4 16k; # 使用4个16KB的缓冲区 }
适用场景:适用于需要高并发和大响应体的场景,如视频流服务和大文件下载。
含义:指定在处理请求时,正在使用的缓冲区的最大大小。
示例:
http { proxy_busy_buffers_size 32k; # 设置为32KB }
适用场景:当后端响应较慢时,增加该值可以防止缓冲区过早地被写入磁盘。
client_body_buffer_size
和 proxy_buffers
可以优化性能。注意
缓冲区的大小直接影响服务器的内存使用,应根据服务器资源合理配置。
在 Nginx 中,文件缓存是一种优化技术,可以显著提高静态文件的传输速度和减少后端服务器的负载。通过将静态文件的响应缓存到本地存储,Nginx 可以在后续请求中快速响应,而无需每次都从后端获取数据。
文件缓存允许 Nginx 将特定类型的响应数据(通常是静态文件)存储在本地,以便在后续请求中快速提供这些数据。这可以减少后端服务器的负载,提高用户的访问速度。
含义:定义缓存路径、缓存键和缓存参数。
示例:
http { proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off; }
参数说明:
/var/cache/nginx
:缓存文件的存储路径。levels=1:2
:定义目录层次结构(如 1
表示一级目录,2
表示二级目录),可优化文件系统性能。keys_zone=my_cache:10m
:定义缓存区域的名称和大小,这里是 10MB。max_size=1g
:最大缓存大小为 1GB。inactive=60m
:在 60 分钟内未被访问的缓存项会被自动删除。use_temp_path=off
:禁用临时路径,直接在目标缓存路径中存储。含义:在特定的 location
块中启用缓存。
示例:
location /api/ { proxy_pass http://backend; proxy_cache my_cache; # 启用之前定义的缓存区域 }
含义:自定义缓存键,可以通过变量构建缓存键。
示例:
location / { proxy_cache my_cache; proxy_cache_key "$scheme$request_method$host$request_uri"; }
含义:设置缓存的有效时间,不同状态码的缓存时间可以不同。
示例:
location / { proxy_cache my_cache; proxy_cache_valid 200 1h; # 200 响应缓存 1 小时 proxy_cache_valid 404 10m; # 404 响应缓存 10 分钟 }
注意
确保合理设置缓存有效时间,以避免过期数据的使用。
在 Nginx 中,负载均衡是一种将请求分发到多个后端服务器的技术,旨在提高应用的可用性和响应速度。通过合理配置负载均衡,Nginx 可以有效地管理服务器资源,确保高并发情况下的稳定性。
负载均衡可以将用户的请求分发到多个后端服务器,以实现更好的资源利用和故障转移。Nginx 支持多种负载均衡算法,可以根据具体需求选择适合的方式。
含义:定义后端服务器组。所有负载均衡的配置都在此块中进行。
示例:
upstream backend { server backend1.example.com; server backend2.example.com; server backend3.example.com; }
Nginx 支持多种负载均衡算法,以下是几种常用的:
upstream backend { server backend1.example.com; server backend2.example.com; server backend3.example.com; }
upstream backend { least_conn; # 使用最少连接算法 server backend1.example.com; server backend2.example.com; server backend3.example.com; }
IP 哈希:根据客户端 IP 地址的哈希值将请求分配到固定的后端服务器。
upstream backend { ip_hash; # 使用 IP 哈希算法 server backend1.example.com; server backend2.example.com; }
在 server
块中使用 proxy_pass
将请求转发到定义的 upstream
服务器组。
示例:
server { listen 80; server_name example.com; location / { proxy_pass http://backend; # 转发请求到 upstream 定义的后端服务器 } }
注意
对于需要会话保持的应用,可以使用 sticky
或 ip_hash
方法,以确保用户的请求始终被发送到同一台服务器。
本文作者:蒋固金
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!