第八周作业

[TOC]

一、redis搭建哨兵原理和集群实现

1.1、搭建哨兵的原理

①专门的Sentinel 服务进程是用于监控redis集群中Master工作的状态,当Master主服务器发生故障的时候,可以实现Master和Slave的角色的自动切换,从而实现系统的高可用性

②Sentinel是一个分布式系统,即需要在多个节点上各自同时运行一个sentinel进程,Sentienl 进程通过流言协议(gossip protocols)来接收关于Master是否下线状态,并使用投票协议(Agreement Protocols)来决定是否执行自动故障转移,并选择合适的Slave作为新的Master

③每个Sentinel进程会向其它Sentinel、Master、Slave定时发送消息,来确认对方是否存活,如果发现某个节点在指定配置时间内未得到响应,则会认为此节点已离线,即为主观宕机Subjective Down,简称为 SDOWN

④如果哨兵集群中的多数Sentinel进程认为Master存在SDOWN,共同利用 is-master-down-by-addr 命令

互相通知后,则认为客观宕机Objectively Down, 简称 ODOWN

⑤接下来利用投票算法,从所有slave节点中,选一台合适的slave将之提升为新Master节点,然后自动修改其它slave相关配置,指向新的master节点,最终实现故障转移failover

注意:Redis Sentinel中的Sentinel节点个数应该为大于等于3且最好为奇数

image-20221110160626143

1.2、搭建集群

1.2.1、集群架构

image-20221111082931387

注意:①每个Redis 节点采用相同的相同的Redis版本、相同的密码、硬件配置

②所有Redis服务器必须没有任何数据

准备六台主机,地址如下:

1
2
3
4
5
6
7
10.0.0.184
10.0.0.185
10.0.0.186
10.0.0.187
10.0.0.188
10.0.0.216
#6台主机都已编译安装完成
1.2.2、启用redis cluster配置

①每个节点修改redis配置,必须开启cluster功能的参数

1
2
[root@Rocky ~]#sed -i.bak -e '/masterauth/a masterauth 123456' -e '/# cluster-enabled yes/a cluster-enabled yes' -e '/# cluster-config-file nodes-6379.conf/a cluster-config-file nodes-6379.conf' -e '/cluster-require-full-coverage yes/c cluster-require-full-coverage no' /apps/redis/etc/redis.conf
[root@Rocky ~]#systemctl restart redis

②验证当前Redis服务状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
#开启了16379的cluster的端口,实际的端口=redis port + 10000
[root@Rocky ~]#ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 511 0.0.0.0:16379 0.0.0.0:*
LISTEN 0 511 0.0.0.0:6379 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 511 [::1]:16379 [::]:*
LISTEN 0 511 [::1]:6379 [::]:*
LISTEN 0 128 *:80 *:*
#注意进程有[cluster]状态
[root@Rocky ~]#ps -ef|grep redis
redis 33345 1 0 09:16 ? 00:00:00 /apps/redis/bin/redis-server 0.0.0.0:6379 [cluster]
1.2.3、创建集群
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#命令redis-cli的选项 --cluster-replicas 1 表示每个master对应一个slave节点
[root@Rocky ~]#redis-cli -a 123456 --cluster create 10.0.0.184:6379 10.0.0.185:6379 10.0.0.186:6379 10.0.0.187:6379 10.0.0.188:6379 10.0.0.216:6379 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 10.0.0.188:6379 to 10.0.0.184:6379
Adding replica 10.0.0.216:6379 to 10.0.0.185:6379
Adding replica 10.0.0.187:6379 to 10.0.0.186:6379
M: cdf92d28ccbf42767778bf65cacb6eda1c406257 10.0.0.184:6379 # :后面的是ID号
slots:[0-5460] (5461 slots) master #[]里面的数字是槽位的起始和结束位
M: 2ca4e638bd3fa22ad94cc238907faf6b613d0b88 10.0.0.185:6379
slots:[5461-10922] (5462 slots) master
M: 56efb05a636f587fd11775f702a427291d4c1cb6 10.0.0.186:6379
slots:[10923-16383] (5461 slots) master
S: 40bbd63934b4201e370de7424b1a8317715c8207 10.0.0.187:6379 #S是从节点slave
replicates 56efb05a636f587fd11775f702a427291d4c1cb6
S: c6ef7581a4752b8e786a4585778427502defd6d5 10.0.0.188:6379
replicates cdf92d28ccbf42767778bf65cacb6eda1c406257
S: 3c15e99e9430bde6184a65554127cd0669b41b05 10.0.0.216:6379
replicates 2ca4e638bd3fa22ad94cc238907faf6b613d0b88
Can I set the above configuration? (type 'yes' to accept): yes #yes自动创建集群
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.
>>> Performing Cluster Check (using node 10.0.0.184:6379)
M: cdf92d28ccbf42767778bf65cacb6eda1c406257 10.0.0.184:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: 56efb05a636f587fd11775f702a427291d4c1cb6 10.0.0.186:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s) #表示分配了一个从节点
S: 40bbd63934b4201e370de7424b1a8317715c8207 10.0.0.187:6379
slots: (0 slots) slave #从节点没有槽位
replicates 56efb05a636f587fd11775f702a427291d4c1cb6
S: 3c15e99e9430bde6184a65554127cd0669b41b05 10.0.0.216:6379
slots: (0 slots) slave
replicates 2ca4e638bd3fa22ad94cc238907faf6b613d0b88 #此从节点对应的主节点的ID
M: 2ca4e638bd3fa22ad94cc238907faf6b613d0b88 10.0.0.185:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: c6ef7581a4752b8e786a4585778427502defd6d5 10.0.0.188:6379
slots: (0 slots) slave
replicates cdf92d28ccbf42767778bf65cacb6eda1c406257
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

