文章目录
- 一、Nginx扩容
- 1、前言
- 2、单机垂直扩容:硬件资源增加
- 3、水平扩展:集群化
- 4、Nginx模块升级
- 二、Nginx高级配置介绍
- 1、会话管理与sticky模块
- 1.1 介绍
- 1.2 下载与安装
- 1.3 错误处理
- 2、KeepAlive
- 2.1 介绍
- 2.2 测试工具charles
- 2.3 KeepAlive使用
- 2.4 对上游服务器使用keepalive
- 2.5 AB压测
- 3、反向代理核心流程
- 3.1 UpStream工作流程
- 3.2 服务端和客户端的限制
- 3.3 重试机制
- 3.4 上游服务器健康检查
- 4、资源压缩
- 4.1 gzip动态压缩
- 4.2 gzip静态压缩
- 4.3 Brotli压缩
- 5、Nginx并发限制
- 5.1 **漏桶算法限制**
- 5.2 **令牌桶限制带宽**
- 5.3 **计数器算法限制并发数**
- 6、Nginx日志
- 6.1 ngx_http_empty_gif_module
- 6.2 ngx_http_log_module
- 6.3 Json日志格式举例
- 6.4 日志分隔
- 6、Concat请求合并与资源静态化
- 6.1 请求合并
- 6.2 资源静态化
- 6.3 Rsync静态文件同步方案
- 1. rsync介绍
- 2. rsync安装与启动(无权限认证)
- 3. 带权限认证的同步传输
- 4. 实时监控与推送
- 5. rsync配置文件详解
- 三、多级缓存
- 1、浏览器缓存
- 2、协商缓存
- 3、浏览器强制缓存
- 4、浏览器缓存原则
- 5、GEOip
- 6、正向代理
- 7、反向代理缓存
- 7.1 proxy缓存
- 7.2 缓存的清理
- 7.3 断点续传缓存 range
- 7.4 一些功能参数
- 8、其他
- 四、Nginx其他缓存
- 1、Nginx 文件元数据缓存
- 1.1 Strace内核执行过程追踪
- 1.2 open_file_cache配置优化
- 2、Nginx外置缓存
- 2.1 error_page错误码
- 2.2 匿名location
- 2.3 nginx + memcached
- 2.4 Nginx+Redis
- 3、Stream模块
- 3.1 Nginx配置Mysql负载均衡
一、Nginx扩容
1、前言
扩容包括单机垂直扩容和水平扩展
2、单机垂直扩容:硬件资源增加
- 云服务资源增加
- 整机:IBM、浪潮、DELL、HP等
- CPU/主板:更新到主流
- 网卡:10G/40G网卡
- 磁盘:SAS(SCSI) HDD(机械)、HHD(混合)、SATA SSD、PCI-e SSD、 MVMe SSD
- SSD
- 多副本机制
- 系统盘/热点数据/数据库存储
- HDD
- 冷数据存储
3、水平扩展:集群化
4、Nginx模块升级
# nginx下载地址
http://nginx.org/en/download.html
# 下载
wget http://nginx.org/download/nginx-1.23.0.tar.gz
# 解压
tar -zxvf nginx-1.23.0.tar.gz
# 进入目录进行解压,选择自己的模块就行
./configure --prefix=/usr/local/nginx/ --with-stream
# 编译
make
# 最后把编译好的目标文件替换即可,不要make install
# 查看编译的模块
nginx -V
二、Nginx高级配置介绍
1、会话管理与sticky模块
upstream httpds {# ip_hash# hash $cookie_jsessionid;# hash $request_uri;# 使用lua逻辑定向分发ip_hash;server 192.168.44.102 ;server 192.168.44.103 ;
}server {listen 80;server_name localhost;location / {proxy_pass http://httpds;# root html;}location ~*/(css|img|js) {root /usr/local/nginx/html;}
1.1 介绍
Sticky是nginx的一个模块,它是基于cookie的一种nginx的负载均衡解决方案,通过分发和识别cookie,来使同一个客户端的请求落在同一台服务器上,默认标识名为route
使用参考**:**http://nginx.org/en/docs/http/ngx_http_upstream_module.html#sticky
tengine中有session_sticky模块我们通过第三方的方式安装在开源版本中。sticky是第三方模块,需要重新编译Nginx,他可以对Nginx这种静态文件服务器使用基于cookie的负载均衡
1.2 下载与安装
项目官网:https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/src/master/
下载:https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/1.2.6.zip
上传解压到服务器,然后重新编译Nginx,依赖openssl-devel,进到源码目录重新编译
#重新编译
./configure --prefix=/usr/local/nginx --add-module=/root/nginx-goodies-nginx-sticky-module-ng-c78b7dd79d0d
# 此时不要执行 make install,要不然就会覆盖原来的版本产生诸多问题。
make
配置方法
upstream httpget {
# 直接这样也行
# sticky;
sticky name=route expires=6h;server 192.168.44.102;
server 192.168.44.103;
}
1.3 错误处理
如果遇到以下错误,可能是版本问题
打开 ngx_http_sticky_misc.c文件,在12行添加
#include <openssl/sha.h>
#include <openssl/md5.h>
备份之前的程序mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old
把编译好的Nginx程序替换到原来的目录里(平滑升级也是如此)cp objs/nginx /usr/local/nginx/sbin/
升级检测make upgrade
检查程序中是否包含新模块nginx -V
2、KeepAlive
2.1 介绍
官网:https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive
在http协议header中可以看到当前连接状态,使用KeepAlive可以在有效期内复用Tcp连接。举个例子,当进行TCP连接后,如果在 65s 内没有活动,则关闭长连接,即在点击一个链接后,在65s内没有点击另一个链接,则会关闭当前TCP连接,如果在65s内点击了其它链接,则会复用当前的TCP连接,不用进行三次握手。
什么时候使用
- 明显的预知用户会在当前连接上有下一步操作
- 复用连接,有效减少握手次数,尤其是https建立一次连接开销会更大
什么时候不用
- 访问内联资源一般用缓存,不需要keepalive
- 长时间的tcp连接容易导致系统资源无效占用
2.2 测试工具charles
抓包工具,可以查看传输次数,模拟重放等
下载地址:https://www.charlesproxy.com/assets/release/4.6.2/charles-proxy-4.6.2-win64.msi?k=fc1457e312
官网:https://www.charlesproxy.com
2.3 KeepAlive使用
http {include mime.types;default_type application/octet-stream;# 用于开启文件高效传输模式sendfile on;# 下面是默认值# 限制keepalive保持连接的最大时间# 超过这个时间 没有活动,会让keepalive失效# 两个65 在浏览器显示两条,为了兼容http1.0keepalive_timeout 65 65; # 用于设置Nginx服务器与客户端保持连接的超时时间keepalive_time 1h; # 一个tcp连接总时长,超过之后 强制失效# 默认60s 此处有坑!! 系统中 若有耗时操作,超过 send_timeout 强制断开连接。 # 注意:准备过程中,不是传输过程send_timeout 60;#一个tcp复用中 可以并发接收的请求个数keepalive_requests 1000;
2.4 对上游服务器使用keepalive
首先需要配置使用http1.1协议。以便建立更高效的传输,默认使用http1.0,在http1.0中需要配置header才可以。在Upstream中所配置的上游服务器(即Tomcat)默认都是用短连接,即每次请求都会在完成之后断开,因此需要请求复用
upstream tomcat-web {# 连接保留时间keepalive_timeout 1000;# 向上游服务器的保留连接数keepalive 100;# 一个tcp复用中 可以并发接收的请求个数keepalive_requests 100;server tomcat01:8080 weight=100 max_fails=2 fail_timeout=15;server tomcat02:8080 weight=100 max_fails=2 fail_timeout=15;
}
server {listen 80;server_name localhost;location / {# root /usr/share/nginx/html;proxy_http_version 1.1;#配置http版本号#默认使用http1.0协议,需要在request中增加”Connection: keep-alive“ header才能够支持,而#HTTP1.1默认支持。proxy_set_header Connection "";proxy_pass http://tomcat-web;root html;index index.html index.htm;# proxy_set_header host $host;}error_page 500 502 503 504 /50x.html;location = /50x.html {root /usr/share/nginx/html;}
}
2.5 AB压测
ab 是 ApacheBench 命令的缩写。会创建多个并发线程访问,模拟多个访问者同时对某一 URL 地址进行访问。它的测试目标是基于 URL 的,因此,它既可以用来测试 apache 的负载压力,也可以测 试nginx、lighthttp、tomcat、IIS 等其它 Web 服务器的压力
# linux安装
apt-get install apache2-utils
# Centos安装
yum install httpd-tools
# 常用的测试
ab -n 100 -c 10 http://sewise.21321.com/redistest/RedisSaveToMysqlJson
参数说明:
- -n 即requests,用于指定压力测试总共的执行次数
- -c 即concurrency,用于指定的并发数
- -t 即timelimit,等待响应的最大时间(单位:秒)
- -b 即windowsize,TCP发送/接收的缓冲大小(单位:字节)
- -p 即postfile,发送POST请求时需要上传的文件,此外还必须设置-T参数
- -u 即putfile,发送PUT请求时需要上传的文件,此外还必须设置-T参数
- -T 即content-type,用于设置Content-Type请求头信息,例如:application/x-www-form-urlencoded,默认值为text/plain
- -v 即verbosity,指定打印帮助信息的冗余级别
- -w 以HTML表格形式打印结果
- -i 使用HEAD请求代替GET请求
- -x 插入字符串作为table标签的属性
- -y 插入字符串作为tr标签的属性
- -z 插入字符串作为td标签的属性
- -C 添加cookie信息,例如:“Apache=1234”(可以重复该参数选项以添加多个)
- -H 添加任意的请求头,例如:“Accept-Encoding: gzip”,请求头将会添加在现有的多个请求头之后(可以重复该参数选项以添加多个)
- -A 添加一个基本的网络认证信息,用户名和密码之间用英文冒号隔开
- -P 添加一个基本的代理认证信息,用户名和密码之间用英文冒号隔开
- -X 指定使用的和端口号,例如:“126.10.10.3:88”
- -V 打印版本号并退出
- -k 使用HTTP的KeepAlive特性
- -d 不显示百分比
- -S 不显示预估和警告信息
- -g 输出结果信息到gnuplot格式的文件中
- -e 输出结果信息到CSV格式的文件中
- -r 指定接收到错误信息时不退出程序
- -h 显示用法信息,其实就是ab -help
3、反向代理核心流程
参考:https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html
3.1 UpStream工作流程
proxy_pass 向上游服务器请求数据共有6个阶段
- 初始化
- 与上游服务器建立连接
- 向上游服务器发送请求
- 处理响应头
- 处理响应体
- 结束
3.2 服务端和客户端的限制
针对上游服务端的限制,可以在http/server/location配置,一般在location里进行配置
# 设置header
proxy_set_header
# 设置用户真是ip
proxy_set_header X-Forwarded-For $remote_addr;# 与上游服务器连接超时时间、快速失败
proxy_connect_timeout
# 定义nginx向后端服务发送请求的间隔时间(不是耗时)。默认60秒,超过这个时间会关闭连接
proxy_send_timeout 60;
# 后端服务给nginx响应的时间,规定时间内后端服务没有给nginx响应,连接会被关闭,
# nginx返回504 Gateway Time-out。默认60秒
proxy_read_timeout 60;# 设置客户端或代理服务器连接上两次连续的读取或写入操作之间的超时(timeout)。
# 如果在此时间内没有数据传输,则连接将关闭
proxy_timeout# 缓冲区,针对上游服务器返回的数据
#缓冲解决的是客户端与上游服务器的网络传输差距# 是否完全读到请求体之后再向上游服务器发送请求,默认开启
proxy_requset_buffering on;
# 是否缓冲上游服务器数据
proxy_buffering on;
# header缓冲区大小
proxy_buffer_size 64k;
# 缓冲区大小 32个 64k大小内存缓冲块
proxy_buffers 32 128k;
proxy_busy_buffers_size 8k;
# proxy_pass读到向磁盘写入的最大值
proxy_max_temp_file_size 1024m;# 当启用从代理服务器到临时文件的响应的缓冲时,一次限制写入临时文件的数据的大小。
# 默认情况下,大小由proxy_buffer_size和proxy_buffers指令设置的两个缓冲区限制。
# 临时文件的最大大小由proxy_max_temp_file_size指令设置
proxy_temp_file_write_size 8k;# 临时文件最大值
proxy_max_temp_file_size 1024m;# 临时缓冲存放位置,1 2指的是层级
proxy_temp_path
proxy_temp_path /spool/nginx/proxy_temp 1 2;# 当后端服务器返回指定的错误时,将请求传递到其他服务器,5xx不会进行重试
# 其默认值是proxy_next_upstream error timeout
proxy_next_upstream
针对客户端的限制,可以在http/server/location中进行配置,可以针对不同请求分别进行配置
# 对客户端请求中的body缓冲区大小。默认32位8k 64位16k
# 如果请求体大于配置,则写入临时文件
client_body_buffer_size# 设置读取客户端请求体的缓冲区大小。 如果请求体大于缓冲区,则将整个请求体或仅将其部分写入临时文件
# 32位8K,64位平台16K。
# 如果一个请求行或者一个请求头字段不能放入这个缓冲区,那么就会使用large_client_header_buffers
client_header_buffer_size# 默认8k
large_client_header_buffers# 默认1m,如果一个请求的大小超过配置的值,会返回413 (request Entity Too Large)错误给客户端
# size设置为0将禁用对客户端请求正文大小的检查。
client_max_body_size 1000M;# 指定客户端与服务端建立连接后发送 request body 的超时时间
# 如果客户端在指定时间内没有发送任何内容,Nginx 返回 HTTP 408(Request Timed Out)
client_body_timeout# 客户端向服务端发送一个完整的 request header 的超时时间
# 如果客户端在指定时间内没有发送一个完整的 request header,Nginx 返回 HTTP 408(Request Timed Out)
client_header_timeout# 在磁盘上客户端的body临时缓冲区位置
client_body_temp_path path [level1 [level2 [level3]]]# 把body写入磁盘文件,请求结束也不会删除,线上不要用
client_body_in_file_only on;# 尽量缓冲body的时候在内存中使用连续单一缓冲区,在二次开发时使用`$request_body`读取数据时性能会有所提高
client_body_in_single_buffer
3.3 重试机制
参考文档:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream
upstream tomcat-web {keepalive_timeout 1000;keepalive 100;keepalive_requests 100;# 这是单台上游服务器的限制,下面是整个上游服务器# max_fails表示最大失败次数,0为标记一直可用,不检查健康状态# fail_timeout表示失败时间,当fail_timeout时间内失败了max_fails次,标记服务不可用,fail_timeout时间后会再次激活次服务server tomcat01:8080 weight=100 max_fails=2 fail_timeout=15;server tomcat02:8080 weight=100 max_fails=2 fail_timeout=15;
}server {listen 80;server_name localhost;location / {# 这是与上游服务器的重试proxy_next_upstream error timeout;# 重试最大超时时间# proxy_next_upstream_timeout时间内允许proxy_next_upstream_tries次重试proxy_next_upstream_timeout 5s;# 重试次数,包括第一次proxy_next_upstream_tries 3;proxy_pass http://tomcat-web;}
}
3.4 上游服务器健康检查
tengine版:https://github.com/yaoweibin/nginx_upstream_check_module
nginx商业版:http://nginx.org/en/docs/http/ngx_http_upstream_hc_module.html
tengine需要版本匹配,具体可以上网找,在nginx目录patch -p1 < /home/nginx_upstream_check_module-master/check_1.20.1+.patch
upstream backend {# server 192.168.44.102 weight=8 down;server 192.168.44.104:8080;server 192.168.44.105:8080;# 3s检查一次,rise请求几次表示正常,fall表示几次表示失败check interval=3000 rise=2 fall=5 timeout=1000 type=http;check_http_send "HEAD / HTTP/1.0\r\n\r\n";check_http_expect_alive http_2xx http_3xx;
}
location /status {check_status;access_log off;
}location / {proxy_pass http://backend;root html;
}
4、资源压缩
4.1 gzip动态压缩
参考:https://nginx.org/en/docs/http/ngx_http_gzip_module.html
# 开关,默认关闭
gzip on;
# 缓冲区大小
gzip_buffers 32 4k|16 8k;
# 压缩等级 1-9,数字越大压缩比越高
gzip_comp_level 6;
# 使用gzip的最小版本
gzip_http_version 1.1;
# 设置将被gzip压缩的响应的最小长度。 长度仅由“Content-Length”响应报头字段确定
gzip_min_length 256;
# 可以多选
gzip_proxied any;
#off 为不做限制
#作为反向代理时,针对上游服务器返回的头信息进行压缩
#expired - 启用压缩,如果header头中包含 "Expires" 头信息
#no-cache - 启用压缩,如果header头中包含 "Cache-Control:no-cache" 头信息
#no-store - 启用压缩,如果header头中包含 "Cache-Control:no-store" 头信息
#private - 启用压缩,如果header头中包含 "Cache-Control:private" 头信息
#no_last_modified - 启用压缩,如果header头中不包含 "Last-Modified" 头信息
#no_etag - 启用压缩 ,如果header头中不包含 "ETag" 头信息
#auth - 启用压缩 , 如果header头中包含 "Authorization" 头信息
#any - 无条件启用压缩# 增加一个header,适配老的浏览器 `Vary: Accept-Encoding`
gzip_vary on;
# 哪些mime类型的文件进行压缩
gzip_types text/plain application/x-javascript text/css application/xml;
# 根据自己情况配置
gzip_typestext/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xmltext/javascript application/javascript application/x-javascripttext/x-json application/json application/x-web-app-manifest+jsontext/css text/plain text/x-componentfont/opentype application/x-font-ttf application/vnd.ms-fontobjectimage/x-icon;
# 禁止某些浏览器使用gzip,建议开启,正则消耗资源
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
4.2 gzip静态压缩
参考:https://nginx.org/en/docs/http/ngx_http_gunzip_module.html
https://nginx.org/en/docs/http/ngx_http_gunzip_module.html
ngx_http_gzip_static_module
模块允许发送带有“ .gz”文件扩展名的预压缩文件;ngx_http_gunzip_module
帮助不支持gzip的客户端解压本地文件(帮助节省磁盘空间),也可以直接传输事先在本地压缩好的文件,需要重新编译nginx
./configure --with-http_gzip_static_module \--with-http_gunzip_module
一般和gunzip配合使用,这样就不需要在客户端进行解压;
# 和下面always配合
gunzip on;
# 默认off,always是总是发送压缩包,on检查客户端是不是支持,不支持就不发送
gzip_static on | off | always;
4.3 Brotli压缩
Brotli 是 Google 开发的一种压缩格式,它通过内置分析大量网页得出的字典,实现了更高的压缩比率,同时几乎不影响压缩 / 解压速度。它可以和nginx本身的gzip共存
官网:https://github.com/google/ngx_brotli / https://github.com/google/brotli
# 下载两个项目,然后解压
# 模块化编译
./configure --with-compat --add-dynamic-module=/root/ngx_brotli-1.0.0rc --prefix=/usr/local/nginx/
# 或者
--add-dynamic-module=brotli目录make# 将ngx_http_brotli_filter_module.so ngx_http_brotli_static_module.so拷贝到/usr/local/nginx/modules/
# 复制nginx主程序
# 配置文件中添加
load_module "/usr/local/nginx/modules/ngx_http_brotli_filter_module.so";
load_module "/usr/local/nginx/modules/ngx_http_brotli_static_module.so";#nginx 配置文件
brotli on;
brotli_static on;
brotli_comp_level 6;
brotli_buffers 16 8k;
brotli_min_length 20;
brotli_types text/plain text/css text/javascript application/javascript text/xml application/xml application/xml+rss application/json image/jpeg image/gif image/png;# 测试,默认http协议是没有br的,https使用
# 要发送到服务端的自定义请求头 (H);仅显示响应文档头(I)
curl -H 'Accept-Encoding: gzip' -I http://localhost
5、Nginx并发限制
官方文档:http://nginx.org/en/docs/http/ngx_http_limit_req_module.html
测试工具:https://jmeter.apache.org/
5.1 漏桶算法限制
配置文件
# 漏桶算法
# 在http模块下,$binary_remote_add表示ip地址(原始数据,也可以直接remote_addr),test是名称,
# 10m为内存空间,rate表示速率,r是request(这个并不算真正的桶,超过限制会返回失败)
limit_req_zone $binary_remote_addr zone=test:10m rate=15r/s;
# burst表示桶大小,nodelay表示快速失败,超过桶大小请求会进入队列状态,nodelay超过桶范围直接报错
limit_req zone=req_zone_wl burst=20 nodelay;localtion /{limit_req zone=test;root html;
}
5.2 令牌桶限制带宽
localtion /{limit_req zone=test;# 限制带宽limit_rate 1k;# 下载多少之后开始限速limit_rate_after 1m;root html;
}
5.3 计数器算法限制并发数
# 计数器算法
limit_conn_zone $binary_remote_addr zone=test2:10m;localtion /{# 并发数限制,只有1,超过需要排队limit_conn test2 1;root html;
}
6、Nginx日志
6.1 ngx_http_empty_gif_module
参考文档:http://nginx.org/en/docs/http/ngx_http_empty_gif_module.html
该模块返回的是一个像素点的图片,一般嵌入到前端,用来收集用户操作信息等
location = /_.gif {empty_gif;
}
6.2 ngx_http_log_module
参考文档:http://nginx.org/en/docs/http/ngx_http_log_module.html
errorlog:http://nginx.org/en/docs/ngx_core_module.html#error_log
# 在http模块,默认开启
# 日志格式定义
log_format compression '$remote_addr - $remote_user [$time_local] ''"$request" $status $bytes_sent ''"$http_referer" "$http_user_agent" "$gzip_ratio"';
# 可以控制刷写时间等
# access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]]
# 加了buffer表示在这个存储内不会立刻写到文件,关机等操作也会刷写,加了flush就强制刷新
# gzip默认为1,内存直接追加到压缩包,9表示压缩比最高速度最慢
access_log /spool/logs/nginx-access.log compression buffer=32k flush=1m gzip=5;
# 文件打开缓存
open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
# /var/log/nginx/
# error_log也同理,也是默认开启
# error_log file [level];
error_log logs/error.log error;
6.3 Json日志格式举例
log_format ngxlog json '{"timestamp":"$time_iso8601",''"source":"$server_addr",''"hostname":"$hostname",''"remote_user":"$remote_user",''"ip":"$http_x_forwarded_for",''"client":"$remote_addr",''"request_method":"$request_method",''"scheme":"$scheme",''"domain":"$server_name",''"referer":"$http_referer",''"request":"$request_uri",''"requesturl":"$request",''"args":"$args",''"size":$body_bytes_sent,''"status": $status,''"responsetime":$request_time,''"upstreamtime":"$upstream_response_time",''"upstreamaddr":"$upstream_addr",''"http_user_agent":"$http_user_agent",''"http_cookie":"$http_cookie",''"https":"$https"''}';
6.4 日志分隔
- 脚本分隔
- **logrotate **
# 一般都会有安装,vim /etc/logrotate.d/nginx
/var/log/nginx/*.log {dailymissingokrotate 52compressdelaycompressnotifemptycreate 640 nginx admsharedscriptspostrotateif [ -f /var/run/nginx.pid ]; thenkill -USR1 `cat /var/run/nginx.pid`fiendscript
}
6、Concat请求合并与资源静态化
6.1 请求合并
Tengine是由淘宝网发起的Web服务器项目。ngx_http_concat模块就是其中之一,作用为在同一个请求里返回多个文件拼接,使用??表示,js/??a.js,b.js,c.js
Nginx官方介绍:https://www.nginx.com/resources/wiki/modules/concat/
git地址:https://github.com/alibaba/nginx-http-concat
下载源码解压缩编译安装,下面是配置
location /static/css/ {concat on;concat_max_files 20;#concat_types 参数很重要,因为默认对js的mime类型是application/x-javascript,导致无法返回jsconcat_types concat_types: text/css text/javascript application/javascript;
}
6.2 资源静态化
解决的方法
- 高并发系统资源静态化方案
- 一致性问题
- 合并文件输出
- 集群文件同步
SSI模块合并资源静态化
利用SSI就可以解决,在静态页面中嵌入个人信息的动态页,由于是服务器端的嵌入,所以用户浏览的时候都是一个嵌入后的页面
官方文档:http://nginx.org/en/docs/http/ngx_http_ssi_module.html
# 是否打开ssi,默认是关闭
ssi on | off;# 设置存储在磁盘上的响应部分的最小大小,和sendfile on 配合
ssi_min_file_chunk# 是否保留lastmodified,允许在SSI处理期间保留原始响应的Last-Modified报头字段,以方便响应缓存,默认关闭
ssi_last_modified# 不显示逻辑错误,自动屏蔽,默认关闭
ssi_silent_errors# 限制脚本参数最大长度
ssi_value_length# 默认text/html;如果需要其他mime类型 需要设置
ssi_types#=================SSI Commands================
# 静态文件直接引用
<!--# include file="footer.html" --># 可以指向location,而不一定是具体文件
include virtual# 阻塞请求
include wait# 在virtual基础上设置变量
include set# 设置临时变量
set# 可以声明一个ssi的命令块,里面可以包裹其他命令
block# 在模板中配置报错情况
config errmsg# 日期格式化
config timefmt# 直接输出变量
# - var变量名称
# - encoding 是否使用特殊编码格式
# - default 变量没有值的时候使用默认值
echo# 逻辑判断
if# 举例==============================
server{listen 80;server_name www.hello.com# 配置SSLssi on; # 开启SSI支持ssi_silent_errors on; # 默认为off,设置为on则在处理SSI文件出错时不输出错误信息ssi_types text/html; # 需要支持的shtml 默认是 text/htmllocation / {# 也可以写在这里root html;index index.html index.htm;}
}# 界面
<h1>我是html3</h1>
<# include file="html1.html">
<# include file="html2.html">
6.3 Rsync静态文件同步方案
1. rsync介绍
remote synchronize是一个远程数据同步工具,可通过 LAN/WAN 快速同步多台主机之间的文件。也可以使用 rsync 同步本地硬盘中的不同目录。rsync 是用于替代 rcp 的一个工具,rsync 使用所谓的 rsync算法 进行数据同步,这种算法只传送两个文件的不同部分,而不是每次都整份传送,因此速度相当快。rsync 基于inotify 开发
rsync官方文档:https://www.samba.org/ftp/rsync/rsync.html
Rsync有三种模式:
- 本地模式(类似于cp命令)
- 远程模式(类似于scp命令)
- 守护进程(socket进程:是rsync的重要功能)
| 选项 | 含义 |
| — | — |
| -a | 包含-rtplgoD |
| -r | 同步目录时要加上,类似cp时的-r选项 |
| -v | 同步时显示一些信息,让我们知道同步的过程 |
| -l | 保留软连接 |
| -L | 加上该选项后,同步软链接时会把源文件给同步 |
| -p | 保持文件的权限属性 |
| -o | 保持文件的属主 |
| -g | 保持文件的属组 |
| -D | 保持设备文件信息 |
| -t | 保持文件的时间属性 |
| –delete | 删除DEST中SRC没有的文件 |
| –exclude | 过滤指定文件,如–exclude “logs”会把文件名包含logs的文件或者目录过滤掉,不同步 |
| -P | 显示同步过程,比如速率,比-v更加详细 |
| -u | 加上该选项后,如果DEST中的文件比SRC新,则不同步 |
| -z | 传输时压缩 |
2. rsync安装与启动(无权限认证)
# 注意该软件传输的两台机器都需要安装
# ubuntu的安装,但是一般都自带了
sudo apt-get install rsync
# Centos安装
yum install -y rsync
配置文件可能不会生成,需要我们手动生成,sudo vim /etc/rsyncd.conf
添加配置文件,然后在需要同步的机器上启动(默认rsync是不启动的,同时关闭需要kill)
# /etc/rsyncd: configuration file for rsync daemon mode
# See rsyncd.conf man page for more options.
# configuration example:# 指定自己的组和用户,否则推会发生问题
# uid = nobody
# gid = nobody
# 推的时候用到
read only = no
# use chroot = yes
# max connections = 4
# pid file = /var/run/rsyncd.pid
# exclude = lost+found/
# transfer logging = yes
# timeout = 900
# ignore nonreadable = yes
# dont compress = *.gz *.tgz *.zip *.z*.Z *.rpm *.deb *.bz2[ftp]path = /home/shawn/test
运行命令,注意rsync服务器需要开启873端口
# 在需要同步的机器运行,可自定义端口
sudo rsync --daemon [--port=3189]# 在另一台机器运行==========# 查看这个模块下的查看远程目录
rsync --list-only 你的ip::ftp/
rsync -avz rsync://你的ip:873/ftp test
rsync -avz --delete 你的ip::ftp/ test
# 使用SSH方式,本机向同步机器发送
rsync -avzP hello.log shawn@你的ip:test
3. 带权限认证的同步传输
首先创建用户密码对,sudo echo "shawn:www" >> /etc/rsyncd.pwd
,同时设置权限为600,sudo chmod 600 /etc/rsyncd.pwd
,然后修改配置。修改完成后kill进程然后启动
secrets file = /etc/rsyncd.pwd
auth users = shawn[ftp]path = /home/shawn/test
在被同步的机器访问rsync --list-only shawn@xx::ftp
,加上用户名和密码即可。当时可以进行免密操作
# 存入密码
ehco "shawn" >> /etc/rsyncd.pwd.client
# 设置权限
chmod 600 /etc/rsync.pwd.client
# 访问
rsync --list-only --password-file=/etc/rsync.pwd.client shawn@ip::ftp
4. 实时监控与推送
推送端安装inotify
# 编码编译安装,需要gcc,make相关依赖# 下载源码包
wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
# 解压到指定目录
tar zxvf /inotify-tools-3.14.tar.gz -C /usr/local/inotify
# 到指定目录
cd /usr/local/inotify
# 编译
./configure --prefix=/usr/local/inotify
make && make install# 运行,当监控的目录发送改变时,会发生变化
/usr/local/inotify/bin/inotifywait -mrq --timefmt '%Y-%m-%d %H:%M:%S' --format '%T %w%f %e' -e close_write,modify,delete,create,attrib,move /home/shawn/test
这里可以写个自动化脚本,一个目录一旦发送变化,就进行同步推送
#!/bin/bash
/usr/local/inotify/bin/inotifywait -mrq --timefmt '%Y-%m-%d %H:%M:%S' --format '%T %w%f %e' -e close_write,modify,delete,create,attrib,move /home/shawn/test| while read file
dorsync -az --delete --password-file=/etc/rsync.pwd.client test shawn@ip::test
done
inotify常用参数
参数 | 说明 | 含义 |
---|---|---|
-r | –recursive | 递归查询目录 |
-q | –quiet | 打印很少的信息,仅仅打印监控事件信息 |
-m | –monitor | 始终保持事件监听状态 |
–excludei | 排除文件或目录时,不区分大小写 | |
–timefmt | 指定事件输出格式 | |
–format | #打印使用指定的输出类似格式字符串 | |
-e | –event[ -e|–event … ]accessmodifyattribcloseopenmove_tomove createdeleteumount | #通过此参数可以指定要监控的事件 #文件或目录被读取#文件或目录的内容被修改#文件或目录属性被改变#文件或目录封闭,无论读/写模式#文件或目录被打开#文件或目录被移动至另外一个目录#文件或目录被移动另一个目录或从另一个目录移动至当前目录#文件或目录被创建在当前目录#文件或目录被删除#文件系统被卸载 |
5. rsync配置文件详解
# sample rsyncd.conf configuration file# GLOBAL OPTIONS#motd file=/etc/motd #登录欢迎信息
#log file=/var/log/rsyncd #日志文件
# for pid file, do not use /var/run/rsync.pid if
# you are going to run rsync out of the init.d script.
pid file=/var/run/rsyncd.pid#指定rsync发送日志消息给syslog时的消息级别,常见的消息级别是:uth, authpriv, cron, daemon, ftp, kern, lpr, mail, news, security, sys-log, user, uucp, local0, local1, local2, local3,local4, local5, local6和local7。默认值是daemon。
#syslog facility=daemon#自定义tcp选项,默认是关闭的
#socket options=#以下是模块信息,我们可以创建多个模块
# MODULE OPTIONS[ftp]comment = public archive #模块描述path = /var/www/pub #需要同步的路径use chroot = yes #默认是yes|true,如果为true,那么在rsync在传输文件以前首先chroot到path参数指定的目录下。这样做的原因是实现额外的安全防护,但是缺点是需要root权限,并且不能备份指向外部的符号连接指向的目录文件。
# max connections=10 #最大连接数lock file = /var/lock/rsyncd #指定支持max connections参数的锁文件。
# the default for read only is yes...read only = yes #只读选项list = yes #客户请求时可用模块时是否列出该模块uid = nobody #设定该模块传输文件时守护进程应该具有的uidgid = nogroup #设定该模块传输文件时守护进程应具有的gid,此项与uid配合可以确定文件的访问权限
# exclude = #用来指定多个由空格隔开的多个模式列表,并将其添加到exclude列表中。这等同于在客户端命令中使用--exclude来指定模式,不过配置文件中指定的exlude模式不会传递给客户端,而仅仅应用于服务器。一个模块只能指定一个exlude选项,但是可以在模式前面使用"-"和"+"来指定是exclude还是include #这个我的理解是排除目录中不需同步的文件
# exclude from = #可以指定一个包含exclude模式定义的文件名
# include = #与exclude相似
# include from = #可以指定一个包含include模式定义的文件名
# auth users = #该选项指定由空格或逗号分隔的用户名列表,只有这些用户才允许连接该模块。这里的用户和系统用户没有任何关系。如果"auth users"被设置,那么客户端发出对该模块的连接请求以后会被rsync请求challenged进行验证身份这里使用的 challenge/response认证协议。用户的名和密码以明文方式存放在"secrets file"选项指定的文件中。默认情况下无需密码就可以连接模块(也就是匿名方式)
# secrets file = /etc/rsyncd.secrets #该文件每行包含一个username:password对,以明文方式存储,只有在auth users被定义时,此选项才生效。同时我们需要将此文件权限设置为0600strict modes = yes #该选项指定是否监测密码文件的权限,如果该选项值为true那么密码文件只能被rsync服务器运行身份的用户访问,其他任何用户不可以访问该文件。默认值为true
# hosts allow = #允许的主机
# hosts deny = #拒绝访问的主机ignore errors = no #设定rsync服务器在运行delete操作时是否忽略I/O错误ignore nonreadable = yes #设定rysnc服务器忽略那些没有访问文件权限的用户transfer logging = no #使rsync服务器使用ftp格式的文件来记录下载和上载操作在自己单独的日志中
# log format = %t: host %h (%a) %o %f (%l bytes). Total %b bytes. #设定日志格式timeout = 600 #超时设置(秒)refuse options = checksum dry-run #定义一些不允许客户对该模块使用的命令选项列表dont compress = *.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz #告诉rysnc那些文件在传输前不用压缩,默认已设定压缩包不再进行压缩
三、多级缓存
1、浏览器缓存
进入开发者模式,刷新即可看见,点击disable_cache即可不使用本地缓存
- memorycache
字面理解是从内存中,其实也是字面的含义,这个资源是直接从内存中拿到的,不会请求服务器一般已经加载过该资源且缓存在了内存当中,当关闭该页面时,此资源就被内存释放掉了,再次重新打开相同页面时不会出现from memory cache的情况
- diskcache
是从磁盘当中取出的,也是在已经在之前的某个时间加载过该资源,不会请求服务器但是此资源不会随着该页面的关闭而释放掉,因为是存在硬盘当中的,下次打开仍会from disk cache
- Age
是CDN添加的属性表示在CDN中缓存了多少秒
- via
用来标识CDN缓存经历了哪些服务器,缓存是否命中,使用的协议
2、协商缓存
发送请求header中携带Last-Modified,服务器可能会返回304 Not Modified
Nginx配置对应Last-Modified和ETag。http1.1支持,在HTTP协议中If-Modified-Since和If-None-Match分别对应Last-Modified和ETag(last-modified 与ssi会发生冲突)
Entity Tag 的缩写,中文译过来就是实体标签的意思。HTTP中并没有指定如何生成ETag,哈希是比较理想的选择。在计算Etag的时候,会产生CPU的耗费,所以也可以用时间戳,但这样直接使用Last-Modified即可。ETag 用来校验用户请求的资源是否有变化,作用和lastmodified很像,区别是lastmodified精确到秒,ETag可以用hash算法来生成更精确的比对内容。当用户首次请求资源的时候返回给用户数据和200状态码并生成ETag,再次请求的时候服务器比对ETag,没有发生变化的话返回304
3、浏览器强制缓存
直接从本机读取,不请求服务器,http1.1的规范,使用max-age表示文件可以在浏览器中缓存的时间以秒为单位,在浏览器和服务器端验证文件是否过期的时候,浏览器在二次请求的时候会携带IF-Modified-Since属性
Cache-Control直接是通过不请求来实现,而ETag是会发请求的,只不过服务器根据请求的东西的内容有无变化来判断是否返回请求的资源
标记 | 类型 | 功能 |
---|---|---|
public | 响应头 | 响应的数据可以被缓存,客户端和代理层都可以缓存 |
private | 响应头 | 可私有缓存,客户端可以缓存,代理层不能缓存(CDN,proxy_pass) |
no-cache | 请求头 | 可以使用本地缓存,但是必须发送请求到服务器回源验证 |
no-store | 请求和响应 | 应禁用缓存 |
max-age | 请求和响应 | 文件可以在浏览器中缓存的时间以秒为单位 |
s-maxage | 请求和响应 | 用户代理层缓存,CDN下发,当客户端数据过期时会重新校验 |
max-stale | 请求和响应 | 缓存最大使用时间,如果缓存过期,但还在这个时间范围内则可以使用缓存数据 |
min-fresh | 请求和响应 | 缓存最小使用时间, |
must-revalidate | 请求和响应 | 当缓存过期后,必须回源重新请求资源。比no-cache更严格。因为HTTP 规范是允许客户端在某些特殊情况下直接使用过期缓存的,比如校验请求发送失败的时候。那么带有must-revalidate的缓存必须校验,其他条件全部失效。 |
proxy-revalidate | 请求和响应 | 和must-revalidate类似,只对CDN这种代理服务器有效,客户端遇到此头,需要回源验证 |
stale-while-revalidate | 响应 | 表示在指定时间内可以先使用本地缓存,后台进行异步校验 |
stale-if-error | 响应 | 在指定时间内,重新验证时返回状态码为5XX的时候,可以用本地缓存 |
only-if-cached | 响应 | 那么只使用缓存内容,如果没有缓存 则504 getway timeout |
Expires过期时间,现在一般用Cache-Control
expires 30s; #缓存30秒
expires 30m; #缓存30分钟
expires 2h; #缓存2小时
expires 30d; #缓存30天
强制缓存与协商缓存总结
- cache-control expires 强制缓存
页面首次打开,直接读取缓存数据,刷新,会向服务器发起请求
- etag lastmodify 协商缓存
没发生变化 返回304 不发送数据
![](https://img-blog.csdnimg.cn/img_convert/6dd67074c2f952344611a882fc53fa86.jpeg#clientId=ubd9e63cc-9837-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=uf9446d2a&margin=[object Object]&originHeight=476&originWidth=500&originalType=url&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=u736da398-3ade-49b1-a9a4-c2c97ac46d2&title=)
location / {# 协商缓存# 关掉etag校验# etag off;# 设置下面的每次就会刷新# if_modified_since off;# add_header Last-Modified "";# 强制缓存# expires 30s;# add_header cache-control "max-age:300";
}
4、浏览器缓存原则
- 多级集群负载时last-modified必须保持一致
- 还有一些场景下我们希望禁用浏览器缓存。比如轮训api上报数据数据
- 浏览器缓存很难彻底禁用,大家的做法是加版本号,随机数等方法。
- 只缓存200响应头的数据,像3XX这类跳转的页面不需要缓存。
- 对于js,css这类可以缓存很久的数据,可以通过加版本号的方式更新内容
- 不需要强一致性的数据,可以缓存几秒
- 异步加载的接口数据,可以使用ETag来校验。
- 在服务器添加Server头,有利于排查错误
- 分为手机APP和Client以及是否遵循http协议
- 在没有联网的状态下可以展示数据
- 流量消耗过多
- 提前下发 避免秒杀时同时下发数据造成流量短时间暴增
- 兜底数据 在服务器崩溃和网络不可用的时候展示
- 临时缓存 退出即清理
- 固定缓存 展示框架这种,可能很长时间不会更新,可用随客户端下发
- 首页有的时候可以看做是框架 应该禁用缓存,以保证加载的资源都是最新的
- 父子连接 页面跳转时有一部分内容不需要重新加载,可用从父菜单带过来
- 预加载 某些逻辑可用判定用户接下来的操作,那么可用异步加载那些资源
- 漂亮的加载过程 异步加载 先展示框架,然后异步加载内容,避免主线程阻塞
5、GEOip
Geo是geographic的缩写,意思是地理的,GeoIP即为IP地理位置数据库,可以根据IP获得地理位置信息,这样就可以进一步加快用户的访问速度。(现在不怎么使用,现在可以使用DNS配置)
# 官网需注册登录
# 下载数据库
maxmind.com# 安装依赖
https://github.com/maxmind/libmaxminddb
# 下载后执行编译安装之后
echo /usr/local/lib >> /etc/ld.so.conf.d/local.conf
ldconfig# Nginx模块
https://github.com/leev/ngx_http_geoip2_module
# 更完整的配置可参考官方文档
http://nginx.org/en/docs/http/ngx_http_geoip_module.html#geoip_proxy# Nginx配置
geoip2 /root/GeoLite2-ASN_20220524/GeoLite2-ASN.mmdb {$geoip2_country_code country iso_code;
}
add_header country $geoip2_country_code;
6、正向代理
基于nginx的正向代理,在服务器A搭建一个代理服务器,使得BC可以通过服务器A的nginx 代理进行访问外网
代理https请求需要第三方模块:https://github.com/chobits/ngx_http_proxy_connect_module
http正向代理配置
proxy_pass $scheme://$host$request_uri;
resolver 8.8.8.8;
https正向代理配置
server {listen 3128;# dns resolver used by forward proxyingresolver 8.8.8.8;# forward proxy for CONNECT requestproxy_connect;proxy_connect_allow 443 563;proxy_connect_connect_timeout 10s;proxy_connect_read_timeout 10s;proxy_connect_send_timeout 10s;# forward proxy for non-CONNECT requestlocation / {proxy_pass http://$host;proxy_set_header Host $host;}}
7、反向代理缓存
7.1 proxy缓存
官方文档:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache
反向代理和正向代理都可以使用缓存,但是使用这个缓存后就不会在去访问上游服务器,因此要考虑好缓存与更新的问题
#http模块
# /ngx_tmp表示目录,levels代表层级,keys_zone表示缓存名称(100m表示在内存中的哈希索引,加速访问)
# inactive表示存储时间,max_size表示存储大小
proxy_cache_path /ngx_tmp levels=1:2 keys_zone=test_cache:100m inactive=1d max_size=10g ;
#location模块:
# 表示缓存有没有命中
add_header Nginx-Cache "$upstream_cache_status";
proxy_cache test_cache;
# 请求过期时间,没有这个每次都会请求
proxy_cache_valid 1h;
7.2 缓存的清理
purger需要第三方模块支持:https://github.com/FRiCKLE/ngx_cache_purge
location ~ /purge(/.*) {# 这是之前的cache $1是uriproxy_cache_purge test_cache $1;
}
# 自定义cachekey
proxy_cache_key $uri;
- proxy_cache_key
默认$scheme$proxy_host$request_uri
;缓存的key
- proxy_cache_revalidate
如果缓存过期了,向上游服务器发送“If-Modified-Since” and “If-None-Match来验证是否改变,如果没有就不需要重新下载资源了
- proxy_cache_valid
可以针对不容http状态码设置缓存过期时间;不设置状态码会默认200, 301, 302
proxy_cache_valid 200 302 10m;
proxy_cache_valid 301 1h;
# any指其他任意状态码
proxy_cache_valid any 1m;
7.3 断点续传缓存 range
在Headers里添加Range bytes=0-10
可以截取部分数据,返回206。当有完整的content-length之后即可断点续传,在反向代理服务器中需向后传递header
# proxy_cache_key中增加range
proxy_set_header Range $http_range;# range最大值,超过之后不做缓存,默认情况下 不需要对单文件较大的资源做缓存
proxy_cache_max_range_offset
7.4 一些功能参数
# 默认 head get
proxy_cache_methods
# 默认1,被请求多少次之后才做缓存
proxy_cache_min_uses
# path 指定存储目录,以cache_key取md5值
proxy_cache_path
# 目录层级数及目录名称位数,取mdb5后几位
levels=1:2
#默认创建缓存文件时,先向缓冲区创建临时文件,再移动到缓存目录,是否使用缓冲区
use_temp_path
# 指定时间内未被访问过的缓存将被删除
inactive
- proxy_cache_use_stale
默认off,在什么时候可以使用过期缓存
可选error
| timeout
| invalid_header
| updating
| http_500
| http_502
| http_503
| http_504
| http_403
| http_404
| http_429
| off
- proxy_cache_background_update
默认off,运行开启子请求更新过期的内容。同时会把过期的内容返回给客户端
- proxy_no_cache proxy_cache_bypass
指定什么时候不使用缓存而直接请求上游服务器
proxy_no_cache $cookie_nocache $arg_nocache$arg_comment;
proxy_no_cache $http_pragma $http_authorization;
如果这些变量如果存在的话不为空或者不等于0,则不使用缓存
- proxy_cache_convert_head
默认 on,是否把head请求转换成get请求后再发送给上游服务器 以便缓存body里的内容。如果关闭 需要在 cache key 中添加 $request_method 以便区分缓存内容
- proxy_cache_lock
默认off,缓存更新锁
- proxy_cache_lock_age
默认5s,缓存锁超时时间
8、其他
- Nginx内存缓存
- 外置内存缓存
- 上游服务器应用缓存
四、Nginx其他缓存
1、Nginx 文件元数据缓存
1.1 Strace内核执行过程追踪
strace一般应用为静态文件元数据信息缓存
#查找nginx进程
ps -ef | grep nginx
# 找到work进程进行监听
strace -p [worker进程号]
sendfile执行过程结果
[{EPOLLIN, {u32=2648526864, u64=139941272965136}}], 512, -1) = 1
accept4(7, {sa_family=AF_INET, sin_port=htons(8163), sin_addr=inet_addr("221.12.170.99")}, [112->16], SOCK_NONBLOCK) = 9
epoll_ctl(11, EPOLL_CTL_ADD, 9, {EPOLLIN|EPOLLRDHUP|EPOLLET, {u32=2648527345, u64=139941272965617}}) = 0
epoll_wait(11, [{EPOLLIN, {u32=2648527345, u64=139941272965617}}], 512, 60000) = 1
recvfrom(9, "GET / HTTP/1.1\r\nHost: 121.199.16"..., 1024, 0, NULL, NULL) = 542
stat("/etc/nginx/html/index.html", {st_mode=S_IFREG|0644, st_size=292, ...}) = 0
openat(AT_FDCWD, "/etc/nginx/html/index.html", O_RDONLY|O_NONBLOCK) = 14
fstat(14, {st_mode=S_IFREG|0644, st_size=292, ...}) = 0
writev(9, [{iov_base="HTTP/1.1 200 OK\r\nServer: nginx/1"..., iov_len=233}], 1) = 233
sendfile(9, 14, [0] => [292], 292) = 292
write(6, "221.12.170.99 - - [08/Jul/2022:0"..., 194) = 194
close(14) = 0
close(9) = 0
epoll_wait(11,
1.2 open_file_cache配置优化
sendfile = off 时,应用程序读取磁盘中的文件以字节流的形式从磁盘中加载文件,然后再将文件以字节流的形式复制到内核中。内核在把文件推送到NC;
sendfile = on 时,应用程序直接向内核发送指令,让内核去读文件。读完文件内核直接推送给NC。只有一次复制操作,实现异步网络IO形式。因此,性能会有很大的提升。具体还要根据实际使用情况来配置sendfile。当读取服务不能解析大量的文件时。还是建议将sendfile配置为off。open_file_cache需要和sendfile配合使用,他会告诉 Nginx 去缓存打开的文件
http {# 打开零拷贝,位置可以在http/server/locationsendfile on;#tcp_nopush on;server {listen 80;location / {# max缓存最大数量,超过数量后会使用LRU淘汰;inactive指定时间内未被访问过的缓存将被删除open_file_cache max=500 inactive=60s# 被访问到多少次后会开始缓存open_file_cache_min_uses 1; # 间隔多长时间去检查文件是否有变化open_file_cache_valid 60s; # 对错误信息是否缓存open_file_cache_errors on}}}
2、Nginx外置缓存
2.1 error_page错误码
nginx的error_page的作用是当发生错误的时候能够显示一个预定义的uri
# 放在server里
# 指定状态码,注意空格
error_page 404 =302 http://www.shawn22.xyz;
# 默认指向location
error_page 500 502 503 504 /50x.html;
location = /50x.html {root /usr/share/nginx/html;
}
2.2 匿名location
error_page 404 = @anonymous;location @anonymous{# 告诉浏览器是文本,显示出来,不加就变成文件了add_header content-type "text/html";# 返回200,返回文本return 200 "hello world";
}
2.3 nginx + memcached
参考文档:http://nginx.org/en/docs/http/ngx_http_memcached_module.html
nginx的memcached_module模块可以直接从memcached服务器中读取内容后输出,后续的请求不再经过应用程序处理,如php-fpm、django,大大的提升动态页面的速度。nginx只负责从memcached服务器中读取数据,要往memcached写入数据丕得需要后台的应用程序来完成,主动的将要缓存的页面缓存到memcached中,可以通过404重定向到后端去处理的。
# ubuntu安装
sudo apt update
sudo apt install memcached libmemcached-toolssudo systemctl status memcached
sudo nano /etc/memcached.conf
sudo systemctl restart memcached# centos安装
yum -y install memcached
# 默认配置文件在/etc/sysconfig/memcached
# 查看状态
memcached-tool 127.0.0.1:11211 stats# 访问
telnet 127.0.0.1 11211
# 查看状态
stats
# key 元数据 过期时间 字节数
set name 0 0 3
get name
nginx配置文件
upstream tomcat-web {keepalive_timeout 1000;keepalive 100;keepalive_requests 100;server tomcat01:8080 weight=100 max_fails=2 fail_timeout=15;server tomcat02:8080 weight=100 max_fails=2 fail_timeout=15;
}server {listen 80;server_name localhost;location / {set $memcached_key $uri;memcached_pass 127.0.0.1:11211;add_header X-Cache-Satus HIT;add_header Content-Type 'text/html; charset=utf-8';}error_page 404 = @fallback;location @fallback{proxy_set_header content-type "text/html";proxy_pass http://tomcat-web;
# return 200 "hello world";}
}
2.4 Nginx+Redis
参考文档(很详细):https://www.nginx.com/resources/wiki/modules/redis2/
redis2-nginx-module是一个支持 Redis 2.0 协议的 Nginx upstream 模块,它可以让 Nginx 以非阻塞方式直接防问远方的 Redis 服务,同时支持 TCP 协议和 Unix Domain Socket 模式,并且可以启用强大的 Redis 连接池功能,需要添加编译
https://github.com/openresty/redis2-nginx-module
# 具体的可以看文档,很详细
# test
location = /foo {
default_type text/html;redis2_query auth 123123;set $value 'first';redis2_query set one $value;redis2_pass 192.168.199.161:6379;}# get
location = /get {
default_type text/html;redis2_pass 192.168.199.161:6379;redis2_query auth 123123;set_unescape_uri $key $arg_key; # this requires ngx_set_miscredis2_query get $key;
}# GET /set?key=one&val=first%20value
location = /set {default_type text/html;redis2_pass 192.168.199.161:6379;redis2_query auth 123123;set_unescape_uri $key $arg_key; # this requires ngx_set_miscset_unescape_uri $val $arg_val; # this requires ngx_set_miscredis2_query set $key $val;}# pipeline
location = /set {set $value 'first';redis2_query set one $value;redis2_query get one;redis2_query set one two;redis2_query get one;redis2_query del key1;
}# 集群
upstream redis_cluster {server 192.168.199.161:6379;server 192.168.199.161:6379;}
location = /redis {default_type text/html;redis2_next_upstream error timeout invalid_response;redis2_query get foo;redis2_pass redis_cluster;
}
3、Stream模块
参考文档:http://nginx.org/en/docs/stream/ngx_stream_core_module.html
nginx支持了四层代理,即传输层,就是我们常说的TCP/UDP层,没有协议解析,就是简单的TCP/UDP转发,该功能依赖于ngx_http_upstream_module
和ngx_stream_upstream_module
,互联网公司将其作为入口代理来工作
3.1 Nginx配置Mysql负载均衡
Mysql集群跨域通过Mycat代理,也可以通过Nginx代理 ,Mysql透明化多主高可用,负载均衡,这样应用就无法感知服务端机器数量,首先要编译Stream模块
# 和http块同级
stream{upstream mysql{server 192.168.1.10:3306;server 192.168.1.11:3306;}server{listen 3306;proxy_pass mysql;}
}