一、Nginx 高可用的重要性
在当今数字化时代,Web 服务已成为人们生活和工作中不可或缺的一部分 ,Nginx 作为一款高性能的开源 Web 服务器和反向代理服务器,在现代 Web 服务架构中占据着举足轻重的地位。它以其卓越的高并发处理能力、低资源消耗和出色的稳定性,广泛应用于从个人博客到大型互联网公司核心服务的各种规模的网站和应用程序中。
Nginx 主要承担着反向代理服务器和静态资源服务器的关键角色。作为反向代理服务器,Nginx 位于客户端和后端真实服务器之间,接收客户端请求并转发到后端服务器,同时将后端服务器的响应返回给客户端。这不仅隐藏了后端服务器的真实 IP 地址,增强了安全性,还能实现负载均衡,将请求合理分配到多个后端服务器,提升系统的整体性能和可用性。例如,当用户访问大型电商网站时,Nginx 会将用户的请求分发到不同的后端服务器上,确保用户能够快速、稳定地获取商品信息和完成交易。在处理静态资源方面,Nginx 采用高效的事件驱动异步非阻塞 I/O 模型,能够快速处理 HTML、CSS、JavaScript、图片等静态文件,减少每个请求的处理时间,提高服务器整体性能。
然而,若 Nginx 出现单点故障,将导致极其严重的后果。当 Nginx 服务器宕机时,所有依赖它的 Web 服务将无法正常提供,客户端的请求无法得到响应,网站将无法访问,应用程序也无法正常运行。这对于电商平台来说,可能导致用户无法下单购物,造成直接的经济损失;对于社交媒体平台,用户无法登录、发布内容和浏览信息,会严重影响用户体验,导致用户流失;对于在线教育平台,学生无法正常上课,影响教学进度和质量。此外,服务中断还会对企业的声誉造成负面影响,降低用户对企业的信任度,在竞争激烈的市场环境中,这可能给企业带来难以挽回的损失。
为了避免 Nginx 单点故障带来的严重影响,实现 Nginx 的高可用至关重要。通过引入 Keepalived 等技术,可以构建高可用的 Nginx 集群,确保在 Nginx 服务器出现故障时,能够快速切换到备用服务器,保障 Web 服务的连续性和稳定性。
二、Keepalived 原理剖析
(一)VRRP 协议详解
VRRP(虚拟路由器冗余协议)是一种网络冗余协议,主要用于解决局域网中默认网关的单点故障问题 ,它的出现极大地提升了网络的可靠性和稳定性。通过 VRRP 协议,一组物理路由器被逻辑地组合成一个虚拟路由器,这个虚拟路由器对外呈现为一个具有唯一固定 IP 地址和 MAC 地址的逻辑实体 ,就像一个 “超级路由器”,为局域网内的主机提供网关服务。
在这个虚拟路由器中,各个物理路由器扮演着不同的角色,其中优先级最高的路由器被选举为主路由器(Master),它承担着实际的网关职责,负责接收局域网内主机发送的数据包,并将这些数据包转发到正确的目的地。而其他路由器则作为备份路由器(Backup),处于待命状态,时刻监听主路由器的工作状态。例如,在一个企业网络中,有路由器 A、B、C 组成了一个虚拟路由器,路由器 A 的优先级最高,成为了主路由器,负责处理企业内部员工访问外部网络的数据包转发任务,而路由器 B 和 C 则作为备份,随时准备接替 A 的工作。
VRRP 协议中的优先级是一个关键概念,它决定了路由器在虚拟路由器中的角色。优先级的取值范围通常是 0 - 255,数值越大表示优先级越高。默认情况下,路由器的优先级为 100 。在选举主路由器时,VRRP 协议会首先比较各个路由器的优先级,优先级高的路由器将成为主路由器。如果多个路由器的优先级相同,那么会进一步比较它们的接口 IP 地址,IP 地址较大的路由器将成为主路由器。例如,在上述企业网络中,如果路由器 A 的优先级设置为 150,路由器 B 和 C 的优先级为 100,那么 A 自然成为主路由器;若 A、B、C 优先级都为 100,但 A 的接口 IP 地址最大,A 依然会当选为主路由器。
IP 地址漂移是 VRRP 协议实现高可用的核心机制之一。当主路由器正常工作时,虚拟 IP 地址会绑定在主路由器的接口上,局域网内的主机将虚拟 IP 地址作为默认网关,所有发往外部网络的数据包都会被发送到主路由器。此时,主路由器就像一个繁忙的交通枢纽,高效地处理着数据包的转发工作。然而,当主路由器出现故障时,备份路由器会通过 VRRP 协议的选举机制,重新选举出一个新的主路由器。新的主路由器会接管虚拟 IP 地址,继续为局域网内的主机提供网关服务,就像接力赛中的选手,无缝衔接,确保网络通信的连续性。这种虚拟 IP 地址在不同路由器之间的转移过程,就是 IP 地址漂移。例如,当企业网络中的主路由器 A 突然故障时,备份路由器 B 或 C 会迅速检测到这一情况,通过选举,优先级较高或 IP 地址较大的备份路由器会立即接管虚拟 IP 地址,企业员工的网络访问不会受到明显影响,几乎感觉不到主路由器的切换。
(二)Keepalived 组件与工作流程
Keepalived 是一个基于 VRRP 协议的高可用解决方案,它通过多个组件的协同工作,实现了对 Nginx 等服务的状态检测和故障转移,为 Web 服务的稳定运行提供了有力保障。Keepalived 主要包含三个核心模块:core、check 和 vrrp,每个模块都肩负着独特而重要的职责 。
core 模块是 Keepalived 的核心组件,犹如人体的心脏,负责主进程的启动、运行和维护,确保整个 Keepalived 系统的稳定运行。它就像一个总指挥,统筹全局,协调各个模块之间的工作。在系统启动时,core 模块会加载并解析全局配置文件,从中获取各种关键配置信息,如虚拟路由器的相关设置、通知邮件的配置等。这些配置信息将指导整个 Keepalived 系统的运行,确保各个模块能够按照预期的方式协同工作。例如,core 模块会根据配置文件中的设置,确定哪些服务器参与虚拟路由器的组建,以及它们的角色和优先级等。
check 模块承担着健康检查的重要任务,它是 Keepalived 的 “健康卫士”,负责实时监测 Nginx 等服务的运行状态。check 模块支持多种健康检查方式,以满足不同场景下的需求。常见的检查方式包括端口检查和 URL 检查。端口检查通过探测 Nginx 服务所使用的端口(如默认的 80 端口或 443 端口)是否开放,来判断 Nginx 服务是否正常运行。如果端口无法访问,那么很可能意味着 Nginx 服务出现了故障。URL 检查则更加深入,它会模拟客户端发送 HTTP 请求到指定的 URL 地址,然后根据返回的状态码和内容来判断 Nginx 服务是否正常响应。例如,check 模块可以定期向 Nginx 服务器的根目录(如 “/”)发送 HTTP GET 请求,如果返回的状态码是 200,说明 Nginx 服务正常;如果返回 404 或 500 等错误状态码,或者长时间没有响应,那么就可以判断 Nginx 服务出现了问题。通过这些健康检查方式,check 模块能够及时发现 Nginx 服务的异常情况,并将相关信息反馈给其他模块,以便采取相应的措施。
vrrp 模块是实现 VRRP 协议的关键组件,它就像一个 “协调员”,负责建立和维护虚拟路由器,实现 IP 地址的漂移和故障转移。在虚拟路由器中,vrrp 模块会根据配置文件中的设置,确定各个服务器的角色(主服务器或备份服务器)和优先级。主服务器会周期性地发送 VRRP 通告报文,向备份服务器宣告自己的存活状态和工作情况。备份服务器则会监听这些通告报文,一旦在规定的时间内没有收到主服务器的通告报文,就会认为主服务器出现了故障,此时备份服务器会根据优先级重新选举新的主服务器。新的主服务器会接管虚拟 IP 地址,继续提供服务,从而实现了高可用性。例如,在一个 Nginx 高可用集群中,有两台服务器 A 和 B,服务器 A 作为主服务器,它的 vrrp 模块会定时向服务器 B 发送通告报文。当服务器 B 长时间未收到服务器 A 的通告报文时,它的 vrrp 模块会启动选举机制,由于服务器 B 的优先级较高,它会成为新的主服务器,接管虚拟 IP 地址,确保 Nginx 服务的连续性。
Keepalived 的工作流程紧密依赖于这三个模块的协同合作。在系统启动阶段,core 模块首先加载并解析配置文件,完成自身的初始化工作,并启动 check 模块和 vrrp 模块。check 模块开始按照配置的检查方式和周期,对 Nginx 服务进行健康检查,持续监控 Nginx 的运行状态。vrrp 模块则根据配置信息,确定当前服务器在虚拟路由器中的角色和优先级,并与其他服务器进行 VRRP 协议的交互。当 Nginx 服务正常运行时,主服务器的 vrrp 模块会定期发送 VRRP 通告报文,备份服务器接收到这些报文后,知道主服务器处于正常状态,继续保持待命状态。一旦 check 模块检测到 Nginx 服务出现故障,它会立即将这一信息通知给 vrrp 模块。vrrp 模块接收到故障信息后,会按照 VRRP 协议的规则,进行主备切换。备份服务器会接替主服务器的工作,接管虚拟 IP 地址,同时启动自身的 Nginx 服务,继续为客户端提供服务。在这个过程中,core 模块始终监控着整个系统的运行,确保各个模块之间的协作顺畅,保障 Web 服务的高可用性。
三、环境准备
(一)服务器规划
在构建 Nginx 高可用集群时,合理的服务器规划是基础。假设我们使用两台服务器来搭建主备模式的 Nginx 高可用环境,其中主服务器(Master)的 IP 地址设为 192.168.1.10,备服务器(Backup)的 IP 地址设为 192.168.1.11。这两台服务器将运行 Nginx 服务,并通过 Keepalived 实现高可用性。
虚拟 IP(VIP)是实现高可用的关键要素之一,它为客户端提供了一个固定的访问入口。在这个示例中,我们规划虚拟 IP 为 192.168.1.20。客户端在访问 Web 服务时,将使用这个虚拟 IP,而无需关心后端实际提供服务的是主服务器还是备服务器。当主服务器正常工作时,虚拟 IP 会绑定在主服务器的网络接口上,客户端的请求会被路由到主服务器。一旦主服务器出现故障,虚拟 IP 会迅速漂移到备服务器,确保客户端的请求能够继续得到响应,实现服务的无缝切换。
(二)软件安装
在主备服务器上安装 Nginx 和 Keepalived 是构建高可用环境的重要步骤,以下分别介绍在 CentOS 和 Ubuntu 系统上的安装方法。
CentOS 系统
安装 Nginx:
首先,更新系统软件包列表,确保获取到最新的软件包信息,使用以下命令:
sudo yum update

然后,安装 Nginx 软件包,Nginx 官方提供了专门的 Yum 源,我们可以通过以下步骤添加并安装:
sudo rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
sudo yum install -y nginx

安装完成后,可以使用以下命令启动 Nginx 服务,并设置为开机自启:
sudo systemctl start nginx
sudo systemctl enable nginx

安装 Keepalived:
同样先更新系统软件包列表:
sudo yum update

接着,直接使用 Yum 命令安装 Keepalived:
sudo yum install -y keepalived

安装完成后,启动 Keepalived 服务并设置开机自启:
sudo systemctl start keepalived
sudo systemctl enable keepalived

Ubuntu 系统
安装 Nginx:
更新系统软件包列表,获取最新的软件包信息:
sudo apt-get update

安装 Nginx 软件包:
sudo apt-get install -y nginx

启动 Nginx 服务并设置开机自启:
sudo systemctl start nginx
sudo systemctl enable nginx

安装 Keepalived:
先更新系统软件包列表:
sudo apt-get update

然后安装 Keepalived:
sudo apt-get install -y keepalived

启动 Keepalived 服务并设置开机自启:
sudo systemctl start keepalived
sudo systemctl enable keepalived

通过以上步骤,在主备服务器上成功安装了 Nginx 和 Keepalived,为后续的配置工作奠定了基础。
四、Nginx 配置
(一)基础配置
Nginx 的基本配置文件通常是nginx.conf,以下是一个基础配置示例,展示了常见的设置:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
worker_connections 1024;
}

http {
include /etc/nginx/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  /var/log/nginx/access.log  main;

sendfile        on;
#tcp_nopush     on;

keepalive_timeout  65;

#gzip  on;

server {
    listen       80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}


include /etc/nginx/conf.d/*.conf;

}

在上述配置中:
user指定运行 Nginx 工作进程的用户和用户组,这里设置为nginx用户。
worker_processes设置工作进程数,auto表示自动根据 CPU 核心数来确定进程数,以充分利用服务器资源。
error_log定义错误日志的路径和日志级别,warn表示记录警告及以上级别的错误信息 。
pid指定 Nginx 进程 ID 文件的存放路径,便于管理和监控 Nginx 进程。
在events块中,worker_connections设置每个工作进程可以同时处理的最大连接数,这里设置为 1024。
http块是 Nginx 配置的核心部分,包含了 HTTP 相关的各种配置指令。
include引入 MIME 类型定义文件,用于识别不同类型的文件,确保正确处理和传输。
default_type设置默认的 MIME 类型为application/octet-stream,表示当无法识别文件类型时的默认处理方式。
log_format定义访问日志的格式,记录了客户端 IP、访问时间、请求内容、响应状态码等重要信息。
access_log指定访问日志的路径和使用的日志格式。
sendfile开启文件高效传输模式,减少文件读取和传输的开销,提高性能。
keepalive_timeout设置长连接的超时时间,这里为 65 秒,即如果在 65 秒内客户端和服务器之间没有数据传输,连接将被关闭。
server块定义了一个虚拟主机,listen指定监听的端口为 80,server_name指定服务器名称为localhost。
location /块定义了根路径的处理方式,root指定网站根目录为/usr/share/nginx/html,index指定默认的索引文件。
error_page配置错误页面的处理,当出现 500、502、503、504 等错误时,将跳转到/50x.html页面。
location = /50x.html块指定/50x.html文件的实际路径。
(二)负载均衡配置(可选)
当 Nginx 承担负载均衡角色时,需要配置upstream模块来定义后端服务器集群,并在location块中使用proxy_pass实现反向代理和负载均衡。假设我们有两个后端服务器,IP 地址分别为 192.168.1.100 和 192.168.1.101,端口均为 8080,以下是负载均衡的配置示例:
http {
upstream backend_servers {
server 192.168.1.100:8080;
server 192.168.1.101:8080;
}

server {
    listen       80;
    server_name  example.com;

    location / {
        proxy_pass http://backend_servers;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

}

在这个配置中:
upstream backend_servers定义了一个名为backend_servers的上游服务器组,其中包含了两个后端服务器的地址和端口。
在server块的location /中,使用proxy_pass http://backend_servers将客户端的请求代理到backend_servers定义的后端服务器集群。
proxy_set_header指令用于设置转发到后端服务器的 HTTP 请求头,Host $host设置主机头,确保后端服务器能正确识别请求的目标主机;X-Real-IP $remote_addr、X-Forwarded-For $proxy_add_x_forwarded_for用于记录客户端的真实 IP 地址;X-Forwarded-Proto $scheme记录请求的协议(HTTP 或 HTTPS),这些设置对于后端服务器正确处理请求和获取客户端信息非常重要。通过这样的配置,Nginx 能够将客户端请求均匀地分配到后端的两台服务器上,实现负载均衡,提高系统的整体性能和可用性。
五、Keepalived 配置
(一)主服务器配置
在主服务器上,Keepalived 的配置文件通常位于/etc/keepalived/keepalived.conf,以下是一个详细的配置示例:
global_defs {
router_id MASTER_NODE # 定义本节点的唯一标识,可自定义,用于区分不同的Keepalived节点
notification_email {
admin@example.com # 接收通知邮件的邮箱地址,可设置多个,用于在故障发生时接收通知
}
notification_email_from keepalived@example.com # 发送通知邮件的源地址
smtp_server 127.0.0.1 # 邮件服务器地址,这里假设是本地邮件服务器
smtp_connect_timeout 30 # 连接邮件服务器的超时时间,单位为秒
}

vrrp_script chk_nginx {
script “/etc/keepalived/check_nginx.sh” # 执行的健康检查脚本路径,用于检测Nginx服务状态
interval 2 # 检查脚本执行的时间间隔,单位为秒,这里每2秒检查一次
weight 2 # 权重,当脚本执行成功时,增加节点的优先级权重;失败时,减少权重,影响主备切换
}

vrrp_instance VI_1 {
state MASTER # 定义本节点的初始状态为MASTER,即主服务器
interface eth0 # 指定用于VRRP通信的网络接口,需根据实际情况修改,这里假设是eth0
virtual_router_id 51 # 虚拟路由器ID,主备服务器必须一致,范围是0 - 255,用于标识同一个VRRP组
priority 100 # 优先级,取值范围是0 - 255,主服务器优先级应高于备服务器,这里设置为100
advert_int 1 # 发送VRRP通告报文的时间间隔,单位为秒,这里每1秒发送一次
authentication {
auth_type PASS # 认证类型,这里使用简单的密码认证
auth_pass 1111 # 认证密码,主备服务器必须一致,用于VRRP通信的认证
}
virtual_ipaddress {
192.168.1.20 # 虚拟IP地址,客户端通过这个IP访问Nginx服务,实现高可用切换
}
track_script {
chk_nginx # 引用前面定义的健康检查脚本chk_nginx,用于实时监控Nginx服务状态
}
}

在这个配置中:
global_defs部分主要配置全局参数,包括邮件通知相关的设置。router_id用于唯一标识本节点,在一个复杂的网络环境中,当存在多个 Keepalived 节点时,通过router_id可以方便地区分不同的节点。notification_email指定了接收故障通知邮件的邮箱地址,在 Nginx 服务出现故障时,管理员可以及时收到通知并进行处理。smtp_server和smtp_connect_timeout分别设置了邮件服务器的地址和连接超时时间,确保通知邮件能够正常发送。
vrrp_script chk_nginx定义了一个名为chk_nginx的检查脚本。script指定了脚本的实际路径,interval设置了脚本的执行间隔,通过定期执行这个脚本来检测 Nginx 服务的运行状态。weight参数则影响着节点在 VRRP 选举中的优先级。当脚本执行成功时,会增加节点的优先级权重;如果脚本执行失败,就会减少权重,从而影响主备切换的决策。例如,当主服务器上的 Nginx 服务正常运行时,脚本执行成功,主服务器的优先级权重增加,更能保持其主服务器的地位;当 Nginx 服务出现故障时,脚本执行失败,主服务器的优先级权重降低,备服务器就有可能成为新的主服务器。
vrrp_instance VI_1定义了一个 VRRP 实例。state MASTER明确了本节点在这个实例中初始状态是主服务器。interface eth0指定了用于 VRRP 通信的网络接口,这个接口必须是服务器实际使用的网络接口,并且要确保该接口正常工作,否则 VRRP 通信会受到影响。virtual_router_id 51是虚拟路由器 ID,主备服务器的这个 ID 必须相同,它就像一个组标识,将主备服务器划分到同一个 VRRP 组中。priority 100设置了本节点的优先级,在正常情况下,优先级高的节点会成为主服务器。advert_int 1表示每隔 1 秒发送一次 VRRP 通告报文,通过这些报文,主备服务器可以互相了解对方的状态。authentication部分配置了 VRRP 通信的认证信息,auth_type PASS表示使用简单的密码认证方式,auth_pass 1111是认证密码,主备服务器的认证密码必须一致,这样可以防止非法节点加入 VRRP 组,提高网络安全性。virtual_ipaddress定义了虚拟 IP 地址,这个 IP 地址是客户端访问 Nginx 服务的入口。在正常情况下,虚拟 IP 会绑定在主服务器的指定网络接口上,当主服务器出现故障时,虚拟 IP 会漂移到备服务器上,客户端通过这个虚拟 IP 访问服务,不会因为主服务器的故障而中断服务。track_script引用了前面定义的chk_nginx检查脚本,通过实时监控 Nginx 服务状态,来决定是否进行主备切换。如果chk_nginx脚本检测到 Nginx 服务异常,会触发相应的操作,如降低主服务器的优先级,从而导致 VRRP 选举新的主服务器,实现高可用切换。
(二)备服务器配置
备服务器的 Keepalived 配置文件同样位于/etc/keepalived/keepalived.conf,与主服务器配置相比,主要有以下差异:
global_defs {
router_id BACKUP_NODE # 本节点唯一标识,与主服务器不同,方便区分
notification_email {
admin@example.com # 接收通知邮件的邮箱地址,可与主服务器相同
}
notification_email_from keepalived@example.com # 发送通知邮件的源地址,可与主服务器相同
smtp_server 127.0.0.1 # 邮件服务器地址,可与主服务器相同
smtp_connect_timeout 30 # 连接邮件服务器的超时时间,可与主服务器相同
}

vrrp_script chk_nginx {
script “/etc/keepalived/check_nginx.sh” # 执行的健康检查脚本路径,与主服务器相同
interval 2 # 检查脚本执行的时间间隔,与主服务器相同
weight 2 # 权重,与主服务器相同
}

vrrp_instance VI_1 {
state BACKUP # 定义本节点的初始状态为BACKUP,即备服务器
interface eth0 # 指定用于VRRP通信的网络接口,与主服务器相同
virtual_router_id 51 # 虚拟路由器ID,与主服务器相同
priority 90 # 优先级,低于主服务器,这里设置为90
advert_int 1 # 发送VRRP通告报文的时间间隔,与主服务器相同
authentication {
auth_type PASS # 认证类型,与主服务器相同
auth_pass 1111 # 认证密码,与主服务器相同
}
virtual_ipaddress {
192.168.1.20 # 虚拟IP地址,与主服务器相同
}
track_script {
chk_nginx # 引用健康检查脚本,与主服务器相同
}
}

在备服务器配置中:
global_defs部分的router_id设置为BACKUP_NODE,与主服务器的router_id不同,这有助于在管理和监控时明确区分主备服务器。其他参数如邮件通知相关设置可以与主服务器保持一致,这样在故障发生时,管理员可以通过相同的邮箱接收通知。
vrrp_script chk_nginx部分与主服务器完全相同,因为主备服务器都需要使用相同的脚本和参数来检测 Nginx 服务状态。通过执行同一个健康检查脚本,主备服务器可以对 Nginx 服务的运行情况进行统一的监测和判断。
vrrp_instance VI_1中,state BACKUP明确了本节点的初始角色是备服务器,处于待命状态,随时准备接替主服务器的工作。priority 90设置的优先级低于主服务器,这使得在正常情况下,主服务器能够承担对外服务的职责。当主服务器出现故障时,备服务器会根据 VRRP 协议,由于其优先级相对较高(在备服务器中优先级最高),有机会成为新的主服务器,接管虚拟 IP 地址并继续提供服务。其他参数如interface、virtual_router_id、advert_int、authentication和virtual_ipaddress都与主服务器保持一致,这些相同的配置参数是保证主备服务器能够协同工作,实现高可用切换的关键。interface相同确保了主备服务器在同一个网络接口上进行 VRRP 通信;virtual_router_id相同将它们划分到同一个 VRRP 组中;advert_int相同保证了它们发送 VRRP 通告报文的时间间隔一致,便于互相感知对方的状态;authentication相同的认证信息确保了 VRRP 通信的安全性和准确性;virtual_ipaddress相同则保证了客户端在主备切换过程中始终使用同一个虚拟 IP 地址访问服务,实现服务的无缝切换。track_script引用相同的健康检查脚本,使得备服务器也能实时监控 Nginx 服务状态,及时响应主服务器的故障。
(三)健康检查脚本
健康检查脚本用于检测 Nginx 的运行状态,以下是一个简单的check_nginx.sh脚本示例:
#!/bin/bash

检测Nginx进程是否存在

A=$(ps -C nginx --no-header | wc -l)
if [ KaTeX parse error: Expected 'EOF', got '#' at position 21: … 0 ]; then #̲ 如果Nginx进程不存在,尝…(ps -C nginx --no-header | wc -l)
if [ $A -eq 0 ]; then
# 如果Nginx启动失败,停止Keepalived服务,触发主备切换
systemctl stop keepalived
fi
fi

这个脚本的工作逻辑如下:
使用ps -C nginx --no-header | wc -l命令统计当前系统中 Nginx 进程的数量,并将结果存储在变量A中。ps -C nginx用于查找名称为nginx的进程,–no-header选项表示不显示表头,wc -l用于统计行数,即 Nginx 进程的数量。
通过if [ $A -eq 0 ]; then条件判断,如果A等于 0,说明 Nginx 进程不存在,即 Nginx 服务可能已经停止或出现故障。
在 Nginx 服务异常时,脚本会尝试使用systemctl start nginx命令启动 Nginx 服务,然后通过sleep 2命令暂停 2 秒,给 Nginx 服务足够的启动时间。
再次使用ps -C nginx --no-header | wc -l命令检测 Nginx 进程是否成功启动,并将结果重新赋值给变量A。
如果再次检测发现A仍然等于 0,说明 Nginx 启动失败,此时脚本会执行systemctl stop keepalived命令,停止 Keepalived 服务。由于 Keepalived 服务停止,主服务器的 VRRP 通告报文将不再发送,备服务器在规定时间内收不到主服务器的通告报文后,会认为主服务器出现故障,从而触发主备切换机制,备服务器会接管虚拟 IP 地址,启动自身的 Nginx 服务,继续为客户端提供服务。这样,通过这个健康检查脚本,实现了对 Nginx 服务状态的实时监测和故障时的自动处理,保障了 Nginx 服务的高可用性。
六、配置验证与测试
(一)启动服务
在完成 Nginx 和 Keepalived 的配置后,需要依次启动主备服务器上的相关服务。在主服务器上,使用以下命令启动 Nginx 和 Keepalived 服务:
sudo systemctl start nginx
sudo systemctl start keepalived

同样,在备服务器上执行相同的命令来启动 Nginx 和 Keepalived 服务:
sudo systemctl start nginx
sudo systemctl start keepalived

启动服务后,可以使用systemctl命令来验证服务是否正常运行。例如,在主服务器上查看 Nginx 服务状态的命令为:
sudo systemctl status nginx

正常情况下,输出结果中会显示Active: active (running),表示 Nginx 服务正在运行。查看 Keepalived 服务状态的命令为:
sudo systemctl status keepalived

如果 Keepalived 服务正常运行,也会显示Active: active (running)。在备服务器上执行相同的命令,确保 Nginx 和 Keepalived 服务都处于正常运行状态。
(二)虚拟 IP 测试
在主服务器上,可以使用ip addr命令检查虚拟 IP(VIP)是否成功绑定。执行命令:
ip addr show eth0

其中eth0是配置 Keepalived 时指定的网络接口,根据实际情况进行修改。如果 VIP 成功绑定,在输出结果中会看到类似如下的信息:
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:xx:xx:xx brd ff:ff:ff:ff:ff:ff
inet 192.168.1.10/24 brd 192.168.1.255 scope global dynamic eth0
valid_lft 86341sec preferred_lft 86341sec
inet 192.168.1.20/32 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fexx:xxxx/64 scope link
valid_lft forever preferred_lft forever

其中inet 192.168.1.20/32 scope global eth0这一行表示虚拟 IP 192.168.1.20 已经成功绑定到eth0接口。
接下来,尝试通过 VIP 访问 Nginx 服务。在浏览器中输入http://192.168.1.20(假设 VIP 为 192.168.1.20),如果 Nginx 配置正确且服务正常运行,应该能够看到 Nginx 的默认页面或配置的网站页面。也可以使用命令行工具curl进行测试,执行命令:
curl http://192.168.1.20

如果返回 Nginx 服务器的响应内容,说明通过 VIP 访问 Nginx 服务是可用的。
(三)故障转移测试
为了验证 Nginx 高可用配置中的故障转移功能,需要模拟主服务器 Nginx 故障的情况。首先,可以在主服务器上停止 Nginx 服务来模拟故障,执行命令:
sudo systemctl stop nginx

或者直接关闭主服务器的电源来模拟更极端的故障情况。
在主服务器 Nginx 服务停止后,观察备服务器的状态。由于 Keepalived 的健康检查机制和 VRRP 协议的作用,备服务器会检测到主服务器的 Nginx 服务故障,然后备服务器会接管虚拟 IP,成为新的主服务器。可以在备服务器上使用ip addr命令检查虚拟 IP 是否已经漂移到备服务器上,执行命令:
ip addr show eth0

如果虚拟 IP 已经漂移到备服务器,会在输出结果中看到虚拟 IP 的相关信息。
同时,在客户端再次尝试通过 VIP 访问 Nginx 服务,在浏览器中输入http://192.168.1.20或使用curl命令进行测试:
curl http://192.168.1.20

如果能够正常访问并得到 Nginx 的响应,说明故障转移成功,客户端能够通过 VIP 继续访问服务,验证了高可用配置中故障转移的及时性和有效性。在测试完成后,记得在主服务器上恢复 Nginx 服务,以便后续的使用,执行命令:
sudo systemctl start nginx

通过以上配置验证与测试步骤,可以确保 Nginx 高可用 Keepalived 配置的正确性和可靠性,保障 Web 服务在各种情况下的稳定运行。
七、常见问题与解决方案
在配置 Nginx 高可用 Keepalived 的过程中,可能会遇到一些问题,以下是一些常见问题及对应的解决方案。
VIP 无法正常漂移
VIP 无法正常漂移是一个比较常见且棘手的问题,它会严重影响 Nginx 高可用集群的正常运行。造成这个问题的原因可能是多方面的。
网络问题:网络是 Keepalived 实现 VIP 漂移的基础,一旦网络出现问题,VIP 漂移就会受到阻碍。比如网络分区,主备服务器之间的网络连接被意外分割成不同的区域,导致它们无法正常通信。此时,主服务器发送的 VRRP 通告报文无法到达备服务器,备服务器就无法得知主服务器的状态,自然也就无法进行 VIP 漂移。又或者存在路由问题,数据包在传输过程中无法按照预期的路径到达目标服务器,这也会影响 VRRP 通信和 VIP 漂移。另外,防火墙的配置不当也可能成为阻碍。防火墙可能会拦截 VRRP 协议使用的多播地址(通常是 224.0.0.18)的通信,导致主备服务器之间无法正常交换 VRRP 通告报文。
网卡问题:网卡作为服务器与网络连接的硬件设备,其状态和配置对 VIP 漂移至关重要。如果网卡出现故障,比如硬件损坏、驱动程序异常等,就无法正常接收和发送 VRRP 通告报文,VIP 也就无法漂移到该网卡所在的服务器上。网卡配置不正确也是一个常见原因,例如 IP 地址配置错误、子网掩码设置不当等,这些错误配置会导致网络通信异常,进而影响 VIP 漂移。
Keepalived 配置问题:Keepalived 的配置文件是其运行的核心依据,如果配置文件存在错误,就会导致 VIP 无法正常漂移。比如 VIP 配置错误,在配置文件中设置的虚拟 IP 地址与实际规划的不一致,或者虚拟 IP 地址的子网掩码、网关等参数设置错误,都会使得 VIP 无法正确绑定到服务器的网卡上,从而无法实现漂移。故障检测配置错误也不容忽视,健康检查脚本的路径设置错误,Keepalived 就无法执行该脚本来检测 Nginx 服务状态;脚本执行的时间间隔设置不合理,可能导致检测不及时,错过最佳的主备切换时机。漂移脚本配置错误同样会影响 VIP 漂移,漂移脚本在 VIP 切换过程中起着关键作用,如果脚本中存在语法错误、逻辑错误,或者脚本没有正确的执行权限,都会导致 VIP 漂移失败。
针对这些问题,我们可以采取以下解决方案:
网络问题排查:首先使用 ping 命令检查 VIP 是否能够正常通信。在主备服务器上分别 ping VIP 地址,如果无法 ping 通,说明网络存在问题。接着使用 traceroute 命令检查 VIP 的路由是否正确,通过 traceroute 命令可以查看数据包从源服务器到目标服务器(VIP)的传输路径,从而发现路由异常的节点。如果怀疑是防火墙问题,可以暂时关闭防火墙进行测试。在 CentOS 系统中,可以使用sudo systemctl stop firewalld命令关闭防火墙;在 Ubuntu 系统中,使用sudo ufw disable命令关闭防火墙。关闭防火墙后,如果 VIP 能够正常漂移,就说明防火墙配置存在问题,需要重新配置防火墙规则,允许 VRRP 协议的通信通过。例如,在 CentOS 系统中,可以使用sudo firewall - cmd --add - service=vrrp – permanent命令允许 VRRP 服务通过防火墙,然后使用sudo firewall - cmd --reload命令重新加载防火墙配置。
网卡问题排查:通过 ifconfig 命令检查网卡的配置是否正确,查看网卡的 IP 地址、子网掩码、广播地址等参数是否与实际规划一致。使用 dmesg 命令查看系统日志,查找网卡相关的错误信息。如果发现网卡驱动程序异常,可以尝试更新网卡驱动程序。在 Linux 系统中,可以通过网卡厂商的官方网站下载最新的驱动程序,然后按照驱动程序的安装说明进行更新。如果网卡硬件损坏,就需要更换网卡硬件设备。
Keepalived 配置检查:仔细检查 Keepalived 的配置文件,确认 VIP 配置是否正确,包括虚拟 IP 地址、子网掩码、网关等参数。检查故障检测配置,确保健康检查脚本的路径正确,脚本执行的时间间隔合理。例如,如果发现健康检查脚本路径设置错误,及时修改为正确的路径;如果觉得脚本执行时间间隔过长或过短,可以根据实际情况进行调整。检查漂移脚本配置,确保脚本没有语法错误和逻辑错误,并且具有正确的执行权限。可以使用chmod +x命令为漂移脚本添加执行权限。还可以查看 Keepalived 的日志文件,通常位于/var/log/keepalived.log,通过分析日志文件中的错误信息,进一步定位和解决问题。
健康检查脚本不生效
健康检查脚本不生效也是配置过程中可能遇到的问题,这会导致 Keepalived 无法及时准确地检测 Nginx 服务状态,从而影响高可用集群的可靠性。
权限问题:健康检查脚本需要有足够的权限才能被 Keepalived 正常执行。如果脚本文件的权限设置不当,例如没有执行权限,Keepalived 在尝试执行脚本时就会失败,导致健康检查无法进行。在 Linux 系统中,文件的权限分为读(r)、写(w)、执行(x)三种,对于脚本文件,必须要有执行权限(x)才能被执行。如果脚本文件所属的用户或用户组不正确,也可能导致权限不足。例如,Keepalived 以某个特定用户身份运行,但脚本文件的所有者是其他用户,且没有赋予该特定用户执行脚本的权限,就会出现权限问题。
脚本语法错误:脚本语法错误是导致健康检查脚本不生效的常见原因之一。脚本语言(如 Bash 脚本)有严格的语法规则,如果在编写脚本时违反了这些规则,脚本就无法正常执行。比如变量定义错误,在 Bash 脚本中,变量定义时不能有空格,否则会被视为语法错误。条件判断语句错误也是常见问题,if语句的条件表达式书写错误,或者if和fi不匹配,都会导致脚本执行失败。此外,命令使用错误,脚本中调用的系统命令不存在、命令参数错误,也会使脚本无法正常运行。
依赖问题:健康检查脚本可能依赖于一些系统命令或库文件,如果这些依赖项缺失或版本不兼容,脚本就无法正常执行。例如,脚本中使用了ps命令来检测 Nginx 进程是否存在,但系统中没有安装procps软件包,ps命令就无法执行,从而导致健康检查失败。又比如脚本依赖于某个特定版本的库文件,而系统中安装的库文件版本过低或过高,都可能导致脚本执行出错。
针对这些问题,我们可以采取以下解决方法:
权限问题解决:使用ls -l命令查看脚本文件的权限,确保脚本文件具有执行权限(x)。如果没有执行权限,可以使用chmod +x命令为脚本文件添加执行权限。例如,对于/etc/keepalived/check_nginx.sh脚本文件,可以使用sudo chmod +x /etc/keepalived/check_nginx.sh命令添加执行权限。检查脚本文件所属的用户和用户组,确保 Keepalived 运行的用户有权限执行该脚本。如果需要,可以使用chown命令修改脚本文件的所有者和用户组。例如,如果 Keepalived 以keepalived用户运行,而脚本文件的所有者是root,可以使用sudo chown keepalived:keepalived /etc/keepalived/check_nginx.sh命令将脚本文件的所有者和用户组修改为keepalived。
脚本语法检查:仔细检查脚本语法,使用bash -n命令对脚本进行语法检查。例如,对于check_nginx.sh脚本,可以使用sudo bash -n /etc/keepalived/check_nginx.sh命令进行检查。如果发现语法错误,根据错误提示进行修改。可以参考相关的脚本语言文档,学习正确的语法规则,避免在编写脚本时出现语法错误。在编写脚本时,养成良好的编程习惯,添加注释,提高脚本的可读性和可维护性,这样也有助于发现和解决语法错误。
依赖问题处理:检查脚本中依赖的系统命令是否存在。可以使用which命令查找命令的路径,如果命令不存在,需要安装相应的软件包。例如,如果脚本中依赖ps命令,而which ps命令返回空,说明系统中没有安装procps软件包,可以使用sudo yum install procps(CentOS 系统)或sudo apt - get install procps(Ubuntu 系统)命令进行安装。如果脚本依赖库文件,检查库文件的版本是否兼容。可以通过查看库文件的官方文档或相关资料,了解其版本要求和兼容性。如果库文件版本不兼容,可以尝试升级或降级库文件,使其与脚本兼容。在升级或降级库文件时,要注意可能会影响其他系统组件的正常运行,因此需要谨慎操作,并进行充分的测试。
八、优化与扩展
(一)性能优化
Keepalived 性能优化:
调整检测间隔:在 Keepalived 的配置文件中,advert_int参数用于设置 VRRP 通告报文的发送时间间隔,默认值为 1 秒。在一些对故障切换及时性要求较高的场景下,可以适当减小这个间隔,比如设置为 0.5 秒,这样可以更快地检测到主服务器的故障并进行切换,减少服务中断时间。但需要注意的是,过小的间隔可能会增加网络带宽的占用,因此需要根据实际网络情况进行调整。
优化健康检查脚本:健康检查脚本的执行效率直接影响到 Keepalived 对 Nginx 服务状态的检测及时性。可以对脚本进行优化,例如减少脚本中的不必要操作,使用更高效的命令和算法。在检测 Nginx 进程是否存在时,使用pidof命令可能比ps -C命令更高效,因为pidof命令专门用于查找进程 ID,执行速度更快。同时,合理设置脚本的执行间隔也很重要,在vrrp_script配置块中,interval参数用于设置脚本的执行间隔,应根据 Nginx 服务的稳定性和业务需求进行调整。如果 Nginx 服务比较稳定,可以适当增大这个间隔,减少系统资源的消耗;如果 Nginx 服务容易出现故障,需要及时检测和切换,则应减小间隔。
Nginx 性能优化:
调整工作进程数:Nginx 的worker_processes参数用于设置工作进程的数量,它对 Nginx 的性能有着重要影响。通常情况下,可以将worker_processes设置为服务器的 CPU 核心数,以充分利用服务器的多核性能。在一个具有 8 个 CPU 核心的服务器上,可以将worker_processes设置为 8,使每个 CPU 核心都能处理一个工作进程,避免进程间的 CPU 竞争和频繁的上下文切换,提高 Nginx 的处理能力。也可以根据实际的业务负载情况进行调整,如果业务负载较轻,设置过多的工作进程可能会浪费系统资源;如果业务负载较重,可以适当增加工作进程数,但需要注意不要超过服务器的承受能力。
优化连接池参数:Nginx 的worker_connections参数定义了每个工作进程可以同时打开的最大连接数,它与worker_processes一起决定了 Nginx 能够处理的最大并发连接数。可以根据服务器的硬件性能和业务需求来调整这个参数,提高服务器的总并发能力。在一台内存充足、网络带宽较高的服务器上,可以将worker_connections设置为一个较大的值,如 10240,以满足高并发场景下的需求。但需要注意,这个值不能超过操作系统对单个进程最大文件描述符的限制,如果需要设置更大的值,可能需要先调整系统的ulimit -n参数,提高系统允许的最大文件描述符数量。
启用高效传输:Nginx 提供了一些参数来优化文件传输和 TCP 连接,提高性能。启用sendfile参数可以使用操作系统的sendfile()系统调用,在内核态完成文件传输,实现零拷贝,这对传输大文件非常高效,可以减少 CPU 开销和数据拷贝次数,提高文件传输速度。同时,启用tcp_nopush参数(需要在sendfile开启的情况下),它会指示 Nginx 将响应头和文件数据合并成一个或多个满载的数据包后再发送,提高网络效率,减少网络延迟。还可以设置tcp_nodelay参数为on,减少延迟,使数据能够及时发送。
优化缓存策略:合理配置 Nginx 的缓存策略可以减少后端服务器的负载,提高响应速度。对于静态资源,如 CSS、JavaScript、图片等,可以设置较长的缓存过期时间,使用expires指令来指定缓存的有效期,例如expires 30d表示将这些静态资源缓存 30 天。对于动态资源,可以使用proxy_cache指令开启代理缓存,并通过proxy_cache_path指令定义缓存路径和区域,设置缓存的相关参数,如缓存大小、缓存有效期等。还可以设置proxy_cache_valid指令来针对不同的 HTTP 状态码设置不同的缓存有效期,例如proxy_cache_valid 200 30m;表示将 HTTP 状态码为 200 的响应缓存 30 分钟。
启用 Gzip 压缩:启用 Gzip 压缩可以显著减小 HTML、CSS、JavaScript 等文本类文件的传输体积,从而加速页面加载时间并节省带宽。在 Nginx 的配置文件中,通过gzip on;指令启用压缩,然后可以使用gzip_types指令指定需要压缩的 MIME 类型,如gzip_types text/plain text/css application/json application/javascript;。还可以通过gzip_comp_level指令设置压缩级别,取值范围是 1 - 9,数值越大压缩比越高,但同时也会消耗更多的 CPU 资源,一般推荐使用中间值 5 或 6,以在 CPU 消耗和压缩率之间取得平衡。此外,还可以设置gzip_min_length指令来指定最小压缩文件大小,只有当文件大小大于这个值时才会进行压缩,例如gzip_min_length 1k;表示文件大小大于 1KB 时才进行压缩,避免对过小的文件进行不必要的压缩。
(二)扩展方案
增加备用服务器数量:在现有主备模式的基础上,可以增加更多的备用服务器,进一步提高系统的可靠性。增加备用服务器后,Keepalived 可以根据配置的优先级和 VRRP 协议,在主服务器出现故障时,从多个备用服务器中选举出一个新的主服务器,确保服务的连续性。在一个对服务可用性要求极高的电商系统中,除了一台主服务器和一台备用服务器外,再增加两台备用服务器。当主服务器出现故障时,Keepalived 会在三台备用服务器中选举优先级最高的作为新的主服务器,其他备用服务器继续待命。这样即使某一台备用服务器也出现故障,还有其他备用服务器可以接替工作,大大降低了服务中断的风险。
引入更多的 Nginx 节点:为了实现更强大的负载均衡和高可用能力,可以引入更多的 Nginx 节点,形成 Nginx 集群。在 Nginx 集群中,多个 Nginx 服务器共同承担负载均衡和反向代理的任务,通过负载均衡算法将客户端请求均匀地分配到各个 Nginx 节点上,提高系统的整体性能和并发处理能力。同时,Keepalived 可以对集群中的所有 Nginx 节点进行状态检测和故障转移,确保整个集群的高可用性。可以在upstream模块中定义多个 Nginx 节点,例如:
upstream nginx_cluster {
server 192.168.1.10:80 weight=3;
server 192.168.1.11:80 weight=3;
server 192.168.1.12:80 weight=2;
server 192.168.1.13:80 backup;
}

在这个配置中,定义了四个 Nginx 节点,其中前三个节点权重较高,承担主要的负载均衡任务,第四个节点作为备份节点,当其他节点出现故障时才会被启用。通过这种方式,可以根据各个 Nginx 节点的硬件性能和负载情况,合理分配权重,实现更高效的负载均衡。同时,Keepalived 会对这四个节点进行健康检查,一旦发现某个节点出现故障,会及时将其从负载均衡池中移除,并将请求转发到其他正常节点上,保证服务的稳定运行。
3. 结合云服务进行扩展:利用云服务提供商(如阿里云、腾讯云等)的弹性计算资源,可以轻松实现 Nginx 高可用架构的扩展。云服务提供了弹性伸缩功能,可以根据业务负载的变化自动调整服务器的数量和配置。在业务高峰期,可以自动增加 Nginx 节点和备用服务器的数量,以应对高并发请求;在业务低谷期,可以自动减少服务器数量,降低成本。云服务还提供了负载均衡器、对象存储等服务,可以与 Nginx 高可用架构进行整合,进一步提升系统的性能和可靠性。可以使用云服务提供商的负载均衡器作为前端入口,将请求分发到多个 Nginx 节点上,实现更高级的负载均衡策略。同时,将静态资源存储在云对象存储中,通过 Nginx 的反向代理功能进行访问,提高静态资源的访问速度和稳定性。

更多推荐