#此时可以看出对应关系
master:10.0.0.184 slave:10.0.0.188
master:10.0.0.185 slave:10.0.0.216
master:10.0.0.186 slave:10.0.0.187
#为了方便,将对应的主机名称更改
master1:10.0.0.184 slave1:10.0.0.188
master2:10.0.0.185 slave2:10.0.0.216
master3:10.0.0.186 slave3:10.0.0.187
1.2.4、验证集群
1.2.4.1、查看主从状态
1
2
3
4
5
6
7
8
9
10
11
12
13
[root@slave3 ~]#redis-cli -a 123456 cluster nodes

40bbd63934b4201e370de7424b1a8317715c8207 10.0.0.187:6379@16379 myself,slave 56efb05a636f587fd11775f702a427291d4c1cb6 0 1668131120000 3 connected

c6ef7581a4752b8e786a4585778427502defd6d5 10.0.0.188:6379@16379 slave cdf92d28ccbf42767778bf65cacb6eda1c406257 0 1668131122687 1 connected

56efb05a636f587fd11775f702a427291d4c1cb6 10.0.0.186:6379@16379 master - 0 1668131121648 3 connected 10923-16383

2ca4e638bd3fa22ad94cc238907faf6b613d0b88 10.0.0.185:6379@16379 master - 0 1668131122000 2 connected 5461-10922

cdf92d28ccbf42767778bf65cacb6eda1c406257 10.0.0.184:6379@16379 master - 0 1668131122000 1 connected 0-5460

3c15e99e9430bde6184a65554127cd0669b41b05 10.0.0.216:6379@16379 slave 2ca4e638bd3fa22ad94cc238907faf6b613d0b88 0 1668131120000 2 connected
1.2.4.2、验证集群状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@master1 ~]#redis-cli -a 123456 CLUSTER INFO
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6 #节点数
cluster_size:3 #3个集群

#查看任意节点的集群状态
[root@master1 ~]#redis-cli -a 123456 --cluster info 10.0.0.187:6379
10.0.0.186:6379 (56efb05a...) -> 0 keys | 5461 slots | 1 slaves.
10.0.0.185:6379 (2ca4e638...) -> 0 keys | 5462 slots | 1 slaves.
10.0.0.184:6379 (cdf92d28...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
1.2.4.3、查看对应关系
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[root@master1 ~]#redis-cli -a 123456 --cluster check 10.0.0.216:6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
10.0.0.184:6379 (cdf92d28...) -> 0 keys | 5461 slots | 1 slaves.
10.0.0.185:6379 (2ca4e638...) -> 0 keys | 5462 slots | 1 slaves.
10.0.0.186:6379 (56efb05a...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 10.0.0.216:6379)
S: 3c15e99e9430bde6184a65554127cd0669b41b05 10.0.0.216:6379
slots: (0 slots) slave
replicates 2ca4e638bd3fa22ad94cc238907faf6b613d0b88
M: cdf92d28ccbf42767778bf65cacb6eda1c406257 10.0.0.184:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: 2ca4e638bd3fa22ad94cc238907faf6b613d0b88 10.0.0.185:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: c6ef7581a4752b8e786a4585778427502defd6d5 10.0.0.188:6379
slots: (0 slots) slave
replicates cdf92d28ccbf42767778bf65cacb6eda1c406257
M: 56efb05a636f587fd11775f702a427291d4c1cb6 10.0.0.186:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 40bbd63934b4201e370de7424b1a8317715c8207 10.0.0.187:6379
slots: (0 slots) slave
replicates 56efb05a636f587fd11775f702a427291d4c1cb6
1.2.5测试集群写入数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@master1 ~]#redis-cli -a 123456
127.0.0.1:6379> dbsize #查看此节点数据,数据为0
(integer) 0
127.0.0.1:6379> set a b #写入数据
(error) MOVED 15495 10.0.0.186:6379 #提示此数据写入到10.0.0.186这个节点
#此时需要到10.0.0.186这台主机去写入
[root@master3 ~]#redis-cli -a 123456
127.0.0.1:6379> dbsize
(integer) 0
127.0.0.1:6379> set a b
OK #写入成功

#造成此现象的是因为通过算法计算,当前key的槽位需要写入指定的node
#为了不需要输入2次,可以加-c(表示集群模式)
[root@master1 ~]#redis-cli -a 123456 -c
127.0.0.1:6379> set a w #此时再输入数据,自动转换到10.0.0.186节点,写入数据
-> Redirected to slot [15495] located at 10.0.0.186:6379
OK
10.0.0.186:6379>
1.2.6、模拟故障实现故障转移
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#将10.0.0.185停止服务
[root@master2 ~]#systemctl stop redis
#此时查看10.0.0.185的记录已发生变化
[root@slave1 ~]#cat /apps/redis/data/nodes-6379.conf
2ca4e638bd3fa22ad94cc238907faf6b613d0b88 10.0.0.185:6379@16379 master,fail - 1668132519648 1668132516486 2 disconnected #master,fail失败的主节点

cdf92d28ccbf42767778bf65cacb6eda1c406257 10.0.0.184:6379@16379 master - 0 1668132534993 1 connected 0-5460

3c15e99e9430bde6184a65554127cd0669b41b05 10.0.0.216:6379@16379 master - 0 1668132536008 7 connected 5461-10922 #10.0.0.216变成主节点了

40bbd63934b4201e370de7424b1a8317715c8207 10.0.0.187:6379@16379 slave 56efb05a636f587fd11775f702a427291d4c1cb6 0 1668132535000 3 connected

