nginx 没有cookie_nginx实现负载均衡的原理及策略
负载均衡在服务端开发中算是一个比较重要的特性。因为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
上面的srv_id代表了cookie的名字,而后面的参数expires、domain、path都是可选的。
(2). Sticky Routes
也是在backend第一次response之后,会产生一个route信息,route信息通常会从cookie/URI信息中提取。
sticky route $route_cookie $route_uri;
这样Nginx会按照顺序搜索$route_cookie、$route_uri参数并选择第一个非空的参数用作route,而如果所有的参数都是空的,就使用上面默认的负载均衡算法决定请求分发给哪个backend。
(3). Learn
较为的复杂也较为的智能,Nginx会自动监测request和response中的session信息,而且通常需要回话一致性的请求、应答中都会带有session信息,这和第一种方式相比是不用增加cookie,而是动态学习已有的session。
这种方式需要使用到zone结构,在Nginx中zone都是共享内存,可以在多个worker process中共享数据用的。(不过其他的会话一致性怎么没用到共享内存区域呢?)
sticky learncreate=$upstream_cookie_examplecookielookup=$cookie_examplecookiezone=client_sessions:1mtimeout=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.0rnHost: localhostrnrn";expect ~* "200 OK";
}
2.6 其他特性
slow_start=30s:防止新添加/恢复的主机被突然增加的请求所压垮,通过这个参数可以让该主机的weight从0开始慢慢增加到设定值,让其负载有一个缓慢增加的过程。
max_conns=30:可以设置backend的最大连接数目,当超过这个数目的时候会被放到queue队列中,同时队列的大小和超时参数也可以设置,当队列中的请求数大于设定值,或者超过了timeout但是backend还不能处理请求,则客户端将会收到一个错误返回。通常来说这还是一个比较重要的参数,因为Nginx作为反向代理的时候,通常就是用于抗住并发量的,如果给backend过多的并发请求,很可能会占用后端过多的资源(比如线程、进程非事件驱动),最终反而会影响backend的处理能力。
三、nginx负责均衡的策略
1、轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
upstream backserver {
server 192.168.0.14;
server 192.168.0.15;
}
2、指定权重
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
upstream backserver {
server 192.168.0.14 weight=10;
server 192.168.0.15 weight=10;
}
3、IP绑定 ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
upstream backserver {
ip_hash;
server 192.168.0.14:88;
server 192.168.0.15:80;
}
4、fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
upstream backserver {
server server1;
server server2;
fair;
}
5、url_hash(第三方)
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
upstream
四、在需要使用负载均衡的server中增加
proxy_pass
server 127.0.0.1:9090 down; (down 表示单前的server暂时不参与负载)
server 127.0.0.1:8080 weight=2; (weight 默认为1.weight越大,负载的权重就越大)
server 127.0.0.1:6060;
server 127.0.0.1:7070 backup; (其它所有的非backup机器down或者忙的时候,请求backup机器)
}
max_fails :允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误
fail_timeout:max_fails次失败后,暂停的时间
对标阿里P6+的Java架构师
获取更多学习资料,可以加群:473984645或扫描下方二维码
nginx 没有cookie_nginx实现负载均衡的原理及策略相关推荐
- Nginx学习之十三-负载均衡-IP哈希策略剖析
前面介绍过nginx负载均衡的加权轮询策略(http://blog.csdn.net/xiajun07061225/article/details/9318871),它是Nginx负载均衡的基础策略, ...
- Nginx、Haproxy、LVS负载均衡从原理到部署(一)
先说些题外话,我记得51博客的号早就注册了,之前只是不间断上来看看别人写的技术文章涨涨见识,自己后面开始接触到运维这块,就想到把平时学的一些相关技术记录到博客上来,只是方便自己可以随时上网回顾,由于多 ...
- Nginx从入门到入坟(十三)- 负载均衡的原理及优化
目录 1. 负载均衡概述 2. 负载均衡的原理及处理流程 2.1 负载均衡的作用 2.2 负载均衡常用的处理方式 2.2.1 用户手动选择 2.2.2 DNS轮询方式 2.2.3 四/七层负载均衡 3 ...
- Nginx负载均衡的原理
1.Nginx负载均衡的原理是什么? 客户端向反向代理发送请求,接着反向代理根据某种负载机制转发请求至目标服务器(这些服务器都运行着相同的应用),并把获得的内容返回给客户端,期中,代理请求可能根据 ...
- Nginx负载均衡的原理及流程分析
负载均衡的原理及处理流程 系统的扩展可以分为纵向扩展和横向扩展. 纵向扩展是从单机的角度出发,通过增加系统的硬件处理能力来提升服务器的处理能力 横向扩展是通过添加机器来满足大型网站服务的处理能力. 这 ...
- Nginx反向代理以及负载均衡配置
一 .nginx 的优缺点: nginx 相对 apache 的优点: 轻量级,同样起web 服务,比apache 占用更少的内存及资源 抗并发,nginx 处理请求是异步非阻塞的,而apache 则 ...
- nginx实现请求的负载均衡 + keepalived实现nginx的高可用
前言 使用集群是网站解决高并发.海量数据问题的常用手段.当一台服务器的处理能力.存储空间不足时,不要企图去换更强大的服务器,对大型网站而言,不管多么强大的服务器,都满足不了网站持续增长的业务需求.这种 ...
- 阿里云MVP乔帮主:五大类型负载均衡的原理场景详解(文末赠书)
乔帮主 读完需要 21 分钟 速读仅需 5 分钟 导读:本文摘自于阿里云 MVP."乔帮主"乔锐杰所撰写的<阿里云运维架构实践秘籍>一书,我们发现常见负载均衡 LVS. ...
- Nginx反向代理与负载均衡等配置文件示例
Nginx反向代理于负载均衡等配置文件示例 Nginx.conf配置文件 worker_processes 8;events {worker_connections 1024; }http {incl ...
- 负载均衡的原理和架构
目录 1 为什么需要负载均衡? 2 负载均衡原理 3 常见负载均衡算法 4 常见负载均衡架构 4.1 DNS域名解析负载均衡 4.2 LVS负载均衡机制:NAT模式 4.3 LVS负载均衡机制:DR模 ...
最新文章
- android开发系列之多线程
- docker容器的构建
- 类variant解剖
- Google AdSense中文官方博客今天公布了AdSense内容广告与AdSense搜索广告的收入分成比例...
- linux apache目录权限配置,Linux系统架构-----Apache的用户访问权限的设置
- 强化学习中的各类算法
- Linux分区的那些方案
- Apple三里屯景泰蓝壁纸(mac版)
- android APK瘦身全面总结——如何从32.6M到13.6M
- 农村没网络怎样安监控,家里没有wifi安哪种监控器
- python基本输入输出函数有_python基本输入输出函数与变量类型
- 传统音乐制作与计算机音乐制作,电脑音乐制作与传统音乐制作的方式差异分析...
- 亚马逊、速卖通、wish、Lazada、shoppe、ebay、煤炉测评跟淘宝shua单区别在哪?
- 用脚本管控小朋友的上网行为可好?
- 什么是1024,为什么是1024?
- java 气泡聊天消息_Html,CSS 实现类似QQ的气泡聊天
- 桌面上文件出现蓝底白色问号
- 通过bt下载旧版debian镜像
- alfresco源代码的编译
- 进入瓶颈期的格力,多元化能助其解围吗?
热门文章
- a:active在ios上无效解决方法
- 2017.6.4 入门组 NO.4——猜数
- android的scrollview视图内部的子视图中android:layout_height=fill_parent无效的解决办法...
- 免安装版的Mysql
- python使用逐行读取,出现空行,清楚空行方法
- linux USR1亦通常被用来告知应用程序重载配置文件
- 3-unit4 postfix+mysql
- 自动化测试基础篇--Selenium等待时间
- 【转】android 常用theme
- Windows server 2008计划任务(批处理命令)不执行