深入浅出Nginx 如何做到高并发下的高效处理?如何做到热部署?
快,关注米兜Java,一起涨姿势~

热点推荐
推荐27个Mybatis-Plus优秀案例foreach循环中为什么不要进行remove/add操作微服务架构如何保证安全性?深入浅出Nginx,如何做到高并发下的高效处理?如何做到热部署?

01前言
Nginx("engine x")是一款是由俄罗斯的程序员Igor Sysoev所开发高效能的 Web和 反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。在高连线并发的情况下,Nginx是Apache服务器不错的替代品。由于它的内存占用少,启动极快,高并发能力强,在互联网专案中广泛应用。

上图简单展示了Nginx的部署,Nginx类似闸道器。
02正向代理与反向代理
正向代理与反向代理有什么区别昵?我们就不废话先,直接上图
这两图这么一整,估计也很难理解清楚那个是正向代理,那个是反向代理。那我现在详细解释一下吧。
正向代理形如1图,我们在aws上申请首次注册送12月的服务器,然后它就是我们的VPN了,然后我们通过它就可以访问YouTube了。不知道大伙能不能明白,正向代理是我们客户端发起的,客户端做出调整。
反向代理形如2图,服务器A,服务器B,服务C部署在内网,我们通过Nginx暴露一个外网地址,小伙伴们就可以访问我们了。
这么讲不知道能不能解释清楚,大伙可以继续看一下下面这个比喻:
正向代理:客户端 代理 一>服务端
正向代理简单地打个租房的比方:
A(客户端)想租C(服务端)的房子,但是A(客户端)并不认识C(服务端)租不到。
B(代理)认识C(服务端)能租这个房子所以你找了B(代理)帮忙租到这个房子。
这个过程中C(服务端)不认识A(客户端)只认识B(代理)
C(服务端)并不知道A(客户端)租了房子,只知道房子租给了B(代理)。
反向代理:客户端 一>代理 服务端
反向代理也用一个租房的例子:
A(客户端)想租一个房子,B(代理)就把这个房子租给了他。
这时候实际上C(服务端)才是房东。
B(代理)是中介把这个房子租给了A(客户端)。
这个过程中A(客户端)并不知道这个房子到底谁才是房东。
03Master-Worker模式

启动Nginx后,其实就是在80埠启动了Socket服务进行监听,如图所示,Nginx涉及Master程序和Worker程序。


