1、简介
Nginx是一个多进程的高性能反向代理服务器
Nginx包含一个master进程,用于接收操作者的指令去管理worker进程,该进程不处理客户端请求
Nginx包含多个worker进程(默认1个,可以再config中的worker_processes
进行配置),worker进程用于接收客户端的请求,每个worker可以连接多个客户端,多个worker之间由于是进程,所以相互完全没有任何影响。
2、网络模型
Nginx在Linux下默认采用Epoll模型来实现异步非阻塞
3、 Worker配置
Nginx在配置中可以对worker的连接数进行配置worker_connections
,默认配置为1024
4、 Nginx配置结构
- main:全局配置
- event:配置工作模式(配置epoll)以及连接数
- http:http模块相关配置
- server: 虚拟主机配置,可以有多个
- location:路由规则,表达式
- upstream: 集群、内网服务器
5、 Nginx路由规则配置
location
后面的路由 会拼接到root的路由后面,如果不想要拼接,则使用alias
配置
- 访问html/test下的资源
location /test {
root html
}
- 等价于
location /static {
alias html/test
}
6、gzip配置
- 开启 gzip压缩功能:提高传输效率,节约带宽
gzip on;
- 限制最小压缩:小于该配置的文件不会被压缩,单位字节
gzip_min_length 1;
- 定义压缩的级别(压缩比):该值越大,压缩后的文件越小,但是占用CPU会越多
gzip_comp_level 3;
- 定义压缩文件的类型:只有配置了的文件类型才会被压缩
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript image/jpeg image/png image/gif application/json;
7、location路由规则
- 空格:默认匹配
-
=
:精准匹配,路由必须与,则路由必须完全匹配 ~
:正则匹配,
-
~*
:不区分大小写匹配 -
~
:精准正则匹配,区分大小写
-
^~
:不使用正则表达式,以某个字符开头的路由匹配
8、Nginx配置跨域问题
当别的Origin
需要访问Nginx的资源时(此时Nginx相当于一个后端服务器),会出现跨域问题,此时才需要针对Nginx进行跨域配置,所以跨域只要配置到真正的资源服务器端就行。如果Nginx
只是用来做反向代理则不用配置跨域,例如利用Nginx
代理SpringBoot
服务,则只需要在SpringBoot
后端进行跨域配置即可
#允许跨域请求的域,*代表所有
add_header 'Access-Control-Allow-Origin' *;
#允许跨域请求携带上cookie
add_header 'Access-Control-Allow-Credentials' 'true';
#允许跨域请求的方法类型
add_header 'Access-Control-Allow-Methods' *;
#允许跨域请求携带的请求头
add_header 'Access-Control-Allow-Headers' *;
9、Nginx静态资源防盗链
valid_referers *.foodie-dev.com;
if ($invalid_referer) {
return 404;
}
10、四层和七层负载均衡
10.1 四层负载均衡
基于IP加端口的负载均衡,通过转发请求到后台的服务器,只负责转发,并记录连接由哪个后台服务处理,并于服务建立长链接,该连接的后续请求都会被指向该后台服务器。是传输层的负载均衡,主要基于TCP和UDP。四层负载均衡只能转发请求,但是不可以处理请求。
- F5:硬负载均衡,基于硬件的商业级别负载均衡
- LVC:基于Linux内核的四层负载均衡
- Haproxy:支持转发功能,可以做四层也可以做七层
- Nginx:四层负载均衡,也可以做七层负载均衡,可以基于Http做负载均衡,1.9版本之后才支持
10.2 七层负载均衡
基于URL或IP的负载均衡,是基于应用层的,是针对HTTP协议的负载均衡。七层负载均衡可以处理请求
- Nginx 七层负载均衡
- Haproxy 七层负载均衡
- apache 七层负载均衡
10.3 DNS低于负载均衡
根据请求IP的地域性,DNS服务器解析时以就近原则选取就近机房的IP进行解析,从而实现了负载均衡
11、upstream反向代理
通upstream
配置多台代理服务器,在路径匹配中通过proxy_pass
来指向upstream
来实现
upstream liumeng-servers{
server liumeng01:8080;
server liumeng02:8080;
server liumeng03:8080;
}
server {
listen 80;
server_name www.liumeng.com;
location / {
proxy_pass http://liumeng-servers;
}
}
11.1 指令参数
max_conns
: 限制服务器的最大连接数,默认值为:0,表示不作任何限制,当使用多个worker
时,该限制是针对每个worker
,那么此时服务器的最大连接总数为max_conns * workers_count
slow_start
(商业版本才支持):设置权重在指定时间内从0开始慢慢缓慢增加设置值,从而设置节点服务器慢慢的加入到集群中。down
:标识服务节点状态为不可用backup
:标识服务节点为备用节点,只有当正常节点不可用时,该节点才会被访问max_fails
:最大失败次数,默认值1,当节点的失败次数达到该配置值时,nginx会将该节点从可用节点中移除,标记为不可用,然后在fail_timeout
后再将该节点标记为可用,然后允许请求转到该节点,如果又失败,则会重复之前的操作fail_timeout
:与max_fails
配合使用,用于配置失败空闲期,表示在节点失败之后,在fail_timeout
时间内该节点不会被使用,默认值为10s
keepalive
(是http
模块的upstream
配置项):用于配置节点长连接的连接数,需要配置location
中prox_http_version
为1.1
(1.0
是不支持长连接的),配置prox_set_header
为Connection ""
来清空请求头中的连接类型
upstream liumeng-servers{
server liumeng01:8080;
#server liumeng02:8080;
#server liumeng03:8080;
keepalive 32;
}
server {
listen 80;
server_name www.liumeng.com;
location / {
proxy_pass http://liumeng-servers;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
12、Nginx负载均衡算法
- 轮询 (默认)
- 加权轮询,轮询也是一个加权轮询,只是权重都是默认值
1
- 一致性Hash:
- ip_hash:根据请求的IP的hash来决定请求后端的哪一台机器,同一个IP的请求都会被转到同一个后台服务,在
upstream
中增加ip_hash;
即可启用。参与hash
运算的之后ip
地址的前三段,即:对地址192.168.1.172
进行ip hash
运算时,运算的是:ip_hash(192, 168, 1)
。 - url_hash:对请求的
url
进行hash
运算。在upstream
中增加hash $request_uri
进行开启 - least_conn:最小连接数。在
upstream
中增加least_conn
进行开启
13、缓存
13.1 浏览器缓存配置
- expires [Time]s:在location中添加该配置来设置缓存时长,例如:
expires 10s;
- expires @[Time]:在location中添加该配置来设置缓存具体的失效时长,例如:
expires @22h10m;
设置在晚上22点10分失效 - expire -[Time]:在location中添加该配置来设置缓存已经失效了多长时间,例如:
expires -1h;
设置缓存已经失效了1个小时 - expire epoch:不设置
cache
- expire off:关闭缓存,默认配置
- expire max:设置缓存失效时间为最大失效时长
13.2 反向代理缓存
(1)缓存空间配置
proxy_cache_path [path] keys_zone=[name]:[size]
来设置代理的缓存,例如:proxy_cache_path /usr/local/nginx/upstream_cache keys_zone=mycache:5m max_size=1g
,表示定义一个名为mycache
的缓存空间,初始化大小为5兆
,缓存存储路径为/usr/local/nginx/upstream_cache
,缓存最大为1g
。
- keys_zone:设置共享空间名称和占用的大小
- max_size:设置缓存空间的最大大小
- inactive:设置缓存有效时长,超过该时长的缓存会自动清理
- use_temp_path:是否使用临时目录,
off
:关闭
(2)缓存启用配置
- proxy_cache:在server中使用
proxy_cache [name]
来开启缓存,例如:proxy_cache mycache
来使用上面配置的缓存 - proxy_cache_valid:在server中使用
proxy_cache_valid [...status][time]
来配置指定状态码的缓存时长,例如:proxy_cache_valid 200 304 4h
来配置对响应状态码为200
或400
的响应缓存4h
14、Nginx的高可用–Keepalived
通过动态绑定虚拟IP来实现的高可用,所以Keepalived只能保证机器的高可用,无法保证机器内部服务的高可用。
- 解决单点故障
- 组件免费
- 可以实现高可用HA机制
- 基于VRRP协议
14.1 虚拟路由冗余协议VRRP
- Virtual Router Redundancy Protocol
- 解决内网单机故障的路由协议
- 构建有多个路由器Master backup
- 虚拟IP-VIP (Virtual IP Address)
Keepalived通过心跳连接多个服务,主备服务共同绑定同一个虚拟IP地址,正常情况下只有Master的虚拟IP地址会生效,当Master宕机后,另外的Backup就会启动在网卡上绑定该虚拟IP地址,从而实现服务的高可用。当Mater又启动可用时,虚拟IP又会绑定到Master机器上。
14.2 配置
-
router_id
:KeepAlived的路由id,当前安装keepalived节点主机的标识符,全局唯一 vrrp_instance
:计算机节点配置
-
state
: MASTER\BACKUP 主节点或备用节点 -
interface
:网卡名称,必须要于当前计算机的网卡名称一致 -
virtual_router_id
:虚拟理由ID,主备机的要保证一致 -
priority
:权重/优先级,当Master挂掉后,谁的权重越高越能成为master -
advert_int
:主备质检同步检查的时间间隔,默认1s -
authentication
:认证授权的密码,防止非法节点的进入 -
virtual_ipaddress
:虚拟ip
14.3 通过定时脚本间接实现服务高可用
通过再机器上绑定一个定时脚本,每隔一段时间来检测一下服务是否存活,如果服务挂掉了,就kill keepalived的进程,从而间接的来实现服务的高可用
#!/bin/bash
# 获取服务的进程ID
procId = `ps -C nginx --no-header | wc -l`
if [ $procId -eq 0 ];then
# 启动服务
/usr/local/nginx/sbin/nginx
sleep 3
if [ `ps -C nginx --no-header | wc -l` -eq 0 ];then
killall keepalived
fi
fi
在keepalived.conf中添加脚本
vrrp_script [脚本名] {
script "[脚本全路径]"
interval 2 #间隔2秒运行一次
weight 10 # 如果脚本运行成功,则升级权重+10
}
然后在vrrp_instance
中添加运行对象
track_script {
[上方定义的脚本名]
}
该方案的确定只有Master节点会工作,Slave节点一直不会被使用
14.4 Keepalived的双主热备
为Keepalived分配2个虚拟IP,让这2台Keepalived互为主备关系。
通过DNS对这2个虚拟IP进行负载均衡,然后分配给互为主备的2台keepalived
- 将
vrrp_instance
复制一份 - 修改
vrrp_instance
名称 - 修改
state
主备状态 - 修改
virtual_router_id
与第一组的virtual_router_id
不同 - 修改
priority
主备的权重值 - 修改
virtual_ipaddress
使用第二组的虚拟ip地址
14.5 Keepalived配置LVS
在Keepalive的配置文件中,virtual_server
即用来配置LVS集群
virtual_server
:配置LVS集群的访问IP+端口,与Keepalived的虚拟端口保持一致
-
delay_loop
:健康检查时间,单位:秒 -
lb_algo
:负载均衡算法,默认:rr轮询 -
lb_kind
:LVS的模式,支持DR NAT等 -
persistence_timeout
:会话持久化的时间 -
protocol
:协议
real_server
:配置真实服务器,有多少个就要配置多少个
TCP_CHECK
:配置健康检查
-
connect_port
:配置健康检查端口 -
connect_timeout
:超时时长 -
nb_get_retry
:重试次数 -
delay_before_retry
:间隔时长,单位:秒
15、LVS负载均衡
LVS(Linux Virtual Server)是一个运行在Linux环境基于ipvs的四层负载均衡。通过ip端口进行负载均衡。LVS可以只转发请求,而不处理响应,从而提升性能。
15.1 LVS的工作模式
- NAT:(Net Address Transaction)地址转换模式。该模式与Nginx类似,会接受请求以及响应。客户端请求会先访问到LVS然后由LVS转发给后端服务,后端服务响应给LVS,然后LVS再响应给客户端
- TUN:ip隧道模式,要求所有后端服务节点必须存在1个网卡。客户端请求会先访问到LVS,然后由LVS转发给后端服务,后端服务处理后直接响应给客户端,不会再经过LVS,注意此模式下后端服务相当于直接暴露在公网。
- DR:(Direct Router)直接路由模式,该模式与TUN类似,不过该模式只需要保证后端服务与LVS处于同一局域网络中。客户端的请求会先访问LVS,然后由LVS通过对请求报文重新包装后转发给后端服务集群,后端服务集群根据请求报文中的Mac地址进行匹配选择是否处理该请求,处理完请求后通过Io0接口将报文发送给eth0网口响应给客户端。
15.2 LVS配置
- LVS机器配置虚拟IP,通过拷贝网卡配置文件(ifcfg-ens33)进行配置
- LVS机器安装ipvsadm,
yum install ipvsadm
,ipvsadm -h
或man ipvsadm
可以查看ipvsadm
的帮助文档 - LVS节点(Nginx所在机器)配置回环IP,通过拷贝lo文件配置(ifcfg-lo),回环IP与LVS机器的虚拟IP保持一致
- LVS节点机器配置ARP
- arp-ignore: ARP响应级别(处理请求)
- 0:只要本机配置了IP,就能响应请求
- 1:请求的目标地址到达对应的网络接口,才响应请求
- arp-announce:ARP通告行为
- 0:本机上任何网络接口都向外通告,所有的网卡都能接受通告
- 1:尽可能避免本网卡与不匹配的目标进行通告
- 2:只在本网卡通告
#修改 /etc/sysctl.conf
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.default.arp_ignore = 1
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_announce = 2
#配置后使用 sysctl -p 刷新配置,使配置生效
- LVS节点配置Router: 配置 route 将10.0.10.213的请求委托给lo:1进行处理
-
route add -host 10.0.10.213 dev lo:1
该方式重启会失效 - 可以将上诉命令添加到系统启动命令中
/etc/rc.local
。操作命令:echo "route add -host 10.0.10.213 dev lo:1" >> /etc/rc.local
- LVS配置:
- 创建集群:
ipvsadm -A -t [虚拟集群IP]:[端口] -s [负载均衡算法]
,例如:ipvsadm -A -t 10.0.10.213:80 -s rr
- 添加节点:
ipvsadm -a -t [虚拟集群IP]:[端口] -r [节点IP]:[端口] [模式]
,例如:ipvsadm -a -t 10.0.10.213:80 -r 10.0.10.115:80 -g
++注意:LVS针对同一客户端的请求会有持久化的配置,在配置时间内,同一客户端的请求都会被转发到同一个节点上,可以通过-p
进行修改,单位为秒
,默认值为30s
,例如: ipvsadm -E -t 10.0.10.213:80 -p 5
++
++ 针对TCP连接,LVS会存在连接空闲时长,连接等待时长的配置,该配置时长过长时将导致客户端持久化配置失效:通过ipvsadm -L --timeout
查看当前配置,使用ipvsadm --set [TCP空闲时长] [TCP客户端等待关闭时长] [UDP关闭等待时长]
命令修改配置 ++
16、LVS+Keepalived+Nginx系统架构图