c6ef7581a4752b8e786a4585778427502defd6d5 10.0.0.188:6379@16379 myself,slave cdf92d28ccbf42767778bf65cacb6eda1c406257 0 1668132534000 1 connected

56efb05a636f587fd11775f702a427291d4c1cb6 10.0.0.186:6379@16379 master - 0 1668132534000 3 connected 10923-16383

[root@master2 ~]#systemctl start redis
[root@slave3 ~]#redis-cli -a 123456 cluster nodes
40bbd63934b4201e370de7424b1a8317715c8207 10.0.0.187:6379@16379 myself,slave 56efb05a636f587fd11775f702a427291d4c1cb6 0 1668132977000 3 connected

c6ef7581a4752b8e786a4585778427502defd6d5 10.0.0.188:6379@16379 slave cdf92d28ccbf42767778bf65cacb6eda1c406257 0 1668132979881 1 connected

56efb05a636f587fd11775f702a427291d4c1cb6 10.0.0.186:6379@16379 master - 0 1668132978841 3 connected 10923-16383

2ca4e638bd3fa22ad94cc238907faf6b613d0b88 10.0.0.185:6379@16379 slave 3c15e99e9430bde6184a65554127cd0669b41b05 0 1668132977798 7 connected
#10.0.0.185恢复后自动变成10.0.0.216的从节点了
cdf92d28ccbf42767778bf65cacb6eda1c406257 10.0.0.184:6379@16379 master - 0 1668132978000 1 connected 0-5460

3c15e99e9430bde6184a65554127cd0669b41b05 10.0.0.216:6379@16379 master - 0 1668132979000 7 connected 5461-10922

1.2.7、验证数据是否同步
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@master1 ~]#redis-cli -a 123456 -c
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> dbsize
(integer) 0
127.0.0.1:6379> set a w
-> Redirected to slot [15495] located at 10.0.0.186:6379
OK
10.0.0.186:6379>

#然后看看186的从节点187是否有此数据
[root@slave3 ~]#redis-cli -a 123456
127.0.0.1:6379> get a #查看不了具体数据
(error) MOVED 15495 10.0.0.186:6379
127.0.0.1:6379> dbsize #只能看见有1个数据
(integer) 1
#说明集群里的从节点既不能写也不能读

二、LVS常用模型工作原理,及实现

2.1、LVS的工作原理

VS根据请求报文的目标IP和目标协议及端口将其调度转发至某RS,根据调度算法来挑选RS。LVS是内核级功能,工作在INPUT链的位置,将发往INPUT的流量进行“处理”

2.2、DR模型实现过程

LVS-DR:Direct Routing,直接路由,LVS默认模式,应用最广泛,通过为请求报文重新封装一个MAC首部进行转发,源MAC是DIP所在的接口的MAC,目标MAC是某挑选出的RS的RIP所在接口的MAC地址;源IP/PORT,以及目标IP/PORT均保持不变

image-20221112162015705

image-20221112161725974

①Director和各RS都配置有VIP

②确保前端路由器将目标IP为VIP的请求报文发往Director

​ ——在前端网关做静态绑定VIP和Director的MAC地址

​ ——在RS上使用arptables工具

1
2
arptables -A IN -d $VIP -j DROP
arptables -A OUT -s $VIP -j mangle --mangle-ip-s $RIP

​ ——在RS上修改内核参数以限制arp通告及应答级别

1
2
/proc/sys/net/ipv4/conf/all/arp_ignore
/proc/sys/net/ipv4/conf/all/arp_announce

③ RS的RIP可以使用私网地址,也可以是公网地址;RIP与DIP在同一IP网络;RIP的网关不能指向DIP,以确保响应报文不会经由Director

④ RS和Director要在同一个物理网络

⑤请求报文要经由Director,但响应报文不经由Director,而由RS直接发往Client

⑥不支持端口映射(端口不能修改)

⑦无需开启 ip_forward

三、LVS的负载策略有哪些,各应用在什么场景,通过LVS DR任意实现1-2种场景

3.1、负载策略及应用场景

①NAT模型:由于配置简单,请求和回应都涉及LVS服务器(LVS服务器压力大),所以应用于并发量不大的中小企业。Real server服务器数量控制在10-20

②DR模型:并发量非常大的企业(DR模型的并发处理量能达到硬件级别的能力)。Real server服务器数量可以达到100

③TUN模型:TUN模式常会用来负载调度缓存服务器组,这些缓存服务器一般放置在不同的网络环境,可以就近折返给客户端。在请求对象不在Cache服务器本地命中的情况下,Cache服务器要向源服务器发送请求,将结果取回,最后将结果返回给用户。Real server服务器数量可以达到100

④FULLNAT模型:此模型主要是阿里云的二次开发使用。

3.2、LVS-DR模式单网段案例

3.2.1、环境

image-20221112170014075

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
环境:5台主机
一台:客户端 (主机名:Internet)
eth0:仅主机模式 192.168.10.184/24 GW:192.168.10.185

一台:路由器(主机名:ROUTER)
eth0:NAT 10.0.0.185/24
eth1:仅主机模式 192.168.10.185/24

一台:LVS(主机名LVS)
eth0:NAT DIP:10.0.0.186/24 GW:10.0.0.185
lo VIP:10.0.0.100/32

两台:RS(主机名web1、web2)
RS1: eth0:NAT RIP:10.0.0.187/24 GW:10.0.0.185
lo VIP:10.0.0.100/32
RS2: eth0:NAT RIP:10.0.0.188/24 GW:10.0.0.185
lo VIP:10.0.0.100/32
3.2.2、LVS的网络配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#所有主机禁用iptables和SELinux

