前言
Nginx 是我们常用的高性能 Web 和反向代理服务,它有很多优越的特性,下面我们详细的讲解如何从0到1实现Nginx高可用集群,包括配置详解、环境搭建、虚拟主机搭建、反向代理与负载均衡配置、代理文件服务器和高可用集群搭建等内容。
一、配置详解
Nginx 的核心配置文件是nginx.conf
,主要由 一下6 个模块部分组成:
模块 | 说明 |
---|---|
main | 用于进行 nginx 全局信息的配置 |
events | 用于 nginx 工作模式的配置 |
http | 用于进行 http 协议信息的一些配置 |
server | 用于进行服务器访问信息的配置 |
location | 用于进行访问路由的配置 |
upstream | 用于进行负载均衡的配置 |
1.1、main模块
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
配置项 | 说明 |
---|---|
user | 指定Nginx Worker进程运行用户,默认是nobody |
worker_processes | Nginx要开启的worker进程数,Nginx分为主进程master process和工作进程worker process,主进程负责监控端口,协调工作进程的工作状态,分配工作任务,工作进程负责进行任务处理,其值一般操作系统的CPU内核数成倍数 |
error_log | 全局错误日志文件,日志输出级别有debug(最详细)、info、notice、warn、error、crit(最少) |
pid | 指定进程pid的存储文件位置 |
1.2、events模块
events {
worker_connections 1024;
}
配置项 | 说明 |
---|---|
events | 设定Nginx的工作模式及连接数上限 |
worker_connections | 每个进程最大连接数,默认1024。最大客户端连接数由worker_processes和worker_connections决定,即Max_client=worker_processes*worker_connections(进程的最大连接数受Linux系统进程的最大打开文件数限制) |
1.3、http模块
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
....
}
}
配置项 | 说明 |
---|---|
include | 设定配置文件所包含的文件,即告诉浏览器文件数据类型是什么,让其进行打开/下载处理 |
default_type | 设定默认类型为二进制流,即当文件类型未定义时使用该方式处理 |
log_format | 用来指定Nginx日志的输出格式 |
access_log | 用来指定日志文件的路径和格式 |
sendfile | 开启高效文件传输模式 |
tcp_nopush | on表示防止网络阻塞 |
keepalive_timeout | 客户端连接保持活动的超时时间 |
gzip | on表示开启GZIP压缩,实时压缩输出数据流 |
server | 虚拟主机模块,下面会单独介绍 |
1.4、server模块
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
}
配置项 | 说明 |
---|---|
listen | 虚拟主机端口 |
server_name | 虚拟主机名称,为IP地址或域名 |
charset | 网页的默认编码格式 |
access_log | 指定该虚拟主机的日志文件路径和格式 |
location | 匹配指定的请求uri,下面会单独介绍 |
error_page | 错误跳转页面 |
1.5、location模块
location / {
root html;
index index.html index.htm;
}
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
#location ~ /\.ht {
# deny all;
#}
配置项 | 说明 |
---|---|
root | 指向根路径 |
index | 默认访问界面 |
proxy_pass | 反向代理配置 |
deny | 表示禁止,可以用来封IP |
1.6、upstream模块
upstream myServer {
ip_hash;
server 192.168.xx.128:8080;
server 192.168.xx.128:8081 weight=2;
server 192.168.xx.128:8082 down;
server 192.168.xx.128:8083 backup;
}
配置项 | 说明 |
---|---|
server | 指向到服务器地址 |
ip_hash | 每个请求按访问IP的hash结果分配,这样来自同一个IP的访客固定访问一个后端服务器,可解决session一致性问题 |
weight | 轮询权重值,值越大被访问的机率越高 |
down | 表示该的server 不参与负载 |
backup | 其它所有的非 backup 机器 down 或者忙的时候,请求 backup 机器 |
max_fails | 允许请求失败的次数,默认为1 |
fail_timeout | 在经历了max_fails次失败后,暂停服务的时间,默认10s |
二、环境搭建
2.1、 从官网下载nginx安装包
使用命令wget http://nginx.org/download/nginx-1.18.0.tar.gz
从官网直接下载到temp临时目录,当然也可以先去官网下载好,然后使用xftp
工具或者rz
命令上传到指定目录(如果需要回顾linux知识可以参考一文搞定Linux常见用法)
备注:
centos版本与nginx版本要适配,否则后面make编译时会报错,我这里使用的centos8和nginx 1.18.0
[root@localhost temp]# wget http://nginx.org/download/nginx-1.18.0.tar.gz
--2020-06-10 22:15:52-- http://nginx.org/download/nginx-1.18.0.tar.gz
正在解析主机 nginx.org (nginx.org)... 95.211.80.227, 62.210.92.35, 2001:1af8:4060:a004:21::e3
正在连接 nginx.org (nginx.org)|95.211.80.227|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:1039530 (1015K) [application/octet-stream]
正在保存至: “nginx-1.18.0.tar.gz”
2.2、安装依赖环境
2.2.1、安装gcc
nginx 是C语言开发的,如果没有 gcc 环境,需要安装 gcc对官网下载的源码包进行编译,命令yum install gcc-c++
[root@localhost temp]# yum install gcc-c++
Waiting for process with pid 1825 to finish.
CentOS-8 - AppStream 1.4 kB/s | 4.3 kB 00:03
CentOS-8 - Base 817 B/s | 3.9 kB 00:04
CentOS-8 - Extras 581 B/s | 1.5 kB 00:02
依赖关系解决。
省略....
2.2.2、安装PCRE
PCRE(Perl Compatible Regular Expressions)是一个 Perl 库,包括 perl 兼容的正则表 达式库。nginx 的 http 模块使用 pcre 来解析正则表达式,所以需要在 linux 上安装 pcre 库,命令yum install -y pcre pcre-devel
[root@localhost temp]# yum install -y pcre pcre-devel
上次元数据过期检查:0:03:29 前,执行于 2020年06月09日 星期二 23时37分44秒。
Package pcre-8.42-4.el8.x86_64 is already installed.
依赖关系解决。
...
2.2.3、安装zlib
zlib 库提供了很多种压缩和解压缩的方式,nginx 使用 zlib 对 http 包的内容进行 gzip, 所以需要在 linux 上安装 zlib 库,命令yum install -y zlib zlib-devel
[root@localhost temp]# yum install -y zlib zlib-devel
上次元数据过期检查:0:05:41 前,执行于 2020年06月09日 星期二 23时37分44秒。
Package zlib-1.2.11-10.el8.x86_64 is already installed.
依赖关系解决。
2.2.4、安装openssl
OpenSSL是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和 证书封装管理功能及 SSL 协议,并提供丰富的应用程序供测试或其它目的使用。nginx 不仅支持 http 协议,还支持 https(即在 ssl 协议上传输 http),所以需要在 linux 安装 openssl 库,命令yum install -y openssl openssl-devel
[root@localhost temp]# yum install -y openssl openssl-devel
上次元数据过期检查:0:07:27 前,执行于 2020年06月09日 星期二 23时37分44秒。
Package openssl-1:1.1.1-8.el8.x86_64 is already installed.
依赖关系解决。
...
2.3、编译安装
2.3.1、解压
命令tar -zxvf nginx-1.8.0.tar.gz
2.3.2、配置./configure
进入nginx根目录,可见configure文件
下面我们要执行一大串配置参数了,但执行前,我们先/var/目录下创建 temp临时目录,再创建nginx 目录(/var/temp/nginx
),上面的命令需要用到
[root@localhost nginx]# pwd
/var/temp/nginx
cd到nginx的根目录执行如下配置参数,里面指定了nginx最终的安装路径为/usr/local/nginx
./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
2.3.3、编译
1)执行make
命令
如果提示-bash: make: 未找到命令
,则需要先执行yum -y install gcc automake autoconf libtool make
[root@localhost nginx-1.18.0]# make
make -f objs/Makefile
make[1]: 进入目录“/root/temp/nginx-1.18.0”
cc -c -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
-o objs/src/core/nginx.o \
...
2)执行make install
命令
[root@localhost nginx-1.18.0]# make install
make -f objs/Makefile install
make[1]: 进入目录“/root/temp/nginx-1.18.0”
test -d '/usr/local/nginx' || mkdir -p '/usr/local/nginx'
...
执行完毕后,进入/usr/local/nginx/
中可查看到相关资源,说明nginx已经安装成功
[root@localhost nginx-1.18.0]# cd /usr/local/nginx/
[root@localhost nginx]# ll
总用量 4
drwxr-xr-x. 2 root root 4096 6月 10 22:22 conf
drwxr-xr-x. 2 root root 40 6月 10 22:22 html
drwxr-xr-x. 2 root root 19 6月 10 22:22 sbin
2.4、验证
2.4.1、启动nginx并查看效果
1)在sbin目录
下执行./nginx
启动服务
备注:
执行./nginx 启动 nginx,这里可以-c 指定加载的 nginx 配置文件,如下: ./nginx -c /usr/local/nginx/conf/nginx.conf 如果不指定-c,nginx 在启动时默认加载 conf/nginx.conf 文件,此文件的地址也可以在 编译安装 nginx 时指定./configure 的参数
[root@localhost /]# cd /usr/local/nginx/sbin/
[root@localhost sbin]# ./nginx
[root@localhost sbin]# ps -ef|grep nginx
root 4525 1 0 22:45 ? 00:00:00 nginx: master process ./nginx
nobody 4526 4525 0 22:45 ? 00:00:00 nginx: worker process
root 4528 1787 0 22:45 pts/0 00:00:00 grep --color=auto nginx
2)开防火墙端口(nginx默认为80端口)
[root@localhost sbin]# firewall-cmd --zone=public --add-port=80/tcp --permanent
success
[root@localhost sbin]# firewall-cmd --reload
success
3)访问测试
2.4.2、其它命令
1)停止服务
方式一:./nginx -s stop
,该命令相当于先查出nginx进程id,使用kill命令强制杀掉进程。
方式二:./nginx -s quit
,该命令停止步骤是待nginx进程处理任务完毕,再进行停止。
2)重启服务
方式一:先停止再启动
方式二:../nginx -s reload
,该命令不用先停nginx,是直接让配置信息在nginx中生效。
2.4.3、重启报错处理
重启机器后,再次启动nginx时会报nginx: [error] open() "/var/run/nginx/nginx.pid" failed (2: No such file or directory)
错误,意思是找不到nginx.pid文件。
nginx.pid这个文件作用是什么呢?它是用来存放nginx的master进程的进程号,而/var/run
目录用来存放描述系统启动以来系统信息的数据,重启时会清除这些数据,所以导致找不到nginx.pid文件无法重启。
解决方法:我们可以将nginx.pid保存到其它目录
我这里其放到logs目录下,先在nginx/下创建logs文件夹,然后修改nginx.conf
配置文件,指定pid的存放路径
pid /usr/local/nginx/logs/nginx.pid;
再次重启后,/usr/local/nginx/logs
下就会生成nginx.pid文件了
[root@localhost logs]# ll
-rw-r--r--. 1 root root 5 6月 13 00:08 nginx.pid
三、基础配置修改
3.1、用户设置
因为我现在使用的是root用户,所有将nobody改为root
user root;
3.2、工作进程设置
worker_processes
我们常设置为4个
,重新加载配置文件后可见1个主进程和4个工作进程
[root@localhost sbin]# ./nginx -s reload
[root@localhost sbin]# ps -ef|grep nginx
root 2531 1 0 10:26 ? 00:00:00 nginx: master process ./nginx
root 2842 2531 0 12:49 ? 00:00:00 nginx: worker process
root 2843 2531 0 12:49 ? 00:00:00 nginx: worker process
root 2844 2531 0 12:49 ? 00:00:00 nginx: worker process
root 2845 2531 0 12:49 ? 00:00:00 nginx: worker process
3.3、日志开启
放开如下3处配置项注释
error_log logs/error.log;
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /usr/local/logs/access.log main;
}
重新加载配置文件后可见logs目录已生成两个日志文件
[root@localhost logs]# ll
总用量 4
-rw-r--r--. 1 root root 0 6月 13 12:49 access.log
-rw-r--r--. 1 root root 0 6月 13 12:49 error.log
-rw-r--r--. 1 root root 5 6月 13 04:19 nginx.pid
四、虚拟主机搭建
4.1、什么是虚拟主机
官话是:
虚拟主机是一种特殊的软硬件技术,它可以将网络上的每一台计算机分成多个虚拟主 机,每个虚拟主机可以独立对外提供 www 服务,这样就可以实现一台主机对外提供多个 web 服务,每个虚拟主机之间是独立的,互不影响的。
人话是:
我们可以在nginx是配置多个域名,每个域名指向一个系统,而这些系统公用一套物理机,从而提高资源利用率。
下面我们画一张简单虚拟主机示意图,在一台机上部署3个系统,然后再nginx上面配置3个IP/域名对应这三个系统,那么对外就可以提供多个不同系统服务了。
4.2、三种配置方式
nginx虚拟主机有三种配置方式,分别为基于端口、基于IP和基于域名,我们只需要修改nginx.conf配置文件中的server即可,一个server就表示一个虚拟主机服务
。
4.2.1、基于端口配置
修改nginx/conf/目录下的nginx.conf
配置文件,配置两个ip相同,端口不同
的server,这样就可以对外部同时提供不同的服务
# 服务一
server {
listen 80;
server_name 192.168.48.128;
location / {
root html;
index index.html index.htm;
}
}
# 服务二
server {
listen 8081;
server_name 192.168.48.128;
location / {
root html;
index index.html index.htm;
}
}
分别访问http://192.168.48.128:8081/
与http://192.168.48.128/
,都可以正常加载(记得先开端口防火墙)
4.2.2、基于IP配置
基于IP的也很简单,两个server的IP不同
即可,我这里两台机器IP分别为192.168.48.128
和192.168.48.129
# 服务一
server {
listen 80;
server_name 192.168.48.128;
location / {
root html;
index index.html index.htm;
}
}
# 服务二
server {
listen 80;
server_name 192.168.48.129;
location / {
root html;
index index.html index.htm;
}
}
4.2.3、基于域名配置
基于域名的虚拟主机将server_name 配置为域名即可,我这里自定义一个域名www.test128.com
# 服务一
server {
listen 80;
server_name www.test128.com;
location / {
root html;
index index.html index.htm;
}
}
打开C:\Windows\System32\drivers\etc的hosts
文件夹,修改hosts文件,进行域名本地解析
192.168.48.128 www.test128.com
重启后访问http://www.test128.com/
地址
五、反向代理与负载均衡
5.1、正向代理与反向代理理解
5.1.1、正向代理
正向代理是代理客户端去请求到服务器
比如我们想访问某个海外站点,但是被墙了无法直接访问,这个时候我们就会采用vpn代理了,它会帮我们去请求该海外站点,然后再将网页资源返回我们。
5.1.2、反向代理
反向代理是代理服务器接受客户端的请求
比如我们在机房部署了一套系统(多台机),为了稳定性和安全性,我们通常会使用nginx或F5产品,它会帮我们接收客户端的请求,然后均匀负载分发到不同的后端机器,处理完后再将结果响应给客户端。这样既可以减轻服务端的压力,也不用直接暴露服务器给外部。
5.2、反向代理配置
反向代理需要注意两个关键配置,upstream
和proxy_pass
,upstream 用来指定需要真实访问的地址,my_server是自定义命名。proxy_pass 配置为 http://my_server,意思会把客户访问www.mytest123.com的请求,转给upstream my_server{}处理。简单理解,其实就是nginx中的server代理了地址为192.168.66.77:8080的服务。当然,upstream
和proxy_pass
都可以配置多个。
下面的配置是通过nginx代理访问tomcat服务
http {
upstream my_server{
server 192.168.48.128:8080;
}
# 服务一
server {
listen 80;
server_name www.test128.com;
location / {
proxy_pass http://my_server;
index index.html index.htm;
}
.....
}
}
在/usr/local/tomcat/bin
目录下,启动tomcat(tomcat安装可参考 一文搞定Linux常见用法 )
[root@localhost bin]# ./startup.sh
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/local/jdk
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Tomcat started.
访问http://www.test128.com/
地址,成功代理到tomcat服务地址了
5.3、负载均衡配置
5.3.1、概念理解
负载
指服务器承担的客户端请求压力,均衡
指将这些压力均匀的分摊到各个服务上面。那么合在一起,负载均衡( Load Balance)
就是指将客户端的请求压力均匀的分摊到多个服务上进行执行,从而增加吞吐量,提高网络的灵活性和可用性。
nginx常见负载均衡策略有3种:轮询、指定权重和ip_hash
5.3.2、轮询方式(默认)
负载均衡通过upstream
来配置,需要将请求分发到几台机器,就在upstream中指定几个server。下面示例指定的两台采用默认轮询策略
,即每个请求按时间顺序逐一分配到不同的后端服务器,比如第一个请求77处理,那第二个就会让78处理,第三个77…这样顺序轮询。如果某一台服务器 down 掉了,则会自动被剔除。
http {
upstream my_server{
server 192.168.48.128:8080;
server 192.168.48.129:8080;
}
# 服务一
server {
listen 80;
server_name www.test128.com;
location / {
proxy_pass http://my_server;
index index.html index.htm;
}
.....
}
}
5.3.3、指定权重
比如我们希望性能好的机器能够多处理请求,那么可以通过weight
指定轮询权重,weight 值大的被轮询的几率更高,承担的请求任务更多,如下配置77轮询的几率会比78的高。
http {
upstream my_server{
server 192.168.48.128:8080 weight=5;
server 192.168.48.129:8080 weight=2;
}
# 服务一
server {
listen 80;
server_name www.test128.com;
location / {
proxy_pass http://my_server;
index index.html index.htm;
}
.....
}
}
5.3.4、ip_hash方式
ip_hash通常用来解决session一致性问题
。
我们假设一个常见的场景,比如有一个用户第一次访问登录时是通过77服务来处理,如果不加ip_hash配置,则会采用默认轮询方式,那么该用户第二次访问站点时很可能会由78服务处理,但是77和78两个服务之间session并没有共享机制,那么这个用户的登录状态就会丢失,这显然不符合我们实际需求。
所以,这个时候就需要ip_hash出马了,它会根据每个请求ip的hash结果进行分配处理,让每个访客固定访问一个后端服务器,这样就能解决session的问题。当然,关于session共享问题还有很多其它方案,比如sso、redis等等,我们这里讲的是nginx本身支持的session一致性问题解决方案。
http {
upstream my_server{
ip_hash;
server 192.168.48.128:8080;
server 192.168.48.129:8080;
}
# 服务一
server {
listen 80;
server_name www.test128.com;
location / {
proxy_pass http://my_server;
index index.html index.htm;
}
.....
}
}
六、代理文件服务器
6.1、简介
对于网站而言,文件服务器是一个绕不开的话题,因为我们上传的资源通常都放在文件服务器中管理,比较常见的有NAS服务器、FTP服务器等。而Nginx则常用来代理访问文件服务器中的资源,比如网站上面的banner图片、免责条款文件等,下面我就来实现这个需求。
6.2、模拟NAS服务
真实NAS服务是一个独立服务器,然后通过挂载方式,绑定到应用服务器的某个目录下,使用时就像是应用服务器自己本身的文件目录一样,我们没有自己搭建NAS服务器,所以直接模拟一个nas挂载目录。
使用mkdir 文件名
命令分别创建三层文件夹(/data/nas/images/
),然后使用rz
命令上传一张1.jpg
图片到images
下
如果对linux命令不太熟悉,请参考一文搞定Linux常见用法
[root@localhost sbin]# cd /data/nas/images/
[root@localhost images]# ll
总用量 216
-rw-r--r--. 1 root root 220250 4月 25 04:32 1.jpg
6.3、nginx.conf配置
这里需要配置两个地方,第一个是server_name
服务名称,我们给它自定义域名image.mytest.com
,第二个是location中的root
需要指向nas目录
,这样,当我们在浏览器中访问域名时会映射到nas目录中的资源文件。
server {
listen 80;
server_name image.mytest.com;
location / {
root /data/nas/images;
index index.html index.htm;
}
....
}
修改配置后重新加载配置文件 ./nginx -s reload
此时如果我们访问 http://image.mytest.com/1.jpg
地址,会发现无法正常现实图片,原因是我们还没有在本地做域名解析,所以浏览器并不知道这个域名是指向哪个IP地址(另外请先确保80端口已开防火墙
)。
6.4、域名本地解析
本地域名解析很简单,修改hosts文件即可,打开C:\Windows\System32\drivers\etc的hosts
文件,加上域名映射关系(192.168.48.128是应用服务器地址)
# localhost name resolution is handled within DNS itself.
# 127.0.0.1 localhost
# ::1 localhost
192.168.48.128 image.mytest.com
6.5、效果查看
访问http://image.mytest.com/1.jpg
地址,可见nas中的1.jpg资源正常加载出来了
七、高可用集群
我们这里是采用Keepalived实现Nginx集群的高可用
7.1、Keepalived简介与原理
简介:Keepalived是集群管理高可用服务软件,它可以检测服务器的状态,当一台服务器出现故障时,它会将故障服务器从系统中剔除,然后自动切换到可用的服务器上面。当故障机器恢复正常后,Keepalive又会自动将服务器加入到集群中,从而实现了集群的高可用性。
原理:下面是Keepalived实现Nginx集群的高可用整体示意图,Keepalived是通过虚拟路由冗余协议
(Virtual Router Redundancy Protocol)来实现故障服务主备切换的,简称VRRP
。如图中的VIP
路由,是一个虚拟IP,它默认指向Master机器,如果Master机器故障或宕机时,它会自动漂移切换到Backup机器,这样就能实现Nginx集群的高可用了。如果是有多台Backup机器,则会通过选举机制产生新的Master,其选举规则为先看优先级值(0-255之间的数),高者当选,如果优先级值相同,IP地址数值大的当选。
7.2、环境搭建
7.2.1、Nginx准备
搭建两台Nginx,并且分别代理到两个tomcat服务器
192.168.48.128
机器代理配置
upstream my_server{
server 192.168.48.128:8080;
server 192.168.48.129:8080;
}
server {
listen 80;
server_name 192.168.48.128;
location / {
proxy_pass http://my_server;
index index.html index.htm;
}
}
192.168.48.129
机器代理配置
upstream my_server{
server 192.168.48.128:8080;
server 192.168.48.129:8080;
}
server {
listen 80;
server_name 192.168.48.129;
location / {
proxy_pass http://my_server;
index index.html index.htm;
}
}
7.2.2、Keepalived安装
分别在128
和129
机器上执行yum install keepalived -y
命令即可
7.2.3、Keepalived配置修改
在/etc/keepalived目录下编辑keepalived.conf
文件,主要配置步骤如下:
1)smtp_server
可以改为localhost,否则会输出找不到邮件服务器地址错误日志;
2)主机器state
为MASTER
,从机器为BACKUP
;
3)检查interface
网卡是否与机器一直(使用ip address查看);
4)优先级值priority
设置,主比从大即可;
5)在virtual_ipaddress
中配置虚拟VIP
6)编写nginx状态监控脚本(如果nginx访问出现问题,则从机器主漂移切换到其它从机器)
先在home/中创建check_nginx.sh
监控脚本
#!/bin/bash
#通过访问check.html页面来检查nginx是否宕机
url="http://127.0.0.1/check.html"
code=`curl -s -o /dev/null -w %{http_code} $url`
#通过判断相应编码是否是200来确定nginx宕机
if [ $code -ne 200 ];then
sleep 1
code=`curl -s -o /dev/null -w %{http_code} $url`
if [ $code -ne 200 ];then
#确定nginx是宕机,关闭本机的keepalived
service keepalived stop
fi
fi
然后在nginx/html中创建一个check.html
文件,内容随意,并新增一个location配置
location ~ .html$ {
root html;
}
7) 脚本授执行权:chmod +x check_nginx.sh
8)可以注释或删除其它暂不需要使用的配置信息
128作为Master完整配置如下
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server localhost # 邮件服务器地址
smtp_connect_timeout 30
router_id LVS_DEVEL
#vrrp_skip_check_adv_addr
#vrrp_strict
#vrrp_garp_interval 0
#vrrp_gna_interval 0
}
vrrp_script my_script { #定义一个脚本
script "/home/check_nginx.sh" #脚本的作用是监控nginx是否宕机
interval 2 # 两秒执行一次脚本
}
vrrp_instance VI_1 {
state MASTER # 主机器
interface ens33 # 网卡信息
virtual_router_id 51
priority 100 # 优先级值
unicast_src_ip 192.168.48.128 #本机ip,将多广播调整为单播
unicast_peer {
192.168.48.129 #对端ip
}
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.48.201 dev ens33 label ens33:1 #指定虚拟IP和别名
}
track_script {
my_script #调用nginx检查脚本
}
129作为Backup完整配置如下
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server localhost # 邮件服务器地址
smtp_connect_timeout 30
router_id LVS_DEVEL
#vrrp_skip_check_adv_addr
#vrrp_strict
#vrrp_garp_interval 0
#vrrp_gna_interval 0
}
vrrp_script my_script { #定义一个脚本
script "/home/check_nginx.sh" #脚本的作用是监控nginx是否宕机
interval 2 # 两秒执行一次脚本
}
vrrp_instance VI_1 {
state BACKUP # 主机器
interface ens33 # 网卡信息
virtual_router_id 51
priority 80 # 优先级值比master小
unicast_src_ip 192.168.48.129 #本机ip,将多广播调整为单播
unicast_peer {
192.168.48.128 #对端ip
}
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.48.201 dev ens33 label ens33:1 #指定虚拟IP和别名
}
track_script {
my_script #调用nginx检查脚本
}
7.3、效果验证
1)确保nginx和tomcat服务已经启动
2)启动128 和129的Keepalived
启动命令:service keepalived start
停止命令:service keepalived stop
查看状态: systemctl status keepalived.service
3)查看虚拟IP
在主机器128上面执行ifconfig
查看192.168.48.201
已经生效
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.48.201 netmask 255.255.255.255 broadcast 0.0.0.0
ether 00:0c:29:bb:03:56 txqueuelen 1000 (Ethernet)
4)访问VIP地址http://192.168.48.201/
成功
7.4、脑裂问题
以上内容都基于Centos 8
和Nginx-1.18.0
版本,如果出现keepalived脑裂问题(即主备两台机器争抢VIP情况),还可以尝试如下方法,分别在两台机器上执行下面的命令
[root@localhost sbin]# firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface ens33 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
success
[root@localhost sbin]# firewall-cmd --reload;
success
ens33
为设备网卡,需要替换为自己的; 224.0.0.18
为vrrp组播地址;
使用sudo tcpdump -i ens33 vrrp -n
命令可以抓包分析请求,如果出现如下128与129交替输出的日志,则说明脑裂了
[root@localhost ~]# sudo tcpdump -i ens33 vrrp -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
06:58:44.657294 IP 192.168.48.128 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
06:58:45.246399 IP 192.168.48.129 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 80, authtype simple, intvl 1s, length 20
06:58:45.657597 IP 192.168.48.128 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
06:58:46.247259 IP 192.168.48.129 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 80, authtype simple, intvl 1s, length 20
结语
读到这里,我们对于工作中常用到的Nginx知识,应该都有个大致解了。当然,在实际项目中需求场景会更复杂一些,那么,我们就需求根据具体情况来进行调整和优化。