前言
Nginx是一个高性能的HTTP和反向代理服务器,也是一种轻量级的Web服务器。
nginx在应用程序中有以下作用:1. 反向代理:将来自客户端的请求转发到后端的真实服务器,然后将响应返回给客户端。以隐藏服务器的真实IP地址,提高安全性。2. 负载均衡:将来自客户端的请求分发到多个后端服务器,提高系统的并发处理能力3. gzip压缩:压缩数据,提高网络传输效率4. 静态资源服务器:提供对静态文件(如HTML、图片)的访问服务。并可配置缓存,以减少对后端服务器的请求次数5. SSL/TLS加密:对传输的数据进行加密,即HTTPS
默认配置文件分析
1、nginx.conf 文件,即Nginx的默认配置文件
//配置工作进程数,如果大于1,则以多进程的方式运行
// worker进程的数量 建议是1 最大为cpu的线程数
worker_processes 1;//配置影响Nginx服务器或与用户的网络连接
events {//单个工作进程可以同时打开的最大连接数//最大客户端连接数由worker_processes和worker_connections决定worker_connections 1024;
}//可以嵌套多个server
http
{//包含其他文件到nginx.conf配置文件中,mime.types文件包含了各种文件类型 include mime.types; 是用来加载 MIME 类型的配置文件。 该配置告诉 Nginx 根据文件扩展名设置正确的 Content-Type 响应头。include mime.types;//设置默认的文件类型,'application/octet-stream'是一种通用的二进制文件类型default_type application/octet-stream;//启用内核级别的文件传输优化sendfile on;//长连接时间,超过时间Nginx会关闭该连接,包括HTTP和WebSocketkeepalive_timeout 65;//配置虚拟主机的相关参数server{ //监听的端口listen 80;//监听的域名server_name localhost;//配置请求的路由,以及各种页面的处理情况location / {root html;index index.html index.htm;}//配置错误页面error_page 500 502 503 504 /50x.html;location = /50x.html {root html;}}
}
注解:
1、include mime.types;
这行配置的作用是让 Nginx 加载一个叫 mime.types 的文件,以便设置文件的 MIME 类型(Media Type)。
MIME 类型决定了当客户端请求静态资源(如 HTML、CSS、JS、图片等)时,Nginx 返回的 Content-Type 响应头的值。
Nginx 的 mime.types 文件
types {text/html html htm shtml;text/css css;application/javascript js;image/jpeg jpeg jpg;image/png png;...
}
支持多种文件类型:现代网站通常需要处理多种类型的文件,比如图片、视频、文档等。通过 mime.types 文件,Nginx 可以轻松支持这些类型。
告知浏览器如何处理文件:例如:text/html 告诉浏览器将文件渲染为网页。
application/javascript 告诉浏览器将文件解释为 JavaScript 脚本。
2、default_type application/octet-stream;
该配置用于设置 默认的 MIME 类型,即当 Nginx 无法根据文件扩展名匹配到对应的 MIME 类型时,返回的默认 Content-Type 响应头值。
它表示任意的二进制数据,告诉客户端(通常是浏览器)无法确定文件的具体类型。
客户端通常会将这种文件处理为下载而不是直接打开或显示。3、sendfile 是 Nginx 用来优化文件传输性能的一个指令。它可以利用操作系统内核的 sendfile 系统调用直接在文件描述符和网络套接字之间传输数据,而无需经过用户空间。这种方式避免了不必要的数据拷贝,提高了文件传输效率。
4、keepalive_timeout 指定了客户端和服务器之间的 HTTP Keep-Alive 连接的超时时间(以秒为单位)
2、根据nginx.conf 默认配置文件可分为6个模块:
全局模块(main)
events模块
http模块upstream模块server模块localtion块localtion块....server模块localtion块localtion块.......
注解:
1、全局模块:配置影响nginx全局的指令,比如运行nginx的用户名,nginx进程pid存放路径,日志存放路径,配置文件引入,worker进程数等。
2、events模块:配置影响nginx服务器或与用户的网络连接。比如每个进程的最大连接数,选取哪种事件驱动模型(select/poll epoll或者是其他等等nginx支持的)来处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。
3、http模块:可以嵌套多个server,配置代理,缓存,日志格式定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。
4、server模块:配置虚拟主机的相关参数比如域名端口等等,一个http中可以有多个server。
5、location模块:模块定义了 URL 路径的路由规则和处理方式。
6、upstream模块:配置上游服务器的地址以及负载均衡策略和重试策略等等。
location 模块的路由匹配规则
常见指令:
location [ = | ~ | ~* | ^~ ] uri { ... }
- 通用匹配 使用一个 / 表示,可以匹配所有请求。
location / {root dist;index index.html index.htm;}
- 无修饰符的前缀匹配 匹配前缀是配置的的url(提示:前缀匹配使用alias来寻找资源)
// 以test_api为例
location /test_api {alias dist; index index.html index.htm;
}
curl http://www.locatest.com/testapi ✅ 301
curl http://www.locatest.com/testapi? ✅ 301
curl http://www.locatest.com/TESTAPI ❌ 404
curl http://www.locatest.com/testapi/ ✅ 200
curl http://www.locatest.com/testapimmm ❌ 404
curl http://www.locatest.com/testapi/mmm ❌ 404
curl http://www.locatest.com/aaa/testapi/❌ 404
域名/testapi,域名/testapi? 和域名/testapi/ 这三个url能够匹配上无修饰符的前缀匹配。
- ^~ 有修饰符的前缀匹配
location ^~ /exacttestapi{ [ configuration ]
}
匹配结果
curl http://www.locatest.com/exacttestapi ✅ 200
curl http://www.locatest.com/exacttestapi/ ✅ 200
curl http://www.locatest.com/exacttestapi? ✅ 200
curl http://www.locatest.com/exacttestapimmm ✅ 200
curl http://www.locatest.com/exacttestapi/mmm ✅ 200
curl http://www.locatest.com/aaa/exacttestapi ❌ 404
curl http://www.locatest.com/EXACT TESEAPI ❌ 404
域名/exacttestapi 和域名/exacttestapi/mmm 是可以匹配上的,而不带修饰符的前缀匹配这两个类型的url是匹配不上的直接返回了404
- = 精确匹配
location = /test {return 200 "test";}# /test ok# /test/ not ok# /test2 not ok# /test/2 not ok
- ~ 区分大小写的正则匹配
location ~ ^/test$ {[ configuration ] }# /test ok# /Test not ok# /test/ not ok# /test2 not ok
- ~* 不区分大小写的正则匹配
location ~* ^/test$ {
[ configuration ]
}
# /test ok
# /Test ok
# /test/ not ok
# /test2 not ok
- 匹配优先级
优先级:精确匹配 > 前缀匹配 >正则匹配>通用匹配
- root 与 alias 的区别
// 1. root 是直接拼接 root + locationlocation /i/ {root /data/w3;
} // 当请求 /i/top.gif ,/data/w3/i/top.gif 会被返回。
// 2. alias 是用 alias 替换 location
location /i/ {alias /data/w3/images/;
} // 当请求 /i/top.gif ,/data/w3/images/top.gif 会被返回
- server 和 location 中的 root
server 和 location 中都可以使用 root,采取就近原则,如果 location 中能匹配到,
就是用 location 中的 root 配置,忽略 server 中的 root,当 location 中匹配不到的时
候,则使用 server 中的 root 配置
解决跨域
假设页面地址:http://172.17.235.35:8080
假设请求接口地址:http://govserver1/?id=fecaace80f47624f
配置Nginx
server {listen 8088;server_name 172.17.235.35;location / {proxy_pass http://172.17.235.35/; //反向代理}location /api {proxy_pass http://govserver1/;}
}
将页面地址代理到8088端口,将接口地址也代理到8088端口
gzip压缩
Nginx 中的 Gzip 模块配置,用于优化 HTTP 响应时的内容传输,通过压缩传输内容
减少流量消耗,加快加载速度,同时降低带宽成本。
http{gzip on; # 是否开启gzip Nginx 会对 HTTP 响应内容进行压缩,前提是客户端支持 Gzip 压缩gzip_min_length 1k;# 开始压缩的最小长度 1024 字节(再小就不要压缩了,意义不大)gzip_buffers 4 16k; # 缓冲(压缩在内存中缓冲几块? 每块多大?)(Nginx 在内存中先将响应内容存入缓冲区,然后对缓冲区内容进行压缩,最后返回给客户端。)gzip_http_version 1.1;# 开始压缩的http协议版本(可以不设置,目前几乎全是1.1协议) HTTP 1.1 及更高版本支持 Gzip 压缩。gzip_comp_level 2;# 推荐6 压缩级别(级别越高,压的越小,越浪费CPU计算资源) (1:最快的压缩速度,但压缩率最低。9:最高的压缩率,但会消耗大量的 CPU 资源。)gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml;# 对哪些类型的文件用压缩 如txt,xml,html ,cssgzip_vary on; # 是否传输gzip压缩标志 (当启用 gzip_vary on 时,Nginx 会在响应头中添加 Vary: Accept-Encoding 告诉客户端和缓存服务器,内容根据 Accept-Encoding 的值不同可能有不同的版本(压缩或未压缩)。)gzip_proxied expired no-cache no-store private auth; #Nginx做为反向代理的时候启用 例如如果header中包含”Expires”头信息,启用压缩gzip_disable "MSIE [1-6]\."; #正则匹配UA,配置禁用gzip条件。此处表示ie6及以下不启用gzip(因为ie低版本不支持)gzip_static on; #开启后会寻找以.gz结尾的文件,直接返回,不会占用cpu进行压缩,如果找不到则不进行压缩 默认是动态压缩,即对每个请求是先压缩后输出。可配置gzip_static on;直接读取生成好的gz文件(前端打包时生成gz文件)(原理:如果客户端请求某文件(如 example.css),且目录中存在同名的 .gz 文件(如 example.css.gz),则直接返回压缩后的 .gz 文件,而不再占用 CPU 动态压缩。如果没有找到对应的 .gz 文件,则执行动态压缩。使用场景:配合前端工具(如 Webpack)生成 .gz 文件,减少服务器 CPU 开销。)
}
将HTTP请求转到HTTPS
在服务器上监听80端口,使用重定向
server{listen 80;server_name service.com;return 301 https://$host$request_uri; //永久性重定向}
// 这样,如果访问http://service.com 将会跳转到 <https://service.com>
// 即将 HTTP 请求升级为 HTTPS 请求,且 URL 和查询参数保持不变。
// server_name 配置可以使用域名,建议使用域名而不是 IP 地址,除非你的服务器是通过 IP 访问的。
// 要确保服务器支持 HTTPS,并且已正确配置 SSL/TLS 证书,以便让重定向到 HTTPS 时不会发生错误。
使用HTTP2
启用 HTTP/2 后,可以提高网站的加载性能,尤其是处理大量资源请求时。在监听443端口后加http2即可开启
listen 443 ssl http2;
需要满足以下条件
1、启用 SSL/TLS:因为 HTTP/2 必须与加密协议(如 TLS)一起使用。未启用 SSL 的连接无法使用 HTTP/2。2、配置 http2:listen 443 ssl http2; 在端口 443 上启用了 HTTP/2。3、使用支持 HTTP/2 的 Nginx 版本:Nginx 从版本 1.9.5 开始支持 HTTP/2。因此,确保你使用的是支持 HTTP/2 的版本。
server {listen 443 ssl http2;server_name example.com;ssl_certificate /etc/nginx/ssl/example.com.crt;ssl_certificate_key /etc/nginx/ssl/example.com.key;# 强制使用 TLS 1.2 或更高版本ssl_protocols TLSv1.2 TLSv1.3;# 启用 HTTP/2http2_push_preload on;location / {# 其他配置}
}
负载均衡
Nginx 用于负载均衡,它将请求分配到 upstream firstdemo 中定义的不同服务器(172.17.235.35:8081 和 172.17.235.35:8082)。灰度发布,可以通过判断 Cookie 来分配请求到不同的服务器
将请求分配给空闲服务器处理(电话号码同一个,但是不同客服接听)
upstream firstdemo {server 172.17.235.35:8081;server 172.17.235.35:8082;
}
// 当请求通过 proxy_pass http://firstdemo; 转发时,Nginx 将根据负载均衡策略(默认是轮询)在这两个服务器之间分配请求server {listen 8080;server_name localhost;location / {proxy_pass http://firstdemo;}
}
灰度系统:可判断cookie版本,走不同服务器
upstream firstdemo {server 192.168.31.123:8081; # 服务器1server 192.168.31.123:8082; # 服务器2
}server {listen 8080;server_name localhost;location / {# 判断请求中的 cookie 是否包含特定版本号if ($http_cookie ~* "version=beta") {# 如果 cookie 包含 "version=beta",请求将被转发到服务器 8082(灰度服务器)proxy_pass http://192.168.31.123:8082;}else {# 否则请求转发到服务器 8081(稳定版服务器)proxy_pass http://192.168.31.123:8081;}}
}
*if ($http_cookie ~ "version=beta")**:这个条件判断请求的 Cookie 中是否包含 version=beta。如果包含,表示该用户需要访问灰度版本(例如,测试版、部分用户版本等),则将请求转发到 192.168.31.123:8082 服务器。
**proxy_pass http://192.168.31.123:8081;**:如果 Cookie 中没有 version=beta,则请求会转发到默认的稳定版服务器 8081。
静态资源服务器
在这个配置中,Nginx 被用于直接提供静态资源,以减少后端服务器的负担,并提高静态资源的访问速度。通过将不常修改的静态资源(如图片、CSS、JavaScript 等)放置在 Nginx 的静态资源目录中,Nginx 负责直接服务这些文件,而不需要将它们传递给后端应用程序进行处理。
把不常修改的静态资源文件放到nginx的静态资源目录中去,这样在访问静态资源时直接读取nginx服务器本地文件目录之后返回,这样就大大减少了后端服务的压力同时也加快了静态资源的访问速度
步骤一:在/www/server/nginx/html下创建images文件夹 用于存放静态资源文件(如图片)。
步骤二:在Nginx进行配置(注意location的访问方式不同,root指定路径也不同)
server{listen 80;server_name 127.0.0.1; # 设置服务器监听的地址index index.html index.htm index.php; # 设置默认索引文件root /www/server/nginx/html; # 设置根目录路径#error_page 404 /404.html;include enable-php.conf;# 当访问 /images/ 路径时location ^~ /images/{expires 1d; # 设置缓存过期时间为 1 天,客户端会缓存图片,减少请求}access_log /www/wwwlogs/access.log; # 设置访问日志路径}
用户请求 http://127.0.0.1/images/1.png。
Nginx 解析到 /images/ 路径,匹配到 location ^~ /images/ 规则。
Nginx 查找路径 /www/server/nginx/html/images/1.png。
如果文件存在,Nginx 会直接返回该文件,而不会经过后端应用处理,极大提高了静态资源的访问速度。
同时,由于设置了 expires 1d,浏览器会在 1 天内缓存该图片,避免频繁访问 Nginx 服务器。
1、减轻后端负担:将静态资源通过 Nginx 提供,不会占用后端服务器的资源,后端只处理动态请求。
2、加快访问速度:Nginx 作为高效的静态文件服务器,能够快速响应静态资源请求。
3、节省带宽:通过设置缓存 (expires) 来减少重复的请求,提升资源加载速度。
防盗链
用于防止图片等静态资源的盗链行为,禁止其他网站未经授权使用您的资源。通过 Nginx 配置的 valid_referers 指令,您可以设定哪些来源地址(Referer)是允许访问某些资源的,其他不在白名单内的来源会被拒绝访问,并返回 HTTP 状态码 403(禁止访问)。
location ~ .*\.(jpg|png|gif)$ { # 匹配防盗链资源的文件类型# 通过 valid_referers 定义合法的地址白名单 $invalid_referer 不合法的返回403 valid_referers none blocked 127.0.0.1;if ($invalid_referer) {return 403;}
}
valid_referers 指令用于定义合法的请求来源(即合法的 Referer)。在此配置中:
none:表示没有 Referer(即请求头中没有 Referer 字段)也是合法的。
blocked:表示被拦截的请求来源,通常是当 Nginx 接收到的请求没有 Referer 或 Referer 被明确屏蔽时。
127.0.0.1:表示本地请求(即来自 127.0.0.1 的请求)是合法的。
如果你还想允许某些特定网站的访问,可以修改 valid_referers:
valid_referers none blocked 127.0.0.1 www.mysite.com another-site.com;
请求限制
在高流量网站中,大量的请求可能会给服务器带来很大的压力,尤其是恶意请求、爬虫或DDoS攻击等。为了防止这种情况,Nginx 提供了两个常用模块来限制请求频率和连接数:limit_conn_module(连接频率限制)和 limit_req_module(请求频率限制)
1、连接数限制 (limit_conn_module)
limit_conn_module 模块用于限制来自同一 IP 地址的连接数。这对于防止某些 IP 地址过多连接到服务器而导致服务器资源耗尽非常有用。
# 定义连接频率限制区域 $binary_remote_addr 代表客户端 IP 地址,zone 定义共享内存区域的名称和大小
limit_conn_zone $binary_remote_addr zone=coon_zone:10m;server {listen 80;server_name example.com;# 设置连接限制,每个 IP 地址最多允许 1 个并发连接limit_conn conn_zone 1;
}
2、limit_req_module:请求频率限制
作用:限制客户端单位时间内的请求数量,防止恶意爬虫或高频请求给服务器带来过大的压力。
# $binary_remote_addr 远程IP地址 zone 区域名称 10m内存区域大小 rate 为请求频率 1s 一次
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;
server {location / {# 设置对应的共享内存区域 burst最大请求数阈值 nodelay不希望超过的请求被延迟limit_req zone=req_zone burst=5 nodelay;}
}
#limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;:定义一个名为 req_zone 的内存区域,大小为 10MB,并设置每秒最多允许 1 次请求(rate=1r/s)。
#limit_req zone=req_zone burst=5 nodelay;:在 location / 中设置限制,每个 IP 地址最大允许每秒 1 次请求,突发流量允许最多 5 次请求,并且不延迟请求(nodelay)。burst 定义了短时间内允许的最大请求数,超过此限制的请求会被丢弃。
连接限制:用于限制同一 IP 的并发连接数,防止某些客户端占用过多的连接资源。
请求限制:用于限制同一 IP 在一定时间内的请求频率,防止高频请求对服务器造成压力