nginx高可用
安装 nginx
rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
yum -y install nginx
systemctl enable nginx.service && systemctl start nginx.service && systemctl status nginx.service
安装 keepalived
在线安装
yum -y install keepalived
## 启动keepalived
systemctl enable keepalived.service && systemctl start keepalived.service && systemctl status keepalived.service
离线安装
mkdir -p ~/app/keepalived && cd ~/app/keepalived
wget https://www.keepalived.org/software/keepalived-2.2.7.tar.gz --no-check-certificate
tar -zxvf keepalived-2.2.7.tar.gz
cd keepalived-2.2.7
## 编译
./configure --prefix=/usr/local/keepalived/ && make && make install
## 查看目录
ll /usr/local/keepalived/
## 启动keepalived
systemctl enable keepalived.service && systemctl start keepalived.service && systemctl status keepalived.service
配置 keepalived
检测脚本
mkdir -p /usr/local/src
cat > /usr/local/src/check_nginx_pid_restart.sh << EOF
#!/bin/sh
## 检测nginx是否启动了
NGINX_NUMBER=\`ps -C nginx --no-header | wc -l\`
## 判断后台是否还有Nginx进程在运行
if [ \$NGINX_NUMBER -eq 0 ];then
## 重启nginx
systemctl start nginx.service
# 重启后等待1s后,再次查询后台进程数
sleep 1
## nginx重启失败,则停掉keepalived服务,进行VIP转移
if [ \`ps -C nginx --no-header | wc -l\` -eq 0 ];then
systemctl stop keepalived.service
fi
fi
EOF
# 在vi命令里面执行,修改编码格式
:set fileformat=unix
# 在vi命令里面执行,查看修改后的编码格式
:set ff
## 脚本授权
chmod 775 /usr/local/src/check_nginx_pid_restart.sh
主配置文件
离线编译配置文件位置:vi /usr/local/keepalived/etc/keepalived/keepalived.conf
yum 安装配置文件位置:vi /etc/keepalived/keepalived.conf
global_defs {
# 自带的邮件提醒服务,建议用独立的监控或第三方SMTP,也可选择配置邮件发送。
notification_email {
root@localhost
}
notification_email_from root@localhost
smtp_server localhost
smtp_connect_timeout 30
# 高可用集群主机身份标识(集群中主机身份标识名称不能重复,建议配置成本机IP)
router_id 192.168.60.91
}
# 定时运行的脚本文件配置
vrrp_script check_nginx {
# 心跳执行的脚本,检测nginx是否启动
script "/usr/local/src/check_nginx_pid_restart.sh"
# 每间隔3秒执行一次
interval 3
# 如果脚本中的条件成立,重启一次则权重-2
weight -2
}
# 定义虚拟路由,VI_1为虚拟路由的标示符(可自定义名称)
vrrp_instance VI_1 {
# 指定keepalived的角色,MASTER为主,BACKUP为备
state MASTER
# 绑定虚拟IP的网络接口,根据自己的机器的网卡配置
interface ens33
# 虚拟路由的ID号,主从两个节点设置必须一样
virtual_router_id 66
# 填写本机IP
mcast_src_ip 192.168.60.91
# 节点权重优先级,主节点要比从节点优先级高
priority 100
# 优先级高的设置nopreempt,解决异常恢复后再次抢占造成的脑裂问题
nopreempt
# 组播信息发送间隔,两个节点设置必须一样,默认1s(类似于心跳检测)
advert_int 1
# 授权访问
authentication {
# 设置验证类型和密码,MASTER和BACKUP必须使用相同的密码才能正常通信
auth_type PASS
auth_pass 123456
}
# 将track_script块加入instance配置块
track_script {
# 执行Nginx监控的脚本
check_nginx
}
# 定义虚拟IP(VIP),可多设,每行一个
virtual_ipaddress {
192.168.60.90
}
}
## 重新加载
systemctl daemon-reload && systemctl restart keepalived.service && systemctl status keepalived.service
备机配置
离线编译配置文件位置:vi /usr/local/keepalived/etc/keepalived/keepalived.conf
yum 安装配置文件位置:vi /etc/keepalived/keepalived.conf
global_defs {
# 自带的邮件提醒服务,建议用独立的监控或第三方SMTP,也可选择配置邮件发送。
notification_email {
root@localhost
}
notification_email_from root@localhost
smtp_server localhost
smtp_connect_timeout 30
# 高可用集群主机身份标识(集群中主机身份标识名称不能重复,建议配置成本机IP)
router_id 192.168.60.92
}
# 定时运行的脚本文件配置
vrrp_script check_nginx {
# 心跳执行的脚本,检测nginx是否启动
script "/usr/local/src/check_nginx_pid_restart.sh"
# 每间隔2秒执行一次
interval 2
# 权重
weight 2
}
# 定义虚拟路由,VI_1为虚拟路由的标示符(可自定义名称)
vrrp_instance VI_1 {
# 指定keepalived的角色,MASTER为主,BACKUP为备
state BACKUP
# 绑定虚拟IP的网络接口,根据自己的机器的网卡配置
interface ens33
# 虚拟路由的ID号,主从两个节点设置必须一样
virtual_router_id 66
# 填写本机IP
mcast_src_ip 192.168.60.92
# 节点权重优先级,主节点要比从节点优先级高
priority 90
# 优先级高的设置nopreempt,解决异常恢复后再次抢占造成的脑裂问题
nopreempt
# 组播信息发送间隔,两个节点设置必须一样,默认1s(类似于心跳检测)
advert_int 1
# 授权访问
authentication {
# 设置验证类型和密码,MASTER和BACKUP必须使用相同的密码才能正常通信
auth_type PASS
auth_pass 123456
}
# 将track_script块加入instance配置块
track_script {
# 执行Nginx监控的脚本
check_nginx
}
# 定义虚拟IP(VIP),可多设,每行一个
virtual_ipaddress {
192.168.60.90
}
}
## 重新加载
systemctl daemon-reload && systemctl restart keepalived.service && systemctl status keepalived.service
性能优化
打开长连接配置
通常 Nginx 作为代理服务,负责分发客户端的请求,那么建议开启 HTTP 长连接,用户减少握手的次数,降低服务器损耗,具体如下:
upstream xxx {
# 长连接数
keepalive 32;
# 每个长连接提供的最大请求数
keepalived_requests 100;
# 每个长连接没有新的请求时,保持的最长时间
keepalive_timeout 60s;
}
开启零拷贝技术
零拷贝这个概念,在大多数性能较为不错的中间件中都有出现,例如 Kafka、Netty 等,而 Nginx 中也可以配置数据零拷贝技术,如下:
sendfile on; # 开启零拷贝机制
零拷贝读取机制与传统资源读取机制的区别:
- 传统方式:「硬件-->内核-->用户空间-->程序空间-->程序内核空间-->网络套接字」
- 零拷贝方式:「硬件-->内核-->程序内核空间-->网络套接字」
开启无延迟或多包共发机制
在 Nginx 中有两个较为关键的性能参数,即 tcp_nodelay、tcp_nopush,开启方式如下:
tcp_nodelay on;
tcp_nopush on;
调整 Worker 工作进程
Nginx 启动后默认只会开启一个 Worker 工作进程处理客户端请求,而我们可以根据机器的 CPU 核数开启对应数量的工作进程,以此来提升整体的并发量支持,如下:
# 自动根据CPU核心数调整Worker进程数量
worker_processes auto;
# 每个Worker能打开的文件描述符,最少调整至1W以上,负荷较高建议2-3W
worker_rlimit_nofile 20000;
开启 CPU 亲和机制
对于并发编程较为熟悉的伙伴都知道,因为进程/线程数往往都会远超出系统 CPU 的核心数,因为操作系统执行的原理本质上是采用时间片切换机制,也就是一个 CPU 核心会在多个进程之间不断频繁切换,造成很大的性能损耗。
而 CPU 亲和机制则是指将每个 Nginx 的工作进程,绑定在固定的 CPU 核心上,从而减小 CPU 切换带来的时间开销和资源损耗,开启方式如下:
worker_cpu_affinity auto;
开启 epoll 模型及调整并发连接数
在最开始就提到过:Nginx、Redis 都是基于多路复用模型去实现的程序,但最初版的多路复用模型 select/poll 最大只能监听 1024 个连接,而 epoll 则属于 select/poll 接口的增强版,因此采用该模型能够大程度上提升单个 Worker 的性能,如下:
events {
# 使用epoll网络模型
use epoll;
# 调整每个Worker能够处理的连接数上限
worker_connections 10240;
}