Nginx负载均衡器

Nginx简介

Nginx是一款轻量级的web服务器/反向代理服务器及电子邮件代理服务器,由俄罗斯的程序设计师lgor Sysoev所开发,最初供俄国大型的入口网站及搜寻引擎Rambler使用。其特点是占内存少,并发能力强,事实上Nginx的并发能力网页服务器中的表现确实教好。
基于反向代理的功能,Nginx作为负载均衡主要有以下几点理由:
1、高并发连接
2、内存消耗少
3、配置文件简单
4、成本低廉
5、支持Rewrete重写规则
6、内置的健康检查功能
7、节省宽带
8、稳定性高

正向代理:
正向代理类似一个跳板机,代理访问外部资源,比如客户端发出请求要访问外部的互联网,那么在到达互联网之前,会通一个代理服务器来进行网络加速,流量压缩操作,把访问转发到外部的网络上。

反向代理:
代理服务器来接受客户端的请求,然后通过一些规则,将请求分发到服务器集群中,这些服务器属于内部网络服务器,并不对外,入口就是代理服务器,因此起到了负载均衡的作用。

反向代理的作用:
1、保证内网的安全,可以使用反向代理提供WAF功能,阻止web攻击。大型网站,通常将反向代理作为公网访问地址,web服务器是内网。
2、负载均衡,通过反向代理服务器来优化网站的负载。

负载均衡

负载均衡原理
负载均衡,单从字面上的意思来理解就可以解释N台服务器平均分担负载,不会因为某台服务器负载高宕机和某台服务器闲置的情况。那么负载均衡的前提就是要2台以上服务器才能实现。
负载均衡有4中方案配置:
1、轮询
轮询就是Round Robin,根据Nginx配置文件中的顺序,依次把客户端的web请求分发到不同的后端服务器上。
配置:
a.缺省配置九四轮询策略。
b.nginx负载均衡支持http和https协议,只需要修改proxy_pass后协议即可。
c.nginx支持FastCGI,uwsgi,SCGI,memcached的负载均衡,只需将proxy_pass改为fastcgi_pass,uwsgi_pass,scgi_pass,memcached_pass即可。
d.此策略适合服务器配置相当,无状态且短平快的服务使用。
Nginx负载均衡器
2、最少连接least_conn
web请求会被转发到连接数最少的服务器上。
配置:
a.最少连接负载均衡通过least_conn指令定义
b.此负载均衡策略适合请求处理时间长短不一造成服务器过载的情况
Nginx负载均衡器
3、IP地址哈希ip_hash
前述的两种负载均衡方案中,同一个客户端连续的web请求可能会被分发到不同的后端服务器进行处理,因此如果涉及到会话Session,那么会话会比较复杂。常见的是基于数据库的会话持久化。要克服上面的难题,可以使用基于IP地址哈希的负载均衡方案。这样的话,同一客户端连续的web请求都会被分发到同一个服务器进行处理。
配置:
a.ip哈希负载均衡使用ip_hash指令定义
b.nginx使用请求客户端的ip地址进行哈希计算,确保使用同一个服务器响应请求
c.此策略适合有状态服务,比如session
Nginx负载均衡器

4、权重weight
基于权重的负载均衡Weighted Load Balancing,这种方式下,我们可以配置Nginx把请求更多地分发到高配置的后后端服务器上,把相对较少的请求分发到低配服务器。
配置:
a.权重负载均衡需要使用weight指令定义
b.权重越高分配到需要处理的请求越多
c.此策略可以与最少连接负载和ip哈希策略结合使用
d.此策略比较适合服务器的硬件配置差别比较大的情况
Nginx负载均衡器

Nginx缓存介绍

nginx的http_proxy模块,可以实现类似于Squid的缓存功能。
Nginx对客户已经访问过的内容在Nginx服务器本地建立副本,这样在一段时间内再次访问该数据,就不需要通过Nginx服务器再次向后端服务器发出请求,所以能够减少Nginx服务器与后端服务器之间的网络流量,减轻网络拥塞,同时还能减小数据传输延迟,提高用户访问速度。
当后端服务器宕机时,Nginx服务器上的副本资源还能够回应相关的用户请求,这样能够提高后端服务器的鲁棒性(健壮性)。
对于缓存,我们需要知道的问题:
1、缓存放在哪?
proxy_cache_path:Nginx使用该参数指定缓存位置。
proxy_cache:该参数为之前指定的缓存名称。
proxy_cache_path:有两个必填参数,第一个为缓存目录,第二个参数keys_zone指定缓存名称和占用内存空间的大小。
Nginx负载均衡器
示例中的10m是对内存中缓存内容元数据信息大小的限制,如果想限制缓存总量大小,需要用max_size参数。

2、如何指定哪些请求被缓存?
a.Nginx默认会缓存所有get和head方法的请求结果,缓存的key默认使用请求字符串。
b.自定义key
例如proxy_cache_key “$ host $ request_uri$cookie_user”;
c.指定请求至少被发送了多少次以上时才缓存,可以防止低频请求被缓存。例如proxy_cache_min_uses 5;
d.指定哪些方法的请求被缓存
例如proxy_cache_methods GET HEAD POST;
Nginx负载均衡器

