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配置项):用于配置节点长连接的连接数,需要配置locationprox_http_version1.11.0是不支持长连接的),配置prox_set_headerConnection ""来清空请求头中的连接类型
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来配置对响应状态码为200400的响应缓存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 ipvsadmipvsadm -hman 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系统架构图

nginx 绿色 nginx keepalive lvs_缓存