跳至主要內容

nginx高可用

知识库集成配置NginxNginx大约 6 分钟

安装 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

官网地址:https://www.keepalived.org/download.htmlopen in new window

在线安装

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;
}