#internet主机环境
[root@Rocky ~]#vim /etc/sysconfig/network-scripts/ifcfg-eth0
IPADDR=192.168.10.184
NETMASK=255.255.255.0
GATEWAY=192.168.10.185
:wq
[root@Rocky ~]#nmcli connection reload
[root@Rocky ~]#nmcli connection up eth0
#然后从本地将网卡有NAT模式改为仅主机模式
[root@Rocky ~]#hostnamectl set-hostname internet
[root@internet ~]#hostname -I
192.168.10.184

###########################################################################
#路由器的网络配置
[root@Rocky ~]#hostnamectl set-hostname ROUTER #更改主机名
[root@ROUTER ~]#echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
[root@ROUTER ~]#sysctl -p #重新加载
[root@ROUTER ~]#cd /etc/sysconfig/network-scripts/
[root@ROUTER network-scripts]#ls
backup ifcfg-eth0
[root@ROUTER network-scripts]#cp ifcfg-eth0 ifcfg-eth1 #创建eth1网卡配置文件
[root@ROUTER network-scripts]#ls
backup ifcfg-eth0 ifcfg-eth1
[root@ROUTER network-scripts]#vim ifcfg-eth1 #编辑eth1网卡配置文件
PROXY_METHOD=none
BOOTPROTO=none
NAME=eth1
DEVICE=eth1
IPADDR=192.168.10.185
NETMASK=255.255.255.0
:wq
[root@ROUTER network-scripts]#nmcli connection #查看现在的网卡
NAME UUID TYPE DEVICE
eth0 9aee0c40-97c5-361f-a1e6-9c0b37325423 ethernet eth0
Wired connection 1 32b154a4-7f4d-32f0-aa39-a0cc460bd562 ethernet eth1
eth1 9c92fad9-6ecb-3e6c-eb4d-8a47c6f50c04 ethernet --
[root@ROUTER network-scripts]#nmcli connection delete Wired\ connection\ 1
Connection 'Wired connection 1' (32b154a4-7f4d-32f0-aa39-a0cc460bd562) successfully deleted.
[root@ROUTER network-scripts]#nmcli connection
NAME UUID TYPE DEVICE
eth0 9aee0c40-97c5-361f-a1e6-9c0b37325423 ethernet eth0
eth1 9c92fad9-6ecb-3e6c-eb4d-8a47c6f50c04 ethernet eth1
[root@ROUTER network-scripts]#nmcli connection reload #重新加载
[root@ROUTER network-scripts]#nmcli connection up eth1 #重新挂载eth1生效
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/4)
[root@ROUTER network-scripts]#hostname -I
10.0.0.185 192.168.10.185

###########################################################################
#RS1的网络配置
[root@Rocky ~]#hostnamectl set-hostname web1 #修改主机名
[root@web1 ~]#yum -y install httpd
[root@web1 ~]#systemctl enable --now httpd
[root@web1 ~]#hostname > /var/www/html/index.html #将主机名写入网页内
[root@web1 ~]#cat /var/www/html/index.html
web1
[root@web1 ~]#vim /etc/sysconfig/network-scripts/ifcfg-eth0
GATEWAY=10.0.0.185
:wq
[root@web1 ~]#nmcli connection reload
[root@web1 ~]#nmcli connection up eth0

#RS2 的网络配置
[root@Rocky ~]#hostnamectl set-hostname web2
[root@web2 ~]#yum -y install httpd
[root@web2 ~]#systemctl enable --now httpd
[root@web2 ~]#hostname > /var/www/html/index.html
[root@web2 ~]#cat /var/www/html/index.html
web2
[root@web2 ~]#vim /etc/sysconfig/network-scripts/ifcfg-eth0
GATEWAY=10.0.0.185
:wq
[root@web2 ~]#nmcli connection reload
[root@web2 ~]#nmcli connection up eth0

###########################################################################
#LVS的网络配置
[root@Rocky ~]#hostnamectl set-hostname LVS
[root@LVS ~]#vim /etc/sysconfig/network-scripts/ifcfg-eth0
GATEWAY=10.0.0.185
:wq
[root@LVS ~]#nmcli connection reload
[root@LVS ~]#nmcli connection up eth0
3.2.3、后端RS的IPVS配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#RS1的IPVS配置
[root@web1 ~]#echo 1 >   /proc/sys/net/ipv4/conf/all/arp_ignore
[root@web1 ~]#echo 2 >   /proc/sys/net/ipv4/conf/all/arp_announce
[root@web1 ~]#echo 1 >   /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@web1 ~]#echo 2 >   /proc/sys/net/ipv4/conf/lo/arp_announce
#此为临时生效,想永久生效可将其写入/etc/sysctl.conf文件里
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
net.ipv4.conf.lo.arp_ignore=1
net.ipv4.conf.lo.arp_announce=2
#注意:必须先设置,然后才能添加VIP

#限制响应级别:arp_ignore
0:默认值,表示可使用本地任意接口上配置的任意地址进行响应
1:仅在请求的目标IP配置在本地主机的接收到请求报文的接口上时,才给予响应
#限制通告级别:arp_announce
0:默认值,把本机所有接口的所有信息向每个接口的网络进行通告
1:尽量避免将接口信息向非直接连接网络进行通告
2:必须避免将接口信息向非本网络进行通告

[root@web1 ~]#ifconfig lo:1 10.0.0.100/32 #添加回环ip
[root@web1 ~]#ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet 10.0.0.100/0 scope global lo:1
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:50:56:2c:b4:3c brd ff:ff:ff:ff:ff:ff
inet 10.0.0.187/24 brd 10.0.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::250:56ff:fe2c:b43c/64 scope link
valid_lft forever preferred_lft forever

