Nginx学习
发行版本
Nginx开源版:提供基础功能
Nginx Plus商业版:提供高级功能,如对微服务整合、云原生整合
Openresty:Nginx和Lua脚本整合提供丰富的功能
Tengine:Nginx和C整合,淘宝提供的稳定的魔改版,如果没二次开发的需求可以选择使用
命令
./nginx # 启动
./nginx -s stop # 快速停止
./nginx -s quit # 优雅关闭。执行的连接请求处理完后再退出
./nginx -s reload # 加载配置文件。在处理的请求用旧配置完成,开启新的子进程加载新的配置来处理新的请求
基本使用
最小配置
worker_processes 12; # 工作线程
events {
worker_connections 1024; # 连接数
}
http {
include mime.types; # 同级目录下的mime.types文件,其定义了浏览器应该用哪种方式解析某种后缀名的数据
default_type application/octet-stream; # 默认解析方式
sendfile on; # 零拷贝
keepalive_timeout 65; # 长连接超时时间
server { # 虚拟主机vhost
listen 80; # 监听端口
server_name localhost; # 域名、主机名
location / { # 匹配URI
root html; # 匹配成功后以哪个目录为根目录,相对于Nginx的主目录
index index.html index.htm; # 默认页
}
error_page 500 502 503 504 /50x.html; # 哪些状态码跳转到出错页面/50x.html
location = /50x.html {
root html; # 匹配URI,跳转到配置的目录下寻找对应的文件
}
}
}
虚拟主机与域名解析
原理:一台Nginx为多个域名提供服务,某个域名的请求过来,Nginx为其找到对应的目录以提供服务。目的是为了提高主机的CPU、内存等的利用率,因为大部分域名的流量非常小,服务器性能过剩。
本地域名解析:hosts文件。
泛域名解析:即配置通配符,可以实现多用户二级域名,如*.sj.com
可以将a.sj.com/b.sj.com
等所有类似的域名都解析到同一个IP地址上。
ServerName匹配规则为首次匹配到就结束,如果都没有匹配到,则以第一个作为匹配结果。有以下匹配方式:
server_name vod.sj.com vodd.sj.com ; # 匹配多个域名
server_name *.sj.com; # 通配符匹配
server_name vod.sj.*; # 通配符结束匹配
server_name ~^[0-9]+\.sj.com$; # 正则匹配
反向代理
能提供的功能:
- URL重写,既可以隐藏真实URL,又可以方便用户记忆,还能提高搜索引擎(这用SSR更好)收录。如用户看到的是
/product/100
,Nginx重写为/product?id=100
。 - 负载均衡
反向代理配置
upstream abc {
server 192.168.0.11:80;
server 192.168.0.12:80;
}
server {
# ...
location / {
proxy_pass http://abc;
}
}
动静分离
常用于中小型项目,大型网站一般是将静态资源作为独立域名。
server {
# ...
location / {
proxy_pass http://192.168.0.11:80;
}
location ~*/(js|img|css) { # 正则匹配
proxy_pass http://192.168.0.12:80;
}
}
location /
的优先级比较低。
URL Rewrite
rewrite <regexp> <replacement> [flag]
。rewrite允许出现的位置:server、location、if。
flag说明:
- last。本条规则匹配完成后,继续向下匹配新的location URI规则。也就是最后面的匹配会返回。
- break。本条规则匹配完成后终止。
- redirect。返回302重定向。
- permanent。返回301永久重定向。
server {
# ...
location / {
rewrite ^/([0-9]+).html$ /index.jsp?page=$1 break;
proxy_pass http://192.168.0.11:80;
}
}
防盗链
盗链定义:其他网站引用了本网站的静态资源。
防盗链:通过HTTP的referer字段。
location ~*/(js|img|css) {
# 校验referer。none表示如果没有referer也允许访问,比如用户拿着给的链接去下载器下载,这种情况就是没有referer
valid_referers none 192.168.0.11;
if (!invalid_referer) {
rewrite ^/ /img/x.png break; # 重写展现防盗链图片
return 403; # 返回错误码
}
proxy_pass http://192.168.0.11:80;
}
HA
依赖keepalived+虚拟IP的能力
高级使用
保持会话
Nginx提供保持会话的功能:
- ip_hash:同一个ip的请求只会在同一台服务器上被处理。优点是服务器扩容方便,缺点是访问倾斜。可用于中小型项目。
hash $cookie_jsessionid;
:Java服务下发给客户端的cookie。hash $request_uri;
:适用于在不支持cookie的场景(如APP),也适用于某些资源不存在于所有服务器上的情况(如视频、音频等)。sticky
模块:通过类似于cookie_jsessionid的方式,在cookie中保存一个字段,值是由该模块产生的。可以设置过期时间。
对上游服务器使用keepalive
upstream配置:
upstream abc {
keepalive 100; # 与上游服务器保持的连接数(类似连接池概念)
keepalive_timeout 65; # 连接保留的时间
keepalive_requests 1000; # 一个tcp连接复用中可以并发接收的请求数
}
server配置:
server {
proxy_http_version 1.1; # http版本号。默认使用1.0版本,需要在request中增加"Connection keep-alive" header才能使用,而1.1默认支持
proxy_set_header Connection ""; # 清除close信息,因为Nginx接收浏览器请求后会将Connection置为close
}
客户端限制
可配置位置:
- http
- server
- location
client_body_buffer_size # 请求体缓冲区大小
client_header_buffer_size # 请求头缓冲区大小
client_max_body_size # 请求大小超过设定值会返回413给客户端,通过检查Content-Length实现。默认1M,设置为0可以禁用
client_body_timeout # 服务端接收request body的超时时间。比如因为网络原因,服务端接收到部分,然后在超时时间内再也没有接收到数据,会返回408
client_header_timeout # 服务端接收request header的超时时间。超时返回408
client_body_in_single_buffer # 缓冲body时尽量在内存中使用连续单一的缓冲区,常用于在二次开发中使用 $request_body 读取数据时,不二次开发不需要配置。
Gzip
一般用于文本格式数据的压缩,对于二进制文件不需要启用压缩。
# 动态压缩。即数据传输过程中压缩
gzip on; # 启用gzip。默认关闭
gzip_buffers 16 8k; # 16个缓冲块,大小8k
gzip_comp_level 6; # 压缩等级1-9,数字越大压缩率越高
gzip_http_version 1.1; # 使用gzip的最小版本
gzip_min_length 2k; # 小于该值的不压缩
gzip_proxied any; # 作为反向代理服务器时,针对上游服务器返回的头信息进行压缩,any表示无条件启用压缩。其他有expired等
# 静态压缩。动态压缩没法利用sendfile,静态压缩的意义在于通过sendfile直接将压缩文件发送
# 需要在编译时加上对应的模块。--with-http_gzip_static_module
gzip_static on; # 启用。默认off,还可选always(需搭配ngx_gunzip_module使用)
高并发系统资源静态化方案
后端取到数据后,输出到模板引擎,修改模板引擎的输出到文件(html),该文件由Nginx代理,从而实现多次访问某个同一页面时响应很快的功能。在并发量很大的情况下,可以利用该方案。
一个页面中由三部分组成:
- 每个页面特有的内容,可由模板引擎生成
- 页面关联的内容(如推荐、销量等)
- 所有页面都有的固定内容(如head、footer等)
需要考虑的问题:
- 一致性问题
- 合并文件(Nginx提供的SSI模块可以实现)
- Nginx集群文件同步(多台Nginx服务器同步某一台主Nginx服务器,通过rsync同步,通过inotify监控文件的变更)。rsync主动推送到其他服务器,需要将readonly改为no,默认只能通过定时的方式推送或拉取,通过引入inotify实现在有变化时才操作。
缓存
浏览器缓存
- 强制缓存:Nginx返回资源并告知缓存时间,浏览器在缓存有效期间内不请求Nginx。Expire或者Cache-Control
- 协商缓存:Nginx返回资源并携带Last-Modified响应头,浏览器下次请求时带上该时间到请求头,Nginx检查本地文件是否改变,未改变则返回304OK,浏览器从本地缓存中取。
GEOip
可以判断浏览器的IP属于哪个城市or哪个国家,从而实现拒绝指定之外的城市访问。
反向代理服务器缓存
将上游服务器中拿到的资源进行缓存
# 缓存路径。levels表示缓存目录的层数。keys_zone表示名称,其在内存中存储key。inactivate表示缓存多久未被访问后会删除
proxy_cache_path /nginx_tmp levels=1:2 keys_zone=test:100m inactivate=1d max_size=100g;
server {
location / {
proxy_pass http://abc;
add_header Nginx-Cache "$upstream_cache_status";
proxy_cache test; # keys_zone
proxy_cache_valid 1h; # 缓存有效期,超时后会重新向上游服务器请求
}
}
清理插件:proxy_cache_purge
strace
strace命令是一个集诊断、调试、统计于一体的工具,可用来追踪调试程序。
匿名location和return
error_page 404 = @666;
# 匿名location
location @666 {
# 指定content type,从而让浏览器显示而不是去下载
add_header Content-Type 'text/html';
return 200 'hello world';
}
限速
请求限速
# 每个请求的地址 1s内只能请求1次,内存空间10m作为缓冲区使用。漏桶算法
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
server {
location / {
# 名称为one,和上面配置的对应。burst表示桶的大小,nodelay表示桶满后,所有请求快速失败,即返回错误,而不是等待进入桶
limit_req zone=one burst=5 nodelay;
}
}
带宽限速
location / {
# 令牌桶算法,限制流出速度
limit_rate_after 1m; # 在1m之后开始限速
limit_rate 1k; # 限速1k/s
}
并发数限制
limit_conn_zone $binary_remote_addr zone=two:10m;
server {
location / {
# 名称为two,只允许1个并发
limit_conn two 1;
}
}
upstream重试机制
被动式重试
upstream abc {
# 10s内失败5次就下线;下线10s后给一次机会上线
server 192.168.0.11:80 max_fails=5 fail_timeout=10s;
server 192.168.0.12:80;
}
location / {
proxy_next_upstream error timeout; # 指定发生error或超时时,进行重试
proxy_next_upstream_timeout 15s; # 重试过程中的总时间,如果超过15s则这次请求失败
proxy_next_upstream_tries 5; # 重试5个机器
proxy_pass http://abc;
root html;
}
主动式重试:需要使用商业版或者第三方如Tengine
一些配置项解释
http下的配置
keepalive_timeout
:在两次请求之间保持打开状态,若在超时时间内有其他请求过来,则复用它,并重新计时。send_timeout
:响应请求时的超时时间,超时后关闭连接。和keepalive_timeout
会有冲突,如果该值设置过小,可能导致keepalive_timeout
没用,因为响应超时导致连接被关闭了。keepalive_time
:限制keepalive保持连接的最大时间。proxy_set_header X-Forwarded-For $remote_addr;
:将客户端IP写入header中,使得上游服务器能拿到客户端的真正IP
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix