一、集群架构总论
1、什么是集群
集群就是把多台设备(服务器+网络设备)集中到一起
形成一个群体,相当于一个整体在对外提供服务
(类比:你们家的网络是如何构建的)
单点故障:
提供服务的设备只有一台,这台挂掉,整体就访问不了了
如何防单点故障:=====》高可用
再来一台设备做冗余,一台挂掉,另外一台可以继续提供服务
2、多种流量类型:
南北流量(14%):内网机器与外网通信(业务量影响)
东西流量(77%):内网机器在局域网内彼此之间进行通信(占比较高,取决于集群规模)
跨数据中心的流量(9%):跨数据中心的流量,例如数据中心之间的灾备,私有云和公有云之间的通讯。(防止机房级别的单点故障,保持数据中心数据的一致)
eg: 个人家庭网络链路
# 可以使用路由器+交换器实现多设备上网,也可以直接将一台设备直接与买的运营商IP相连
(查询公网# ip curl cip.cc)
3、上万台服务器集群是如何构建的
痛点:
1、交换机的性能问题
交换机的接口数有限(没有上万个接口)
广播包不能很大
2、地域限制
总结下来其实就一个点------想要把服务器都组织到一个二层网络里,但是无法把所有机器都组织到一台交换机里
解决方案:分层组织
1、接入层: 负责接入服务器,形成一个个的局域网
2、汇聚层:把接入层的交换机重新汇聚成一个二层网络
不同汇聚层代表不同的业务场景
3、核心层:把多个汇聚层给组织到一起
# 不断进行细分----专门的人做专门的事-----解耦合----拓展性强,方便性能优化,高可用(隔离故障),降低复杂性
# 接入Internet骨干网----用于业务服务 接入业务骨干网络----用于不同地域公司服务器间的通信
# 出口方案: 1.防火墙(也具有路由功能) 2.路由器(特殊场景) 3.路由器+防火墙
4、数据中心
把接入层以上的网络都组好了,你的服务器托管到数据中心即可(用户自己组好二层网络接入接入层)
5、SDN网络(了解)
SDN网络:软件定义网络--》附加在/依托于物理网络之上的虚拟网络
云服务:
## 公有云---用户买入,标准化服务 私有云---自行搭建,可定制化
用户请求-----》云平台管理软件(例如openstack)------》虚拟化软件(kvm、esxi、xen)---》虚拟机----》为虚拟机准备好sdn网络
(虚拟化)
# Veth 对----是一对虚拟网络接口,相当于一条虚拟网线
# Overlay 网络是 SDN 实现网络虚拟化的重要手段之一
sdn网络中的网络模式
vlan模式:
底层依托的物理网络:二层网络(局限性)
缺点: 公有云用户过多vlanid(4096个)不够用 不能跨地域(数据中心)通信
gre、vxlan
底层依托的物理网络:二层网络、三层网络
6、云计算
IAAS:卖虚拟机
PAAS:卖虚拟机+操作系统
SAAS:卖虚拟机+操作系统+应用程序
7、内网服务器集群架构
VPN--------在两个公网ip之间搭建一个隧道,使其可以通过隧道访问私网ip
内网:服务器集群的网络
集群:
部署集群的目的是为了承载/运行我们的基于网络通信的应用程序
网络通信的应用程序服务端构成:
负责网络通信--------------》拿来主义,直接用现成的
负责处理业务逻辑
例如:
用php开发网络应用软件
1、业务逻辑部分:用php语言写
2、网络通信部分:直接用别人开发好的php-fpm
===
用python开发网络应用软件
1、业务逻辑部分:用python语言写
2、网络通信部分:直接用别人开发好的uwsgi
===
用java开发网络应用软件
1、业务逻辑部分:用java语言写
2、网络通信部分:直接用别人开发好的tomcat
===
用go开发网络应用软件
1、业务逻辑部分:用go语言写
2、网络通信部分:go程序编译后的二进制文件直接就带http服务,不需要额外安装
网络通信的应用程序有两种架构
CS架构
client(放到“网盘”里让用户下载)-------------------------server
BS架构
浏览器+前端代码(html给内容打记号、css进行修饰、js动态效果)---------------server
# 浏览器访问某个服务端就去某个服务端将其客户端代码拿到本地运行
重要:
访问以此页面,会产生很多次请求
集群两大注意点:
时间
网络
二、集群性能指标与集群架构
1、构建前:
需要预估出集群的容量/规模----》依据性能指标
性能指标:
PV与UV(一般都是以天为单位统计)-----吸引用户的能力
PV:page view,访问一次页面算一次pv
强调:加一个页面会产生很多请求
UV:user view,一个用户访问一次算一个uv
查询----nginx---->access.log
根据访问ip统计uv awk '{print $1}' access.log | sort | uniq -c |wc -l
统计访问url统计pv awk '{print $7}' access.log | wc -l
注意:
1、看日志分析出的pv、uv代表的是过去的信息,不能用于评估未来的集群规模
最多可以作为一个经验参考,例如:发现用户80%的访问都是集中在20%的时间内
2、预估集群规模,应该与业务人员对齐,拿到一个未来可能发生的pv与uv数
通常会在此基础上乘以一个系数(经验值)
吞吐量(Throughput)---》请求与响应的速率---------反应集群的性能
QPS(Queries Per Second)1s内完成的请求数(访问一次页面会产生多次请求)
###重要指标
注意:
1、统计的是一段时间内的完成的请求数
2、代表的是完成了的请求的数
公式: 完成处理的总请求数 / 时间段
案例: 我们预估一个网站每天有10w活跃用户,称之为10w日活,每人平均访问4个页面,每个页面平均衍生4个接口请求(80%的访问都是集中在20%的时间内)
100000*4*4=160w 160w*0.8 / (24*60*60)*0.2=......
TPS(Transactions Per Second)1s内完成的事务数
一个事务包含了多个操作,这多个操作是有可能跨越多个page的,必然涉及到多个请求
TPS体现了系统在单位时间内处理事务的能力
QPS与TPS------------一秒内完成购买了某个商品的动作,但是该动作内包含了一次查找商 品请求、一次添加购物车请求,一次支付请求,计为1个“TPS”,但 是记为3个“QPS”
RT(Response-time,代表响应时长)
指的是一个请求从发出到拿到响应一整过程所经历的时间
包含:
1、 一去一回的网络传输时间
2、服务器处理的时间
页面加载完成时间:
访问一个页面的url地址,到看到一整个页面所需要的时间:
注意:
页面加载完成时间包含有:
1、与该页面相关的所有的请求完成的时间
2、解析html、css、js代码的时间
并发量(Concurrency)
在某一时刻/时间点正在发生的请求
与qps的区别:
1、qps代表完成的请求数
2、qps是某一个时段的内完成的请求数
例如:
此刻系统有5个请求,但是每个请求都需要花费2s才能处理完成
问:
并发量是:5
qps是:5 / 2 = 2.5
总结:
极限qps----反映的是系统的最大处理效率
能抗住的并发量----反映系统能最大承受的压力
补充: DAV---日活 MAU----月活
如何预估集群规模:
1、问运营、产品同学预估出某段时间可以达到的pv总数
2、预估峰值QPS
计算方式一:80%的请求集中在20%的时间段内
( 3000000 * 10 * 0.8 ) / (86400 * 0.2 ) = 1388 (QPS)
计算方式二:
( 3000000 * 10 ) / 86400 = 347 (QPS)
347 (平均值)* 峰值因子 = 峰值qps
3、压测得到单台机器的峰值/极限qps------->不断增加并发数
4、计算机出需要多少机器来共同承载请求
预估的未来发生的峰值qps / 单机的极限qps = 需要多少台机器
5、此外还需考虑网络带宽(都是预估的)
带宽(bps)=总流量数(bit)/产生流量的时长(秒)=(PV*衍生请求数*每个请求的平均大小*8)/统计时间(秒) 1B=8bit
得到结果 * 峰值因子 = 峰值带宽
6、如何提升一套系统的整体处理速度
提升最慢那个点的速度(通常都是跟io有关系)
2、开始构建
架构师-----》将军
预估集群容量----》估算需要招募多少士兵
接下来指挥大家去打仗------》构建一套集群
需要注意的点
1、时间需要一致
2、网络通信畅通
2、集群需要分层(解耦合)---》对士兵角色进行划分
网页缓存层--->CDN--------静态(大部分)与动态数据分开存储
补充:
静态数据:相对不变的数据,例如图片、css文件、js文件
动态数据:需要后台服务端每次计算得到一个新的结果
每次请求得到结果都不固定,即动态的
负载均衡层---》饭店里的领班负责调度---分散请求的压力
web应用层(web服务+web应用)----》饭店里厨师----存在多个
文件服务器层--------------------》共享存储,相当于一块大网盘
数据库及数据的缓存层
五层架构推演
单机--》web层
问题:用户访问增加,单机硬件性能不足---》解决:把单机里的组件拆出来部署到单独的机器上--》诞生数据库及数据的缓存层
问题:用户访问量持续增加,web层只有一台机器扛不住压力--》解决:引入负载均衡层,代理多台web层服务器
问题:web层服务需要共享数据-----》解决:引入了文件服务器层,便于更新数据和防止数据冗余
问题:访问压力变大速度变慢---》解决:引入cdn网页缓存层(分离静态与动态数据存放)
问题:单点故障
每一层慢慢都会演变成一个小集群
# 负载均衡层主备之间用keepavlied实现ip漂移进行主备切换(vip虚拟IP---存活检测)
# CDN网页缓存层通过将大部分静态数据分离至别处从而避免地域问题导致的高延迟,提升访问速率,减轻服务器访问压力
三、快速构建一套架构(******)
一套集群需要考虑的一些关键点:
1、性能
2、高可用性
每一层都要演变成一个小集群
集群五层概述
数据库与数据库缓存层(高压下最大的性能瓶颈)
数据库缓存(非关系型):redis、memcache
name="egon" # 数据彼此之间没有关联性
name1="tom"
age=18
age1=19
gender1="male"
gender="male"
特点:
1、数据库没有帮你组织好数据之间的关系
2、数据的存取都是在内存中
(也会定期开一个进程将数据写入硬盘)
优缺点:存容易取难
优点:
数据库本身的设计复杂度低+内存读写----》读写速度非常快
缺点:
应用程序开发的复杂度高(应用程序需要自己组织数据的关系)
数据库(关系型):mysql、 oracle、 db2、 sql server、 mariadb(从mysql分离出来的)
create table user(name varchar(15),age int,gender varchar(6)); # 存在关联
特点:
1、数据库帮你组织好数据之间的关系
2、数据的存取都是在硬盘
优缺点:
优点:
应用程序开发的复杂度低
缺点:
数据的存取速度相对慢一些
文件服务器层:
nfs共享存储:存在单点故障问题
单nfs+备份nfs innotify(监测变动)+rsync(同步变动 增量拷贝 || scp为全量拷贝)
主nfs挂掉需要人为的更改挂载到备份nfs,业务无法正常进行
DRBD+HeartBeat+NFS---不存在单点故障但是也存在压力过大的情况
分布式存储:ceph
分布式文件系统----MFS 、Glustr
web层----处理负载均衡层的网络缓存
服务:负责接收网络请求+解析协议
应用:负责处理业务逻辑、与数据库打交道
python
应用:自己用python开发、负责与数据库、数据库缓存通信
服务:uwsgi(支持http uwsgi协议)
java
应用:自己用java开发、负责与数据库、数据库缓存通信
服务:tomcat 、jboss、weblogic
php
应用:自己用php开发、负责与数据库、数据库缓存通信
服务:php-fpm
go
应用+服务---》编译在一个二进制文件里
web层的部署( 通常)
nginx----web服务----web应用 # nginx(套接字软件)本质也是web服务
最前面增加部署nginx的好处
1、缓冲压力,提升性能----nginx的性能十分强大
2、动静分离----分离动态与静态请求
3、安全防护-----设置规则进行匹配
4、日志管理
5、兼容各种协议,对外提供一种统一的协议HTTP,放行服务端所支持的协议
总结好处:
1、性能的提升
2、功能的增强
#增加一个nginx可以增加负载均衡层的灵活性,对外统一提供http协议负载均衡层也只用遵循http协议进行发送
负载均衡层:
软件:
haproxy:支持七层与四层
nginx:支持七层与四层
lvs:支持四层负载均衡
硬件负载均衡:F5
总结:
做四层转发(基于端口转发):
lvs
F5
做七层转发(基于HTTP协议转发):
nginx
haproxy
# haproxy不支持uwsgi协议,使用时需要在web层部署nginx
## 访问量增加,七层负载均衡顶不住加上四层负载均衡,同时将keepavlied移至四层,七层的每台服务器都投入使用
网页缓存层-CDN
后期管理
1、部署好监控与报警
nagios
cacti
ganglia
zabbix
promethus
2、连接机器进行管理:jumpserver(跳板机)、vpn
3、批量管理:ansible
4、自动发布流程
gitlab代码仓库(对于运维人员来讲这就是一块存放代码的大网盘)
公共:
github
gitee
jenkins(管理一系列流水线---将代码仓库中的代码取出并进行编译,将结果发布给web)
5、日志管理
ELK
EFK
6、k8s+容器技术
扩副本
自愈(发现故障、自动重启)
### 1、用户访问流程
1、用户在浏览器输入域名
2、浏览器拿着域名去DNS服务器解析
3、DNS服务器将解析后的IP返回给浏览器
4、浏览器根据IP去访问真实服务器
5、访问真实服务器的防火墙
6、请求通过防火墙后通过内网交换机传给负载均衡
7、负载均衡将请求平均分配给后端的web服务器
8、web服务器判断是静态请求还是动态请求
9、如果是静态请求,web服务器会去文件服务器获取数据
10、如果是动态请求,web服务器会去数据库或者缓存获取数据
11、数据从数据库或者NFS服务器返回给web服务器,web服务器将数据返回给负载均衡,负载均衡通过防火墙将数据传给浏览器
# 数据库:主要用于存储和管理结构化数据,如用户信息、订单数据、业务流程相关的数据等。
NFS 服务器:主要用于提供网络共享存储,以文件系统的形式将存储资源共享给集群中的多个 节点。它更适合存储非结构化数据,如文档、图片、视频等文件,或者作为应用 程序的共享配置文件、日志文件等的存储场所。
### 2、运维访问流程
1、管理人员连接跳板机或者vpn
2、通过跳板机或者vpn连接内网服务器
3、通过zabbix监控查看服务器状态
4、如果有问题则连接响应的机器解决问题
5、日常巡检,查看服务器配置
6、管理备份和备份数据
7、日志收集和整理展示
单机部署
1、环境准备
时间
网络-》静态ip
规范主机名-》添加到hosts
关selinux
关防火墙
setenforce 0 vim /etc/sysconfig/selinux
systemctl stop firewalld ( disable)
iptables -F
2、下载应用包、解压
方式一:
git clone xxx
方式二:
wget xxxx
3、准备好软件的运行环境
1、安装依赖包
# 1、下载gcc包
yum install gcc* glibc* -y # gcc--c /c++编译器 glibc--c程序依赖的基础库
# 2、依赖python环境
yum -y install python3 python3-devel python3-pip
#3、下载软件依赖的python库(由开发人员编写需求文档)
pip3 install flask -i https://mirrors.aliyun.com/pypi/simple/
pip3 install pymysql -i https://mirrors.aliyun.com/pypi/simple/
2、安装web服务---》uwsgi
4、准备数据库
yum install mariadb* -y
systemctl start mariadb
[root@localhost ~]# mysql -uroot -p # 执行下述命令
-- 创建账号xxx密码123,web应用链接的时候会用
grant all on testDB.* to 'xxx'@'127.0.0.1' identified by '123';
flush privileges; # 刷新权限
[root@localhost ~]# mysql -uroot -p # 执行下述命令
-- 创建库、表。项目中会用到
CREATE DATABASE testDB;
USE testDB;
create table messages(id int primary key auto_increment,text varchar(15)) charset=utf8mb4;
# 有时建库建表操作会给一个sql文件直接导入即可 mysql -uroot -p '密码' < abc.sql
5、修改软件的配置文件 # cat conf/settings.py 修改数据库链接信息
略
6、安装并配置web服务---》uwsgi
pip3 install uwsgi -i https://mirrors.aliyun.com/pypi/simple/
配置uwsgi拉起应用程序
uwsgi.ini-------------->自定义文件目录建立配置文件,一般就放入所安装的应用文件中 # 配置文件每一条后面不能跟任何符号
[uwsgi]
#1、监听的http协议端口
http = :8080
#2、启动后切换到该目录下作为项目根目录-----软件对应的目录
chdir = /soft/flask-web-app-main
#3、my_app对应项目根目录下的my_app.py文件(后端文件),冒号后的app--->文件内的实例名字(代码中的)
module = my_app:app
#4、启动的工作进程数量
processes = 4
#5、每个进程开启的线程数量
threads = 2
启动
uwsgi uwsgi.ini
# 打开网页----读取数据库数据----GET请求
# 写入数据----将数据写入数据库----POST请求
压力测试:
# uwsgi uwsgi.ini &>> /tmp/access.log & 后台运行并将结果写入日志进行分析
tail -f /tmp/access.log
单机极限qps:463.84----(测试记录)
先摸底:
1、先高并发去测试 10000
2、1000
3、500
4、400
5、300
6、200
7、100 ----》 失败数为0
再触底反弹一下
100每次加10,直到出现失败数
集群部署
准备6台机器:
负载均衡器
三台web服务器(压力测试计算所预估的数量)
文件服务器层
数据库层
预估规模(压力测试)---》三台web层服务器---》增加数据库服务器,对web服务器抽离出数据库层并指向数据库服务器---》加一个负载均衡服务器---》增加文件服务器,配置nfs服务
增加数据库层:
卸载掉三台web上的mariadb
systemctl stop mariadb
yum -y remove mariadb-server
找一个单独的机器做数据库服务器
setenforce 0
iptables -t filter -F
systemctl stop firewalld
yum install mariadb* -y
systemctl start mariadb
[root@localhost ~]# mysql -uroot -p # 执行下述命令
-- 1、创建库、表。项目中会用到
CREATE DATABASE testDB;
USE testDB;
create table messages(id int primary key auto_increment,text varchar(15)) charset=utf8mb4;
-- 2、创建账号xxx密码123,注意,此时需要创建的是远程账号,因此用%号
grant all on testDB.* to 'xxx'@'%' identified by '123';
flush privileges;
对于三台web
先停掉服务 pkill -9 uwsgi
修改配置文件将数据库指向刚刚建好的数据库服务器
vi /soft/flask-web-app-main/conf/settings.py
重启服务
uwsgi /soft/flask-web-app-main/uwsgi.ini
添加负载均衡
找一台机器做负载均衡服务器
setenforce 0
systemctl stop firewalld
iptables -F
yum install nginx -y
配置
mv /etc/nginx/nginx.conf /tmp/nginx.conf
cat > /etc/nginx/nginx.conf <<EOF
events {
worker_connections 1024;
}
http {
upstream web_app_servers {
server 192.168.71.207:8080 weight=1;
server 192.168.71.232:8080 weight=1;
server 192.168.71.231:8080 weight=1;
}
server {
listen 80;
location / {
proxy_pass http://web_app_servers;
# 注意:此处埋一颗雷,后面会炸
# 请求流程:客户端请求----》负载均衡-----》后端的web服务
# 问题点:后端的web服务拿到的访问者ip地址是负载均衡的地址,而不是客户端的,这会产生两方面影响
# 1、web服务器上的访问日志里看到的客户端ip都是负载均衡的、而不是真实客户端自己的,这个问题并不会导致程序运行出问题所以并不致命
# 2、web服务器上的程序可能需要根据客户端ip地址+协议来生成一些静态资源的url地址供给客户端二次请求,如果看不到真实的客户端ip,应用程序将会将地址拼接成http://web_app_servers/static/img/1.jpg的格式,导致访问失败
# 如何解决呢?如何能让web服务获取到的ip地址是真实的客户端ip而非负载均衡的呢?不着急,反正我们现在的应用程序都是测试程序、用不到真实的客户端ip,所以现在也并不致命,留着这颗雷,往后学吧。记住一点,带着真实的ip送给后端的web服务很重要就可以了,怎么做,后面再说
}
}
}
EOF
启动服务 systemctl restart nginx
增加文件系统层
增加一台文件系统服务器
# 1、初始化环境+安装
setenforce 0
systemctl stop firewalld
iptables -F
yum -y install nfs*
# 2、配置共享给外界哪个目录,并指定共享给哪个网段的机器用
vim /etc/exports
/data 192.168.71.0/24(rw,sync,all_squash)
# 3、导出
exportfs -a
# 3、创建共享目录
mkdir /data
# 4、把三台web中共享的代码放到/data里
[root@rockylinux ~]# ls /data/
flask-web-app-main
# 5、启动服务
systemctl start nfs-server # centos7中叫nfs
# 6、然后在三台web服务器必须先安装nfs支持,然后才能远程挂载过来
yum install nfs* -y
rm -rf /soft/*
mount -t nfs 192.168.71.206:/data /soft
# 7、重启启动
uwsgi /soft/flask-web-app-main/uwsgi.ini
# 8、访问负载均衡进行测试
# 9、
修改源代码后,如果不生效可以重启一下uwsgi
四、CDN层---网页缓存层详解
面对的问题:用户访问量暴增---》高并发的压力
1、网站的性能不足,访问慢(图片加载慢、网站响应慢)
2、数据量太大,资源占用过大
高并发优化思路
如何优化?---》如何应对高并发
高并发的问题总结下来就是两点问题:
1、高频读
解决思路-------让用户:少读、读缓存、就近读
少读:主要开发人员负责,
例如
1、雪碧图(降低网络io次数,将多次请求合并)
2、压缩数据(例如gzip压缩算法,降低io的数据量)
读缓存--相当于去自己最近的地方取
开发人员+运维人员
开发人员:控制redis作为mysql的缓存
运维人员:
配置响应头(与用户对接的负载均衡层)开启缓存(回复给浏览器让浏览器)把静态文件缓存到用户本地
就近读:
读本地:读用自己机器上的数据--》最近的
CDN:
2、高频写
解决思路------少写、漏斗写、buffer写---》多次合一次,减少io次数
CDN
CDN是什么--------------Content Distribution Network内容分发网络
内容:
网站的内容,可以分为两大类:
1、静态内容:在程序运行过程中,基本不变化
例如:图片、js、css、视频
2、动态的内容:在程序运行过程中,每次都是变化的、动态的(基本上都会与数据库交互)
例如:付费、转账
总结:
问题1:网站中静态内容多还是动态内容多?
egonlin.com ----> 静态的多
淘宝------------》静态、动态都很多
问题2:静态数据量大,还是动态数据量大?
静态数据量大
问题3:优化谁性价比最高
降低静态文件的访问压力,性价比最高
cdn主要帮我们优化静态数据的访问,但是cdn也可以优化动态数据
分发网络:指的是把内容发到离用户近的网络节点上
### 问题排查(无法访问)----->检查是否是客户端自己的问题,包是否能送给服务端 ping命令检测 (IP 网关 dns )--------->浏览器进行域名解析-------->检查服务端ip+端口号是否正常(三次握手是否建立成功)----------->服务端的内核防火墙是否阻拦--------->排查负载均衡服务器的nginx、端口(netstat/nginx配置文件)是否启用--------->检查是否能向web层发送数据(telnet)-------->检测web层(防火墙、访问检测)------->排查web层关联的文件服务器是否挂载,数据库是否能正常连接
为何用CDN
1、提升用户访问速度(就近读)
2、降低了集群的访问压力、资源使用量
注意:访问量很大的时候才能用cdn来加速,否则cdn会变成减速器(CDN会定期清理缓存,没有访问量用户需要不断地溯源,不如直接访问站点)
CDN服务器很少也会造成减速(用户需要去离自己很远的CDN服务器获取数据,距离可能会更长)
如何用CDN
储备知识:
1、本地dns:很多解析记录都是从别人那里拿过来缓存在本地---》不权威
2、权威dns/授权dns:存放的解析记录就来自于自己的本地文件配置着,不是从缓存拿的--》权威
本地DNS如果没有找到----递归、迭代向上查找至权威DNS
cdn运行原理---》cdn的核心组成部分:
1、GSLB(global server load balance全局负载均衡)
整个cdn的大脑
用户访问cdn时,先访问的是GSLB,然后GSLB会计算出
离用户最近那一台cdn服务,把该cdn服务器的ip地址返回给用户
用户拿着这个ip地址去访问
2、分布在全国/全世界各地的cdn服务器
负责具体干活的、响应用户的请求
3、数据源
可以有两种:
1、一块cdn服务器可以访问到大网盘
2、把你的站点整体当成一个数据源
4、配置权威dns
自己申请一个域名(cdn域名),作为所有静态请求的前缀:
cdn.egonlinhaifeng.com
接下来的目的就是:
控制域名cdn.egonlinhaifeng.com解析离用户最近那个dns的ip地址
然后为该域名添加解析
cdn.egonlinhaifeng.com -----》 GSLB(负载均衡) -----》算出一个离我最近的ip地址返回
在权威dns上添加一个CNAME的解析记录
从一个域名解析到另外一个域名
cdn.egonlinhaifeng.com---CNAME解析---->GSLB的域名(可对应多个cdn服务器IP)
## 用户发送第一个请求,负载均衡服务器拿到index.html,解析文件时,只有路径的请求默认在路径前加第一次请求使用的的ip和端口; 通过程序预留的cdn_url接口添加cdn域名从而修改文件服务器上的应用服务的配置文件templates/index.html, 在静态请求前添加新的ip地址(访问申请的CDN域名)可实现动态与静态请求分离,静态请求不会继续访问web层,转向对应的ip(CDN)去获取数据。
具体如何用?
可以分成两大类:
部分托管
域名解析
主域名:egonlin.com ---》集群的负载均衡ip地址
访问cdn的域名:cdn.egonlinhaifeng.com----CNAME解析----》GSLB的域名
数据源用什么-----------------一块大网盘(其中的数据可以自定义放入)
特点:
请求打到我们自己的负载均衡上,由我们自己的负载均衡做一个动静分离
针对静态请求被cdn分散压力
优点:
可定性强用一些,可以自己任意控制数据源中的数据
缺点:
访问大的情况,会对我们集群的负载均衡造成高压力
配置复杂
全站托管
域名解析
主域名:egonlin.com ------> CNAME解析----GSLB的域名
数据源用什么-------------你自己的整个站点
优点:
配置简单
抗压力性强
缺点:
可定制弱
都已经做完全站托管了,你自己的集群是否还需要做动静分离?
需要!
针对第一次访问cdn失败,溯源的场景,能走更短的路拿到数据(速度会更快),肯定也是有性能提升的
基于这一点:我们自己的集群还是要做一下动静分离----溯源的时候静态数据可以直接在负载均衡的服务器上取,速度更快
溯源:用户请求cdn服务器,命中数据失败,会请求数据源来获取数据,并在cdn中缓存
以备下次访问
预热:提前把数据源的数据推送到/上传到cdn服务器里
实验实现
实验思路:
实验步骤:
1、先准备好域名
主域名省略,一会直接拿着负载均衡的ip地址访问
申请好用于cdn转发的域名:
命名中最好带着cdn标识
域名必须要备案才能使用
如何申请域名:https://egonlin.com/?p=8894
域名备案:https://egonlin.com/?p=8966
2、数据源准备
1、申请一个大网盘-----》(阿里云oss)
2、往网盘里上传静态数据
static/img/1.jpg
static/css/a.css
结果-------------------------》得到一个数据源的域名:
egonlinhaifeng-bucket.oss-cn-beijing.aliyuncs.com
3、开通cdn,cdn的数据源配置为你的大网盘的域名
得到一个cdn的gslb的域名
xxxx.gslb.com
4、权威dns添加CNAME解析
egonlin.cn CNAME xxxx.gslb.com
实际:
egonlin.cn CNAME egonlin.cn.w.kunlunaq.com
5、配置我们自己的站点
### 修改应用的配置文件,指定cdn_url=http://cdn.egonlin.com(开发的任务)
如果程序没有留接口----需要去index.html中在静态请求前添加新的ip地址
也可以去负载均衡服务器上进行配置修改(速度相对较慢)----第一次请求拿到index.html后还要将请求再次发给集群的负载均衡服务器/etc/nginx/nginx.conf
## 网站访问量少,cdn服务器规模小有可能不增反降
cdn也可以发送动态内容
cdn客户--公司厂商 cdn用户--普通访问者
CDN衡量指标-----命中率(命中CDN缓存) 回源率(未命中资源出发回源动作)
CDN防盗刷---修改代码(开发)
提升命中率-----预热 合理设置缓存时间(静态更新周期长,动态短)
负载均衡 增加节点数量和覆盖范围
五、文件服务层详解
一、可用方案
NFS主----------rsync+inotify实时同步---------------NFS备
问题:解决了单点故障但是故障切换需要人为参与
DRBD+HeartBeat+NFS高可用文件服务器
特点:解决了单点故障、故障可以自动切换
问题:性能不足
兼顾:性能+高可用+数据安全性 ====》 分布式存储
ceph
MFS
Gluster
二、NFS
network file system:网络文件系统
网络存储可以分为三大类:
1、文件存储:对外提供的文件 ----》NFS 拿到的是现成做好的文件系统
2、块存储:对外提供一个块设备(就是一块裸盘) 拿到的是硬盘,还需要自己制作文件系统
ceph可以提供块存储
# 相当于顺着网络给你的设备插上一个硬盘
3、对象存储:存储数据的单位是一个个的对象
### 文件存储和块存储底层都是一个个block块,用的都是文件
三、NFS架构图
CS架构
服务端:/etc/exports
/data 192.168.71.0/24(rw,all_squash,sync)
准备本地硬盘---》格式化制作文件系统---》挂载到一个文件夹---》nfs将文件夹对外共享
客户端:
mount -t nfs 服务端ip地址:/data /本地路径
# nfs基于TCP/IP连接服务端
客户端使用
读写数据------------》/本地路径 -----------------》nfs数据源
四、nfs使用详解
服务端
环境初始化
关selinux、防火墙
yum install nfs-utils rpcbind(centos7默认安装) -y
配置:/etc/exports
/data 192.168.71.0/24(rw,sync,all_squash)
重新导出/etc/exports文件里定义的所有NFS共享目录,一般在修改配置文件后使用使新的共享配置生效:
exportfs -a
创建目录
mkdir /data
启动服务
systemctl start nfs-server
验证配置
cat /var/lib/nfs/etab
客户端
# 客户端不用启动nfs
环境初始化
关selinux、防火墙
yum install nfs-utils rpcbind -y
showmount -e 服务端ip # 查看挂载点
mount -t nfs 服务端ip地址:/data /本地路径
df -h # 验证挂载
卸载的两种方式
umount /本地路径
umount 服务端ip地址:/data
强制取消挂载
umount -lf /backup
开机自动挂载
编辑fstab文件
vim /etc/fstab
服务端ip地址:/data /本地路径 nfs defaults 0 0
#验证fstab是否写正确
mount -a
# 文件夹可以比作水龙头,接到那个数据源就会展示哪个数据源的东西
# 客户端写入数据到nfs服务端文件中的两道枷锁-----nfs服务的权限,服务端文件夹的权限
all_squash----让所有远程连接的nfs客户端不受服务端文件权限的影响,统一映射为一个匿名的用户和用户组
sync----同时写入内存与硬盘
rw----赋予nfs服务读写权限
anonuid aningid ------指定NFS的用户uid和gid(所有主机都创建一份一模一样的用户便于管理) 文件服务器的共享目录也用 chown -R 重新设置成一样的
# 并行写入数据的冲突问题------应用程序应该考虑的问题
五、制作nfs的备份/镜像机
方案一:
rsync+inotify
inotify:帮们检测一个文件下的变动,一旦该文件夹下有变动,都可以检测到
rsync:帮我们把变动文件同步到远程的备份机上(对比增加,数据同步)
方案二:
sersync=rsync+inotify的封装
缺点:
故障切换要人手动完成
六:rsync的使用
yum install rsync -y
rsync命令即可以当客户端又可以当服务端------服务端和客户端需要同时安装,服务端不用启动
客户端:
优点:
1、rsync涵盖了scp、cp二者功能,即rsync同时支持本地拷贝与远程拷贝
2、scp与cp每次拷贝都是全量的,而rsync是增量的(io量小)
3、scp远程传输不支持断电续传,而rsync支持
4、灵活性、可配置性强
缺点:
1、命令行选项复杂
2、本身没有检测文本何时变化的能力
3、对cpu消耗比较大
服务端:
rsync --deamon # systemctl start rsyncd
对比:
scp ----------------ssh协议-----------------》sshd
rsync:
rsync----------------ssh协议-----------------》sshd(有泄露系统账号的风险)
本地--》远程:
rsync /a.txt 系统账号@1.1.1.111:/test ---用法和scp相同
远程--》本地:
rsync 系统账号@1.1.1.111:/test /a.txt
rsync----------------rsync协议-----------------》rsyncd
rsync /a.txt 虚拟账号@1.1.1.111::模块名 (在配置文件中规定模块名对应哪个文件)
# 用法同上
rsync--------------------ssh协议----------------------------->sshd服务
要求服务端必须开启sshd服务(默认都是开启的)
基于ssh协议通信的话:
1、使用的账号是系统账号
2、ssh协议支持密码登录、密钥登录
本地模式
cp命令只是本地复制,每次cp都会用源文件内容覆盖新文件,所以cp命令会修改文件时间属性
rsync可本地可远程,首次rsync与cp一样,后续rsync会对比两个文件的不同,只传输文件更新的部分,如果未更新,则rsync不会修改文件任何属性
[root@local ~]# rsync -r /etc/cron.d /test # 把文件夹cron.d拷贝到/test下
[root@local ~]# rsync -r /etc/cron.d/ /test # 把文件夹cron.d下的内容拷贝到/test下
[root@local ~]# rsync -r -R /src/./aaa/bbb/ccc /dst/ # 以点左侧为相对路径起始,拷贝其后目录
[root@local ~]# ls /dst/
aaa
#如果源文件与目标文件命名冲突, -backup防止被覆盖,目标位置下的同名文件会被重命名默认~结尾
# 可以使用"--suffix"指定备份后缀,例如
[root@remote ~]# rsync -r --backup --suffix=".bak" /egon111/ /egon222/
# rsync 拷贝的时候会先读取要拷贝的内容,然后读取目标文件内容并与其进行比对,拷贝不一样的内容
# 如果不确定 rsync 执行后会产生什么结果,可以先用`-n`或`--dry-run`参数模拟执行的结果,不真实执行
# 如果要使得目标目录成为源目录的镜像副本,则必须使用`--delete`参数,这将删除只存在于目标目录、不存在于源目录的文件
# rsync -av --include="[0-9].txt" --exclude='*' source/ destination 条件拷贝 --include必须在--exclude之前
# rsync -zavn --exclude={'1.txt','a/*'} /aaa/ /bbb/ 要拷贝例如/aaa/a/* (a文件夹下的所有内容) --exlucde里指定的路径只能是相对目录
远程模式
用法与scp非常像
#1、上传/推送push
scp -r /aaa root@192.168.71.115:/bbb
#2、下载/拉取pull
scp -r root@192.168.71.115:/bbb /aaa
#1、上传/推送push
rsync -avz /aaa root@192.168.71.115:/bbb
#2、下载/拉取pull
rsync -avz root@192.168.71.115:/bbb /aaa
指定端口
scp -r -P 2222 root@192.168.71.115:/bbb /aaa
rsync -avz -e 'ssh -p 2222' root@192.168.71.115:/bbb /aaa 一般情况下ssh的端口(22)都会改
# -p ssh指定端口 -P scp指定端口
注意点:
1、虽然服务端启动的服务是sshd而不是rsyncd,但也必须安装rsync
2、scp是全量传输(内部有优化机制),rsync都是增量传输
rsync--------------------rsync协议----------------------------->rsyncd服务(rsync --deamon)
与ssh协议的区别是,基于rsync协议传输采用的是虚拟用户,而不是系统用户
1、客户端与服务端都需要做
关selinux、防火墙
yum install rsync -y
2、配置服务端
配置文件 见博客
#可以限制用户所能操作的目录 设置模块例如[xxx]
#虚拟用户信息只是作为客户端登陆的验证手段,登陆完成后自动切换为配置中的用户身份进行操作(守护进程)-------安全性
3、做好准备工作(远程主机上----服务端)
useradd rsync -s /sbin/nologin -M 创建启动守护进程时的用户
[root@nfs ~]# cat /etc/rsync.passwd 配置虚拟用户
egon:123
[root@nfs ~]# chmod 600 /etc/rsync.passwd root用户可以查看
mkdir /egon_bak 为模块[xxx]创建真实的目录
chown -R rsync.rsync /egon_bak/
4、启动服务
systemctl start rsyncd 以root用户身份启动进程
虚拟用户egon-------------------》系统用户rsync-----------》操作xxx下的文件夹/egon_bak1
5、修改模块目录的属主与属组
chown rsync.rsync /egon_bak1
chown rsync.rsync /egon_bak2
6、测试使用
rsync -avz /aaa/1.txt egon@192.168.71.115::xxx/111.txt
rsync -avz /aaa/1.txt egon@192.168.71.115::yyy/111.txt
rsync -avz egon@192.168.71.115::yyy/111.txt /abc/1.txt
总结:
基于ssh认证: I:使用的是远程主机的系统账号与密码
II:通过ssh隧道进行传输
需要远程主机开启sshd服务
只需要双方安装rsync,不需要双方启动rsync,
类似于scp工具,同步操作不局限于rsync中定义的同步文件夹
基于守护进程rsync-daemon:
I:使用的是远程主机的虚拟账号,在rsync-daemon认证下,rsync可以 把密码写入到一个文件中。
II:在rsync-daemon认证方式下
只需要双方安装rsync,并且远程主机需要开启rsync进程,默认监听 tcp的873端口
同步操作只能同步到远程主机指定的目录下
三种备份思想:
全量:
特点:每次都是一次完整的“拷贝”
恢复:
只需要一个文件
差异:
特点:每次都是跟第一次全量备份比较,只备份差异部分
此刻目录内文件的变化:1.txt 2.txt 3.txt 4.txt 5.txt
第一次全量:1.txt 2.txt