#RS2的IPVS配置
[root@web2 ~]#echo 1 >   /proc/sys/net/ipv4/conf/all/arp_ignore
[root@web2 ~]#echo 2 >   /proc/sys/net/ipv4/conf/all/arp_announce
[root@web2 ~]#echo 1 >   /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@web2 ~]#echo 2 >   /proc/sys/net/ipv4/conf/lo/arp_announce
[root@web2 ~]#ip a a 10.0.0.100/32 dev lo:1 #此命令也可添加ip
[root@web2 ~]#ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet 10.0.0.100/32 scope global lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:50:56:3c:10:b0 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.188/24 brd 10.0.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::250:56ff:fe3c:10b0/64 scope link
valid_lft forever preferred_lft forever
3.2.4、LVS主机的配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#在LVS上添加VIP
[root@LVS ~]#ip a a 10.0.0.100/32 dev lo label lo:1
[root@LVS ~]#ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet 10.0.0.100/32 scope global lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:50:56:3d:ba:4d brd ff:ff:ff:ff:ff:ff
inet 10.0.0.186/24 brd 10.0.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever

#实现LVS 规则
[root@LVS ~]#yum -y install ipvsadm
[root@LVS ~]#ipvsadm -A -t 10.0.0.100:80 -s rr
[root@LVS ~]#ipvsadm -a -t 10.0.0.100:80 -r 10.0.0.187:80 -g
[root@LVS ~]#ipvsadm -a -t 10.0.0.100:80 -r 10.0.0.188:80 -g
[root@LVS ~]#ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.0.0.100:80 rr
-> 10.0.0.187:80 Route 1 0 0
-> 10.0.0.188:80 Route 1 0 0
3.2.5、测试访问
1
2
3
4
[root@internet ~]#curl 10.0.0.100
web1
[root@internet ~]#curl 10.0.0.100
web2

四、web http协议通信过程,相关技术术语总结

4.1、http协议通信过程

image-20221113094804559

4.2、相关技术术语总结

4.2.1、WEB开发语言

http:Hyper Text Transfer Protocol 应用层协议,默认端口: 80/tcp

html:Hyper Text Markup Language 超文本标记语言,编程语言,主要负责实现页面的结构

CSS:Cascading Style Sheet 层叠样式表, 定义了如何显示(装扮) HTML 元素,比如:字体大小和颜色属性等。样式通常保存在外部的 .css 文件中,用于存放一些HTML文件的公共属性,从而通过仅编辑一个简单的 CSS 文档,可以同时改变站点中所有页面的布局和外观。

Js:javascript,实现网页的动画效果,但实属于静态资源

4.2.2、MIME

MIME : Multipurpose Internet Mail Extensions 多用途互联网邮件扩展

文件 /etc/mime.types ,来自于mailcap包

MIME格式:type/subtype txt html jpg bmp

4.2.3、URI和URL

URI: Uniform Resource Identifier 统一资源标识,分为URL 和 URN

URN:Uniform Resource Naming,统一资源命名

示例: P2P下载使用的磁力链接是URN的一种实现 magnet:?xt=urn:btih:660557A6890EF888666

URL:Uniform Resorce Locator,统一资源定位符,用于描述某服务器某特定资源位置

两者区别:URN如同一个人的名称,而URL代表一个人的住址。换言之,URN定义某事物的身份,而

URL提供查找该事物的方法。URN仅用于命名,而不指定地址。

URL组成

image-20221113182755150

1
2
3
4
5
6
7
8
9
scheme:方案,访问服务器以获取资源时要使用哪种协议
user:用户,某些方案访问资源时需要的用户名
password:密码,用户对应的密码,中间用:分隔
Host:主机,资源宿主服务器的主机名或IP地址
port:端口,资源宿主服务器正在监听的端口号,很多方案有默认端口号
path:路径,服务器资源的本地名,由一个/将其与前面的URL组件分隔
params:参数,指定输入的参数,参数为名/值对,多个参数,用;分隔
query:查询,传递参数给程序,如数据库,用?分隔,多个查询用&分隔
frag:片段,一小片或一部分资源的名字,此组件在客户端使用,用#分隔

五、总结网络IO模型和nginx架构

5.1、网络IO模型

阻塞型、非阻塞型、复用型、信号驱动型、异步

5.1.1、阻塞型I/O模型(blocking IO)

image-20221113183313090

①阻塞IO模型是最简单的I/O模型,用户线程在内核进行IO操作时被阻塞

②用户线程通过系统调用read发起I/O读操作,由用户空间转到内核空间。内核等到数据包到达后,然后将

接收的数据拷贝到用户空间,完成read操作

③用户需要等待read将数据读取到buffer后,才继续处理接收的数据。整个I/O请求的过程中,用户线程是

被阻塞的,这导致用户在发起IO请求时,不能做任何事情,对CPU的资源利用率不够

优点:程序简单,在阻塞等待数据期间进程/线程挂起,基本不会占用 CPU 资源

缺点:每个连接需要独立的进程/线程单独处理,当并发请求量大时为了维护程序,内存、线程切换开销

较大,apache 的prefork使用的是这种模式。

5.1.2、非阻塞型I/O模型(nonblocking IO)

image-20221113183553729

用户线程发起IO请求时立即返回。但并未读取到任何数据,用户线程需要不断地发起IO请求,直到数据

到达后,才真正读取到数据,继续执行。即 “轮询”机制存在两个问题:如果有大量文件描述符都要等,

