精华内容
下载资源
问答
  • nginx负载均衡原理

    万次阅读 多人点赞 2018-11-15 09:44:52
    负载均衡在服务端开发中算是一个比较重要的特性。因为Nginx除了作为常规的Web服务器外,还会被大规模的用于反向代理前端,因为Nginx的异步框架可以处理很大的并发请求,把这些并发请求hold住之后就可以分发给后台...

    负载均衡在服务端开发中算是一个比较重要的特性。因为Nginx除了作为常规的Web服务器外,还会被大规模的用于反向代理前端,因为Nginx的异步框架可以处理很大的并发请求,把这些并发请求hold住之后就可以分发给后台服务端(backend servers, 后面简称backend)来做复杂的计算、处理和响应,并且在业务量增加的时候可以方便地扩容后台服务器。
    负载均衡可以分为硬件负载均衡和软件负载均衡,前者一般是专用的软件和硬件相结合的设备,设备商会提供完整成熟的解决方案,通常也会更加昂贵。软件的复杂均衡以Nginx占据绝大多数,本文也是基于其手册做相应的学习研究的。

    在这里插入图片描述
    一、基本简介
    负载均衡涉及到以下的基础知识。

    (1) 负载均衡算法

    a. Round Robin: 对所有的backend轮训发送请求,算是最简单的方式了,也是默认的分配方式;

    b. Least Connections(least_conn): 跟踪和backend当前的活跃连接数目,最少的连接数目说明这个backend负载最轻,将请求分配给他,这种方式会考虑到配置中给每个upstream分配的weight权重信息;

    c. Least Time(least_time): 请求会分配给响应最快和活跃连接数最少的backend;

    d. IP Hash(ip_hash): 对请求来源IP地址计算hash值,IPv4会考虑前3个octet,IPv6会考虑所有的地址位,然后根据得到的hash值通过某种映射分配到backend;

    e. Generic Hash(hash): 以用户自定义资源(比如URL)的方式计算hash值完成分配,其可选consistent关键字支持一致性hash特性;

    (2) 会话一致性

    用户(浏览器)在和服务端交互的时候,通常会在本地保存一些信息,而整个过程叫做一个会话(Session)并用唯一的Session ID进行标识。会话的概念不仅用于购物车这种常见情况,因为HTTP协议是无状态的,所以任何需要逻辑上下文的情形都必须使用会话机制,此外HTTP客户端也会额外缓存一些数据在本地,这样就可以减少请求提高性能了。如果负载均衡可能将这个会话的请求分配到不同的后台服务端上,这肯定是不合适的,必须通过多个backend共享这些数据,效率肯定会很低下,最简单的情况是保证会话一致性——相同的会话每次请求都会被分配到同一个backend上去。

    (3) 后台服务端的动态配置

    出问题的backend要能被及时探测并剔除出分配群,而当业务增长的时候可以灵活的添加backend数目。此外当前风靡的Elastic Compute云计算服务,服务商也应当根据当前负载自动添加和减少backend主机。

    (4) 基于DNS的负载均衡

    通常现代的网络服务者一个域名会关连到多个主机,在进行DNS查询的时候,默认情况下DNS服务器会以round-robin形式以不同的顺序返回IP地址列表,因此天然将客户请求分配到不同的主机上去。不过这种方式含有固有的缺陷:DNS不会检查主机和IP地址的可访问性,所以分配给客户端的IP不确保是可用的(Google 404);DNS的解析结果会在客户端、多个中间DNS服务器不断的缓存,所以backend的分配不会那么的理想。

    二、Nginx中的负载均衡
    Nginx中的负载均衡配置在 手册 中描述的极为细致,此处就不流水帐了。对于常用的HTTP负载均衡,主要先定义一个upstream作为backend group,然后通过proxy_pass/fastcgi_pass等方式进行转发操作,其中fastcgi_pass几乎算是Nginx+PHP站点的标配了。

    2.1 会话一致性
    Nginx中的会话一致性是通过sticky开启的,会话一致性和之前的负载均衡算法之间并不冲突,只是需要在第一次分配之后,该会话的所有请求都分配到那个相同的backend上面。目前支持三种模式的会话一致性:

    (1). Cookie Insertion

    在backend第一次response之后,会在其头部添加一个session cookie,之后客户端接下来的请求都会带有这个cookie值,Nginx可以根据这个cookie判断需要转发给哪个backend了。

    sticky cookie srv_id expires=1h domain=.example.com path=/;
    上面的srv_id代表了cookie的名字,而后面的参数expires、domain、path都是可选的。

    (2). Sticky Routes

    也是在backend第一次response之后,会产生一个route信息,route信息通常会从cookie/URI信息中提取。

    sticky route $route_cookie r o u t e u r i ; 这 样 N g i n x 会 按 照 顺 序 搜 索 route_uri; 这样Nginx会按照顺序搜索 routeuri;Nginxroute_cookie、$route_uri参数并选择第一个非空的参数用作route,而如果所有的参数都是空的,就使用上面默认的负载均衡算法决定请求分发给哪个backend。

    (3). Learn

    较为的复杂也较为的智能,Nginx会自动监测request和response中的session信息,而且通常需要回话一致性的请求、应答中都会带有session信息,这和第一种方式相比是不用增加cookie,而是动态学习已有的session。

    这种方式需要使用到zone结构,在Nginx中zone都是共享内存,可以在多个worker process中共享数据用的。(不过其他的会话一致性怎么没用到共享内存区域呢?)

    sticky learn
    create= u p s t r e a m c o o k i e e x a m p l e c o o k i e l o o k u p = upstream_cookie_examplecookie lookup= upstreamcookieexamplecookielookup=cookie_examplecookie
    zone=client_sessions:1m
    timeout=1h;
    2.2 Session Draining
    主要是有需要关闭某些backend以便维护或者升级,这些关键性的服务都讲求gracefully处理的:就是新的请求不会发送到这个backend上面,而之前分配到这个backend的会话的后续请求还会继续发送给他,直到这个会话最终完成。

    让某个backend进入draining的状态,既可以直接修改配置文件,然后按照之前的方式通过向master process发送信号重新加载配置,也可以采用Nginx的on-the-fly配置方式。

    $ curl http://localhost/upstream_conf?upstream=backend
    $ curl http://localhost/upstream_conf?upstream=backend&id=1&drain=1
    通过上面的方式,先列出各个bacnkend的ID号,然后drain指定ID的backend。通过在线观测backend的所有session都完成后,该backend就可以下线了。

    2.3 backend健康监测
    backend出错会涉及到两个参数,max_fails=1 fail_timeout=10s;意味着只要Nginx向backend发送一个请求失败或者没有收到一个响应,就认为该backend在接下来的10s是不可用的状态。

    通过周期性地向backend发送特殊的请求,并期盼收到特殊的响应,可以用以确认backend是健康可用的状态。通过health_check可以做出这个配置。

    match server_ok {
    status 200-399;
    header Content-Type = text/html;
    body !~ “maintenance mode”;
    }
    server {
    location / {
    proxy_pass http://backend;
    health_check interval=10 fails=3 passes=2 match=server_ok;
    }
    }
    上面的health_check是必须的,后面的参数都是可选的。尤其是后面的match参数,可以自定义服务器健康的条件,包括返回状态码、头部信息、返回body等,这些条件是&&与关系。默认情况下Nginx会相隔interval的间隔向backend group发送一个”/“的请求,如果超时或者返回非2xx/3xx的响应码,则认为对应的backend是unhealthy的,那么Nginx会停止向其发送request直到下次改backend再次通过检查。

    在使用了health)check功能的时候,一般都需要在backend group开辟一个zone,在共享backend group配置的同时,所有backend的状态就可以在所有的worker process所共享了,否则每个worker process独立保存自己的状态检查计数和结果,两种情况会有很大的差异哦。

    2.4 通过DNS设置HTTP负载均衡
    Nginx的backend group中的主机可以配置成域名的形式,如果在域名的后面添加resolve参数,那么Nginx会周期性的解析这个域名,当域名解析的结果发生变化的时候会自动生效而不用重启。

    http {
    resolver 10.0.0.1 valid=300s ipv6=off;
    resolver_timeout 10s;

    server {
        location / {
            proxy_pass http://backend;
        }
    }
    
    upstream backend {
        zone backend 32k;
        least_conn;
        ...
        server backend1.example.com resolve;
        server backend2.example.com resolve;
    }
    

    }
    如果域名解析的结果含有多个IP地址,这些IP地址都会保存到配置文件中去,并且这些IP都参与到自动负载均衡。

    2.5 TCP/UDP流量的负载均衡
    除了专长的HTTP负载均衡,Nginx还支持TCP和UDP流量的负载均衡,适用于LDAP/MySQL/RTMP和DNS/syslog/RADIUS各种应用场景。这类情况的负载均衡使用stream来配置,Nginx编译的时候需要支持–with-stream选项。查看 手册 ,其配置原理和参数和HTTP负载均衡差不多。

    因为TCP、UDP的负载均衡都是针对通用程序的,所以之前HTTP协议支持的match条件(status、header、body)是没法使用的。TCP和UDP的程序可以根据特定的程序,采用send、expect的方式来进行动态健康检测。

    match http {
    send “GET / HTTP/1.0\r\nHost: localhost\r\n\r\n”;
    expect ~* “200 OK”;
    }
    2.6 其他特性
    slow_start=30s:防止新添加/恢复的主机被突然增加的请求所压垮,通过这个参数可以让该主机的weight从0开始慢慢增加到设定值,让其负载有一个缓慢增加的过程。

    max_conns=30:可以设置backend的最大连接数目,当超过这个数目的时候会被放到queue队列中,同时队列的大小和超时参数也可以设置,当队列中的请求数大于设定值,或者超过了timeout但是backend还不能处理请求,则客户端将会收到一个错误返回。通常来说这还是一个比较重要的参数,因为Nginx作为反向代理的时候,通常就是用于抗住并发量的,如果给backend过多的并发请求,很可能会占用后端过多的资源(比如线程、进程非事件驱动),最终反而会影响backend的处理能力。

    以上如有不足 请下方留言!

    展开全文
  • Nginx负载均衡原理

    千次阅读 2020-03-13 16:27:32
    负载均衡

    Nginx简介

    Nginx是通过反向代理实现的负载均衡。

    什么是正向代理与反向代理?

    正向代理就是,客户端通过一台代理服务器访问服务端。
    反向代理就是,服务端通过代理服务器为客户端提供服务。

    看起来似乎没有什么区别,举个例子。
    正向代理:当我们访问google.com,是无法直接访问的,因为被墙,因而我们需要先访问一台代理服务器(VPN),告诉它我们要访问google.com,代理服务器会访问google.com,并将访问的结果返回给我们。
    反向代理:服务器想要提供服务给客户,但是没法直接面对客户,就需要一台代理服务器。让客户直接访问代理服务器,代理服务器将请求发给自己,然后自己处理请求,返回结果给代理服务器,再返回给客户。

    看似两者是一样的,但是一个是客户的需求,一个是服务端的需求。使用代理服务器的主体不同。

    Nginx内核与模块划分

    内核

    其设计非常微小和简洁,完成的工作也非常简单。仅通过查找配置文件将客户端请求映射到一个location block(location是nginx配置中的一个指令,用例URL匹配),而在这个location中所配置的每个指令将会启动不同的模块取完成相应的工作。

    从结构上划分:

    1. 核心模块:HTTP模块、EVENT模块和MAIL模块。
    2. 基础模块:HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块。
    3. 第三方模块:HTTP Upstream Request Hash模块、Notice模块和HTTP Access Key模块。

    从功能上划分

    1. Core(核心模块):构建nginx基础服务、管理其他模块。
    2. Handlers(处理器模块):此类模块直接处理请求,并进行输出内容和修改headers信息等操作。Handlers处理器模块一般只能有一个。
    3. Filters (过滤器模块):此类模块主要对其他处理器模块输出的内容进行修改操作,最后由Nginx输出。
    4. Proxies (代理类模块):此类模块是Nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如FastCGI等进行交互,实现服务代理和负载均衡等功能。

    Nginx模块处理流程

    模块处理流程大致如下:

    1. 收到HTTP请求。
    2. Nginx基于配置文件中的位置选择一个合适的处理模块(Handlers)。
    3. Handlers模块需要把请求反向代理到后端服务器,就需要就变成另外一类的模块:load-balancers(负载均衡模块)。
    4. 负载均衡模块的配置中有一组后端服务器,当一个HTTP请求过来时,它决定哪台服务器应当获得这个请求。
    5. 处理完成后,filters(过滤模块)将被调用。每个请求都可以被压缩成块,依次经过多个filters(过滤模块)过。它们的执行顺序在编译时决定。过滤模块链以流水线的方式高效率地向客户端发送响应信息。每个filters(过滤模块)不会等上一个filters(过滤模块)全部完成,就像是流水线一样。
    6. 最后把响应发给客户端。

    如下图,展示了Nginx模块常规的HTTP请求和响应过程:
    在这里插入图片描述
    Nginx本身做的工作实际很少,当它接到一个HTTP请求时,它仅仅是通过查找配置文件将此次请求映射到一个location block,而此location中所配置的各个指令则会启动不同的模块去完成工作,因此模块可以看做Nginx真正的劳动工作者。

    通常一个location中的指令会涉及一个handler模块和多个filter模块(当然,多个location可以复用同一个模块)。handler模块负责处理请求,完成响应内容的生成,而filter模块对响应内容进行处理。

    Nginx负载均衡的几种算法

    目前nginx提供3种自带的负载均衡,还有2种常用的第三方策略。

    1. 安装轮询(默认):每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。虽然这种方式简便、成本低,但缺点是:可靠性低和负载分配不均衡。
    2. 权重:指定轮询几率,weight和访问比例成正比,用于后端服务器性能不均的情况。如下图,8080和8081分别占90%和10%。
      在这里插入图片描述
    3. ip_hash:上面2种方式都有一个问题,就是下一个请求来的时候,请求可能分发到另外一个服务器,当我们的程序不是无状态的时候(采用session保存数据),这个时候,就有一个很大的问题,比如把登录信息保存到了session中,那么跳转到另外一个服务器的时候就需要重新登录了,所以很多时候,我们只需要一个客户只访问一个服务器,那么就需要用到iphash。iphash的每个请求按访问ip的hash结果分配,这个每个访客访问一个后端服务器,可以解决session问题。
      在这里插入图片描述
    4. fair(第三方):按后端服务器的响应时间来分配请求,响应时间短的优先分配。
    5. url_hash(第三方):按访问URL的hash结果进行分配请求,使每个URL定向到同一个后端服务器,后端服务器为缓存时比较有效。在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用hash算法。

    Nginx处理请求

    Nginx在启动时会以daemon形式在后台运行,采用多进程+异步非阻塞IO事件模型来处理各种连接请求。

    多进程模型

    多进程模型包括一个master进程,多个worker进程,一般worker进程个数是根据服务器CPU核数来决定的。master进程负责管理Nginx本身和其他worker进程。

    在这里插入图片描述
    从上图中可以很明显地看到,4个worker进程的父进程都是master进程,表明worker进程都是从父进程fork出来的,并且父进程的ppid为1,表示其为daemon进程。

    Master进程的作用是?

    读取并验证配置文件nginx.conf;管理worker进程,包括:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。

    Worker进程的作用是?

    处理基本的网络事件,在nginx多进程中,每个worker都是平等的,因此每个进程处理外部请求的机会权重都是一致的。

    每一个Worker进程都维护一个线程(避免线程切换),处理连接和请求;注意Worker进程的个数由配置文件决定,一般和CPU个数相关(有利于进程切换),配置几个就有几个Worker进程。

    一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。

    多进程模型的优点

    1. 对于每个worker进程来说,独立的进程,不需要加锁,所以省掉了锁带来的开销。
    2. 采用独立的进程,可以让worker互相之间不会影响,一个worker退出后,其它worker还在工作,服务不会中断,master进程则很快启动新的worker进程。

    异步非阻塞IO事件模型

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

    Nginx采用了Linux的epoll模型,epoll模型基于事件驱动机制,它可以监控多个事件是否准备完毕,如果OK,那么放入epoll队列中,这个过程是异步的。worker只需要从epoll队列循环处理即可。

    和Java的NIO类似。

    Nginx如何做到热部署

    所谓热部署,就是配置文件nginx.conf修改后,不需要stop Nginx,不需要中断请求,就能让配置文件生效!(nginx -s reload 重新加载/nginx -t检查配置/nginx -s stop)

    通过上文我们已经知道worker进程负责处理具体的请求,那么如果想达到热部署的效果,有两种方法:

    1. 方案一,修改配置文件nginx.conf后,主进程master负责推送给woker进程更新配置信息,woker进程收到信息后,更新进程内部的线程信息。
    2. 方案二,修改配置文件nginx.conf后,重新生成新的worker进程,当然会以新的配置进行处理请求,而且新的请求必须都交给新的worker进程,至于老的worker进程,等把那些以前的请求处理完毕后,kill掉即可。

    Nginx采用的就是方案二来达到热部署的!

    Nginx挂了怎么办?

    Nginx既然作为入口网关,很重要,如果出现单点问题,显然是不可接受的。

    答案是:Keepalived+Nginx实现高可用。

    Keepalived是一个高可用解决方案,主要是用来防止服务器单点发生故障,可以通过和Nginx配合来实现Web服务的高可用。(其实,Keepalived不仅仅可以和Nginx配合,还可以和很多其他服务配合)

    Keepalived+Nginx实现高可用的思路:

    1. 请求不要直接打到Nginx上,应该先通过Keepalived(这就是所谓虚拟IP,VIP)。
    2. Keepalived应该能监控Nginx的生命状态,提供一个用户自定义的脚本,定期检查Nginx进程状态,进行权重变化,,从而实现Nginx故障切换。

    在这里插入图片描述

    链接:https://www.jianshu.com/p/6215e5d24553
    https://www.cnblogs.com/fancy-yeah/p/9120240.html

    展开全文
  • Nginx负载均衡原理实验原理和实验环境二级目录三级目录 原理和实验环境 实验环境: 负载均衡器:150.17.239.40 web服务器01:150.17.232.10 web服务器02:150.17.239.40 实验环境如下图所示,当客户端发送请求时...

    原理和实验环境

    • 实验环境:
      负载均衡器:150.17.239.40
      web服务器01:150.17.232.10
      web服务器02:150.17.239.40

    • 实验环境如下图所示,当客户端发送请求时,访问地址150.17.239.40:8080,负载均衡器将会把请求转发到均衡池,池中的web服务器通过特定的轮询策略,发送内容到均衡器,再响应给用户。
      在这里插入图片描述

    实验环境配置

    均衡池内web服务器部署

    负载均衡池内的Web服务器安装好Nginx,并独立测试是否能打开网页

    • 理论上均衡器为独立服务器负责转发,但实验环境关系均衡器和均衡池中其中一台服务器为同一台服务器。

    在这里插入图片描述

    • 均衡池内另外一台web服务器
      在这里插入图片描述
      在这里插入图片描述

    负载均衡器设置

    在这里插入图片描述

    实验结果确认

    • 用户访问150.17.239.40:8080,均衡池默认策略会重复从池内两台web服务器相应内容给用户。
      在这里插入图片描述
      在这里插入图片描述
    展开全文
  • 看尚硅谷汪洋老师的视频做的笔记 具体的原理写好放在gitbook上了 LVS和Nginx负载均衡原理

    看尚硅谷汪洋老师的视频做的笔记

    具体的原理写好放在gitbook上了

    LVS和Nginx负载均衡原理

    展开全文
  • Nginx负载均衡原理简介与负载均衡配置详解 by:授客 QQ:1033553122 测试环境 nginx-1.10.0 负载均衡原理 客户端向反向代理发送请求,接着反向代理根据某种负载机制转发请求至目标服务器(这些服务器都...
  • nginx负载均衡原理 负载均衡在服务端开发中算是一个比较重要的特性。因为Nginx除了作为常规的Web服务器外,还会被大规模的用于反向代理前端,因为Nginx的异步框架可以处理很大的并发请求,把这些并发请求hold住之后...
  • Nginx 负载均衡原理与实践 本篇摘自《亿级流量网站架构核心技术》第二章 Nginx 负载均衡与反向代理 部分内容。 当我们的应用单实例不能支撑用户请求时,此时就需要扩容,从一台服务器扩容到两台、几十台、几百台。...
  • 前言 环境:centos 7.9 nginx-...nginx负载均衡两个重要组件 http_proxy_module模块:proxy代理模块,用于把请求后抛给服务器节点或upstream服务器池; http_upstream_module模块:负载均衡模块,可以实现网站的负载
  • 今天这篇文章介绍了负载均衡原理以及对应的四种负载均衡算法,当然还有对应的指令及实战,欢迎品尝。有不同意见的朋友可以评论区留言! 负载均衡 所谓负载均衡,就是 Nginx 把请求均匀的分摊给上游的应用服务器...
  • Nginx负载均衡与可用性检查 在业界,一直流传这样一句话:Nginx抗并发能力强!为什么Nginx抗并发能力强?原因是使用了非阻塞、异步传输 阻塞:如apache代理tomcat时,apache开启10个进程,同时处理着10个请求,在...
  • 浅谈Nginx负载均衡原理与实现

    万次阅读 多人点赞 2016-03-17 09:27:16
    1 负载均衡 先来简单了解一下什么是负载均衡,单从字面上的意思来理解就可以解释N台服务器平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置的情况。那么负载均衡的前提就是要有多台服务器才能实现,...
  • Nginx负载均衡与反向代理—《亿级流量网站架构核心技术》 原创:张开涛开涛的博客2017-03-24 本篇摘自《亿级流量网站架构核心技术》第二章 Nginx负载均衡与反向代理 部分内容。 当我们的应用单实例不能支撑用户...
  • nginx负载均衡 一 、负载均衡概述 二、负载均衡实现方式 硬件负载均衡 软件负载均衡 三、Nginx负载均衡 四、案例 一 、负载均衡概述 在网站创立初期,我们一般都使用单台机器对外提供集中式服务。随着业务量的增大,...
  • 一个执着于技术的公众号Nginx系列导读给小白的 Nginx 10分钟入门指南Nginx编译安装及常用命令完全卸载nginx的详细步骤Nginx 配置文件详解理解正向代理与反向代理的区别...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 42,493
精华内容 16,997
关键字:

nginx负载均衡原理