3、缓存的有效期是多久?
默认情况下,缓存内容时长期存留的,除非缓存的总量超出限制。可以指定缓存有效时间,例如:
a.相应状态码为200 302时,10分钟有效proxy_cache_valid 200 302 10m
b.对应任何状态码,5分钟有效proxy_cache_valid any 5m
Nginx负载均衡器
4、对于某些请求,是否可以不走缓存?
proxy_cache_bypass:该指令响应来自原始服务器而不是缓存。
a.例如proxy_cache_bypass $ cookie_nocache $ arg_nocache $ arg_comment
b.如果任何一个参数值不为空,或者不等于0,nginx就不会查找缓存,直接进行代理转发。
Nginx负载均衡器
解决这些问题后,nginx的缓存也就基本配置完成了。

网页的缓存是由HTTP消息头中 “Cache-control” 来控制的,常见的取值有private、no-cache、max_age、must_revalidate等,默认为private。其作用根据不同的重新浏览方式分为以下几种情况。
Nginx负载均衡器

通过Lua拓展Nginx

ngx_lua模块
Nginx模块需要用c开发,而且必须符合一系列复杂的规则,最重要的用c开发模块必须要熟悉Nginx的源代码,使得开发者对其望而生畏。
ngx_lua模块通过将lua解释器集成进Nginx,可以采用lua脚本实现业务逻辑。
该模块具备以下特性:
1、高并发、非阻塞的处理各种请求
2、Lua内建协程,这样就可以很好的将异步回调换成顺序调用的形式。
3、每个协程都有一个独立的全局环境(变量空间),继承于全局共享的、只读的"comman data"

得益于Lua协程的支持,ngx_lua在处理10000个并发请求时只需要很少的内存。根据测试,ngx_lua处理每个请求只需要2KB的内存,如果使用LuaJIT则会更少。

协程(Coroutine):
1、协程并非os线程,所以创建、切换开销比线程相对要小。
2、协程与线程一样有自己的栈、局部变量等,但是协程的栈时在用户进程空间模拟的,所以创建、切换开销很小。
3、多线程程序是多个线程并发执行,也就是说在一瞬间有多个控制流在执行。而协程强调的是一种多个协调间协作的关系,只有当一个协程主动放弃执行权,另一个协程才能获得执行权,所以在某一瞬间,多个协程间只能有一个在运行。
4、由于多个协程时只有一个在运行,所以对临界区的访问不需要枷锁,而多线程的情况必须加锁。
5、多线程程序由于有多个控制流,所以程序的行为不可控,而多个协程的执行是由开发者定义的所以是可控的。

Nginx进程模型
Nginx采用多进程模型,单Master—多Worker,Master进程主要用来管理Worker进程,Worker进程采用单线程、非阻塞的事件模型(Event Loop,事件循环)来实现端口的监听及客户端请求的处理和响应,同时Worker还要处理来自Mater的信号。Worker进程个数一般设置为机器CPU核数。

Master进程具体包括如下4个主要功能:
(1)接收来自外界的信号
(2)向各worker进程发送信号
(3)监控worker进程的运行状态
(4)当worker进程退出后(异常情况下),会自动重新启动新的worker进程。
Nginx负载均衡器
nginx有11个生命周期,我们可以根据nginx不同的生命周期去扩展。
第一阶段:
post-read:读取请求内容阶段,nginx读取并解析完请求头之后立即开始运行。

第二阶段:
server-rewrite:server请求地址重写阶段

第三阶段:
find-config:配置查找阶段,用来完成当前请求与location配重块之间的配对工作

第四阶段:
rewrite:location请求地址重写阶段,当ngx_rewrite指令用于location中,就是在这个阶段运行的。

第五阶段:
post-rewrite:请求地址重写提交阶段,当nginx完成rewrite阶段所要求的内部跳转动作,如果rewrite阶段有这个要求的话。

第六阶段:
preaccess:访问权限检查准备阶段,ngx_limit_req和ngx_limit_zone在这个阶段运行,ngx_limit_req可以控制请求的访问频率,ngx_limit_zone可以控制访问的并发度。

第七阶段:
access:权限检查阶段,ngx_access在这个阶段运行,配置指令多是执行访问控制相关的任务,如检查用户的访问权限,检查用户的来源ip是否合法。

第八阶段;
post-access:访问权限检查提交阶段

第九阶段:
try-access:配置项try-files处理阶段

第十阶段:
content:内容产生阶段,是所有请求处理阶段中最为重要的阶段,因为这个阶段的指令通常是用来生成HTTP响应内容的

第十一阶段:
log:日志模块处理阶段

Openresty
概念:OpenResty是一个基于Nginx与Lua的高性能web平台,其内部继承了大量精良的Lua库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理高并发、扩展性极高地动态web应用、web服务和动态网关。

工作原理:OpenResty通过汇聚各种设计精良地Nginx模块(主要由OpenResty团队自主开发),从而将Nginx有效地变成一个强大地通过web应用平台。这样web开发人员和系统工程师可以使用Lua脚本语言调动Nginx支持的各种C以及Lua模块,快速构造出足以胜任10k乃至1000k以上单机并发连接的高性能web应用系统。

目标:OpenResty的目标是让你的web服务直接跑在Nginx服务内部,充分利用Nginx的非阻塞I/O模型,不仅仅对HTTP客户端请求,甚至于对远程后端诸如MySql、PostgreSQL、Memchched以及redis等都进行一致的高性能响应。