您的位置 首页 java

深入理解Nginx及使用Nginx实现负载均衡

前言

最近在部署项目时要求实现 负载均衡 ,有趣的是发现网上一搜全部都是以下类似的配置文件

upstream localhost{
 server 127.0.0.1:8080 weight=1;
 server 127.0.0.1:8081 weight=1;
 }
 server {
 listen 80;
 server_name localhost;
 location / {
 proxy_pass 
 index index.html index.htm index.jsp;
 
 }
 }
 

所以打算来看看Nginx内部原理,这篇博客主要介绍Nginx如何实现 反向代理 以及在Nginx中负载均衡的参数使用

一、正向代理与反向代理

正向代理是代理客户端,也就是客户端能真正接触到的,比如访问外网时需要使用VPN软件,在这个软件中用户可以选择连接哪里的服务器。

反向代理则是代理服务端,用户感知不到,只是客户端把请求发到服务端的端口时,Nginx监听到了便把该端口的请求转发到不同的服务器上。就以上面配置文件来讲解,当在网址中输入时(不加80一样时默认进入 80端口 ,这里为了表示清楚),而后Nginx监听到80端口的请求之后,就会查找对应的location来执行。由上面的配置文件我们可以看出是将请求转发到了不同的端口。这是在服务器中执行的,用户不可见。

而服务端中我们最常使用的反向代理的工具就是Nginx。

二、Nginx内部基本架构

nginx在启动后 以daemon的方式在后台运行 ,会有 一个master进程 多个worker进程

master进程: 主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。

worker进程: 处理基本的网络事件了。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致,或者直接设置参数worker_processes auto;

深入理解Nginx及使用Nginx实现负载均衡

所以Nginx基本的架构就如下:

深入理解Nginx及使用Nginx实现负载均衡

当我们输入./nginx -s reload,就是来重启nginx,./nginx -s stop,就是来停止nginx的运行,这里面是如何做到的?执行命令时,我们是启动一个新的nginx进程,而新的nginx进程在解析到reload参数后,就知道我们的目的是控制nginx来重新加载配置文件了,它会向master进程发送信号。master进程在接到信号后,会先重新加载配置文件,然后再启动新的worker进程,并向所有老的worker进程发送信号,告诉他们可以光荣退休了。新的worker在启动后,就开始接收新的请求,而老的worker在收到来自master的信号后,就不再接收新的请求,并且在当前进程中的所有未处理完的请求处理完成后,再退出。所以 使用上面命令重启Nginx的时候服务是不中断的

三、Nginx如何处理客户端请求

首先来解释一下上面的架构图 :每个worker进程都是从master进程分支过来的,在master进程里面,先建立好需要监听的 socket 之后,然后再分支出多个worker进程。所有worker进程的listenfd(socket中listenfd是指客户端连接本机时的fd,是用来和客户端通信用的)会在新连接到来时变得可读,为保证只有一个进程处理该连接,所有worker进程在注册listenfd读事件前抢 accept _mutex,抢到互斥锁的那个进程注册listenfd读事件,在读事件里调用accept接受该连接。

在Nginx中worker进程之间是平等的,每个进程,处理请求的机会也是一样的。当Nginx监听80端口时,一个客户端的连接请求过来,每个进程都有可能处理这个连接,上面说到是每个worker进程都会去抢注listenfd读事件。当一个worker进程在accept这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,这样一个完整的请求就是这样的了。这里需要注意的是 一个请求,完全由worker进程来处理,而且只在一个worker进程中处理

下面两幅流程图能很好的帮我们理解

深入理解Nginx及使用Nginx实现负载均衡

四、Nginx如何处理事件并且实现高并发

Nginx内部采用了异步非阻塞的方式来处理请求,也就是说,Nginx是可以同时处理成千上万个请求的。

异步非阻塞: 当一个网络请求过来时,我们并不依赖于这个请求才能做后续操作,那么这个请求就是异步操作,也就是调用者在没有得到结果之前同样可以执行后续的操作。非阻塞就是当前进程/ 线程 没有得到请求调用的结果时也不会妨碍到进程/线程后续的操作。可以看出异步和非阻塞的对象是不同的。

五、Nginx负载均衡的 算法 及参数

round robin(默认): 轮询方式, 依次 将请求分配到后台各个服务器中,适用于后台机器性能一致的情况,若服务器挂掉,可以自动从服务列表中剔除

weight: 根据权重来分发请求到不同服务器中,可以理解为比例分发,性能较高服务器分多点请求,较低的则分少点请求

IP_hash: 根据请求者ip的hash值将请求发送到后台服务器中,保证来自同一ip的请求被转发到固定的服务器上,解决session问题

upstream localhost { 
ip_hash; 
server 127.0.0.1:8080; 
server 127.0.0.1:8080; 
} 
 

上面是最基本的三种算法,我们还可以通过改变参数来自行配置负载均衡

upstream localhost{ 
ip_hash; 
server 127.0.0.1:9090 down; 
server 127.0.0.1:8080 weight=2; 
server 127.0.0.1:6060; 
server 127.0.0.1:7070 backup; 
}
 

参数列表如下:

关注我,后续更多干货奉上!

文章来源:智云一二三科技

文章标题:深入理解Nginx及使用Nginx实现负载均衡

文章地址:https://www.zhihuclub.com/200728.shtml

关于作者: 智云科技

热门文章

网站地图