Nginx 是一个轻量级的、基于http的、高性能的反向代理的服务器和静态web服务器。
不管是正向代理还是反向代理都是基于客户端来说的。
1、nginx的负载均衡策略有两种:内置策略和扩展策略
2、内置策略:轮询、权重轮询、IP hash、least_conn
3、扩展策略:自己想怎么实现就怎么实现
轮询是upstream默认的负载均衡策略,每个请求会按时间顺序逐一分配到不同的服务器
参数如下:
例子:
#动态服务器组
upstream dynamic_zuoyu {
server localhost:8080; #Tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082 backup; #tomcat 8.5
server localhost:8083 max_fails=3 fail_timeout=20s; #tomcat 9.0
}
注:此策略适合服务器配置相当,无状态且短平快的服务使用
权重的方式,是在轮询基础上制定轮询的几率;权重分配越高,需要处理的请求越多;此策略也可和ip_hash、least_conn结合使用。
例子:
#动态服务器组
upstream dynamic_zuoyu {
server localhost:8080 weight=2; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082 backup; #tomcat 8.5
server localhost:8083 max_fails=3 fail_timeout=20s; #tomcat 9.0
}
注:此策略适合服务器硬件配置差异比较大时使用
ip哈希的方式,基于客户端IP来分配,确保统一IP地址的客户端请求都到同一台服务器,保证session会话。可以解决session不能跨域的问题
例子:
#动态服务器组
upstream dynamic_zuoyu {
ip_hash; #保证每个访客固定访问一个后端服务器
server localhost:8080 weight=2; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082; #tomcat 8.5
server localhost:8083 max_fails=3 fail_timeout=20s; #tomcat 9.0
}
注:此策略适合服务器解决session不能跨域的问题时使用
最少连接方式,将请求转发给连接数较少的服务端。由于轮询的方式是平均将请求转发给各个服务器,使得负载大致相同。但是也存在其中某些请求的链路过长,占用时间长,导致某一些服务器的负载较高。所以最少连接的方式可以平衡轮询会出现的这种问题
例子:
#动态服务器组
upstream dynamic_zuoyu {
least_conn; #把请求转发给连接数较少的后端服务器
server localhost:8080 weight=2; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082 backup; #tomcat 8.5
server localhost:8083 max_fails=3 fail_timeout=20s; #tomcat 9.0
}
注:此策略适合请求时间长短不一造成服务器负载的情况时使用
按照服务器的响应时间来分配请求,响应时间短的服务器优先分配(能者多劳)
例子:
#动态服务器组
upstream dynamic_zuoyu {
server localhost:8080; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082; #tomcat 8.5
server localhost:8083; #tomcat 9.0
fair; #实现响应时间短的优先分配
}
按照url哈希来分配请求到服务器,使得相同的url每次到的服务器一致,这样也可以减轻对服务器的压力(配合缓存命中来使用)
例子:
#动态服务器组
upstream dynamic_zuoyu {
hash $request_uri; #实现每个url定向到同一个后端服务器
server localhost:8080; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082; #tomcat 8.5
server localhost:8083; #tomcat 9.0
}
注:此策略适合同一个资源多次请求的情况时使用
location / {
root /data/paibo_web_8081_css; #前端代码存放路径
index index.html index.htm;
}
location /upfile/ {
root /home/audit_files/; #文件存放路径
index index.html;
}
#下载gcc编译器
yum -y install gcc gcc-c++
#下载PCRE
yum -y install pcre-devel openssl-devel
#下载nginx,官方网站是 http://nginx.org ,自己找到需要的版本,右键复制下载链接
wget http://nginx.org/download/nginx-1.19.2.tar.gz
#解压
tar -zxvf nginx-1.19.2.tar.gz
#生成makefile。使用./configure --help查看各个模块的使用情况,使用--without-http_ssi_module的方式关闭不需要的模块。可以使用--with-http_perl_modules方式安装需要的模块
cd nginx-1.19.2
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
#编译安装
make && make install
#进入到安装目录
cd /usr/local/nginx/
#将 /usr/local/nginx/sbin/nginx 软连接到 /usr/local/sbin 下,就可以在任意地方使用nginx命令
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
#修改配置文件
vim /usr/local/nginx/conf/nginx.conf
#测试nginx配置文件是否正常
nginx -t
#启动nginx
nginx
#关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
#外部访问,nginx默认监听80端口
192.168.198.98:80
#重新载入配置文件
nginx -s reload
#重启nginx
nginx -s reopen
#停止nginx
nginx -s stop
#在两台服务器安装nginx,参考<Nginx的下载与安装>
#我这里用的是下面两台服务器,为了区分,做了以下修改
192.168.198.6 #编辑index.html,<h1>Welcome to nginx! 2</h1>
192.168.198.98 #编辑index.html,<h1>Welcome to nginx! 1</h1>
#两台服务器都需要执行以下操作
#下载keepalived安装包
cd /data/soft/
wget https://www.keepalived.org/software/keepalived-2.1.0.tar.gz
#解压安装包
tar -zxvf keepalived-2.1.0.tar.gz
#编译安装
cd keepalived-2.1.0
./configure --prefix=/usr/local/keepalived
make && make install
#keepalived启动脚本变量引用文件,默认文件路径是/etc/sysconfig/,也可以不做软链接,直接修改启动脚本中文件路径即可(安装目录下)
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/keepalived
#将keepalived主程序加入到环境变量(安装目录下)
cp /usr/local/keepalived/sbin/keepalived /usr/sbin/keepalived
#keepalived启动脚本(源码目录下),放到/etc/init.d/目录下就可以使用service命令便捷调用
cp /data/soft/keepalived-2.1.0/keepalived/etc/init.d/keepalived /etc/init.d/keepalived
#将配置文件放到默认路径下
mkdir /etc/keepalived
cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf
#加为系统服务
chkconfig –add keepalived
#开机启动
chkconfig keepalived on
#查看开机启动的服务
chkconfig –list
#启动、关闭、重启
service keepalived start|stop|restart
######################### 至此,安装完成;以下就是在keepalived.conf做HA的配置 #########################
vim /etc/keepalived/keepalived.conf
##### master #####
! Configuration File for keepalived
# 全局定义块
global_defs {
router_id redis-rocketMQ #标志本节点的字符串,建议使用hostname
}
# keepalived 会定时执行脚本并对脚本执行的结果进行分析,动态调整 vrrp_instance 的优先级。如果脚本执行结果为 0,并且 weight 配置的值大于 0,则优先级相应>的增加。如果脚本执行结果非 0,并且 weight配置的值小于 0,则优先级相应的减少。其他情况,维持原本配置的优先级,即配置文件中 priority 对应的值。
vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh" #检测 nginx 状态的脚本路径
interval 2 #检测时间间隔
weight -20 #如果条件成立,权重-20
}
# 定义虚拟路由,VI_1 为虚拟路由的标示符,自己定义名称
vrrp_instance VI_1 {
state MASTER #主节点为MASTER,备用节点为BACKUP
interface eno16777736 #与本机网卡名称一致
virtual_router_id 51 #虚拟路由的id号,两个节点必须设置一样
mcast_src_ip 192.168.198.98
priority 100 #设置优先级,值范围 0~254,master要比backup高
nopreempt #优先级高的设置 nopreempt 解决异常恢复后再次抢占的问题
advert_int 1 #组播信息发送间隔,节点必须设置一致
authentication { #设置验证信息,节点必须设置一致
auth_type PASS
auth_pass 1111
}
#将 track_script 块加入 instance 配置块
track_script {
chk_nginx #执行 Nginx 监控的服务
}
virtual_ipaddress { #虚拟节点池,节点必须设置一样
192.168.198.111 #虚拟ip,可设置多个
}
}
##### backup #####
! Configuration File for keepalived
global_defs {
router_id zk_alone
}
vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh"
interval 2
weight -20
}
vrrp_instance VI_1 {
state BACKUP
interface eno16777736
virtual_router_id 51
mcast_src_ip 192.168.198.6
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
chk_nginx
}
virtual_ipaddress {
192.168.198.111
}
}
#编写 Nginx 状态检测脚本
#ps -C nginx | wc -l,查看当前有多少个nginx进程
#逻辑:如果 nginx 停止运行,尝试启动,如果无法启动则杀死本机的 keepalived 进程, keepalied将虚拟 ip 绑定到 BACKUP 机器上
vi /etc/keepalived/nginx_check.sh
#!/bin/bash
A=`ps -C nginx –no-header |wc -l`
if [ $A -eq 0 ];then
/usr/local/nginx/sbin/nginx
sleep 2
if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
killall keepalived
fi
fi
#赋权限
chmod +x /etc/keepalived/nginx_check.sh
#启动 两台Keepalived
service keepalived start
#访问虚拟IP
192.168.198.111 # Welcome to nginx! 1
######################### HA测试 #########################
#由于我们写了一个自动启动nginx的脚本再keepalived中,故关闭时,先关闭keepalived,再关闭nginx
192.168.198.98
service keepalived stop
nginx -s stop
#再次访问192.168.198.111查看变化 Welcome to nginx! 2
192.168.198.98
service keepalived start #由于有启动nginx的脚本,故省去启动nginx的操作
#再次访问192.168.198.111查看变化 Welcome to nginx! 1
高并发一般是由多进程、多线程和异步机制来处理的,而正好nginx采用了这三种有效的处理高并发的方式。
进程模型采用Master/Worker 方式。当 nginx 启动的时候,会创建一个 Master 进程,Master进程会根据nginx.conf配置文件中相应的配置项来fork出多个worker子进程去处理请求(怎么处理也是根据配置文件中相应的配置文件)。
Master进程负责管理Worker进程的生命周期、处理网络事件、接收外界信号等。由于Master进程可以fork出多个Worker进程,所以说Nginx是多进程的。
线程模型是指worker进程用于接收和处理客户端请求。每个worker进程可以同时处理多个用户请求。
异步处理模式是指nginx处理请求的时候是采用I/O多路复用技术(select | poll | epoll 模型),即多个 I/O 可以复用一个进程。当 worker 进程接收到客户端的请求后,会调用服务端对其请求进行处理,如果没有立即得到响应结果, worker 进程没有阻塞,而是去处理其他请求,知道有请求被服务端处理完成并返回响应结果。
这里的 worker 进程默认就是采用 epoll 多路复用机制来对服务端进行处理的。当服务端返回响应结果时,回调 epoll 多路复用器,epoll 告知 worker 进程,worker 会挂起当前正在处理的线程,去获取响应结果返回客户端,完成后再去执行被挂起的线程。整个过程中不会出现等待的情况,所以理论上Ngnix的一个进程就可以处理无限数量的连接,而且无需轮询。
注:worker 进程接收客户端请求不是采用的 epoll 模型,而是互斥锁机制;只有对服务端的请求和响应采用的是 epoll 模型。
一个nginx的默认并发量为1024,是因为默认一个woker进程,每个进程处理量为1024,故1*1024;但是,在硬件条件满足的条件下,nginx可以支持5~10w的并发量。具体做法如下:
####################### 操作系统配置 start #######################
#查看当前会话中所有的linux核心配置,而我们只需要关注open file这项
ulimit -a
#查看linux系统的“进程最大可打开文件数的设置”,默认时1024
ulimit -n
#修改“进程最大可打开文件数的设置”
vim /etc/security/limit.conf
#添加下面两行
soft nofile 65535 #应用软件级别限制的最大可打开文件数的限制
hard nofile 65535 #操作系统级别限制的最大可打开文件数的限制
#文件保存后不会马上生效,所以还得更改当前会话级别的配置
ulimit -n 65535
####################### 操作系统配置 end #######################
####################### nginx配置 start #######################
#修改nginx配置文件(下面两行)
vim /src/local/nginx/conf/nginx.conf
user root root;
worker_processes 4;
worker_rlimit_nofile 65535; #这行,看这里看这里
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
use epoll;
worker_connections 65535; #这行,看这里看这里
}
#热部署重新加载配置文件
nginx -s reload
####################### nginx配置 end #######################
####################### 验证配置是否正确 start #######################
#查看当前nginx进程信息
ps -ef | grep nginx
root 103734 1 0 13:27 ? 00:00:00 nginx: master process nginx
nobody 103735 103734 0 13:27 ? 00:00:00 nginx: worker process
root 105129 3066 0 14:50 pts/0 00:00:00 grep --color=auto nginx
#注意,也是看open files这项
cat /proc/103735/limits
####################### 验证配置是否正确 start #######################
####################### max client计算方式 start #######################
max client = worker_processes * worker_connections
或
max client = worker_processes * worker_connections / 4
#第一种很好理解,进程数*每个进程并发数
#第二种为什么要除以4呢?是因为在nginx官网有这么一段话
Since a browser opens 2 connections by default to a server and nginx uses the fds (file descriptors) from the same pool to connect to the upstream backend。
#就是说,浏览器会建立两条链接到nginx,而nginx也会建立两条链接到服务端,故就是4
####################### max client计算方式 end #######################
一万个非活跃性链接,消耗内存仅暂用2.5M,故对于一般的dos攻击不受影响,但是ddos还是有问题。
可以在7*24小时不间断服务提供,进行版本和配置平滑升级
#命令
nginx -s reload
####################### 命令过程解析 start #######################
1、当上面的命令一执行,如果发现配置文件已更改,会创建一个新的主进程
2、当前所有的worker进程不会再接收新的请求并把当前正在处理的请求执行完就关闭
3、master主进程会创建新的worker进程来接收并处理新的请求
####################### 命令过程解析 end #######################
之所以实现高可用,是因为在nginx中,woker都一个一个的进程,就算其中某个进程挂掉了,也对其他的进程没得影响,而且其他的进程会接替出问题的进程。
由于nginx是模块化集成,故在我们使用中,缺少什么模块我们就安装什么模块(模块一般分为C语言扩展模块和Lua脚本扩展模块)
#下载模块
git clone https://github.com/agentzh/echo-nginx-module
#放入指定位置
mv echo-nginx-module-master /usr/local/nginx/echo-nginx-module
#就用这个命令生成新的makefile
./configure
--prefix=/usr/local/nginx
--with-http_stub_status_module
--with-http_ssl_module
--add-module=/usr/local/nginx/echo-nginx-module
#编译(这里只需要make,一定不要执行make install,不然会被覆盖)
make
#备份原文件
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
#替换nginx二进制文件
cp /usr/local/nginx/objs/nginx /usr/local/nginx/sbin/nginx
#重新建立软连接,检测配置文件并平滑启动
ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/nginx
nginx -t
nginx -s reload
配置影响nginx的全局指令。包括:
配置影响nginx服务器或与用户的网络连接。包括:
可以嵌套多个server模块,配置代理、缓存、日志定义等和第三方模块的配置。包括:
配置虚拟主机相关参数。包括:
配置请求的路由,以及页面和其他静态资源的处理。包括:
文章到这里就结束了!Nginx 是一个高性能的 HTTP 和反向代理服务器,特点是占用内存少,并发能力强,事实上 Nginx 的并发能力确实在同类型的网页服务器中表现较好。Nginx 专为性能优化而开发,性能是其最重要的要求,十分注重效率,有报告 Nginx 能支持高达 50000 个并发连接数。
大家看完有什么不懂的可以在下方留言讨论.
谢谢你的观看。
觉得文章对你有帮助的话记得关注我点个赞支持一下!
作者:麒麟才子
链接:https://juejin.cn/post/6912616466513100807