第八周
1、总结 Redis多种安装方法和内核参数优化
一、apt安装redis
root@ubuntu2004:~# apt install -y redis
root@ubuntu2004:~# systemctl enable --now redis-server
root@ubuntu2004:~# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 127.0.0.1:6010 0.0.0.0:*
LISTEN 0 511 127.0.0.1:6379 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:111 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 128 [::1]:6010 [::]:*
LISTEN 0 511 [::1]:6379 [::]:*
LISTEN 0 4096 [::]:111 [::]:*
root@ubuntu2004:~# redis-cli ping
PONG
二、二进制编译安装Redis
下载二进制包
http://download.redis.io/releases/
[root@Rocky8 ~]# ll
total 3312
-rw-------. 1 root root 1297 Aug 8 17:02 anaconda-ks.cfg
drwxr-xr-x. 2 root root 43 Aug 9 17:22 date
-rw-r--r--. 1 root root 3384816 Nov 2 16:24 redis-7.2.3.tar.gz
安装依赖包
[root@Rocky8 ~]# yum install -y gcc systemd-devel
解压
[root@Rocky8 ~]# tar xvf redis-7.2.3.tar.gz redis-7.2.3/
编译安装
[root@Rocky8 redis-7.2.3]# make -j 2 USE_SYSTEMD=yes PREFIX=/apps/redis install
配置环境变量
[root@Rocky8 redis-7.2.3]# echo 'PATH=/apps/redis/bin:$PATH' > /etc/profile.d/redis.sh
[root@Rocky8 redis-7.2.3]# tree /apps/redis/
/apps/redis/
└── bin
├── redis-benchmark
├── redis-check-aof -> redis-server
├── redis-check-rdb -> redis-server
├── redis-cli
├── redis-sentinel -> redis-server
└── redis-server
准备相关目录和文件
[root@Rocky8 redis-7.2.3]# mkdir /apps/redis/{etc,log,data,run}
[root@Rocky8 redis-7.2.3]# cp redis.conf /apps/redis/etc/
前台启动redis
[root@Rocky8 redis-7.2.3]# redis-server /apps/redis/etc/redis.conf
[root@Rocky8 ~]# 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 128 127.0.0.1:6379 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 128 [::1]:6379 [::]:*
2、总结 Redis 常见指令和数据类型
一、Redis键(key)
● keys *:查看当前库的所有key(匹配:keys *1)
● exists key:判断某个key是否存在
● type key:查看你的key是什么类型
● del key:删除指定的key数据
● unlink key:根据value选择非阻塞删除(仅将keys从keyspace元数据中删除,真正的删除会在后续异步操作)
● expire key time:给指定的key设置过期时间
● ttl key:查看还有多少秒过期,-1表示永不过期,-2表说已过期
● select index: 命令切换数据库
● dbsize:查看当前数据库的key数量
● flushdb:清空当前库
● flushall:通杀全部库
二、String类型
1.简介
● String是Redis最基本的类型,一个key对应一个value。
● String类型是二进制安全的。意味着Redis的string可以包含任何数据。比如jpg或者序列化的对象
●String类型是Redis最基本的数据类型,一个Redis中字符串value最多可以是512M
2.常用命令
● set
● get
● append
● strlen
● setnx
● incr
● decr
● incrby/decrby
● mset
● mget
● msetnx
● getrange
● setrange
● setex
● getset
3.数据结构
String数据结构为简单动态字符串(SDS),是可以修改的字符串,内部结构实现上类似于Java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配
三、List列表
1.简介
单键多值,Redis列表是简单的字符串列表,按照插入顺序排序,可以添加一个元素到列表的头部( 左边)或者尾部(右边)。
它的底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差
2.常用命令
● lpush/rpush
● lpop/rpop
● rpoplpush
● lrange
● lindex
● llen
● linsert
● lrem
● lset
3.数据结构
List的数据结构为快速链表quickList。首先在列表元素较少的情况下会使用一块连续的内存存储,这个结构是ziplist,也即是压缩列表,它将所有的元素紧挨着一起存储,分配的一块连续的内存。
当数据量比较多的时候才会改成quickList
Redis将链表和ziplist结合起来组成了quicklist。也就是将多个ziplist使用双向指针串起来使用。这样既满足了快速的插入性能,又不会出现太大的空间冗余。
四、Set集合
1.简介
Set对外提供的功能与lisst类似是一个列表的功能,set可以自动排重,需要用列表数据,又不希望出现重复数据时,set是一个很好的选择。set提供了判断某个元素是否在set集合内的重要接口。
Redis的set是string类型的无序集合。它底层其实是一个value为null的hash表,所以添加、删除、查找的复杂度都是O(1)。一个算法,随着数据的增加,执行时间长短,如果是O(1),数据增加,查找数据的时间不变。
2.常用命令
● sadd
● smembers
● smember
● scard
● srem
● spop
● srandmember
● smove
● sinter
● sunion
● sdiff
3.数据结构
set数据是dict字典,字典是用哈希表实现的。
Java中的HashSet的内部实现使用的是HashMap,只不过所有的value都指向同一个对象。Redis的Set结构也是一样,它的内部也使用hash结构,所有的value都指向同一个内部值
五、Hash哈希
1.简介
● Redis hash是一个键值对集合。
● Redis hash是一个string类型的field和value的映射表,hash特别适用用于存储对象,类似Java里面的Map<Strinf,Object>。
2.常用命令
● hset
● hget
● hmset
● hexists
● hkeys
● hvals
● hincrby
● hsetnx
3.数据结构
Hash类型对应的数据结构是两种:ziplist(压缩列表),hashtable(哈希表),当field-value长度较短且个数较少时,使用ziplist,否则使用hashtable
六、Zset有序集合
1.简介
Redis有序集合zset与普通集合set非常相似,是一个没有重复元素的字符串集合。有序集合zset的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高分的方式
排序集合中的成员。集合的成员是唯一的,但是评分可以是重复的。因为元素是有序的所以你也可以很快的根据评分(score),或者次序(position)来获取一个范围的元素。访问有序集合的中间
元素也是非常快的。
2.常用命令
● zadd
● zrange
● zrangebyscore key minmax [withscores] [limit offset count]:返回有序集合key中,所以score值介于min和max之间(包括等于min或max)的成员,有序集合成员按score值递增次序排序
● zrangebyscore key minmax [withscores] [limit offset count]:同上,改为从大到小排列
● zincrby
● zrem
● zcount
● zrank
3.数据结构
Zset是Redis提供的一个特别的数据结构,一方面它等价于java的数据结构Map<String,Double>,可以给每一个元素赋予一个权重score,另一方面它又类似于TreeSet,内部的元素会按照权重
score进行排序,可以得到每个元素的名次,还可以通过score的范围来获取元素的列表。
zset底层使用了两个数据结构。
(1)hash,hash的作业就是关联元素value和权重score,保障元素value的唯一性,可以通过元素value找到相应的score值。
(2)跳跃表,跳跃表的目的在于给元素value排序,根据score的范围获取元素列表
3、总结 哨兵机制实现原理,并搭建主从哨兵集群。
原理
哨兵是一个分布式系统,可以在一个架构中运行多个哨兵进程,这些进程使用流言协议(gossip protocols)来传播Master是否下线的信息,并使用投票协议(agreement protocols)来决定是否执行自动故障迁移,以及选择哪个Slave作为新的Master。哨兵模式的具体工作原理如下:
1、心跳机制:
(1)Sentinel 与 Redis Node:Redis Sentinel 是一个特殊的 Redis 节点。在哨兵模式创建时,需要通过配置指定 Sentinel 与 Redis Master Node 之间的关系,然后 Sentinel 会从主节点上获取所有从节点的信息,之后 Sentinel 会定时向主节点和从节点发送 info 命令获取其拓扑结构和状态信息。
(2)Sentinel与Sentinel:基于 Redis 的订阅发布功能, 每个 Sentinel 节点会向主节点的 sentinel:hello 频道上发送该 Sentinel 节点对于主节点的判断以及当前 Sentinel 节点的信息 ,同时每个 Sentinel 节点也会订阅该频道, 来获取其他 Sentinel 节点的信息以及它们对主节点的判
2、 判断主主机是否下线
3、 基于Raft算法选举领头sentinel
4、 故障转移:
Sntinel(哨兵)是Redis 的高可用性解决方案:由一个或多个Sentinel 实例 组成的Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。
原理:当主节点出现故障时,由Redis Sentinel自动完成故障发现和转移,并通知应用方,实现高可用性
(最少一主一从 设置哨兵高可用 就是从主机一直监控主主机 检测住住挂了 就从主机就上位了 )
环境准备
主节点:10.0.0.14
从节点:10.0.0.24 10.0.0.34
主c从节点配置
[root@Rocky8 ~]# cat /etc/redis.conf
bind 0.0.0.0
requirepass 123456
masterauth 123456
所有从节点配置
[root@Rocky8 ~]# echo " REPLICAOF 10.0.0.14 6379" /etc/redis.conf
[root@Rocky8 ~]# systemctl restart redis
验证
master:
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=10.0.0.24,port=6379,state=online,offset=1372,lag=1
slave1:ip=10.0.0.34,port=6379,state=online,offset=1372,lag=0
master_replid:aac5fadc3e08e1449514c33ba07164adfb356cc7
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1372
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1372
slave(10.0.0.24/34)
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:10.0.0.14
master_port:6379
master_link_status:up
master_last_io_seconds_ago:9
master_sync_in_progress:0
slave_repl_offset:1442
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:aac5fadc3e08e1449514c33ba07164adfb356cc7
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1442
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1442
##哨兵配置
[root@Rocky8 /]# vi /etc/redis-sentinel.conf
bind 0.0.0.0
默认端口
port 26379
#日志文件
logfile "/var/log/redis/sentinel.log"
#指定主机IP地址和端口
sentinel monitor mymaster 10.0.0.14 6379 2
#链接Redus客户端需要提供密码
sentinel auth-pass mymaster 123456
#设置主机多长时间无响应,则认为挂了
sentinel down-after-milliseconds mymaster 3000
#设置后台启动
daemonize:yes
[root@Rocky8 /]# systemctl enable --now redis-sentinel.service
其他两个也设置一样
验证:
[root@Rocky8 /]# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:26379 0.0.0.0:*
LISTEN 0 128 0.0.0.0:6379 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:6379 [::]:*
LISTEN 0 128 [::]:22 [::]:*
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.0.0.14:6379,slaves=2,sentinels=3
127.0.0.1:26379>
4、总结redis cluster工作原理,并搭建集群实现扩缩容。
- redis cluster可以实现对节点的灵活上下线控制
搭建集群
环境:
10.0.0.4 ---10.0.0.34
10.0.0.14 ---10.0.0.44
10.0.0.24 ---10.0.0.54
#六台机器都安装redis,并且设置开机自启动
[root@Rocky8 ~]# yum install redis -y
[root@Rocky8 ~]# systemctl enable --now redis
#修改redis的配置文件
[root@Rocky8 ~]# vi /etc/redis.conf
bind 0.0.0.0
masterauth 123456
requirepass 123456
#开启集群
cluster-enabled yes
#集群状态数据文件
cluster-config-file nodes-6379.conf
#防止一个节点不可用,导致整个集群不可用
cluster-require-full-coverage no
#全部重启redis服务
[root@Rocky8 ~]# systemctl restart redis
#创建集群
[root@Rocky8 ~]# redis-cli -a 123456 --cluster create 10.0.0.4:6379 10.0.0.14:6379 10.0.0.24:6379 10.0.0.34:6379 10.0.0.44:6379 10.0.0.54:6379 --cluster-replicas 1
#验证集群
[root@Rocky8 ~]# redis-cli -a 123456 -c info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.34,port=6379,state=online,offset=2240,lag=0
master_replid:b92ed266361907b0af77d8000c6a4f38b870e0b1
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2240
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2240
[root@Rocky8 ~]# redis-cli -a 123456 cluster nodes
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
ccce4feb7f81c7f0b3b645a70eb6546fcd94e55b 10.0.0.24:6379@16379 master - 0 1699865036551 3 connected 10923-16383
3894b5d686cfe6c9fb1d15237c5abfaa0d360684 10.0.0.4:6379@16379 myself,master - 0 1699865034000 1 connected 0-5460
0274b8d0df1639a2bd8170f20b00cd6f05ccae53 10.0.0.34:6379@16379 slave 3894b5d686cfe6c9fb1d15237c5abfaa0d360684 0 1699865034000 4 connected
210437d8b7f0453795bddb0dfbe404bd26a17dd8 10.0.0.14:6379@16379 master - 0 1699865037559 2 connected 5461-10922
38c606402924e5fe5bbe3cb311a610c84158566e 10.0.0.44:6379@16379 slave 210437d8b7f0453795bddb0dfbe404bd26a17dd8 0 1699865035000 5 connected
830d19ed7c59a59f2c9b74ae9491487b9acc94bd 10.0.0.54:6379@16379 slave ccce4feb7f81c7f0b3b645a70eb6546fcd94e55b 0 1699865036000 6 connected
[root@Rocky8 ~]# 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
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:1698
cluster_stats_messages_pong_sent:1539
cluster_stats_messages_sent:3237
cluster_stats_messages_ping_received:1534
cluster_stats_messages_pong_received:1698
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:3237
#扩容
环境:10.0.0.64 10.0.0.74
[root@Rocky8 ~]# yum install redis -y
[root@Rocky8 ~]# systemctl enable --now redis
#修改redis的配置文件
[root@Rocky8 ~]# vi /etc/redis.conf
bind 0.0.0.0
masterauth 123456
requirepass 123456
#开启集群
cluster-enabled yes
#集群状态数据文件
cluster-config-file nodes-6379.conf
#防止一个节点不可用,导致整个集群不可用
cluster-require-full-coverage no
#全部重启redis服务
[root@Rocky8 ~]# systemctl restart redis
#增加节点
[root@Rocky8 ~]# redis-cli -a 123456 --cluster add-node 10.0.0.64:6379 10.0.0.4:6379
#重新分配槽位
[root@Rocky8 ~]# redis-cli -a 123456 --cluster reshard 10.0.0.64:6379
#为扩容的主节点增加slaves
[root@Rocky8 ~]# redis-cli -a 123456 --cluster add-node 10.0.0.74:6379 10.0.0.4:6379 --cluster-slave --cluster-id ccce4feb7f81c7f0b3b645a70eb6546fcd94e55b
#缩容
[root@Rocky8 ~]# redis-trib.rb reshard 10.0.0.100:6379
slot已经迁移完成后删除节点
Redis提供了cluster forget{downNodeId}命令来通知其他节点忘记下线节点,当节点接收到cluster forget {down NodeId}命令后,会把nodeId指定的节点加入到禁用列表中,在禁用列表内的节点不再与其他节点发送消息,禁用列表有效期是60秒,超过60秒节点会再次参与消息交换。也就是说当第一次forget命令发出后,我们有60秒的时间让集群内的所有节点忘记下线节点
线上操作不建议直接使用cluster forget命令下线节点,这需要跟大量节点进行命令交互,建议使用redis- trib.rb del-node {host:port} {downNodeId}命令
另外,先下线slave,再下线master可以防止不必要的数据复制
5、总结 LVS的NAT和DR模型工作原理,并完成DR模型实战。
LVS-NAT模型的工作原理
LVS(Linux Virtual Server)是一种开源的负载均衡软件,在其NAT模式下,工作原理如下:
- 客户端发送请求到LVS的VIP(Virtual IP)地址。
- 请求到达LVS后,LVS根据预定义的负载均衡算法,选择一个服务器作为后端服务器。
- LVS通过修改数据包的目标IP和端口,将请求转发给选中的后端服务器。
- 后端服务器处理请求并将响应返回给LVS。
- LVS再次修改数据包的源IP和端口,将后端服务器的响应发送回给客户端。
在NAT模式下,LVS使用网络地址转换(NAT)技术,通过修改数据包的源IP和目标IP来实现负载均衡和服务转发。客户端和后端服务器之间的通信经过LVS进行代理,这样后端服务器就可以感知不到客户端的真实IP地址,而是只见到LVS的IP地址。
总结来说,LVS的NAT模式通过使用网络地址转换技术,将客户端的请求转发给后端服务器,并将响应返回给客户端,实现负载均衡和透明的服务转发。
LVS-DR模型的工作原理
其工作原理如下:
- 在LVS-DR模型中,客户端将请求发送到LVS集群的VIP(Virtual IP)地址。
- LVS收到请求后,根据预定义的负载均衡算法选择一个后端服务器,并将请求的数据包通过IP路由方式转发给该后端服务器。
- 后端服务器接收到请求后,处理请求并生成响应,将响应直接发送回给客户端,而不是经过LVS。
- 同时,后端服务器需要将响应的源IP地址修改为LVS的VIP地址,以确保客户端接收到的响应可以正确返回给LVS。
在LVS-DR模型中,LVS并不实际处理请求和响应的数据包,而是将原始数据包直接传递给后端服务器进行处理。这种方式可以减轻LVS的工作负载,提高性能和处理效率。
在LVS-DR模型中,后端服务器需要与LVS集群处于同一子网,并且需要进行特定的网络配置,例如ARP(Address Resolution Protocol)解决冲突和IP地址仿冒等。此外,LVS集群中的所有服务器应保持相同的状态,以便可以在它们之间有效地分配请求。
总结来说,LVS-DR模型通过直接路由方式将请求数据包传递给后端服务器处理,并将响应直接发送回客户端,以提高性能和处理效率,同时要求后端服务器进行特定的网络配置。
LVS-DR模型案例
LVS-DR模型案例
环境:
一台:internet client:192.168.10.10/24
一台:lvs :10.0.0.4/24 GW:10.0.0.200
一台:ROUTER
eth0:10.0.0.200
eth1:192.168.10.200
两台:RS
RS1:10.0.0.14 GW:10.0.0.200
RS2:10.0.0.24 GW:10.0.0.200
配置过程
internet环境
网络配置:
[root@Rocky8 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.10.200 0.0.0.0 UG 100 0 0 ens160
192.168.10.0 0.0.0.0 255.255.255.0 U 100 0 0 ens160
[root@Rocky8 ~]# ping 10.0.0.14
PING 10.0.0.14 (10.0.0.14) 56(84) bytes of data.
64 bytes from 10.0.0.14: icmp_seq=1 ttl=63 time=0.519 ms
64 bytes from 10.0.0.14: icmp_seq=2 ttl=63 time=0.504 ms
^C
--- 10.0.0.14 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1062ms
rtt min/avg/max/mdev = 0.504/0.511/0.519/0.023 ms
[root@Rocky8 ~]# ping 10.0.0.4
PING 10.0.0.4 (10.0.0.4) 56(84) bytes of data.
64 bytes from 10.0.0.4: icmp_seq=1 ttl=63 time=0.458 ms
^C
--- 10.0.0.4 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.458/0.458/0.458/0.000 ms
路由器ROUTER配置
[root@Rocky8 ~]# echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
[root@Rocky8 ~]# sysctl -p
net.ipv4.ip_forward = 1
[root@Rocky8 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.200 0.0.0.0 UG 101 0 0 ens224
192.168.10.0 0.0.0.0 255.255.255.0 U 100 0 0 ens160
RS1网络配置:
root@Rocky8 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.200 0.0.0.0 UG 100 0 0 ens160
10.0.0.0 0.0.0.0 255.255.255.0 U 100 0 0 ens160
[root@Rocky8 ~]# ping 192.168.10.10 -c1
PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
64 bytes from 192.168.10.10: icmp_seq=1 ttl=63 time=0.517 ms
--- 192.168.10.10 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.517/0.517/0.517/0.000 ms
[root@Rocky8 ~]#
RS2网络配置:
[root@Rocky8 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.200 0.0.0.0 UG 100 0 0 ens160
10.0.0.0 0.0.0.0 255.255.255.0 U 100 0 0 ens160
[root@Rocky8 ~]# ping 192.168.10.10 -c1
PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
64 bytes from 192.168.10.10: icmp_seq=1 ttl=63 time=0.430 ms
--- 192.168.10.10 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.430/0.430/0.430/0.000 ms
[root@Rocky8 ~]#
LVS网络配置
[root@Rocky8 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.200 0.0.0.0 UG 100 0 0 ens160
10.0.0.0 0.0.0.0 255.255.255.0 U 100 0 0 ens160
[root@Rocky8 ~]# ping 192.168.10.10 -c1
PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
64 bytes from 192.168.10.10: icmp_seq=1 ttl=63 time=0.413 ms
--- 192.168.10.10 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.413/0.413/0.413/0.000 ms
[root@Rocky8 ~]#
后端RS的IPVS配置
RS1:
[root@Rocky8 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@Rocky8 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
[root@Rocky8 ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@Rocky8 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
[root@Rocky8 ~]# ifconfig lo:1 10.0.0.100/32
[root@Rocky8 ~]# ip ad
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: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:27:ca:a5 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.14/24 brd 10.0.0.255 scope global noprefixroute ens160
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe27:caa5/64 scope link noprefixroute
valid_lft forever preferred_lft forever
RS2:
[root@Rocky8 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@Rocky8 ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@Rocky8 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
[root@Rocky8 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
[root@Rocky8 ~]# ifconfig lo:1 10.0.0.100/32
[root@Rocky8 ~]# ip ad
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: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:1e:ec:77 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.24/24 brd 10.0.0.255 scope global noprefixroute ens160
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe1e:ec77/64 scope link noprefixroute
valid_lft forever preferred_lft forever
LVS:
[root@Rocky8 ~]# ifconfig lo:1 10.0.0.100/32
[root@Rocky8 ~]# ipvsadm -A -t 10.0.0.100:80 -s rr
[root@Rocky8 ~]# ipvsadm -a -t 10.0.0.100:80 -r 10.0.0.24:80 -g
[root@Rocky8 ~]# ipvsadm -a -t 10.0.0.100:80 -r 10.0.0.14:80 -g
[root@Rocky8 ~]# 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.14:80 Route 1 0 0
-> 10.0.0.24:80 Route 1 0 0
测试验证
[root@Rocky8 ~]# curl 10.0.0.100
10.0.0.14
[root@Rocky8 ~]# curl 10.0.0.100
10.0.0.24
[root@Rocky8 ~]# curl 10.0.0.100
10.0.0.14
[root@Rocky8 ~]# curl 10.0.0.100
10.0.0.24
[root@Rocky8 ~]# curl 10.0.0.100
10.0.0.14
[root@Rocky8 ~]# curl 10.0.0.100
10.0.0.24
[root@Rocky8 ~]# curl 10.0.0.100
10.0.0.14
[root@Rocky8 ~]# curl 10.0.0.100
10.0.0.24
[root@Rocky8 ~]# curl 10.0.0.100
10.0.0.14
[root@Rocky8 ~]# curl 10.0.0.100
10.0.0.24
6、总结 http协议的通信过程详解
HTTP(Hyper Text Transfer Protocol)是一种用于传输超文本数据的协议,通常使用 TCP/IP 进行通信。
HTTP 协议的通信过程一般包括以下步骤:
- 建立连接:客户端与服务器建立 TCP 连接。可以是新开一个连接,也可以是重用一个现有的连接。
- 发送请求:客户端向服务器发送 HTTP 请求,请求包括请求方法、URL、HTTP 版本、HTTP 头信息等。
- 服务器处理请求:服务器收到客户端的请求后,处理请求并返回相应的 HTTP 响应,响应包括 HTTP 版本、状态码、状态消息、HTTP 头信息以及实体内容等。
- 数据传输:服务器向客户端传输响应数据,客户端接收数据并进行处理。
- 关闭连接:客户端与服务器断开 TCP 连接。
总的来说,HTTP 协议是一个“请求-响应”协议,客户端通过发送请求来要求服务器做出响应。在通信过程中发送的数据都是以“文本”形式进行传输的,因此 HTTP 协议的通信过程具有简单、灵活、易于调试等特点。
在 HTTP 协议的请求和响应中,还有一些常见的要素,如下:
请求方法:HTTP 定义了几种不同的方法(也称为动作或操作),可以用来请求服务器执行某些操作,如 GET、POST、PUT、DELETE 等。
URL:Uniform Resource Locator(统一资源定位器),即 HTTP 请求的地址,表示要访问的资源在网络上的位置。
HTTP 版本:HTTP 协议有很多版本,最常用的是 HTTP/1.1 和 HTTP/2。
状态码:HTTP 响应的第一行就是状态行,其中包括一个状态码和一个状态消息。状态码是一个 3 位数,用于描述服务器对请求的处理结果。
请求头:客户端向服务器发送请求时,可以在请求头中添加一些附加信息,比如 Accept、User-Agent、Referer 等。
响应头:服务器向客户端发送响应时,同样可以在响应头中添加一些附加信息,比如 Content-Type、Last-Modified、Cache-Control 等。
实体内容:HTTP 响应的实体内容指的是服务器返回的文本、图片、视频、音频等数据。实体内容的格式由 Content-Type 指定,可能是 HTML、XML、JSON 等格式。
以上是 HTTP 协议的一些重要要素和基本通信过程。在实际的网络应用中,HTTP 协议的具体实现会更加复杂,需要考虑诸如缓存、压缩、验证码、安全认证等问题。
7、总结网络IO模型和nginx架构
总结网络IO模型
网络IO模型是指在网络通信中,对于输入(接收数据)和输出(发送数据)的处理方式的不同模型。常见的网络IO模型包括:
- 阻塞IO模型(Blocking IO):在这种模型下,当进行网络IO操作时,应用程序会被阻塞,直到数据的接收或发送操作完成。这意味着应用程序在等待IO操作完成期间无法执行其他任务。
- 非阻塞IO模型(Non-blocking IO):这种模型下,应用程序会周期性地检查数据是否可用,如果数据尚未准备好,应用程序可以继续执行其他任务,而不会被阻塞。在非阻塞模型中,应用程序需要不断地轮询(Polling)来检查IO操作的状态。
- 多路复用IO模型(Multiplexing IO):多路复用模型使用特定的系统调用(例如select、poll和epoll)来检查多个IO操作的状态。这允许应用程序同时等待多个IO操作,而不需要使用多线程或多进程。
- 信号驱动IO模型(Signal-driven IO):在这种模型中,应用程序会通过注册信号处理函数来处理特定的IO事件。当一个IO事件发生时,操作系统会发送一个信号给应用程序,应用程序在接收到信号后进行相应的处理。
- 异步IO模型(Asynchronous IO):异步IO模型最大程度地提高了并发性,应用程序可以在等待IO操作完成之前继续处理其他任务。在异步IO模型中,应用程序发起IO请求后可以立即返回,并通过回调函数或事件通知的方式得到IO操作完成的通知。
实际上,以上模型并不是相互独立的,而是包含了一定的层次关系。在不同的操作系统和编程语言中,可能会使用不同的网络IO模型来满足不同的需求。
nginx架构
NGINX 是一款高性能的开源 Web 服务器和反向代理服务器。它的架构采用了事件驱动和异步非阻塞的模式,具有较高的并发处理能力和低的内存消耗。以下是 NGINX 的架构要点:
- Master-Worker 架构:NGINX 采用主从(Master-Worker)架构。Master 进程负责管理 Worker 进程,包括启动、停止以及向 Worker 进程分发任务和管理共享内存。
- Worker 进程:Worker 进程执行实际的网络 IO 操作,接收来自客户端的连接请求,并处理请求。每个 Worker 进程是独立的,能够处理多个并发连接。
- 异步非阻塞事件驱动模型:NGINX 使用事件驱动的模型来处理网络连接和 IO 操作,通过使用异步非阻塞的方式处理请求。这样可以避免线程或进程的阻塞,提高并发处理能力。
- 多进程模型:NGINX 可以启动多个 Worker 进程,每个进程之间相对独立,不会相互影响。这种设计使得 NGINX 能够利用多核处理器,并充分利用系统资源,提高处理能力。
- 进程间通信:Worker 进程之间通过共享内存和事件通知等方式进行通信,避免了复杂的锁机制和线程间的竞争。
- 高效的负载均衡和反向代理:NGINX 可以作为反向代理服务器,将客户端的请求负载均衡地分发给多个后端服务器,实现高可用性和高性能。
- 动态模块化架构:NGINX 具有动态模块化的架构,允许用户自定义并扩展 NGINX 的功能,通过添加或删除相应的模块来满足特定的需求。
总的来说,NGINX 的架构设计使得它能够高效地处理并发连接和大量网络请求,同时提供了灵活的配置和扩展能力。这也是 NGINX 在高流量环境下被广泛应用的原因之一。
8、完成nginx编译安装脚本
#!/bin/bash
SRC_DIR=/usr/local/src
NGINX_URL=http://nginx.org/download/
NGINX_FILE=nginx-1.24.0
TAR=.tar.gz
NGINX_INSTALL_DIR=/apps/nginx
CPUS=`lscpu |awk '/^CPU\(s\)/{print $2}'`
. /etc/os-release
color () {
RES_COL=60
MOVE_TO_COL="echo -en \\033[${RES_COL}G"
SETCOLOR_SUCCESS="echo -en \\033[1;32m"
SETCOLOR_FAILURE="echo -en \\033[1;31m"
SETCOLOR_WARNING="echo -en \\033[1;33m"
SETCOLOR_NORMAL="echo -en \E[0m"
echo -n "$1" && $MOVE_TO_COL
echo -n "["
if [ $2 = "success" -o $2 = "0" ] ;then
${SETCOLOR_SUCCESS}
echo -n $" OK "
elif [ $2 = "failure" -o $2 = "1" ] ;then
${SETCOLOR_FAILURE}
echo -n $"FAILED"
else
${SETCOLOR_WARNING}
echo -n $"WARNING"
fi
${SETCOLOR_NORMAL}
echo -n "]"
echo
}
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
9、总结nginx核心配置,并实现nginx多虚拟主机
Nginx的配置文件的组成部分:
●主配置文件: nginx.conf
●子配置文件: include conf.d/*.conf
●fastcgi,uwsgi, scgi等协议相关的配置文件
●mime.types:支持的mime类型,MIME(Multipurpose Internet MailExtensions)多用途互联网邮件扩展类型,MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据,是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
nginx配置文件格式说明:
配置文件有指令和指令快构成
每条指令以;分号结束,指令与值之间以空格符号分隔
可以将多条指令放在同一行,用分号分隔即可,但可读性差,不推荐
指令块以{}大括号将多条指令组织在一起,且可以嵌套指令块
include语句允许组合多个配置文件以提示可维护性
使用#符号添加注释,提高可读性
使用$符号使用变量
部分指令的参数支持正则表达式
主配置文件结构:
worker_processes:用于设置 Nginx 启动的 worker 进程数,通常与 CPU 核心数一致或稍多一些。
worker_connections:用于设置每个 worker 进程能够同时处理的连接数。
events:用于配置 Nginx 的事件处理模型,包括使用的事件驱动模型(epoll、kqueue、select 等)以及连接超时等相关设置。
http:用于配置 HTTP 协议相关的选项,如设置默认字符集、启用或禁用服务器签名、设置请求头等。
server:用于定义虚拟主机,一个 Nginx 实例可以同时监听多个不同的域名或 IP,每个虚拟主机可以有独立的配置。
location:在 server 内部使用,用于进一步匹配 URL,设置更具体的规则,如不同的代理设置、缓存设置等。
try_files:在 location 内部使用,用于尝试寻找请求的文件路径,若找到则直接返回,否则按照规则进行下一步操作。
proxy_pass:在 location 内部使用,用于设置反向代理,将请求转发给指定的后端服务器。
rewrite:在 location 内部使用,用于重写 URL,实现重定向、URL 路径的替换等。
access_log 和 error_log:用于设置访问日志和错误日志的路径和格式等信息。
这些是 Nginx 核心配置中一些重要的指令和选项,通过合理配置可以满足不同的需求,如实现负载均衡、反向代理、缓存加速、安全防护等功能。同时,还可以结合 Nginx 的其他模块和插件来进行更高级的配置和功能扩展。
当涉及到 Nginx 的核心配置时,还有一些其他指令和选项值得关注。以下是更多与 Nginx 核心配置相关的重要指令和作用:
ssl_certificate 和 ssl_certificate_key:用于配置 SSL/TLS 证书和私钥,启用 HTTPS 服务。
gzip:用于启用压缩功能,减少传输内容的大小,提升网站性能。
proxy_set_header:在代理过程中设置请求头,例如 X-Forwarded-For 字段,用于获取客户端真实 IP 地址。
client_max_body_size:用于限制请求体的最大大小,防止恶意或异常请求导致服务器负载过高。
limit_req_zone 和 limit_req:用于限制请求速率,防止 DDOS 攻击或者爬虫等对服务器造成过大压力。
proxy_cache 和 proxy_cache_key:用于配置反向代理的缓存设置,提高响应速度和性能。
error_page:用于配置自定义的错误页面,例如 404 页面。
auth_basic 和 auth_basic_user_file:用于启用基本认证功能,限制只有提供正确的凭证才能访问网站。
upstream:用于定义一组后端服务器,实现负载均衡和高可用性。
resolver:用于设置 DNS 解析服务器地址,对于反向代理和负载均衡配置非常重要。
实现Nginx多虚拟主机
原理:基于不同的IP、不同的端口以及不同域名实现不同虚拟主机,依赖于核心模块ngx_http_core_module实现
#定义子配置文件路径
[root@Rocky8 ~]# mkdir /apps/nginx/conf/conf.d
[root@Rocky8 ~]# vi /apps/nginx/conf/nginx.conf
http {
....
include /apps/nginx/conf/conf.d/*.conf
...
}
[root@Rocky8 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
#创建PC网址设置
[root@Rocky8 ~]# cat /apps/nginx/conf/conf.d/pc.conf
server {
listen 80;
server_name www.magedu.org;
location / {
root /data/nginx/html/pc;
}
}
[root@Rocky8 ~]# mkdir -p /data/nginx/html/{pc,mobile}
[root@Rocky8 ~]# tre
tred tree
[root@Rocky8 ~]# tree /data/nginx/html/
/data/nginx/html/
├── mobile
└── pc
2 directories, 0 files
[root@Rocky8 ~]# echo "pc web" > /data/nginx/html/pc/index.html
[root@Rocky8 ~]#nginx -s reloed
#创建一个mobile web设置
[root@Rocky8 ~]# cat /apps/nginx/conf/conf.d/mobile.conf
server {
listen 80;
server_name m.magedu.org
location / {
root /data/nginx/html/mobile;
}
}
[root@Rocky8 ~]# echo "mobile web" >> /data/nginx/html/mobile/index.html
[root@Rocky8 ~]# nginx -s reload
10、总结nginx日志格式定制
默认格式日志定制
定制化 Nginx 日志格式是通过配置 Nginx 的 http
块中的 log_format
指令来实现的。log_format
指令允许您指定日志记录的内容和格式。
以下是一些常用的 Nginx 日志格式占位符:
$remote_addr
:客户端 IP 地址$remote_user
:客户端请求中的用户名(如果有的话)$time_local
:本地时间的访问时间和日期$request
:请求的 URL 和 HTTP 协议$status
:响应的 HTTP 状态码$body_bytes_sent
:发送给客户端的响应主体大小(以字节为单位)$http_referer
:引导用户到当前页面的 URL$http_user_agent
:客户端浏览器的用户代理字符串$request_time
:请求处理时间(以秒为单位)$upstream_response_time
:向上游服务器发出请求并接收到响应的时间(用于反向代理)
json格式日志定制
SON 日志格式的优势在于它们易于解析,特别是在用于日志聚合、监控和分析时。除了将请求相关的信息保存在日志文件中,您还可以通过自定义占位符来记录其他有用的信息,以便进一步分析。
例子:
http {
log_format json escape=json '{'
'"time_local":"$time_iso8601",'
'"request_method":"$request_method",'
'"server_protocol":"$server_protocol",'
'"status":$status,'
'"request_time":$request_time,'
'"upstream_response_time":$upstream_response_time,'
'"http_user_agent":"$http_user_agent",'
'"http_x_forwarded_for":"$http_x_forwarded_for",'
'"remote_addr":"$remote_addr",'
'"remote_user":"$remote_user",'
'"request":"$request",'
'"request_length":$request_length,'
'"body_bytes_sent":$body_bytes_sent,'
'"referer":"$http_referer",'
'"host":"$host",'
'"server_name":"$server_name",'
'"upstream_cache_status":"$upstream_cache_status",'
'"scheme":"$scheme",'
'"ssl_protocol":"$ssl_protocol",'
'"ssl_cipher":"$ssl_cipher"'
'}';
access_log /var/log/nginx/access.json json;
}
标签:10.0,0.0,redis,第八,nginx,root,Rocky8
From: https://www.cnblogs.com/LKzzZ/p/17893939.html