那么就得一个一个的read。这会带来大量的Context Switch(read是系统调用,每调用一次就得在用户

态和核心态切换一次)。轮询的时间不好把握。这里是要猜多久之后数据才能到。等待时间设的太长,

程序响应延迟就过大;设的太短,就会造成过于频繁的重试,干耗CPU而已,是比较浪费CPU的方式,一

般很少直接使用这种模型,而是在其他IO模型中使用非阻塞IO这一特性。

5.1.3、I/O多路复用型(I/O multiplexing)

①多路复用IO指一个线程可以同时(实际是交替实现,即并发完成)监控和处理多个文件描述符对应各自

的IO,即复用同一个线程

②一个线程之所以能实现同时处理多个IO,是因为这个线程调用了内核中的SELECT,POLL或EPOLL等系统调

用,从而实现多路复用IO

image-20221113183810139

③它的基本原理就是select/poll/epoll这个function会不断的轮询所负责的所有socket,当某个socket有数

据到达了,就通知用户进程。

④当用户进程调用了select,那么整个进程会被block,而同时,kernel会“监视”所有select负责的socket,

当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从

kernel拷贝到用户进程。

优点:可以基于一个阻塞对象,同时在多个描述符上等待就绪,而不是使用多个线程(每个文件描述

符一个线程),这样可以大大节省系统资源

缺点:当连接数较少时效率相比多线程+阻塞 I/O 模型效率较低,可能延迟更大,因为单个连接处

理需要 2 次系统调用,占用时间会有增加

IO多路复用适用如下场合

当客户端处理多个描述符时(一般是交互式输入和网络套接口),必须使用I/O复用

当一个客户端同时处理多个套接字时,此情况可能的但很少出现

当一个服务器既要处理监听套接字,又要处理已连接套接字,一般也要用到I/O复用

当一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用

当一个服务器要处理多个服务或多个协议,一般要使用I/O复用

5.1.4、信号驱动式I/O模型(signal-driven IO)

image-20221113184103536

信号驱动I/O的意思就是进程现在不用傻等着,也不用去轮询。而是让内核在数据就绪时,发送信号通知

进程。

调用的步骤:通过系统调用 sigaction ,并注册一个信号处理的回调函数,该调用会立即返回,然后

主程序可以继续向下执行,当有I/O操作准备就绪,即内核数据就绪时,内核会为该进程产生一个 SIGIO

信号,并回调注册的信号回调函数,这样就可以在信号回调函数中系统调用 recvfrom 获取数据,将用户

进程所需要的数据从内核空间拷贝到用户空间

此模型的优势在于等待数据报到达期间进程不被阻塞。用户主程序可以继续执行,只要等待来自信号处

理函数的通知。

在信号驱动式 I/O 模型中,应用程序使用套接口进行信号驱动 I/O,并安装一个信号处理函数,进程继

续运行并不阻塞

当数据准备好时,进程会收到一个 SIGIO 信号,可以在信号处理函数中调用 I/O 操作函数处理数据。

优点:线程并没有在等待数据时被阻塞,内核直接返回调用接收信号,不影响进程继续处理其他请求因此

可以提高资源的利用率

缺点:信号 I/O 在大量 IO 操作时可能会因为信号队列溢出导致没法通知

5.1.5、异步I/O模型(asynchronous IO)

image-20221113184355631

执行过程:用户进程进行aio_read系统调用之后,无论内核数据是否准备好,都会直接返回给用户进程,然后用户态进程可以去做别的事情。等到socket数据准备好了,内核直接复制数据给进程,然后从内核向进程发送通知。IO两个阶段,进程都是非阻塞的。

信号驱动IO当内核通知触发信号处理程序时,信号处理程序还需要阻塞在从内核空间缓冲区拷贝数据到

用户空间缓冲区这个阶段,而异步IO直接是在第二个阶段完成后,内核直接通知用户线程可以进行后续

操作了

优点:异步 I/O 能够充分利用 DMA 特性,让 I/O 操作与计算重叠

缺点:要实现真正的异步 I/O,操作系统需要做大量的工作。目前 Windows 下通过 IOCP 实现了真正的

异步 I/O,在 Linux 系统下,Linux 2.6才引入,目前 AIO 并不完善,因此在 Linux 下实现高并发网络编

程时以 IO 复用模型模式+多线程任务的架构基本可以满足需求

5.2、Nginx架构

image-20221118084915567

六、nginx总结核心配置和优化

6.1、Nginx的配置文件的组成部分

①主配置文件:nginx.conf