1--程序数,建议设定和CPU个数一样或2倍
2--日志级别,预设error级别
3--Nginx 启动后的pid 存放位置
4--配置每个程序的连线数,总的连线数= worker_processes * worker_connections根据实体内存大小来配置,预设1024
Master程序的作用是?
读取并验证配置档案nginx.conf;管理worker程序;
Worker程序的作用是?
每一个Worker程序都维护一个执行绪(避免执行绪切换),处理连线和请求;注意Worker程序的个数由配置档案决定,一般和CPU个数相关(有利于程序切换),配置几个就有几个Worker程序。
由nginx程序图可以看到,我这边配了两个worker_processes,所以有两个worker程序。
04如何做到高并发下的高效处理?
上文已经提及Nginx的worker程序个数与CPU系结、worker程序内部包含一个执行绪高效回环处理请求,这的确有助于效率,但这是不够的。作为专业的程序员,我们可以开一下脑洞:BIO/NIO/AIO、异步/同步、阻塞/非阻塞...
要同时处理那么多的请求,要知道,有的请求需要发生IO,可能需要很长时间,如果等着它,就会拖慢worker的处理速度。
Nginx采用了Linux的epoll模型,epoll模型基于事件驱动机制,它可以监控多个事件是否准备完毕,如果OK,那么放入epoll伫列中,这个过程是异步的。worker只需要从epoll伫列循环处理即可。
05如何做到热部署?
所谓热部署,就是配置档案nginx.conf修改后,不需要stop Nginx,不需要中断请求,就能让配置档案生效!(nginx -s reload 重新载入|nginx -t检查配置|nginx -s stop 停止nginx)通过上文我们已经知道worker程序负责处理具体的请求,那么如果想达到热部署的效果,可以想象:
方案一:
修改配置档案nginx.conf后,主程序master负责推送给woker程序更新配置资讯,woker程序收到资讯后,更新程序内部的执行绪资讯。(有点valatile的味道)
方案二:
修改配置档案nginx.conf后,重新生成新的worker程序,当然会以新的配置进行处理请求,而且新的请求必须都交给新的worker程序,至于老的worker程序,等把那些以前的请求处理完毕后,kill掉即可。
Nginx采用的就是方案二来达到热部署的!
模拟一个例子:
首先在本地模拟一个线上需要升级 Nginx 的环境,假设旧版本为 nginx-1.0.15,需要升级到 nginx-1.16.0。
开始之前,先牢记一下以下几个命令:
-HUP 平滑启动(相当于reload)-USR2 平滑升级可执行程式,主要用在版本升级-WINCH 从容关闭工作程序-USR1 重新开启日志档案,主要用在日志切割(相当于reopen) 配置旧版本
# 下载 nginx-1.0.15
wget http://nginx.org/download/nginx-1.0.15.tar.gz
# 解压压缩包
tar -zxf nginx-1.0.15.tar.gz
# 进入解压后的目录
cd nginx-1.0.15
# 配置 nginx
./configure --prefix=/home/nginx
# 编译安装
make && make install
# 执行 nginx
sudo /home/nginx/sbin/nginx
此时访问服务器地址应该可以看到 nginx 的欢迎页面了。
获得新版本二进位制
# 下载 nginx-1.16.0
wget http://nginx.org/download/nginx-1.16.0.tar.gz
# 解压压缩包
tar -zxf nginx-1.16.0
# 进入解压后的目录
cd nginx-1.16.0/
# 配置 nginx
./configure --prefix=/home/nginx
# 只编译不需要安装
make
在编译后的 objs 目录中,可以看到二进位制档案 nginx。
热部署
经过以上步骤,我们实现了一个正在执行的旧版本 nginx 和编译完成的新版本 nginx 二进位制执行档案。
热部署的流程是:
备份旧的 nginx 可执行档案新的 nginx 可执行档案直接替换旧的(此时旧的 nginx 程序还在执行)向 nginx master 程序传送热部署讯号,新的 nginx 程序启动,旧的 worker 不再就收请求。关闭旧的 worker 程序,完成热部署。# 备份
cp /home/nginx/sbin/nginx /home/nginx/sbin/nginx.old
# 替换
cp -f objs/nginx /home/nginx/sbin/nginx
# 检视 master pid
ps -ef | grep nginx
root 23712 1 0 21:21 ? 00:00:00 nginx: master process /home/nginx/sbin/nginx
nobody 23715 23712 0 21:21 ? 00:00:00 nginx: worker process
# 传送热部署讯号,这里 master pid 替换为自己查询到的
kill -USR2 23712
# 检视当前 nginx 程序情况,27522 就是新的 master 程序
ps -ef | grep nginx
root 23712 1 0 21:21 ? 00:00:00 nginx: master process /home/nginx/sbin/nginx
nobody 23715 23712 0 21:21 ? 00:00:00 nginx: worker process
root 27522 23712 0 21:41 ? 00:00:00 nginx: master process /home/nginx/sbin/nginx
nobody 27524 27522 0 21:41 ? 00:00:00 nginx: worker process
# 关闭旧的 worker
kill -WINCH 23712
# 再次检视程序,可以发现旧的worker程序关闭了
ps -ef | grep nginx
root 23712 1 0 21:21 ? 00:00:00 nginx: master process /home/nginx/sbin/nginx
root 27522 23712 0 21:41 ? 00:00:00 nginx: master process /home/nginx/sbin/nginx
nobody 27524 27522 0 21:41 ? 00:00:00 nginx: worker process
保留旧的 master 程序是为了在新的版本存在问题时,可以快速回退到原版本。如果发现问题要紧急回滚呢?
cp -f nginx.old nginx
# 拉起旧版本的worker程序(-HUP 相当于 -s reload)
kill -HUP old_master_pid
# 让新版本的 worker 不再接受请求
kill -USR2 new_master_pid
# 关闭新版本的 woker 程序
kill -WINCH new_master_pid
如果确认无误要退出老版本的 nginx,可以执行命令
kill -QUIT old_master_pid

请留下你指尖的温度
让太阳拥抱你
记得这是一个有温度的头条号
米兜Java
print_r('点个好看吧!');
var_dump('点个好看吧!');
NSLog(@"点个好看吧!");
System.out.println("点个好看吧!");
console.log("点个好看吧!");
print("点个好看吧!");
printf("点个好看吧! ");
cout
Console.WriteLine("点个好看吧!");
fmt.Println("点个好看吧!");
Response.Write("点个好看吧!");
alert("点个好看吧!")
echo "点个好看吧!"