集群阶段开篇概述
本阶段规划:
- 从单体到集群过度
- Nginx入门
- Nginx实现集群与负载均衡
- 高可用Nginx方案与实现
- 生产环境Nginx替换tomcat
目前,项目采用单体部署得方式,前端后端和数据库都是放在单节点上进行部署的。
如果有条件的话,我们也可以将前端、后端和数据库分别放在单独的结点上。
单体架构的优点:
- 小团队成型即可完成开发、测试和上线
- 迭代周期短,速度快
- 打包方便,运维省事
单体结构的缺点:
- 单节点宕机造成所有服务不可用
- 耦合度太高(迭代、测试、部署)
- 单节点并发能力有限
集群概念:
- 计算机‘群体’构成整个系统
- 这个’群体’构成一个整体,不能独立存在
- ‘人多力量大’,群体提升并发与可用性
只要是多台服务器去实现共同的业务,那么我们就称之为集群。
如果每台计算机结点运行的服务不同,那么我们称之为分布式。
使用集群的优势:
- 提高系统性能
- 提高系统的可用性
- 可扩展性高
使用集群的注意点:
- 用户会话。使用集群后,用户会话是不可能跨tomcat的,所以我们要采用分布式会话,我们会通过redis缓存来实现分布式会话。
- 定时任务。集群环境下,所有计算机在同一时刻都去做同样的事情(比如关闭订单),这无疑会浪费计算机资源,解决方法:1、把定时任务单独做成一个服务,让一台计算机结点去做;2、或者采用MQ延时任务去做。
- 内网互通
什么是Nginx?常用的Web服务器有哪些?
Nginx的活跃度在上升,而Apache的使用者在减少。
什么是反向代理?
什么是正向代理?
- 客户端请求目标服务器之间的一个代理服务器
- 请求会先经过代理服务器,然后再转发请求到目标服务器,获得内容后最后响应给客户端。
比如说,我们打开浏览器访问网页,并不是直接访问到的网页后端服务,而是先经过电信联通这些运营商,然后再到达的网页服务器。这就是一个正向代理的例子。
再举一个例子,在网吧上网,每个人的网速可能不一样,vip的速度会快一些。这也是同各国网吧的代理服务器实现的。甚至,当你访问一些非法网站的时候,他甚至可以屏蔽掉。
比如,ping 淘宝,多次访问,访问的服务器ip是不一样的
用户请求目标服务器,由代理服务器决定访问哪个ip。
Nginx安装与运行
1、去Nginx官网下载对应的nginx包,推荐使用稳定版本:
官网地址:http://nginx.org/en/download.html
2、上传nginx到linux系统:
3、安装依赖环境
-
安装gcc环境:
yum install gcc-c++
-
安装PCRE库,用于解析正则表达式
yum install -y pcre pcre-devel
-
zlib压缩和解压缩依赖
yum install -y zlib zlib-devel
-
SSL安全的加密的套接字协议层,用于HTTP安全传输,也就是https
yum install -y openssl openssl-devel
4、解压,需要注意,解压后得到的是源码,源码需要编译后才能安装
tar -zxvf nginx-1.20.1.tar.gz
5、编译之前,先创建nginx临时目录,如果不创建,在启动nginx的过程中会报错。
mkdir /var/temp/nginx -p
6、在nginx目录,输入如下命令进行配置,目的是为了创建makefile文件。
./configure \
--prefix=/usr/local/nginx \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--http-scgi-temp-path=/var/temp/nginx/scgi
-
配置说明:
7、make编译
make
8、安装
make install
9、进入sbin目录启动nginx(找到nginx的安装目录使用命令:whereis nginx
)
./nginx
- 停止:./nginx -s stop
- 重新加载:./nginx -s reload
10、打开浏览器,访问服务器ip(如果是虚拟机的话,就应该访问内网ip)即可打开nginx默认页面,显示如下便表示安装成功:
这里展示的html页面实际上就是nginx/html/index.html页面的内容,我们可以修改里面的内容:
Nginx显示默认首页过程解析
这里监听80端口是可以修改的:在nginx/conf/nginx.conf文件
vim nginx.conf
这里映射到了root(同级目录)下的html文件夹下的index.html文件。修改一下端口,改成88。
并且。./nginx -s reload一下
现在访问80端口:
而访问88端口,则能够成功访问:
Nginx的进程模型
Nginx工作的时候有两个进程:
- master进程:主进程,相当于领导者。
- worker进程:工作进程,worker为master服务的。
master接收到了外面的信号,会传递给worker执行。
信号:
- ./nginx -s stop
- ./nginx -s quit
- ./nginx -s reload
- ./nginx -t
一般来讲,master进程只有一个,worker进程也只有一个。但是worker进程数可以配置。
修改nginx.conf文件,配置worker进程数:
reload一下nginx,然后再次查看进程数:
如果master发送关闭请求,则worker会等到客户端的连接释放后再关闭。
被黑客攻击的worker只需要将其关闭即可,不影响其他进程的worker工作。
Nginx处理Web请求机制解析
accept_mutex是互斥锁,和client对应,worker争抢这个锁。
传统服务器事件处理:同步阻塞的方式,性能比较低。
Nginx事件处理:异步非阻塞的方式(类似多路复用器)。当client1和client2阻塞了,worker1会切换到处理client3请求。
我们可以修改nginx.conf文件,修改worker的最大连接数。
nginx.conf配置结构与指令语法
补同步与异步、阻塞与非阻塞的概念:
nginx.conf核心配置文件详解-1
1、设置worker进程的用户(操作者),会涉及到nginx操作目录或者文件的权限,默认为nobody。
打开nginx.conf,可以修改:
修改前:
修改后:
2、worker进程数配置。一般来讲,有几个cpu就设置为几个,如果说云服务器上有一些其他的软件,可以设置为N-1.
3、nginx日志级别 debug info notice warn error crit alert emerg,错误级别从左到右越来越大。
之前在安装nginx的时候设置了日志保存路径:
--error-log-path=/var/log/nginx/error.log \
可以进入到这个目录看一下:
这都是之前操作nginx的日志。
4、设置nginx进程pid。
pid logs/nginx.pid;
之前在安装的时候设置了pid路径:
--pid-path=/var/run/nginx/nginx.pid \
打开/var/run/nginx/nginx.pid文件:
nginx.conf核心配置文件详解-2
1、设置工作模式:
这里设置的最大连接数不能设置的太大,否则可能会有反作用。
2、http指令块,针对http网络传输的一些指令配置。
http{}
3、include引入外部配置,提高了可读性,避免单个配置文件过大。
include mime.types;
4、设置日志格式,main为定义的格式名称,这样的话access.log就可以使用main了。
可以打开access.log看一下,客户端发起的所有请求日志都在这里显示。
nginx.conf核心配置文件详解-3
1、sendfile使用高效文件传输,提升传输性能。启用后才能使用tcp_nopush,是指当数据表累积到一定大小后才发送,提高了效率。
sendfile on;tcp_nopush on;
2、keepalive_timeout设置客户端与服务端请求的超时时间,保证客户端多次请求的时候不会重复建立新的连接,节约资源损耗。
#keepalive_timeout 0;keepalive_timeout 65; #以秒为单位
3、gzip启用压缩,html/css压缩后传输会更快。
gzip on;
4、server可以在http指令块中设置多个虚拟主机
- listen监听端口
- server_name localhost ip 域名
- location 请求路由映射 匹配拦截
- root请求位置
- index首页设置
server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; }}
两台虚拟主机配置:
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server {
listen 89;
server_name localhost;
location / {
root html;
index nju.html index.htm;
}
}
测试:
当然,也可以将这两段配置写到一个配置文件中,然后使用include导入。
nginx.pid打开失败以及失效的解决方案
如果是/var/run/nginx目录找不到就手动创建一个文件夹
mkdir /var/run/nginx
然后再使用nginx -c 命令重新指定配置文件。
./nginx -c /usr/local/nginx/conf/nginx.conf
Nginx常用命令解析
1、比较友好地停止nginx,如果检测到由用户连接,那么会等到用户断开连接再停止nginx。比较暴力的就是./nginx -s stop
./nginx -s quit
2、检测配置文件对不对
./nginx -t
3、手动指定配置文件
./nginx -c
4、寻求帮助
./nginx -?或者./nginx -h
5、查看nginx版本信息
./nginx -v./nginx -V
Nginx日志切割-手动
现有的日志都会存在 access.log 文件中,但是随着时间的推移,这个文件的内容会越来越多,体积会越来越大,不便于运维人员查看,所以我们可以通过把这个大的日志文件切割为多份不同的小文件作为日志,切割规则可以以天为单位,如果每天有几百G或者几个T的日志的话,则可以按需以每半天或者每小时对日志切割一下。
具体步骤如下:
1、进入到/usr/local/nginx/sbin/,创建一个shell可执行文件:cut_my_log.sh,内容为:
#!/bin/bashLOG_PATH="/var/log/nginx/"RECORD_TIME=$(date -d "yesterday" +%Y-%m-%d+%H:%M)PID=/var/run/nginx/nginx.pidmv ${LOG_PATH}/access.log ${LOG_PATH}/access.${RECORD_TIME}.logmv ${LOG_PATH}/error.log ${LOG_PATH}/error.${RECORD_TIME}.log# 向Nginx主进程发送信号,用于重新打开日志文件kill -USR1 `cat $PID`
2、为cut_my_log.sh添加可执行的权限:
chmod +x cut_my_log.sh
3、测试日志切割后的结果:
./cut_my_log.sh
多次切割:
Nginx日志切割-定时
推荐一篇博客:https://www.cnblogs.com/leechenxiang/p/7110382.html
1、安装定时任务
yum install crontabs
2、crontab -e 编辑并且添加一行新的任务:
*/1 * * * * /usr/local/nginx/sbin/cut_my_log.sh
3、重启定时任务:
service crond restart
常见的定时任务命令:
service crond start //启动服务service crond stop //关闭服务service crond restart //重启服务service crond reload //重新载入配置crontab -e // 编辑任务crontab -l // 查看任务列表
启动后,查看/var/log/nginx目录下的日志文件,每分钟切割了一次。
定时任务表达式:
Cron表达式是,分为5或6个域,每个域代表一个含义,如下所示:
虚拟主机-使用Nginx为静态资源提供服务
将foodie-shop和一些静态资源上传至/home
在nginx.conf同级目录下,新建一个imooc.conf
然后配置访问foodie-shop和imooc文件夹的虚拟主机:
server { listen 90; server_name localhost; location / { root /home/foodie-shop; index index.html; } # 第一种写法 location /imooc { root /home; } # 第二种写法 location /static { alias /home/imooc; }}
说明:第一种写法访问imooc,nginx会把imooc拼接在/home的后面
第二种写法使用别名,访问/static,nginx会直接定位到/home/imooc。
在nginx.conf文件中加上:include imooc.conf
并且reload一下nginx服务。
测试:
访问:http://121.43.149.168:90/
访问:http://121.43.149.168:90/imooc/userface1.jpg
访问:http://121.43.149.168:90/imooc/music.mp3
访问:[http://121.43.149.168:90/imooc/Adele-Someone%20Like%20You.mp4](http://121.43.149.168:90/imooc/Adele-Someone Like You.mp4)
使用Gzip压缩提升请求效率
开启gzip压缩功能后,可以提高传输效率,节约带宽
location的匹配规则解析
1、精确匹配:=
修改imooc.conf文件,添加两个精准匹配:
server { listen 91; server_name localhost; location = /imooc/userface1.jpg { root /home; } location = / { root html; index index.html; }}
2、正则表达式匹配:~
*代表不区分大小写。
server { listen 92; server_name localhost; location ~* \.(gif|png|jpg|bmp|jpeg) { root /home; }}
3、以某个字符路径开头的请求 ^~
server { listen 93; server_name localhost; location ^~ /imooc { root /home; }}
DNS域名解析
查看我们自己的电脑只需在百度搜索ip:
这个ip每天都会变化的。所以我们自己的电脑是不能作为一台服务器去使用的。而云服务器是有一个固定的IP地址的。
使用SwitchHosts模拟本地域名解析访问
linux在etc下有一个hosts文件
那么,在windows目录下,也会有一个hosts文件,在里面可以添加ip和域名的对应关系。
这里修改对应关系,可以直接在hosts文件上修改,也可以使用工具SwitchHosts来修改。
推荐一篇博客:https://blog.csdn.net/gui951753/article/details/79210535
114.212.124.58为本机内网ip,可以通过ipconfig命令查询出来。
在Nginx中解决跨域问题
Nginx的跨域:
CORS跨域资源共享:
- Cross-Origin Resource Sharing
- 允许浏览器向跨Origin的服务器发起js请求获取响应
- Jsonp、SpringBoot cors、Nginx
Nginx的跨域支持配置:
# 允许跨域请求的域,*代表所有add_header 'Access-Control-Allow-Origin' *;# 允许带上cookie请求add_header 'Access-Control-Allow-Credentials' 'true';# 允许请求的方法,比如 GET/POST/PUT/DELETEadd_header 'Access-Control-Allow-Methods' *;# 允许请求的headeradd_header 'Access-Control-Allow-Headers' *;
那么这样的话,我们写一个页面,请求云服务器的资源,将这个页面放到本地tomcat中,就可以访问了!
在Nginx中配置静态资源防盗链
# 对源站点验证
valid_referers *.imooc.com;
# 非法引入会进入下方判断
if ($invalid_referer) {
return 404;
}
同样的,将上述代码加入到imooc.conf文件中。
Nginx的模块化设计解析
Nginx的模块化体系:
- event module:事件模块,epoll,操作系统层面
- phase handler:处理客户端的请求,响应内容
- output filter:过滤器,gzip压缩的过程实际上就是过滤的过程。
- upstream:将请求转发到真实的服务器地址
- load balancer:负载均衡器
- extend module:第三方模块
查看nginx的安装包:
auto:识别操作系统的脚本
CHANGES:历史版本的说明
configure:编译时配置的
contrib:与工具相关
man:nginx的守则
objs:第三方的插件
src:源码(比如http、mail),我们主要用得到的就是http。
Nginx的集群负载均衡解析
1+1>2,2核4G+2核4G>4核8G
上游(upstream)指的是tomcat服务器,下游指的是客户端。
四层、七层与DNS负载均衡
四层负载均衡:
- F5硬负载均衡:基于硬件,商业级别,非常昂贵
- LVS四层负载均衡:基于CS端,可以转发一些请求
- Haproxy四层负载均衡:灵活性很高,也可以做7层
- Nginx四层负载均衡:一般来说使用nginx做7层,可以基于http。
七层负载均衡:
- Nginx七层负载均衡:性能好
- Haproxy七层负载均衡:灵活性很高
- apache七层负载均衡:性能远不如Nginx,并发百万后会越来越差。
四层一般用于转发请求,七层一般处理tcp/udp请求
DNS地域负载均衡:
所有的负载均衡功能由DNS处理,基于就近原则:
OSI网络模型
网络模型就是 OSI(Open System Interconnect) ,意思为开放网络互联,是由国际标准化组织(ISO)和国际电报电话咨询委员会(CCITT)共同出版的,他是一种互联模型,也是一种规范。
网络模型分为七层,也就是当用户发起请求到服务器接收,会历经七道工序,或者说用户利用互联网发送消息给另一个用户,也会历经七道工序。这七层可以分为:
以上七层每层可以与上下相邻层进行通信。每一层都是非常复杂的,我们不在这里深究,我们以举例的形式来阐述每一层是干嘛的。
-
应用层:这是面向用户的,最靠近用户,为了让用户和计算机交互,在计算机里会有很多软件,比如eclipse,idea,qq,nginx等,这些都是应用软件,用户可以通过这些应用软件和计算机交互,交互的过程其实就是接口的调用,应用层为用户提供了交互的接口,以此为用户提供交互服务。那么在这一层最常见的协议有:HTTP,HTTPS,FTP,SMTP,POP3等。*Nginx在本层,为七层负载均衡。*
举例:我要寄一封信给远在天边的老外LiLei,我会打开快递软件下单,这个时候我是用户,快递软件就是应用服务,是建立在计算机上的,提供给用户交互的一种服务或称之为手段。
-
表示层:该层提供数据格式编码以及加密功能,确保请求端的数据能被响应端的应用层识别。
举例:我写中文给LiLei,他看不懂,这个时候我就会使用翻译软件把中文翻译成英文,随后信中涉及到一些比较隐私的信息我会加密一下,这个时候翻译软件和加密器就充当了表示层的作用,他用于显示用户能够识别的内容。
-
会话层: 会话可以理解为session,请求发送到接受响应的这个过程之间存在会话,会话层就充当了这一过程的管理者,从创建会话到维护会话最后销毁会话。
举例:我每次写信给LiLei都会记录在一个小本本上,寄信时间日期,收信时间日期,这本小本本上存有每次通信记录,这个小本本就相当于是一个会话的管理者。又或者说,我们平时在打电话,首先需要拨打电话,这是建立会话,对方接听电话,此时正在通话(维持并管理会话),通话结束后会话销毁,那么这也是一次会话的生命周期。
-
传输层: 该层建立端到端的连接,他提供了数据传输服务,在传输层通信会涉及到端口号,本层常见的协议为TCP、UDP,*LVS就是在传输层,也就是四层负载均衡。*
举例:我和LiLei通信过程中会借助快递公司,快递公司会分配快递员取件和寄件,那么这个快递员则充当传输层的作用。
-
网络层: 网络通信的时候必须要有本机IP和对方的IP,请求端和响应端都会有自己的IP的,IP就相当于你家地址门牌号,在网络上云服务器有固定的公网IP,普通计算机也有,只不过是动态IP,运营商每天会分配不同的IP给你的计算机。所以网络层也能称之为IP层,IP是互联网的基础根本。能提供IP分配的设备则为路由器或交换机。
举例:对于拥有固定IP的云服务来说,他们都是由腾讯云、阿里云等这样的供应商提供的,他们为云服务器提供固定ip;电信、移动、联调等运营商为你的计算机动态分配ip,每天都不同;则这些供应商和运营商都是网络层。同理,快递员由物流公司分配和管理,那么物流公司就是网络层。
-
数据链路层: 这一层会提供计算机MAC地址,通信的时候会携带,为了确保请求投递正确,所以他会验证检测MAC地址,以确保请求响应的可靠性。
举例:快递员在投递派送的时候,他(或客服)会预先提前打电话给你,确认你家地址对不对、有没有人、货到付款有没有准备好钱等等,这个时候快递员(或客服)就充当了数据链路层的职责。
-
**物理层:**端到端请求响应过程中的媒介,”物理介质,比如网线、中继器等等设备,都是你在端到端交互过程中不可缺少的基础设备。
举例:快递员在投递的过程中,你写的信会历经一些交通运输工具,比如首先通过飞机运输到国外,在海关统一拿到信以后会通过汽车运输到LiLei所在城市的物流集散地,最后快递员通过三轮电频车寄到LiLei家里,这个时候,飞机、汽车、三轮电瓶车都是物理层的媒介。
Nginx构建Tomcat集群
再另外准备三台虚拟机Tomcat1、Tomcat2、Tomcat3,他们对应的ip地址如下:
nginx:192.168.163.149Tomcat1:192.168.163.145Tomcat2:192.168.163.147Tomcat3:192.168.163.148
配置imooc.conf:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7XAuafri-1625445337390)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(1)].png)
重启nginx:sbin下:
nginx -tnginx -s reload
使用JMeter测试单节点与集群的并发异常率
JMeter下载网址:https://jmeter.apache.org/download_jmeter.cgi
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7P7FXB4a-1625445337391)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(2)].png)
设置50个用户,每个用户请求100次:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DPdFfORY-1625445337391)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(3)].png)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MVCKoBvk-1625445337392)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(4)].png)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gob6obae-1625445337392)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(5)].png)
添加聚合报告
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PW4e0SZo-1625445337393)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(6)].png)
添加查看结果树:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EOmvY5dG-1625445337394)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(7)].png)
添加用表格查看结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O686b94k-1625445337394)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(8)].png)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UP2QLL8D-1625445337394)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(9)].png)
平均值:请求的平均响应时间,单位ms
90%Line:5000次的请求90%的请求时间,另外10%请求时间高于该值。
利用本地虚拟机的一个tomcat和腾讯云的tomcat做真正的集群,再来测试一下。
本地:192.168.163.145:8080腾讯云:119.29.197.107:8080
新建一个JMeter的测试任务:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jBbr6BmE-1625445337395)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(10)].png)
可以看到延迟明显增加(这是因为一台是本机,另一台为其他的计算机结点),吞吐量也变小(更符合实际情况),但实际上使用集群后异常率会有很明显的降低,一般认为会有一个异常率的临界点,到了临界说明不能再增加更多的用户请求量了或者扩容。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yBQqOm7e-1625445337396)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(11)].png)
负载均衡-轮询
复原Nginx的配置文件:
修改Tomcat1:
cd /usr/local/apache-tomcat-9.0.24/webapps/ROOTvim index.jsp
同理,也修改一下Tomcat2和Tomcat3。
这时候再次访问http://www.tomcats.com时,会按照Tomcat1、3、2的顺序不断轮询。
负载均衡-加权轮询
修改nginx的imooc.conf配置文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zyHmN0kT-1625445337398)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(12)].png)
重新运行之后,大多数请求会落在tomcat3上。
upstream的指令参数-max_conns
upstream的指令参数主要有:
- max_conns
- slow_start
- down
- backup
- max_fails
- fail_timeout
max_conns:限制每台server的连接数,用于保护避免过载。可起到限流的作用。
测试配置如下:
# worker进程设置1个,便于测试观察成功的连接数
worker_processes 1;
upstream tomcats {
server 192.168.1.173:8080 max_conns=2;
server 192.168.1.174:8080 max_conns=2;
server 192.168.1.175:8080 max_conns=2;
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dh6Ib1Bz-1625445337398)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(13)].png)
并且,将nginx.conf的worker_processes设置为1,这样的话就不会用到共享内存了。
使用JMeter做测试:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xzcQR0Dm-1625445337399)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(14)].png)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OzWEyVhK-1625445337399)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(15)].png)
当连接数达到上限后,就不会在接收请求了,报bad gateway错误
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8IYehBby-1625445337400)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(16)].png)
upstream的指令参数-slow_start
商业版,需要付费
配置参考如下:
upstream tomcats { server 192.168.1.173:8080 weight=6 slow_start=60s; # server 192.168.1.190:8080; server 192.168.1.174:8080 weight=2; server 192.168.1.175:8080 weight=2;}
注意:
- 该参数不能使用在hash和random load balancing中。
- 如果在upstream中只有一台server,则该参数无效。
slow_start=time 设置服务器权重从0恢复到标准值的时间。
默认值为0,缓慢的启动。
upstream的指令参数-down和backup
down用于标记服务节点不可用:
upstream tomcats { server 192.168.1.173:8080 down; # server 192.168.1.190:8080; server 192.168.1.174:8080 weight=1; server 192.168.1.175:8080 weight=1;}
测试发现,只能访问tomcat2和tomcat3。
backup表示当前服务器节点时备用机,只有在其他的服务器都宕机之后,自己才会加入到集群当中,被用户访问到。
upstream tomcats { server 192.168.1.173:8080 backup; # server 192.168.1.190:8080; server 192.168.1.174:8080 weight=1; server 192.168.1.175:8080 weight=1;}
注意:backup参数不能使用在hash和random load balancing中。
这时候,我们将tomcat2和tomcat3停掉,我们再次访问www.tomcats.com,多次刷新,发现只能访问到tomcat1。
upstream的指令参数-max_fails和fail_time_out
- max_fails:表示失败几次,则标记server已宕机,剔出上游服务
- fail_time_out:表示失败的重试时间。
假设目前的配置如下:
max_fail=2fail_timeout=15s
则代表在15秒内请求某一个server失败2次后,则认为该server已经宕机了,随后再过15秒,这15秒内不会有新的请求到达刚刚挂掉的节点上,而是会请求到正常运作恶的server,15秒后会再有新请求尝试连接挂掉的server,如果还是失败,重复上一过程。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jOH0lQlE-1625445337401)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(17)].png)
使用Keepalived提高吞吐量
keeplive可以让一部分的链接作为长链接
使用JMeter测试:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XOm1eqBc-1625445337406)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(18)].png)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VOdZ5VUX-1625445337406)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(19)].png)
只开放腾讯云的服务器做一个吞吐量测试:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4t8vokFT-1625445337407)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(20)].png)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6juWjL66-1625445337407)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(21)].png)
使用keepalive:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0NbHVlhf-1625445337408)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(22)].png)
重新测试:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RimNF6Mt-1625445337408)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(23)].png)
keepalived : 设置长连接处理的数量proxy_http_version :设置长连接http版本为1.1proxy_set_header :清除connection header 信息upstream tomcats { # server 192.168.1.173:8080 max_fails=2 fail_timeout=1s; server 192.168.1.190:8080; # server 192.168.1.174:8080 weight=1; # server 192.168.1.175:8080 weight=1; keepalive 32;}server { listen 80; server_name www.tomcats.com; location / { proxy_pass http://tomcats; proxy_http_version 1.1; proxy_set_header Connection ""; }}
负载均衡之ip_hash
对ip计算hash值并对应到某一个tomcat上
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LcVf5pk0-1625445337409)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(24)].png)
配置ip_hash:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e1B4Oa4T-1625445337409)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(25)].png)
发现不管从哪一个虚拟机节点上访问192.168.163.149这个ip,最后都是tomcat2页面。
原因:是在进行hash的时候取的是前面三个数字,例如:
所以都会访问到同一个tomcat结点服务中。
ip_hash可以保证用户访问可以请求到上游服务中的固定的服务器,前提是用户ip没有发生更改。
使用ip_hash的注意点:
如果要想把某个服务器做一个临时移除,不能并且后台服务器直接移除,只能标记为down。
upstream tomcats { ip_hash; server 192.168.1.173:8080; server 192.168.1.174:8080 down; server 192.168.1.175:8080;}
nginx官方文档关于ip_hash的参考:
http://nginx.org/en/docs/http/ngx_http_upstream_module.html#ip_hash
一致性hash算法
hash算法带来的问题:
如果有一台tomcat宕机,之前所有的求模运算都要重来,开销比较大。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y9N5CdXt-1625445337410)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(26)].png)
用户按照顺时针方向,离哪个节点近,就去访问哪个节点。
此时如果有服务器宕机,直接顺着找下一个服务器节点就可以了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OxSj2QSc-1625445337410)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(27)].png)
如果要增加节点:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d55Guo6r-1625445337410)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(28)].png)
负载均衡原理-urlhash与least_conn
url_hash
根据请求的url做hash映射到不同的tomcat上。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rLylyWMI-1625445337411)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(29)].png)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-opXKq6uZ-1625445337411)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(30)].png)
如果某个tomcat的请求过多,可以将其变成Nginx再挂在多个tomcat。
根据每次请求的url地址,hash后访问固定的tomcat节点。
upstream tomcats { # url hash hash $request_uri; # 最少连接数 # least_conn server 192.168.1.173:8080; server 192.168.1.174:8080; server 192.168.1.175:8080;}server { listen 80; server_name www.tomcats.com; location / { proxy_pass http://tomcats; }}
注意,www.tomcats/nginx-url-hash/account/和www.tomcats/nginx-url-hash/account,有没有斜杠/对应地hash值是不同的。
least_conn
最少的连接数。那一台服务器的连接数少就去连接哪一台。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6FbRgjGu-1625445337412)(https://gitee.com/Curryforthreeeeee30/HexoPicture/raw/master/PicturteBed/clipboard%20(31)].png)
Nginx控制浏览器缓存
- 浏览器缓存:
加速用户访问,提升单个用户(浏览器访问者)体验,缓存在本地
- Nginx缓存
缓存在nginx端,提升所有访问到nginx这一端的用户
提升访问上游(upstream)服务器的速度
用户访问仍然会产生请求流量
为了演示,可以在/home/imooc下创建cache.html
<html> <body> <h1> Hello, Nginx ~ ! ~ </h1> </body></html>
shift + F5强制刷新
再普通刷新一次。
通过nginx可以控制浏览器的缓存,expires命令:
- expires [time]
修改imooc.conf
如果我们此时修改网页内容的话,http请求的status会变成200,重新加载进缓存,对应上面Last-Modified字段被修改。
-
expires @[time]
-
- @22h30m就表示晚上十点半
Date加上max-age就是刚刚设置的晚上十点半。
-
wxpires -[time]
-
- 缓存在之前就过期了
-
expires epoch
-
- 不设置缓存
-
expires off
-
- nginx端不添加cache,但不意味着浏览器没有
-
expires max
-
- 永不过期
Nginx的反向代理缓存
# proxy_cache_path 设置缓存目录# keys_zone 设置共享内存以及占用空间大小# max_size 设置缓存大小# inactive 超过此时间则被清理# use_temp_path 临时目录,使用后会影响nginx性能proxy_cache_path /usr/local/nginx/upstream_cache keys_zone=mycache:5m max_size=1g inactive=1m use_temp_path=offlocation / { proxy_pass http://tomcats; # 启用缓存,和keys_zone一致 proxy_cache mycache; # 针对200和304状态码缓存时间为8小时 proxy_cache_valid 200 304 8h;}
使用FTP工具向三台Tomcat的webapps中传入静态文件
nginx目录下多了一个文件夹
前端通过nginx访问一下tomcat
发现upstream_cache中会多出一些文件
过了30s之后文件会被清理掉
使用Nginx配置SSL证书提供HTTPS访问
会使用到下载的Nginx文件夹下的文件,需要上传到云服务器里。
将这两个文件放到nginx/conf目录下
1. 安装SSL模块
要在nginx中配置https,就必须安装ssl模块,也就是: http_ssl_module。
- 进入到nginx的解压目录: /home/software/nginx-1.16.1
- 新增ssl模块(原来的那些模块需要保留)
./configure \--prefix=/usr/local/nginx \--pid-path=/var/run/nginx/nginx.pid \--lock-path=/var/lock/nginx.lock \--error-log-path=/var/log/nginx/error.log \--http-log-path=/var/log/nginx/access.log \--with-http_gzip_static_module \--http-client-body-temp-path=/var/temp/nginx/client \--http-proxy-temp-path=/var/temp/nginx/proxy \--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \--http-scgi-temp-path=/var/temp/nginx/scgi \--with-http_ssl_module
-
编译和安装
make make install
2. 配置HTTPS
- 把ssl证书 *.crt 和 私钥 *.key 拷贝到/usr/local/nginx/conf 目录中。
- 新增 server 监听 443 端口(代表https):
server { listen 443; server_name www.imoocdsp.com; # 开启ssl ssl on; # 配置ssl证书 ssl_certificate 1_www.imoocdsp.com_bundle.crt; # 配置证书秘钥 ssl_certificate_key 2_www.imoocdsp.com.key; # ssl会话cache ssl_session_cache shared:SSL:1m; # ssl会话超时时间 ssl_session_timeout 5m; # 配置加密套件,写法遵循 openssl 标准 ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on; location / { proxy_pass http://tomcats/; index index.html index.htm; }}
3.reload nginx
./nginx -s reload
腾讯云Nginx配置https文档地址:
https://cloud.tencent.com/document/product/400/35244
动静分离
- 本质是分布式,将动态资源与静态资源分开。
- 前后端解耦。
- 静态资源归nginx管理。
- 接口服务化,接口单独部署,让前端进行对接。可以同时为多个跨平台的应用提供对接服务。
静态数据:css/js/html/images/audios/videos/…
动态数据:得到的响应可能会和上一次不同。
动静分离的方式CDN:
当请求数据的时候,会从离我们最近的服务节点拉取数据。
动静分离的方式Nginx:
当访问静态资源时,直接将静态资源放到Nginx里面,或者在Nginx的上游再挂载多台Nginx用于存放静态资源,即静态资源集群。
如果要请求接口数据,则会映射到Tomcat集群里
动静分离的问题:
-
跨域
-
- 可以通过springboot或nginx或jsonp控制
-
分布式会话
-
- 分布式缓存中间件Redis
部署Nginx到云端
现有架构:
Nginx部署架构:
2.17.1 安装Nginx
上传压缩包到云服务器
```bash
yum install gcc-c++
yum install -y pcre pcre-devel
yum install -y zlib zlib-devel
yum install -y openssl openssl-devel
```
解压,注意解压后得到的是源码,源码需要编译后才能安装
tar -zxvf nginx-1.16.1.tar.gz
编译之前,先创建nginx临时目录,不创建的话启动时会报错
mkdir /var/temp/nginx -p
在nginx目录,输入如下命令进行配置,目的是为了创建makefile文件
./configure \
--prefix=/usr/local/nginx \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--http-scgi-temp-path=/var/temp/nginx/scgi
编译
make
安装
make install
运行,进入到nginx的sbin目录下
nginx
2.17.2 配置反向代理
查询一下内网ip
在nginx的conf目录下新增一个配置文件tomcats.conf:
upstream wjwqxy.cn { server 10.0.8.15:8088;}server { listen 80; server_name wjwqxy.cn; location ~ { proxy_pass http://wjwqxy.cn; }}
不要忘了在nginx.conf中引入:
2.17.3 实现动静分离与虚拟主机
在/home下创建一个新的目录用于存放静态网站,之前是放在一个tomcat里了,这里不使用了。
mkdir website
停掉tomcat-fronted
cd /usr/local/tomcat-frontend/ bin/shutdown.sh
随后拷贝webapps中的foodie-center和foodie-shop
cp foodie-* /home/website/ -rf
注意要修改两个前端项目的app.js
在腾讯云设置二级域名:
进入nginx的配置文件夹,新建frontend.conf:
server { listen 80; server_name shop.wjwqxy.top; location / { root /home/website/foodie-shop; index index.html; }}server { listen 80; server_name center.wjwqxy.top; location / { root /home/website/foodie-center; index index.html; }}
不要忘了在nginx.conf中include:
2.17.4 测试与日志调试
cd /usr/local/tomcat-api/logs/
查看后台代码运行日志
tail catalina.out
动态日志,实时更新:
tail catalina.out -f
修改回调通知的url,把端口号去掉,才能使得回调到nginx里:
**小结一下:**Nginx目前的作用就是反向代理,负载均衡器,网关和动静分离。如果在一个配置比较差的云服务器里,nginx发挥的性能优势并不会很大,甚至可能降低,因为进行代理时会有损耗的。
Keepalived
3.1 高可用集群架构 Keepalived 双机主备原理
Nginx高可用(High Availability, HA)
Keepalived:
- 解决单点故障
- 组件免费
- 可以实现高可用HA机制
- 基于VRRP协议
虚拟路由冗余协议VRRP:
- Virtual Router Redundancy Protocol
- 解决内网单机故障的路由协议
- 构建有多个路由器,分为MASTER和BACKUP
- 虚拟IP - VIP(Virtual IP Address)
当MASTER挂了之后,BACKUP之间会有一个选举的流程。
Keepalived双机主备原理:
用户访问一个虚拟ip,相应的nginx的内容就可以显示给用户。如果nginx挂了,相应的虚拟ip就可以指向备用机,用户请求的ip不变。
但有一点需要注意,两台的Nginx配置需要相同,以免影响用户体验。
3.2 Keepalived安装
这里主Nginx为192.168.163.149
备用Nginx为192.168.163.150
虚拟ip设为192.168.163.161
https://www.keepalived.org/index.html
通过ftp工具上传到Nginx主机和备用机中,/home/software
解压
tar -zxvf keepalived-2.0.18.tar.gz
解压后进入到解压出来的目录,看到会有configure ,那么就可以做配置了(配置安装和nginx一模一样)
./configure --prefix=/usr/local/keepalived --sysconf=/etc
配置过程中可能会出现警告信息
安装libnl/libnl-3依赖
yum -y install libnl libnl-devel
重新configure一下
运行完成之后会生成Makefile,再安装
make && make install
进入keepalived目录下
3.3 keepalived核心配置文件
1. 通过命令 vim keepalived.conf 打开配置文件
配置文件在/etc/keepalived
global_defs { # 路由id:当前安装keepalived的节点主机标识符,保证全局唯一 router_id keep_149}vrrp_instance VI_1 { # 表示状态是MASTER主机还是备用机BACKUP state MASTER # 该实例绑定的网卡 interface ens33 # 保证主备节点一致即可 virtual_router_id 51 # 权重,master权重一般高于backup,如果有多个,那就是选举,谁的权重高,谁就当选 priority 100 # 主备之间同步检查时间间隔,单位秒 advert_int 1 # 认证权限密码,防止非法节点进入 authentication { auth_type PASS auth_pass 1111 } # 虚拟出来的ip,可以有多个(vip) virtual_ipaddress { 192.168.163.161 }}
附:查看网卡名称
2. 启动 Keepalived
cd /usr/local/keepalived/sbin
在sbin目录中进行启动(同nginx),如下图:
启动之后查看ip
ip addr
发现多了一个192.168.163.161
3.4 把Keepalived 注册为系统服务
测试之前的安装
可以将keepalived注册到linux操作系统中,一遍更好地对其操作
cd /home/software/keepalived-2.0.18/keepalived/etc
拷贝两个文件
cp init.d/keepalived /etc/init.d/ cp sysconfig/keepalived /etc/sysconfig/
刷新一下
systemctl daemon-reload
此时的启动命令
systemctl start keepalived.service
停止命令
systemctl stop keepalived.service
重启命令
systemctl restart keepalived.service
3.5 Keepalived实现双机主备高可用
1. 通过命令 vim keepalived.conf 打开配置文件
cd /etc/keepalived/
global_defs { router_id keep_150}vrrp_instance VI_1 { # 备用机设置为BACKUP state BACKUP interface ens33 virtual_router_id 51 # 权重低于MASTER priority 80 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { # 注意:主备两台的vip都是一样的,绑定到同一个vip 192.168.163.161 }}
2. 启动 Keepalived
cd /usr/local/keepalived/sbin/ ./keepalived
由于这个是备用机,所以现在没有192.168.163.161这个ip
或者
# 启动keepalivedsystemctl start keepalived# 停止keepalivedsystemctl stop keepalived# 重启keepalivedsystemctl restart keepalived
3. 查看进程
ps -ef|grep keepalived
现在停止一下主Nginx的keepalived
systemctl stop keepalived.service
再看备用机的ip,发现多了虚拟ip那一个
再重新启动主Nginx的keepalived
systemctl start keepalived.service
发现虚拟ip和备用机解绑了,又和主机连接上了。
3.6 Keepalived配置Nginx自动重启,实现7x24不间断服务
如果是主Nginx挂了不是keepalived挂了,那么绑定会不变但访问虚拟节点时会访问不到。这里需要写脚本来进行配置。
1. 增加Nginx重启检测脚本
cd /etc/keepalived/ vim check_nginx_alive_or_not.sh
#!/bin/bashA=`ps -C nginx --no-header |wc -l`# 判断nginx是否宕机,如果宕机了,尝试重启if [ $A -eq 0 ];then /usr/local/nginx/sbin/nginx # 等待一小会再次检查nginx,如果没有启动成功,则停止keepalived,使其启动备用机 sleep 3 if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then killall keepalived fifi
-
增加运行权限
chmod +x /etc/keepalived/check_nginx_alive_or_not.sh ./check_nginx_alive_or_not.sh
2. 配置keepalived监听nginx脚本
vim keepalived.conf
vrrp_script check_nginx_alive {
script "/etc/keepalived/check_nginx_alive_or_not.sh"
interval 2 # 每隔两秒运行上一行脚本
weight 10 # 如果脚本运行成功,则升级权重+10
}
3. 在vrrp_instance 中新增监控的脚本
track_script {
check_nginx_alive # 追踪 nginx 脚本
}
4. 重启Keepalived使得配置文件生效
systemctl restart keepalived
测试:
cd /usr/local/nginx/sbin/ ./nginx -s stop
发现nginx会自动重启
3.7 高可用集群架构 Keepalived 双主热备原理
上面的方案需要购买两台服务器,成本较高。
双主热备:
为了让两台节点都发挥作用,可以再建立一个虚拟ip192.168.163.162与备用机192.168.163.150绑定,如果150发生故障,162就与主机192.168.163.149绑定。
这里就没有主备关系了,而是互为主备。
此时前端请求会轮询访问两个虚拟ip。
3.8 实现keepalived双主热备
规则:以一个虚拟ip分组归为同一个路由
主节点配置:
cd /etc/keepalived/
global_defs { router_id keep_171}vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.163.161 }}vrrp_instance VI_2 { state BACKUP interface ens33 virtual_router_id 52 priority 80 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.163.162 }}
备用节点配置
global_defs { router_id keep_172}vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 51 priority 80 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.163.161 }}vrrp_instance VI_2 { state MASTER interface ens33 virtual_router_id 52 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.163.162 }}
重启两个keepalived
systemctl restart keepalived.service
测试:
149主机和161这个虚拟ip绑定,150主机和162这个虚拟ip绑定
关闭150的keepalived
systemctl stop keepalived.service
虚拟ip自动切换到149
虚拟ip1 192.168.163.161
虚拟ip2 192.168.163.162
Nginx主 192.168.163.149
Nginx备 192.168.163.150
Tomcat1 145
Tomcat2 147
Tomcat3 148
LVS
4.1 简介
- Linux Virtual Server
- 章文嵩博士主导的开源负载均衡项目
- LVS(ipvs)已被集成到Linux内核中
- 负载均衡调度器,基于四层,即ip+端口号(七层是在应用层对请求报文的负载均衡)
http://www.linux-vs.org/index.html
The Linux Virtual Server is a highly scalable and highly available server built on a cluster of real servers(真实服务器), with the load balancer running on the Linux operating system. The architecture of the server cluster is fully transparent to end users, and the users interact as if it were a single high-performance virtual server.
和Nginx的道理类似。
LVS网络拓扑图:
4.2 为什么要使用 LVS + Nginx
- LVS基于四层,工作效率高,Nginx多了一个对请求处理的步骤
- 单个Nginx承受不了压力,需要集群
- LVS充当Nginx集群的调度者,LVS不需要处理报文,所以负载能力更高
- Nginx接受请求来回,LVS可以只接受不响应
Nginx:
LVS:
ipvs是LVS的核心,可以产生虚拟ip,用户通过虚拟ip进行访问
4.3 LVS的三种模式
4.4 搭建LVS-DR模式- 配置LVS节点与ipvsadm
前期准备:
1、服务器与ip规划:
- LVS-1台
- VIP(虚拟ip):192.168.163.170
- DIP(转发者ip/内网ip):192.168.163.151
- Nginx-2台
- RIP(真实ip/内网ip):192.168.163.149
- RIP(真实ip/内网ip):192.168.163.150
2、所有计算机节点关闭网络配置管理器,因为有可能会和网络接口冲突:
systemctl stop NetworkManager
systemctl disable NetworkManager
创建子接口:
1、进入到网卡配置目录,找到ens33:
cd /etc/sysconfig/network-scripts/
2、拷贝并且创建子接口:
cp ifcfg-ens33 ifcfg-ens33:1
* 注:数字1
为别名,可以任取其他数字都行
3、修改子接口配置:vim ifcfg-ens33:1
4、配置参考如下:
- 注:配置中的192.168.163.170就是咱们的vip,是提供给外网用户访问的ip地址,道理和nginx+keepalived那时讲的vip是一样的。
5、重启网络服务,或者重启linux。
6、重启成功之后,ip addr查看一下,会发现多了一个ip,那个就是虚拟ip(vip)。
安装ipvsadm:
现如今的centod都是集成了LVS,所以ipvs都是自带的,相当于苹果手机自带ios,我们只需要安装ipvsadm即可(ipvsadm是管理集群的工具,通过ipvs可以管理集群,查看集群等操作),命令如下:
yum install ipvsadm
安装成功的检测:
图中显示目前版本为1.2.1,此外是一个空列表,因为集群还没有配置好。
关于虚拟ip在云上的事:
-
阿里云不支持虚拟IP,需要购买他的负载均衡服务
-
腾讯云支持虚拟IP,但是需要额外购买,一台节点最大支持10个虚拟ip。
4.5、搭建LVS-DR模式
4.5.1、为两台RS配置虚拟ip
对两台Nginx进行配置
配置虚拟网络子接口(回环接口)
1、进入到网卡配置目录,找到lo(本地环回接口,用户构建虚拟网络子接口),拷贝一份新的随后进行修改:
使用lo来构建子接口,构建虚拟ip,并且这个虚拟ip仅用于返回用户数据,而不能被用户访问到真实的服务器。
2、修改ifcfg-lo:1内容如下
ip设置为和LVS的虚拟ip相同192.168.163.170
刷新
ifup lo
3、重启后通过ip addr查看如下,表示ok:
对第二台Nginx重复上面的步骤。
4.5.2、为两台RS配置arp
arp-ignore:ARP响应级别,可以简单地理解为处理请求。
- 0:只要本机配置了ip,就能响应请求。
- 1:请求的目标地址到达对应地网络接口,才会响应。
arp-announce:ARP通告行为(返回响应)
- 0:本机上任何网络接口都向外通告,所有的网卡都能接收到通告。
- 1:尽可能避免本网卡与不匹配的目标进行通告
- 2:只在本网卡通告。
配置ARP:
1、打开sysctl.conf
vim /etc/sysctl.conf
2、配置所有的网卡、默认网卡以及虚拟网卡的arp响应级别和通告行为,分别对应:all、default、lo。
# configration for lvs
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
3、刷新配置文件
4、 增加一个网关,用于接收数据报文,当有请求到本机后,会交给lo去处理
yum install net-tools
route add -host 192.168.163.170 dev lo:1
5、防止重启失效,做如下处理,用于开机启动
echo "route add -host 192.168.163.170 dev lo:1" >> /etc/rc.local
打开rc.local文件进行查看
4.5.3、使用ipvsadm配置集群规则
在192.168.163.151LVS服务机上配置
1、创建LVS节点,用户访问的集群调度者
ipvsadm -A -t 192.168.163.170:80 -s rr -p 5
- -A:添加集群
- -t:tcp协议
- ip地址:设定的集群的访问ip,也就是LVS的虚拟ip
- -s:设置负载均衡的算法,rr表示轮询。
- -p:设置连接持久化的时间。
2、创建2台RS真实服务器
ipvsadm -a -t 192.168.163.170:80 -r 192.168.163.149:80 -g
ipvsadm -a -t 192.168.163.170:80 -r 192.168.163.150:80 -g
- -a:添加真实服务器
- -t:tcp协议
- -r:真实服务器的ip地址
- -g:设定DR模式
3、保存到规则库,否则重启失效
ipvsadm -S
4、检查集群
- 查看集群列表
ipvsadm -Ln
-
查看集群状态
ipvsadm -Ln --stats
5、其他命令:
# 重启ipvsadm,重启后需要重新配置
service ipvsadm restart
# 查看持久化连接
ipvsadm -Ln --persistent-conn
# 查看连接请求过期时间以及请求源ip和目标ip
ipvsadm -Lnc
# 设置tcp tcpfin udp 的过期时间(一般保持默认)
ipvsadm --set 1 1 1
# 查看过期时间
ipvsadm -Ln --timeout
6、更详细的帮助文档:
ipvsadm -h
man ipvsadm
4.5.4、验证DR模式,探讨LVS的持久化机制
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dr7F2SQU-1625445337451)(D:\java后端\笔记\图片\clipboard (15)].png)
out在这里是0,表示返回的那一部分不经过nginx返回,符合LVS-DR架构。
最开始连接上的时候有300s的持久化连接,所以一直刷新都是同一个页面(可以通过-p参数设置持久化的时间)。
除此之外还有一个tcp tcpfin udp的超时时间,可通过–set修改。
ipvsadm --set 1 1 1
4.5.6、搭建Keepalived+LVS+Nginx高可用负载均衡