②子配置文件: include conf.d/*.conf

③fastcgi, uwsgi,scgi 等协议相关的配置文件

④mime.types:支持的mime类型,MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据,是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。

MIME参考文档:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_Types

6.2、nginx 配置文件格式说明

1
2
3
4
5
6
7
8
配置文件由指令与指令块构成
每条指令以;分号结尾,指令与值之间以空格符号分隔
可以将多条指令放在同一行,用分号分隔即可,但可读性差,不推荐
指令块以{ }大括号将多条指令组织在一起,且可以嵌套指令块
include语句允许组合多个配置文件以提升可维护性
使用#符号添加注释,提高可读性
使用$符号使用变量
部分指令的参数支持正则表达式

6.3、主配置文件结构:四部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
directive value [value2 ...];
注意
(1) 指令必须以分号结尾
(2) 支持使用配置变量
内建变量:由Nginx模块引入,可直接引用
自定义变量:由用户使用set命令定义,格式: set variable_name value;
引用变量:$variable_name
主配置文件结构:四部分
main block:主配置段,即全局配置段,对http,mail都有效
#事件驱动相关的配置
event {
...
}  
#http/https 协议相关配置段
http {
...
}          
#默认配置文件不包括下面两个块
#mail 协议相关配置段
mail {
...
}    
#stream 服务器相关配置段
stream {
...
}

6.4、全局配置中的必备配置和优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
user nginx nginx; #启动Nginx工作进程的用户和组
worker_processes [number | auto]; #启动Nginx工作进程的数量,一般设为和CPU核心数相同
worker_cpu_affinity 00000001 00000010 00000100 00001000 | auto ; #将Nginx工作进程绑定到指定的CPU核心,默认Nginx是不进行进程绑定的,绑定并不是意味着当前nginx进程独占以一核心CPU,但是可以保证此进程不会运行在其他核心上,这就极大减少了nginx的工作进程在不同的cpu核心上的来回跳转,减少了CPU对进程的资源分配与回收以及内存管理等,因此可以有效的提升nginx服务器的性能。
CPU MASK: 00000001:0号CPU
         00000010:1号CPU
 10000000:7号CPU
#示例:
worker_cpu_affinity 0001 0010 0100 1000;第0号---第3号CPU
worker_cpu_affinity 0101 1010;

#错误日志记录配置,语法:error_log file [debug | info | notice | warn | error | crit | alert | emerg]
#error_log logs/error.log;
#error_log logs/error.log notice;
error_log /apps/nginx/logs/error.log error;

#pid文件保存路径
pid       /apps/nginx/logs/nginx.pid;

worker_priority 0; #工作进程优先级,-20~20(19)
worker_rlimit_nofile 65536; #所有worker进程能打开的文件数量上限,包括:Nginx的所有连接(例如与代理服务器的连接等),而不仅仅是与客户端的连接,另一个考虑因素是实际的并发连接数不能超过系统级别的最大打开文件数的限制.最好与ulimit -n 或者limits.conf的值保持一致,

daemon off;  #前台运行Nginx服务用于测试、或者以容器运行时,需要设为off
master_process off|on; #是否开启Nginx的master-worker工作模式,仅用于开发调试场景,默认为on

events {
  worker_connections  65536;  #设置单个工作进程的最大并发连接数
  use epoll; #使用epoll事件驱动,Nginx支持众多的事件驱动,比如:select、poll、epoll,只能设置在events模块中设置。
  accept_mutex on; #on为同一时刻一个请求轮流由worker进程处理,而防止被同时唤醒所有worker,避免多个睡眠进程被唤醒的设置,默认为off,新请求会唤醒所有worker进程,此过程也称为"惊 群",因此nginx刚安装完以后要进行适当的优化。建议设置为on
  multi_accept on; #on时Nginx服务器的每个工作进程可以同时接受多个新的网络连接,此指令默认为off,即默认为一个工作进程只能一次接受一个新的网络连接,打开后几个同时接受多个。建议设置为on
}

6.5、http 协议配置中的必备配置和优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
http {
  include       mime.types; #导入支持的文件类型,是相对于/apps/nginx/conf的目录
  default_type application/octet-stream; #除mime.types中文件类型外,设置其它文件默认类型,访问其它类型时会提示下载不匹配的类型文件
 
#日志配置部分
   #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
   #                 '$status $body_bytes_sent "$http_referer" '
   #                 '"$http_user_agent" "$http_x_forwarded_for"';
   #access_log logs/access.log main;
   
#自定义优化参数
  sendfile       on;
   #tcp_nopush     on; #在开启了sendfile的情况下,合并请求后统一发送给客户端,必须开启sendfile
   #tcp_nodelay   off; #在开启了keepalived模式下的连接是否启用TCP_NODELAY选项,当为off时,延迟0.2s发送,默认On时,不延迟发送,立即发送用户响应报文。
   #keepalive_timeout 0;
  keepalive_timeout  65 65; #设置会话保持时间,第二个值为响应首部:keepAlived:timeout=65,可以和第一个值不同
   #gzip on; #开启文件压缩
   
  server {
      listen       80; #设置监听地址和端口
      server_name localhost; #设置server name,可以以空格隔开写多个并支持正则表达式,如:*.magedu.com www.magedu.* ~^www\d+\.magedu\.com$ default_server
       #charset koi8-r; #设置编码格式,默认是俄语格式,建议改为utf-8
       #access_log logs/host.access.log main;
      location / {
          root   html;
          index index.html index.htm;
      }
     
       #error_page 404             /404.html;
       # redirect server error pages to the static page /50x.html
       #
      error_page   500 502 503 504 /50x.html; #定义错误页面
      location = /50x.html {
          root   html;
      }
     
       # proxy the PHP scripts to Apache listening on 127.0.0.1:80
       #
       #location ~ \.php$ { #以http的方式转发php请求到指定web服务器
       #   proxy_pass   http://127.0.0.1;
       #}
       
       # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
       #
       #location ~ \.php$ { #以fastcgi的方式转发php请求到php处理
       #   root           html;
       #   fastcgi_pass   127.0.0.1:9000;
       #   fastcgi_index index.php;
       #   fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
       #   include       fastcgi_params;
       #}
       
         # deny access to .htaccess files, if Apache's document root
       # concurs with nginx's one
       #
       #location ~ /\.ht { #拒绝web形式访问指定文件,如很多的网站都是通过.htaccess文件来改变自己的重定向等功能。
       #   deny all;
       #}
      location ~ /passwd.html {
          deny all;
      }
  }
 
   # another virtual host using mix of IP-, name-, and port-based configuration
   #
   #server { #自定义虚拟server
   #   listen       8000;
   #   listen       somename:8080;
   #   server_name somename alias another.alias;
   
   #   location / {
   #       root   html;
   #       index index.html index.htm; #指定默认网页文件,此指令由
ngx_http_index_module模块提供
   #   }
   #}
   
   # HTTPS server
   #
   #server { #https服务器配置
   #   listen       443 ssl;
   #   server_name localhost;
   
   #   ssl_certificate     cert.pem;
   #   ssl_certificate_key cert.key;
   
   #   ssl_session_cache   shared:SSL:1m;
   #   ssl_session_timeout 5m;
   
   #   ssl_ciphers HIGH:!aNULL:!MD5;
   #   ssl_prefer_server_ciphers on;
   
   #   location / {
   #       root   html;
   #       index index.html index.htm;
   #   }
   #}

七、使用脚本完成一键编译安装nginx任意版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/bin/bash
SRC_DIR=/usr/local/src
NGINX_URL=http://nginx.org/download/
NGINX_FILE=nginx-1.20.2
TAR=.tar.gz
NGINX_INSTALL_DIR=/apps/nginx
CPUS=`lscpu |awk '/^CPU\(s\)/{print $2}'`
. /etc/os-release

os_type () {
awk -F'[ "]' '/^NAME/{print $2}' /etc/os-release
}

os_version () {
awk -F'"' '/^VERSION_ID/{print $2}' /etc/os-release
}

check () {
[ -e ${NGINX_INSTALL_DIR} ] && { color "nginx 已安装,请卸载后再安装" 1; exit; }
cd ${SRC_DIR}
if [ -e ${NGINX_FILE}${TAR} ];then
color "相关文件已准备好" 0
else
color '开始下载 nginx 源码包' 0
wget ${NGINX_URL}${NGINX_FILE}${TAR}
[ $? -ne 0 ] && { color "下载 ${NGINX_FILE}${TAR}文件失败" 1; exit; }
fi
}

install () {
color "开始安装 nginx" 0
if id nginx &> /dev/null;then
color "nginx 用户已存在" 1
else
useradd -s /sbin/nologin -r nginx
color "创建 nginx 用户" 0
fi
color "开始安装 nginx 依赖包" 0
if [ $ID == "centos" ] ;then
if [[ $VERSION_ID =~ ^7 ]];then
yum -y -q install make gcc pcre-devel openssl-devel zlib-devel perl-ExtUtils-Embed
elif [[ $VERSION_ID =~ ^8 ]];then
yum -y -q install make gcc-c++ libtool pcre pcre-devel zlib zlib-devel openssl openssl-devel perl-ExtUtils-Embed
else
color '不支持此系统!' 1
exit
fi
elif [ $ID == "rocky" ];then
yum -y -q install make gcc-c++ libtool pcre pcre-devel zlib zlib-devel openssl openssl-devel perl-ExtUtils-Embed
else
apt update &> /dev/null
apt -y install make gcc libpcre3 libpcre3-dev openssl libssl-dev zlib1g-dev &> /dev/null
fi
cd $SRC_DIR
tar xf ${NGINX_FILE}${TAR}
NGINX_DIR=`echo ${NGINX_FILE}${TAR}| sed -nr 's/^(.*[0-9]).*/\1/p'`
cd ${NGINX_DIR}
./configure --prefix=${NGINX_INSTALL_DIR} --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
make -j $CPUS && make install
[ $? -eq 0 ] && color "nginx 编译安装成功" 0 || { color "nginx 编译安装失败,退出!" 1 ;exit; }
echo "PATH=${NGINX_INSTALL_DIR}/sbin:${PATH}" > /etc/profile.d/nginx.sh
cat > /lib/systemd/system/nginx.service <<EOF
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=${NGINX_INSTALL_DIR}/logs/nginx.pid
ExecStartPre=/bin/rm -f ${NGINX_INSTALL_DIR}/logs/nginx.pid
ExecStartPre=${NGINX_INSTALL_DIR}/sbin/nginx -t
ExecStart=${NGINX_INSTALL_DIR}/sbin/nginx
ExecReload=/bin/kill -s HUP \$MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
LimitNOFILE=100000

