一、集群阶段开篇概述
1、单体部署
1.1 单台服务器(节点)部署
1.2、多台服务器(节点)部署
集群、分布式、微服务中的各个服务器节点必须互通,必须在同一个局域网(内网要通)
1.3、单体架构的优点
1.4、单体架构面临的缺点
2、集群
2.1 “集群”与“分布式”概念区别
- 如果各个服务器节点处理的任务相同(相同的业务分配给了不同的节点去处理,降低单个节点的压力),则这些节点组成的系统成为“集群”
- 如果各个服务器节点处理的任务不同,则这些节点组成的系统成为“分布式”
2.2 “集群”的优势
- 提高系统性能
- 提高系统可用性(高可用)
- 可扩展性高
2.3 使用集群的注意点
- 用户会话(分布式会话)
- 定时任务
- 内网互通
二、Nginx集群
Nginx 可 实 现 功 能 { 单 节 点 { 网 关 反 向 代 理 动 静 分 离 集 群 : 负 载 均 衡 ( 通 过 nginx.conf 配 置 文 件 里 的 upstream 参 数 配 置 集 群 ) \text{Nginx}\ 可实现功能 \begin{cases} 单节点 \begin{cases} 网关\\ 反向代理\\ 动静分离 \end{cases} \\ 集群:负载均衡(通过\text{nginx.conf}配置文件里的\text{upstream}参数配置集群) \end{cases} Nginx 可实现功能⎩⎪⎪⎪⎨⎪⎪⎪⎧单节点⎩⎪⎨⎪⎧网关反向代理动静分离集群:负载均衡(通过nginx.conf配置文件里的upstream参数配置集群)
1、Nginx单节点配置
1.1 什么是Nginx?常用的Web服务器有哪些
1.2 什么是反向代理
1.2.1 正向代理
1.2.2 反向代理
反向代理用于:集群、负载均衡
1.3 Nginx安装与运行
- 去官网http://nginx.org/下载对应的nginx包,推荐使用稳定版本
- 上传nginx到linux系统
- 安装依赖环境
(1)安装gcc环境
yum install gcc-c++
(2)安装PCRE库,用于解析正则表达式
yum install -y pcre pcre-devel
(3)zlib压缩和解压缩依赖,
yum install -y zlib zlib-devel
(4)SSL 安全的加密的套接字协议层,用于HTTP安全传输,也就是https
yum install -y openssl openssl-devel
- 解压,需要注意,解压后得到的是源码,源码需要编译后才能安装
tar -zxvf nginx-1.16.1.tar.gz
- 编译之前,先创建nginx临时目录,如果不创建,在启动nginx的过程中会报错
mkdir /var/temp/nginx -p
- 在nginx目录,输入如下命令进行配置,目的是为了创建makefile文件
./configure \n --prefix=/usr/local/nginx \n --pid-path=/v...
配置命令:
- make编译
make
- 安装
make install
- 进入sbin目录启动nginx
./nginx
- 停止:./nginx -s stop
- 重新加载:./nginx -s reload
- 打开浏览器,访问虚拟机所处内网ip即可打开nginx默认页面,显示如下便表示安装成功:
注意事项:
- 如果在云服务器安装,需要开启默认的nginx端口:80
- 如果在虚拟机安装,需要关闭防火墙
- 本地win或mac需要关闭防火墙
1.4 Nginx显示默认首页
1.5 Nginx进程模型
1.6 Nginx处理Web请求机制
1.6.1 传统服务器
一个worker进程处理一个Client
1.6.2 Nginx服务器
一个worker进程处理多个Client,默认是1024
实现高并发的原因:
- worker抢占机制
- 异步非阻塞模式(多路复用器)
修改每个worker的默认连接数
阻塞 与 非阻塞 、 同步 与 异步
- 同步阻塞: 客户端发送请求给服务端,此时服务端处理任务时间很久,则客户端则被服务端堵塞了,所以客户端会一直等待服务端的响应,此时客户端不能做
事,服务端也不会接受其他客户端的请求。这种通信机制比较简单粗暴,但是效率不高。 - 同步非阻塞: 客户端发送请求给服务端,此时服务端处理任务时间很久,这个时候虽然客户端会一直等待响应,但是服务端可以处理其他的请求,过一会回来
的。这种方式很高效,一个服务端可以处理很多请求,不会在因为任务没有处理完而堵着,所以这是非阻塞的。 - 异步阻塞: 客户端发送请求给服务端,此时服务端处理任务时间很久,但是客户端不会等待服务器响应,它可以做其他的任务,等服务器处理完毕后再把结果
端,客户端得到回调后再处理服务端的响应。这种方式可以避免客户端一直处于等待的状态,优化了用户体验,其实就是类似于网页里发起的ajax异步请求。 - 异步非阻塞: 客户端发送请求给服务端,此时服务端处理任务时间很久,这个时候的任务虽然处理时间会很久,但是客户端可以做其他的任务,因为他是异步
回调函数里处理响应;同时服务端是非阻塞的,所以服务端可以去处理其他的任务,如此,这个模式就显得非常的高效了。
以上四点,除了第三点,其余的分别为BIO/NIO/AIO,面试官如果问你 “请简述一下BIO/NIO/AIO之间的概念与区别” ,那么你就可以组织一下语言来回答
下生活实例来阐述也是可以的:
- BIO: 我去上厕所,这个时候坑位都满了,我必须等待坑位释放了,我才能上吧?!此时我啥都不干,站在厕所里盯着,过了一会有人出来了,我就赶紧蹲上
- NIO: 我去上厕所,这个时候坑位都满了,没关系,哥不急,我出去抽根烟,过会回来看看有没有空位,如果有我就蹲,如果没有我出去接着抽烟或者玩会手
- 异步阻塞: 我去上厕所,这个时候坑位都满了,没事我等着,等有了新的空位,让他通知我就行,通知了我,我就蹲上去。
- AIO: 我去上厕所,这个时候坑位都满了,没事,我一点也不急,我去厕所外面抽根烟再玩玩手机,等有新的坑位释放了,会有人通知我的,通知我了,我就
了。
从这个生活实例中能可以看得出来:
- 同步 就是我需要自己每隔一段时间,以轮训的方式去看看有没有空的坑位;
- 异步 则是有人拉完茅坑会通知你,通知你后你再回去蹲;
- 阻塞 就是在等待的过程中,你不去做其他任何事情,干等着;
- 非阻塞 就是你再等待的过程中可以去做其他的事,比如抽烟、喝酒、烫头、玩手机。
小结: 异步 的优势显而易见,大大优化用户体验, 非阻塞 使得系统资源开销远远小于 阻塞 模式,因为系统不需要创建新的进程(或线程),大大地节省了系统
多出来的系统资源可以给其他的中间件去服务了
1.7 nginx.conf 配置
-
设置worker进程的用户,指的linux中的用户,会涉及到nginx操作目录或文件的一些权限,默认为 nobody
user root;
-
worker进程工作数设置,一般来说CPU有几个,就设置几个,或者设置为N-1也行
worker_processes 1;
-
nginx 日志级别 debug | info | notice | warn | error | crit | alert | emerg ,错误级别从左到右越来越大
-
设置nginx进程 pid
pid logs/nginx.pid;
-
设置工作模式
events { # 默认使用epoll use epoll; # 每个worker允许连接的客户端最大连接数 worker_connections 10240; }
-
http 是指令块,针对http网络传输的一些指令配置
http { }
-
include 引入外部配置,提高可读性,避免单个配置文件过大
include mime.types;
-
设定日志格式, main 为定义的格式名称,如此 access_log 就可以直接使用这个变量了
-
sendfile 使用高效文件传输,提升传输性能。启用后才能使用 tcp_nopush ,是指当数据表累积一定大小后才发送,提高了效率。
sendfile on; tcp_nopush on;
-
keepalive_timeout 设置客户端与服务端请求的超时时间,保证客户端多次请求的时候不会重复建立新的连接,节约资源损耗。
#keepalive_timeout 0; keepalive_timeout 65;
user www www;
worker_processes auto;
error_log /www/wwwlogs/nginx_error.log crit;
pid /www/server/nginx/logs/nginx.pid;
worker_rlimit_nofile 51200;
events
{
use epoll;
worker_connections 51200;
multi_accept on;
}
http
{
include mime.types;
#include luawaf.conf;
include proxy.conf;
default_type application/octet-stream;
server_names_hash_bucket_size 512;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 50m;
sendfile on;
tcp_nopush on;
keepalive_timeout 60;
tcp_nodelay on;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_disable "MSIE [1-6]\.";
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
server_tokens off;
access_log off;
server
{
listen 888;
server_name phpmyadmin;
index index.html index.htm index.php;
root /www/server/phpmyadmin;
location ~ /tmp/ {
return 403;
}
#error_page 404 /404.html;
include enable-php.conf;
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
location ~ .*\.(js|css)?$
{
expires 12h;
}
location ~ /\.
{
deny all;
}
access_log /www/wwwlogs/access.log;
}
include /www/server/panel/vhost/nginx/*.conf;
}
1.8 Nginx常用命令
1.9 Nginx日志切割
现有的日志都会存在 access.log 文件中,但是随着时间的推移,这个文件的内容会越来越多,体积会越来越大,不便于运维人员查看,所以我们可以通过把
文件切割为多份不同的小文件作为日志,切割规则可以以 天 为单位,如果每天有几百G或者几个T的日志的话,则可以按需以 每半天 或者 每小时 对日志切割一
1.9.1 Nginx 日志切割-手动
具体步骤如下:
-
创建一个shell可执行文件: cut_my_log.sh ,内容为:
#!/bin/bash LOG_PATH="/var/log/nginx/" RECORD_TIME=$(date -d "yesterday" +%Y-%m-%d+%H:%M) PID=/var/run/nginx/nginx.pid mv ${LOG_PATH}/access.log ${LOG_PATH}/access.${RECORD_TIME}.log mv ${LOG_PATH}/error.log ${LOG_PATH}/error.${RECORD_TIME}.log #向Nginx主进程发送信号,用于重新打开日志文件 kill -USR1 `cat $PID`
-
为 cut_my_log.sh 添加可执行的权限:
chmod +x cut_my_log.sh
-
测试日志切割后的结果:
./cut_my_log.sh
1.9.2 Nginx 日志切割-自动
使用定时任务
-
安装定时任务:
yum install crontabs
-
crontab -e 编辑并且添加一行新的任务:
*/1 * * * * /usr/local/nginx/sbin/cut_my_log.sh
-
重启定时任务:
service crond restart
附:常用定时任务命令:
service crond start //启动服务 service crond stop //关闭服务 service crond restart //重启服务 service crond reload //重新载入配置 crontab -e // 编辑任务 crontab -l // 查看任务列表
定时任务表达式:
Cron表达式是,分为5或6个域,每个域代表一个含义,如下所示:
常用表达式:
-
每分钟执行:
*/1 * * * *
-
每日凌晨(每天晚上23:59)执行:
59 23 * * *
-
每日凌晨1点执行:
0 1 * * *
参考文献:每天定时为数据库备份:https://www.cnblogs.com/leechenxiang/p/7110382.html
1.10 虚拟主机 - 使用Nginx为静态资源提供服务
1.10.1 前端html页面
/homt/foodie-shop文件夹里放前后端分离项目的前端页面部分
1.10.2 静态资源文件
css、js、音频、视频、图片等
假如服务器路径为:/home/imooc/files/img/face.png
-
root 路径完全匹配访问
配置的时候为:location /imooc { root /home }
用户访问的时候请求为: url:port/imooc/files/img/face.png
-
alias 可以为你的路径做一个别名,对用户透明
配置的时候为:location /hello { root /home/imooc }
用户访问的时候请求为: url:port/hello/files/img/face.png ,如此相当于为目录 imooc 做一个自定义的别名。
1.11 使用Gzip压缩提升请求效率
1.12 nginx.conf配置文件中的location的匹配规则解析
1.12.1 精确匹配【=】
1.12.2 正则表达式匹配【~*】
1.12.3 以某个字符路径开头的匹配
location 的匹配规则
-
空格 :默认匹配,普通匹配
location / { root /home; }
-
= :精确匹配
location = /imooc/img/face1.png { root /home; }
-
~* :匹配正则表达式,不区分大小写
#符合图片的显示location ~ \.(GIF|jpg|png|jpeg) { root /home; }
-
~ :匹配正则表达式,区分大小写
#GIF必须大写才能匹配到 location ~ \.(GIF|jpg|png|jpeg) { root /home; }
-
^~ :以某个字符路径开头
location ^~ /imooc/img { root /home; }
1.13 DNS域名解析【阿里云、腾讯云】
-
只有Nginx对外可见
-
Tomcat1、Tomcat2是对外不可见的
使用SwitchHosts 模拟本地域名解析访问
虚拟机测试时可以使用SwithcHosts工具
1.14 在Nginx中解决跨域问题
Nginx 跨域配置支持
#允许跨域请求的域,*代表所有
add_header 'Access-Control-Allow-Origin' *;
#允许带上cookie请求
add_header 'Access-Control-Allow-Credentials' 'true';
#允许请求的方法,比如 GET/POST/PUT/DELETE
add_header 'Access-Control-Allow-Methods' *;
#允许请求的header
add_header 'Access-Control-Allow-Headers' *;
1.15 在Nginx中配置静态资源防盗链
Nginx 防盗链配置支持
#对源站点验证
valid_referers *.imooc.com;
#非法引入会进入下方判断
if ($invalid_referer) {
return 404;
}
1.16 Nginx的模块化体系
2、Nginx的集群【配置upstream】
2.1 OSI 网络模型
在讲到Nginx负载均衡的时候,其实Nginx是七层负载均衡,后续我们还会涉及到LVS,是四层负载均衡,七层和四层是什么概念呢?这就必须提到网络模型。网络模型是计算机网络基础的一部分内容,一般大学计算机系都会讲到此知识点,并且会作为考点;其实在面试过程中有时候也会被问到。所以我们还是有必要来复习或学习一些重要知识的。
网络模型就是 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地址,以确保请求
性。
举例:快递员在投递派送的时候,他(或客服)会预先提前打电话给你,确认你家地址对不对、有没有人、货到付款有没有准备好钱等
候快递员(或客服)就充当了 数据链路层 的职责。
2.2 四层、七层与DNS负载均衡法案
2.2.1 四层负载均衡【一般用LVS】
四层负载均衡一般用于处理TCP协议的请求
一般用于转发请求,而不是处理请求
2.2.2 七层负载均衡【一般用Ngnix】
七层负载均衡一般用于处理http协议,一般用于web服务器,比如Tomcat、Apach、Nginx等
可以处理请求
2.3 DNS地域负载均衡
2.4 使用Nginx搭建3台Tomcat集群【配置upstream】
使用4台服务器节点,其中一台作为Nginx服务器,另外3台作为Tomcat服务器
假设要访问的域名为:www.tomcats.com
在Nginx所在服务器修改配置文件,实现反向代理
访问www.tomcat.com后,请求就会被Nginx服务器转发到3个Tomcat服务器之一
2.5 使用JMeter测试单节点与集群的并发异常率
如果现有集群并发的异常率开始高于临界点(比如:20%),则考虑增加节点。
2.5.1 单节点测试
2.5.2 集群测试
2.6 集群负载均衡策略
2.6.1 “轮训”策略【默认】
默认策略,每个请求会按时间顺序逐一分配到不同的节点服务器
2.6.2 “加权轮询”策略
如果各个节点服务器的硬件条件不一样,有的配置高,有的配置低,则给配置高的节点处理更多的请求。
weight 默认为1
- 1/8的请求分发给192.168.1.173
- 2/8的请求分发给192.168.1.174
- 5/8的请求分发给192.168.1.175
2.6.3 “ip_hash”策略
同一个用户的ip在一定时间内是固定的,该ip通过hash函数后得到的值也是固定的,会被Nginx转发到同一台节点服务器,其session就固定在该台节点服务器。
如果该用户的ip发生了动态变化,则该ip通过hash函数后,可能会被Nginx转发到其他节点服务器上。
ip_hash 可以保证用户访问可以请求到上游服务中的固定的服务器,前提是用户ip没有发生更改。
使用ip_hash的注意点:不能把后台服务器直接移除,只能标记 down ,否则之前通过ip_hash计算的所有用户的ip的hash值都会发生变化,那么用户的会话、服务器缓存都要重新计算,引起不必要的麻烦。
upstream tomcats {
ip_hash;
server 192.168.1.173:8080;
server 192.168.1.174:8080 down;
server 192.168.1.175:8080;
}
ip_hash算法只会拿ip的前3段数据进行hash计算
2.6.3.1 普通hash算法的问题
如果某个节点服务器挂掉,则用户ip的hash值需要重新计算一遍,会造成用户会话、服务器缓存的重置。
2.6.3.2 一致性hash算法
2.6.4 “url_hash”策略
2.6.5 “least_conn”策略
哪一台节点服务器上的连接数最少,则新的连接就转发到此台节点。
2.7 Upstream指令参数
2.7.1 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;
}
2.7.2 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,则该参数失效。
2.7.3 down
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;
}
2.7.4 backup
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 中。
2.7.5 max_fails、fail_timeout
max_fails :表示失败几次,则标记server已宕机,剔出上游服务。
fail_timeout :表示失败的重试时间。
假设目前设置如下:
max_fails=2 fail_timeout=15s
则代表在15秒内请求某一server失败达到2次后,则认为该server已经挂了或者宕机了,随后再过15秒,这15秒内不会有新的请求到达刚刚挂掉的节点上,而是会转发到正在运作的server,15秒后会再有新请求尝试连接挂掉的server,如果还是失败,重复上一过程,直到恢复。
3、提高Nginx的集群吞吐量【配置nginx.config文件中的upstream里的参数】
3.1 不使用Keepalive
upstream tomcats {
server 192.168.1.190:8080;
}
server {
listen 80;
server_name www.tomcats.com;
location / {
proxy_pass http://tomcats;
}
}
3.2 使用Keepalived
keepalive : 设置长连接处理的数量
proxy_http_version :设置长连接http版本为1.1
proxy_set_header :清除connection header 信息
upstream tomcats {
server 192.168.1.190:8080;
keepalive 32;
}
server {
listen 80;
server_name www.tomcats.com;
location / {
proxy_pass http://tomcats;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
4、Nginx控制缓存
4.1 浏览器缓存【静态资源】
加速用户访问,提升单个用户(浏览器访问者)体验,缓存在本地
4.2 Nginx的反向代理缓存
- 缓存在nginx端,提升所有访问到nginx这一端的用户
- 提升访问上游(upstream)服务器的速度
- 用户访问仍然会产生请求流量
# 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=30s use_temp_path=off
location / {
proxy_pass http://tomcats;
# 启用缓存,和keys_zone一致
proxy_cache mycache;
# 针对200和304状态码缓存时间为8小时
proxy_cache_valid 200 304 8h;
}
5、使用Nginx配置SSL证书提供HTTPS访问
5.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
5.2 配置HTTPS
- 把ssl证书 *.crt 和 私钥 *.key 拷贝到 /usr/local/nginx/conf 目录中。
- 新增 server 监听 443 端口(443是https默认端口,80端口是http默认端口):
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;
}
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
6、动静分离【动态资源与静态资源分开部署;分布式部署】
6.1 动静分离的方式一:CDN
将自己公司应用的静态资源(css/js/图片/视频/音频)放到第三方CDN服务器上,第三方CDN在全国、全球有很多节点,放到此CDN上的静态资源会分发到各个节点,用户访问应用时(比如:html网页),html需要加载这些静态资源时,会直接从离用户最近的CDN节点服务器下载这些静态资源。
6.2 动静分离的方式二:Nginx
将静态资源放在自己的服务器节点上,通过Nginx提供静态资源的缓存。
参考:五、Nginx控制缓存
6.3 动静分离的问题
7、部署Nginx到云端服务器(比如:阿里云ECS)
7.1 将动态资源、静态资源分开
将静态资源(前端项目)放在一个文件夹中:将原来放在Tomcat服务器中的前端项目资源拷贝到专门放静态资源的文件夹 /home/website/中
7.2 配置Nginx对静态资源、动态资源的反向代理
在Nginx所在服务器配置反向代理,
- 静态资源:域名shop.z.mukewang.com指向其文件所在本节点文件夹地址 /home/website/foodie-shop
- 静态资源:域名center.z.mukewang.com指向其文件所在本节点文件夹地址 /home/website/foodie-center
- 动态资源:域名api.z.mukewang.com 指向动态资源所在的服务器ip及端口。
三、Nginx高可用【使用Keepalived组件】(HA=High Availability)
当只有一台节点服务器充当Nginx作用的话,如果该服务器宕机,则整个系统不可用。需要备用节点服务器来实现高可用。
Nginx主备节点不会同时提供服务【同一个时刻,只有一个Nginx提供服务】
主备节点服务器的配置要保持一致。
通过VRRP,主节点向备用节点发送心跳,当备用节点感知到主节点是否存活,如果备用节点在规定时间内感知不到主节点的心跳,则备用节点开始与虚拟ip绑定,接管主节点的Nginx任务。
当主节点服务器恢复正常,则备用节点自动将权限交给主节点,备用节点重新进入待命状态。
1、安装keepalived组件【www.keepalived.org】
将下载的keepalived安装包上传到Linux服务器,并解压
进入keepalived文件夹,设置配置:
通过 make && make install
安装
安装成功:
keepalived核心配置文件:/etc/keepalived/keepalived.conf
2、配置keepalived
keepalived核心配置文件:/etc/keepalived/keepalived.conf
2.1 主节点Nginx配置keepalived
- 通过命令 vim keepalived.conf 打开配置文件
附:查看网卡名称global_defs { # 路由id:当前安装keepalived的节点主机标识符,保证全局唯一 router_id keep_171 } vrrp_instance VI_1 { # 表示状态是MASTER主机还是备用机BACKUP state MASTER # 该实例绑定的网卡 interface ens33 # 保证主备节点一致即可 virtual_router_id 51 # 权重,master权重一般高于backup,如果有多个,那就是选举,谁的权重高,谁就当选 priority 100 # 主备之间同步检查时间间隔,单位秒 advert_int 2 # 认证权限密码,防止非法节点进入 authentication { auth_type PASS auth_pass 1111 } # 虚拟出来的ip,可以有多个(vip) virtual_ipaddress { 192.168.1.161 } }
- 启动 Keepalived
在sbin目录中进行启动(同nginx),如下图:# 启动keepalived systemctl start keepalived # 停止keepalived systemctl stop keepalived # 重启keepalived systemctl restart keepalived
开启之后会多一个192.168.1.161虚拟ip
查看keepalived相关进程
查看keepalived相关进程ps -ef|grep keepalived
- 将keepalived命令注册到Linux系统
2.2 备用节点Nginx配置keepalived
- 通过命令 vim keepalived.conf 打开配置文件
global_defs { # 路由id:当前安装keepalived的节点主机标识符,保证全局唯一 router_id keep_172 } vrrp_instance VI_1 { # 备用机设置为BACKUP state BACKUP interface ens33 virtual_router_id 51 # 权重低于MASTER priority 80 advert_int 2 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { # 注意:主备两台的vip都是一样的,绑定到同一个vip 192.168.1.161 } }
- 开启备用节点的keepalived
./keepalived
主节点正常,所以备用节点中没有虚拟节点ip192.168.1.161
。
2.3 模拟主节点Nginx故障
- 停止主节点 192.168.1.171 的keepalived服务
- 查看备用节点 192.168.1.172 的keepalive的ip状态
可以看到备用节点的Nginx开始启用,请求域名后,显示备用节点的内容
- 重新启用主节点
主节点的虚拟ip恢复
备用节点的虚拟ip消失
请求域名后,又再次显示主节点的内容
3、Keepalived配置Nginx自动重启
如果主节点的Keepalived组件正常,但是仅仅是Nginx异常,则虚拟ip依旧会指向主节点,这样就是出现访问异常。
为了保障整个系统正常访问,Keepalive组件要定时检测Nginx是否正常,如果检测到Nginx异常,则重启该Nginx,如果该节点的Nginx无法启动,则将虚拟节点切换到备用节点。
3.1 增加Nginx重启检测脚本
进入 /etc/keepalived 目录,添加 check_nginx_alive_or_not.sh 脚本文件。
vim /etc/keepalived/check_nginx_alive_or_not.sh
#!/bin/bash
A=`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
fi
fi
增加运行权限:chmod +x /etc/keepalived/check_nginx_alive_or_not.sh
3.2 配置keepalived监听nginx脚本
进入keepalived核心配置文件:/etc/keepalived/keepalived.conf,添加以下方法:
vrrp_script check_nginx_alive {
script "/etc/keepalived/check_nginx_alive_or_not.sh"
interval 2 # 每隔两秒运行上一行脚本
weight 10 # 如果脚本运行成功,则升级权重+10
}
在 vrrp_instance VI_1 中新增监控的脚本
track_script {
check_nginx_alive # 追踪 nginx 脚本
}
3.4 重启Keepalived使得配置文件生效
systemctl restart keepalived
4、Keepalived双主热备【充分利用多个Nginx节点】
双机主备的缺点:如果主节点不挂掉,备用节点永远都没有事情做,造成资源浪费。
让域名绑定到2个不同的ip上,实现轮询,域名会根据各个ip的权重来分配域名转发到该ip所在服务器节点的比例。
DNS轮询配置
4.1 “节点1”上的Keepalived配置文件
规则:以一个虚拟ip分组归为同一个路由
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.1.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.1.162
}
}
4.2 “节点2”上的Keepalived配置文件
global_defs {
router_id keep_171
}
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.1.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.1.162
}
}
如果节点1宕机,原来连接节点1的虚拟ip转发到节点2
模拟节点1宕机:
原来连接到节点1的虚拟ip(192.168.1.161)转到节点2
四、LVS负载均衡【4层负载均衡】
LVS官网:http://www.linux-vs.org
LV为四层负载均衡,只转发请求,而不处理请求,而Nginx为七层负载均衡,会处理请求,所以LVS可处理的并发量远远大于Nginx,是Nginx的几十倍。
1、LVS的三种模式
1.1 LVS模式:NAT
此时,LVS与Nginx的作用一样,LVS直接连接公网,普通用户可以ping通LVS节点服务器的ip。外网的普通用户无法ping通处于内网的RealServer服务器。
1.2 LVS模式:TUN【ip隧道模式】
每一个RealServer 节点必须要有单独的网卡,分别给用户返回数据。RealServer 是暴露给公网的
1.3 LVS模式:DR【直接路由模式】
LVS、Router直接连接公网,普通用户可以ping通LVS、Router节点服务器的ip。外网的普通用户无法ping通处于内网的RealServer服务器。
2、搭建LVS-DR模式
2.1 前期准备
服务器与ip规划:
- LVS - 1台
- VIP(虚拟IP):192.168.1.150
- DIP(转发者IP/内网IP):192.168.1.151
- Nginx - 2台(RealServer)
- RIP(真实IP/内网IP):192.168.1.171
- RIP(真实IP/内网IP):192.168.1.172
所有计算机节点关闭网络配置管理器,因为有可能会和网络接口冲突:
systemctl stop NetworkManager
systemctl disable NetworkManager
2.2 为LVS节点配置虚拟ip、在LVS节点安装 ipvsadm软件
注意:阿里云上的ESC不能创建虚拟ip,需要购买他们的负载均衡服务套餐。
腾讯云可以购买虚拟ip,因为虚拟ip是建立在网卡之上的,是有成本的。腾讯云每台ECS支持的虚拟ip数量最多为10个。
首先通过 ip addr
命令可以看到:
网卡ens33上的内网ip只有:192.168.1.151
进入到网卡配置目录,找到咱们的ens33:
拷贝并且创建子接口:
# 注:`数字1`为别名,可以任取其他数字都行
cp ifcfg-ens33 ifcfg-ens33:1
修改子接口配置:
vim ifcfg-ens33:1
配置参考如下:
重启网卡
可以看到,网卡ens33上多了一个192.168.1.150 虚拟ip
安装 ipvsadm软件【集群管理工具】
2.3 为两台RealServer(Nginx所在节点服务器)配置虚拟ip
配置虚拟ip(回环接口),此接口可以给用户返回数据,但是不能被用户访问到。
- 进入到网卡配置目录,找到 lo(本地环回接口,用户构建虚拟网络子接口),拷贝一份新的随后进行修改:
- 修改内容如下:
- 重启后通过ip addr 查看如下,表示ok:
2.4 为两台RealServer(Nginx所在节点服务器)配置arp
ARP响应级别与通告行为 的概念
-
arp-ignore:ARP响应级别(处理请求)
0:只要本机配置了ip,就能响应请求
1:请求的目标地址到达对应的网络接口,才会响应请求 -
arp-announce:ARP通告行为(返回响应)
0:本机上任何网络接口都向外通告,所有的网卡都能接受到通告
1:尽可能避免本网卡与不匹配的目标进行通告
2:只在本网卡通告
打开sysctl.conf:
vim /etc/sysctl.conf
配置 所有网卡 、 默认网卡 以及 虚拟网卡 的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
刷新配置文件:
增加一个网关,用于接收数据报文,当有请求到本机后,会交给lo去处理:
route add -host 192.168.1.150 dev lo:1
当Linux重启后,会失效,所以需要将此命令加入开机自启动文件里。
2.5 使用ipvsadm配置集群规则【在LVS节点上】
创建LVS节点,用户访问的集群调度者
ipvsadm -A -t 192.168.1.150:80 -s rr -p 5
- -A:添加集群
- -t:tcp协议
- ip地址:设定集群的访问ip,也就是LVS的虚拟ip
- -s:设置负载均衡的算法,rr表示轮询
- -p:设置连接持久化的时间
创建2台RS真实服务器
ipvsadm -a -t 192.168.1.150:80 -r 192.168.1.171:80 -g
ipvsadm -a -t 192.168.1.150:80 -r 192.168.1.172:80 -g
- -a:添加真实服务器
- -t:tcp协议
- -r:真实服务器的ip地址
- -g:设定DR模式
保存到规则库,否则重启失效
ipvsadm -S
检查集群
- 查看集群列表
ipvsadm -Ln
- 查看集群状态
ipvsadm -Ln --stats
其他命令:
# 重启ipvsadm,重启后需要重新配置
service ipvsadm restart
# 查看持久化连接
ipvsadm -Ln --persistent-conn
# 查看连接请求过期时间以及请求源ip和目标ip
ipvsadm -Lnc
# 设置tcp tcpfin udp 的过期时间(一般保持默认)
ipvsadm --set 1 1 1
# 查看过期时间
ipvsadm -Ln --timeout
更详细的帮助文档:
ipvsadm -h
man ipvsadm