目录
一、单机垂直扩容:硬件资源增加
云服务资源增加
整机:IBM、浪潮、DELL、HP等
CPU/主板:更新到主流
网卡:10G/40G网卡
磁盘:SAS(SCSI) HDD(机械)、HHD(混合)、SATA SSD、PCI-e SSD、 MVMe SSD
SSD
多副本机制
系统盘/热点数据/数据库存储
HDD
冷数据存储
二、水平扩展:集群化
(一)会话管理
1、Nginx高级负载均衡
ip_hash
对ip取hash值,因此每次同个ip地址访问的结果是相同的
此时通过固定的ip访问,访问的结果是一样的
hash request_uri
加?后hash值与index.jsp不一样了,一个05一个04
2、使用sticky模块完成对Nginx的负载均衡
使用参考
Module ngx_http_upstream_module
tengine中有session_sticky模块我们通过第三方的方式安装在开源版本中
sticky是第三方模块,需要重新编译Nginx,他可以对Nginx这种静态文件服务器使用基于cookie的负载均衡
①下载模块
项目官网
另外一个版本
GitHub - bymaximus/nginx-sticky-module-ng: nginx-sticky-module-ng
下载
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
如遇报错修改源码
打开 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.bk
把编译好的Nginx程序替换到原来的目录里
cp objs/nginx /usr/local/nginx/sbin/
升级检测
make upgrade
检查程序中是否包含新模块
nginx -V
配置方法
upstream httpget {
// 名字 过期时间
sticky name=route expires=6h;
server 192.168.44.102;
server 192.168.44.103;
}
会话管理总结:
第一个是通过hash方法使得通过ip hash后访问的nginx的代理服务器相同
第二个是通过类似JessionID的方式使用sticky模块生成自定义名字和过期时间的令牌,以该令牌访问服务器,达到访问的nginx的代理服务器相同的功能
3、keepalive
在http协议header中可以看到当前连接状态
我们查看一些js或者jpg的访问请求会发现请求头中没有keep-alive字段
什么时候使用?
可以知道只有明显的预知用户会在当前连接上有下一步操作才需要保持连接,因此我们需要复用连接,有效减少握手次数,尤其是https建立一次连接开销会更大
什么时候不用?
访问内联资源一般用缓存,不需要keepalive
长时间的tcp连接容易导致系统资源无效占用
keepalive分为两个方向,上游(服务端)和下游(客户端)
① 对客户端使用keepalive
keepalive_time
限制keepalive保持连接的最大时间
1.19.10新功能
keepalive_timeout
用于设置Nginx服务器与客户端保持连接的超时时间
用于踢出不活动连接
keepalive_timeout = 0 即关闭
send_timeout
两次向客户端写操作之间的间隔 如果大于这个时间则关闭连接 默认60s
此处有坑,注意耗时的同步操作有可能会丢弃用户连接
-
send_timeout 10; 10秒
-
send_timeout 10 10; 同时下发一个header 告诉浏览器
该设置表示Nginx服务器与客户端连接后,某次会话中服务器等待客户端响应超过10s,就会自动关闭连接。
keepalive_request
默认1000
单个连接中可处理的请求数
keepalive_disable
不对某些浏览器建立长连接
默认msie6
例子:
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65 65; #超过这个时间 没有活动,会让keepalive失效
keepalive_time 1h; # 一个tcp连接总时长,超过之后 强制失效
send_timeout 60;# 默认60s 此处有坑!! 系统中 若有耗时操作,超过 send_timeout 强制断开连接。 注意:准备过程中,不是传输过程
keepalive_requests 1000; #一个tcp复用中 可以并发接收的请求个数server {
……
}
}
② 对上游使用keepalive
首先需要配置使用http1.1协议。以便建立更高效的传输,默认使用http1.0,在http1.0中需要配置header才能
在Upstream中所配置的上游服务器默认都是用短连接,即每次请求都会在完成之后断开
相关配置
upstream中配置
配置
keepalive 100;
向上游服务器的保留连接数
keepalive_timeout
连接保留时间
keepalive_requests
一个tcp复用中 可以并发接收的请求个数
server中配置
proxy_http_version 1.1;
配置http版本号
默认使用http1.0协议,需要在request中增加”Connection: keep-alive“ header才能够支持,而HTTP1.1默认支持。
proxy_set_header Connection "";
清除 close信息
例子:
upstream httpsd {
keepalive 100;
keepalive_requests 1000;
keepalive_timeout 65;
server 192.168.23.101:80;
}
server {
listen 80;
server_name localhost;location / {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass http://httpsd;}
}
③ 压测AB工具安装
yum install httpd-tools
参数说明:
-
-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。
测试命令
ab -n 100000 -c 30 http://192.168.23.101/
直连nginx
Server Software: nginx/1.21.6
Server Hostname: 192.168.23.101
Server Port: 80Document Path: /
Document Length: 634 bytesConcurrency Level: 30
Time taken for tests: 12.718 seconds
Complete requests: 100000
Failed requests: 0
Write errors: 0
Total transferred: 86700000 bytes
HTML transferred: 63400000 bytes
Requests per second: 7863.11 [#/sec] (mean)
Time per request: 3.815 [ms] (mean)
Time per request: 0.127 [ms] (mean, across all concurrent requests)
Transfer rate: 6657.54 [Kbytes/sec] receivedConnection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.4 0 9
Processing: 0 3 0.8 3 20
Waiting: 0 3 0.8 3 19
Total: 1 4 0.8 4 21Percentage of the requests served within a certain time (ms)
50% 4
66% 4
75% 4
80% 4
90% 4
95% 4
98% 5
99% 7
100% 21 (longest request)
反向代理
Server Software: nginx/1.21.6
Server Hostname: 192.168.23.100
Server Port: 80Document Path: /
Document Length: 634 bytesConcurrency Level: 30
Time taken for tests: 21.061 seconds
Complete requests: 100000
Failed requests: 0
Write errors: 0
Total transferred: 86700000 bytes
HTML transferred: 63400000 bytes
Requests per second: 4748.19 [#/sec] (mean)
Time per request: 6.318 [ms] (mean)
Time per request: 0.211 [ms] (mean, across all concurrent requests)
Transfer rate: 4020.19 [Kbytes/sec] receivedConnection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.3 0 18
Processing: 2 6 1.9 5 21
Waiting: 2 6 1.9 5 21
Total: 3 6 1.9 6 27Percentage of the requests served within a certain time (ms)
50% 6
66% 6
75% 6
80% 7
90% 10
95% 11
98% 12
99% 12
100% 27 (longest request)
nginx反向代理+keepalive
Server Software: nginx/1.21.6
Server Hostname: 192.168.23.100
Server Port: 80Document Path: /
Document Length: 634 bytesConcurrency Level: 30
Time taken for tests: 13.525 seconds
Complete requests: 100000
Failed requests: 0
Write errors: 0
Total transferred: 86700000 bytes
HTML transferred: 63400000 bytes
Requests per second: 7393.85 [#/sec] (mean)
Time per request: 4.057 [ms] (mean)
Time per request: 0.135 [ms] (mean, across all concurrent requests)
Transfer rate: 6260.22 [Kbytes/sec] receivedConnection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.3 0 12
Processing: 1 4 1.6 3 46
Waiting: 1 4 1.6 3 46
Total: 2 4 1.5 3 47Percentage of the requests served within a certain time (ms)
50% 3
66% 4
75% 5
80% 6
90% 6
95% 7
98% 7
99% 8
100% 47 (longest request)
(二)upstream的工作流程
缓冲区
nginx接收到一个二进制http请求后首先会将它反序列化成一个可读的文本,处理完请求行之后才处理请求头和请求体
对于请求体的读取可以甚至client_body_buffer_size设置缓冲区大小,大于设置值则写入临时文件。读取请求体的过程中可以通过proxy_request_buffering决定是否向上游发起请求,off即边读边发(异步)
在上游服务器连接前,nginx首先会选择服务器(在upstream中),然后将http请求打包成标准的二进制请求报文,此时可以通过set_header往请求头添加想要发送给上游的信息,然后向epoll事件队列中注册回调函数,以便接收到返回数据后做处理。
这里无论是epoll或者是Java中的nio,这些数据读取,网络连接和网络连接断开其实都是以事件的形式触发的
在nginx多线程并发的过程中,有可能出现上下游速率问题,即下游发送速度慢,上游发送速度快,此时下游没发送完资源,与上游的连接一直被占用无法中断,此时可以通过开启proxy_buffering缓冲读到的内容,通过proxy_buffers设置缓冲区的大小,多次读取从而断开或者复用与上游的网络连接。当上游缓冲的响应太大时,会写入临时文件,可通过proxy_max_temp_file_size设置临时文件的大小,proxy_temp_path 设置临时文件的目录和层级
总结:
proxy_pass 向上游服务器请求数据共有6个阶段
初始化
与上游服务器建立连接
向上游服务器发送请求
处理响应头
处理响应体
结束
set_header
设置header
proxy_connect_timeout
与上游服务器连接超时时间、快速失败
proxy_send_timeout
定义nginx向后端服务发送请求的间隔时间(不是耗时)。默认60秒,超过这个时间会关闭连接
proxy_read_timeout
后端服务给nginx响应的时间,规定时间内后端服务没有给nginx响应,连接会被关闭,nginx返回504 Gateway Time-out。默认60秒
缓冲区
proxy_requset_buffering
是否完全读到请求体之后再向上游服务器发送请求
proxy_buffering
是否缓冲上游服务器数据
proxy_buffers 32 64k;
缓冲区大小 32个 64k大小内存缓冲块
proxy_buffer_size
header缓冲区大小
proxy_requset_buffering on; proxy_buffering on; proxy_buffer_size 64k; proxy_buffers 32 128k; proxy_busy_buffers_size 8k; proxy_max_temp_file_size 1024m;
proxy_temp_file_write_size 8k
当启用从代理服务器到临时文件的响应的缓冲时,一次限制写入临时文件的数据的大小。 默认情况下,大小由proxy_buffer_size和proxy_buffers指令设置的两个缓冲区限制。 临时文件的最大大小由proxy_max_temp_file_size指令设置。
proxy_max_temp_file_size 1024m;
临时文件最大值
proxy_temp_path
proxy_temp_path /spool/nginx/proxy_temp 1 2;
a temporary file might look like this:
/spool/nginx/proxy_temp/7/45/00000123457
对客户端的限制
可配置位置
-
http
-
server
-
location
小范围可以覆盖大范围,比如location内的配置可以覆盖server的配置
client_body_buffer_size
对客户端请求中的body缓冲区大小
默认32位8k 64位16k
如果请求体大于配置,则写入临时文件
client_header_buffer_size
设置读取客户端请求体的缓冲区大小。 如果请求体大于缓冲区,则将整个请求体或仅将其部分写入临时文件。 默认32位8K。 64位平台16K。
client_max_body_size 1000M;
默认1m,如果一个请求的大小超过配置的值,会返回413 (request Entity Too Large)错误给客户端
将size设置为0将禁用对客户端请求正文大小的检查。
client_body_timeout
指定客户端与服务端建立连接后发送 request body 的超时时间。如果客户端在指定时间内没有发送任何内容,Nginx 返回 HTTP 408(Request Timed Out)
client_header_timeout
客户端向服务端发送一个完整的 request header 的超时时间。如果客户端在指定时间内没有发送一个完整的 request header,Nginx 返回 HTTP 408(Request Timed Out)。
client_body_temp_path path[
level1[
level2[
level3`]]]
在磁盘上客户端的body临时缓冲区位置
client_body_in_file_only on;
把body写入磁盘文件,请求结束也不会删除
client_body_in_single_buffer
尽量缓冲body的时候在内存中使用连续单一缓冲区,在二次开发时使用$request_body
读取数据时性能会有所提高
client_header_buffer_size
设置读取客户端请求头的缓冲区大小
如果一个请求行或者一个请求头字段不能放入这个缓冲区,那么就会使用large_client_header_buffers
large_client_header_buffers
默认8k
(三)获取客户端真实地址
反向代理后通过remote_addr拿到的是代理服务器的ip地址
可以通过配置nginx往上游请求头中存放X-Forwarded-For
remote_addr是与nginx连接到主机ip
思考:这里如果宿主在发送请求时往请求头中添加X-Forwarded-For伪造了一个假ip,那么还能拿到真实ip吗?
答:没有影响,这里是nginx通过读取remote_addr构造的X-Forwarded-For,remote_addr是无法虚假的
ipAddress是真实的客户端ip,remoteHost是反向代理服务器的ip
那如果有一串nginx服务器相连,此时后面的服务器会覆盖前面的X-Forwarded-For,有什么应对方法?
① 后面的nginx直接在请求头中添加而不是覆盖
② 后面的nginx直接转发前面的nginx发送过来的数据,不对该字段做处理
(四)Gzip
作用域 http, server, location
gzip on;
开关,默认关闭
gzip_buffers 32 4k|16 8k
缓冲区大小
gzip_comp_level 1;
压缩等级 1-9,数字越大压缩比越高
gzip_http_version 1.1;
使用gzip的最小版本
gzip_min_length
设置将被gzip压缩的响应的最小长度。 长度仅由“Content-Length”响应报头字段确定。
gzip_proxied 多选
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 - 无条件启用压缩
gzip_vary on;
增加一个header,适配老的浏览器 Vary: Accept-Encoding
gzip_types
哪些mime类型的文件进行压缩
gzip_disable
禁止某些浏览器使用gzip
完整实例
gzip on;
gzip_buffers 16 8k;
gzip_comp_level 6;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_types
text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml
text/javascript application/javascript application/x-javascript
text/x-json application/json application/x-web-app-manifest+json
text/css text/plain text/x-component
font/opentype application/x-font-ttf application/vnd.ms-fontobject
image/x-icon;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
ngx_http_gunzip_module
帮助不支持gzip的客户端解压本地文件
http_gzip_static_module
需要重新编译nginx
./configure --with-http_gzip_static_module
(五)请求合并
访问3个css文件的请求合并成一个请求,在请求的后边携带文件名参数,这种技术叫Concat,淘宝研发出来且正在使用的
比如访问淘宝网页时,css和js都是用了Concat
Nginx官方介绍
git地址
https://github.com/alibaba/nginx-http-concat
-
安装
下载源码解压缩编译安装
-
配置
concat on;
concat_max_files 30;
(六)rsync
remote synchronize是一个远程数据同步工具,可通过 LAN/WAN 快速同步多台主机之间的文件。也可以使用 rsync 同步本地硬盘中的不同目录。 rsync 是用于替代 rcp 的一个工具,rsync 使用所谓的 rsync算法 进行数据同步,这种算法只传送两个文件的不同部分,而不是每次都整份传送,因此速度相当快。
rsync 基于inotify 开发
Rsync有三种模式:
-
本地模式(类似于cp命令)
-
远程模式(类似于scp命令)
-
守护进程(socket进程:是rsync的重要功能)
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 | 传输时压缩 |
安装
两端安装
yum install -y rsync
###
密码文件
创建文件/etc/rsync.password
内容(账号:密码)
admin:admin
修改权限
chmod 600 /etc/rsync.password
修改配置
auth users = admin
secrets file = /etc/rsyncd.pwd
[ftp]
path = /usr/local/nginx/html
开机启动
在/etc/rc.local
文件中添加
rsync --daemon
将100为源机,101为同步机 ,源机需要开启rsync
此时在同步机上可以通过rsync --list-only 用户名@源机ip::路径
同步文件,100上多出了一个dist目录
rsync -avz 用户@源机ip::源机目录 本机目录
rsync没有重启命令,想要重启只能杀死原本的进程