[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now nginx &> /dev/null
systemctl is-active nginx &> /dev/null || { color "nginx 启动失败,退出!" 1 ; exit; }
color "nginx 安装完成" 0
}

check
install

八、任意编译一个第3方nginx模块,并使用

nginx-module-vts模块实现流量监控

1
https://github.com/vozlt/nginx-module-vts

image-20221127183749418

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[root@Rocky ~]#cd /usr/local/src
[root@Rocky src]#wget https://github.com/vozlt/nginx-module-vts/archive/refs/tags/v0.2.1.tar.gz
[root@Rocky src]#tar xf v0.2.1.tar.gz
[root@Rocky src]#ls
nginx-1.22.1 nginx-1.22.1.tar.gz nginx-module-vts-0.2.1 v0.2.1.tar.gz
[root@Rocky src]#cd nginx-1.22.1/
[root@Rocky nginx-1.22.1]#nginx -V #查看Nginx已安装的模块
nginx version: nginx/1.23.2
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-10) (GCC)
built with OpenSSL 1.1.1k FIPS 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
#添加新模块--add-module=/usr/local/src/nginx-module-vts-0.2.1
[root@Rocky nginx-1.22.1]#./configure --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module --add-module=/usr/local/src/nginx-module-vts-0.2.1
[root@Rocky nginx-1.22.1]#make -j 2 && make install

http {
......
vhost_traffic_status_zone; #添加此行
......
server {
......
location /status {
vhost_traffic_status_display;
vhost_traffic_status_display_format html;
}
......
}
}
:wq
[root@Rocky nginx-1.20.2]#systemctl restart nginx

添加监控模块前

image-20221127192944905

添加监控模块后

image-20221127192850248


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!