概述
Nginx是一个高性能的HTTP和反向代理服务器,及电子邮件(IMAP/POP3)代理服务器,同时也是一个非常高效的反向代理、负载平衡中间件。
正向代理是不知道客户端是谁,代理是一个跳板,所有客户端通过这个跳板来访问到对应的内容。
反向代理是不知道服务端是谁,用户的请求被转发到内部的某台服务器去处理。
基本工作流程
用户通过域名发出访问Web服务器的请求,该域名被DNS服务器解析为反向代理服务器的IP地址;
反向代理服务器接受用户的请求;
反向代理服务器在本地缓存中查找请求的内容,找到后直接把内容发送给用户;
如果本地缓存里没有用户所请求的信息内容,反向代理服务器会代替用户向源服务器请求同样的信息内容,并把信息内容发给用户,如果信息内容是缓存的还会把它保存到缓存中。
优点
保护了真实的web服务器,保证了web服务器的资源安全
节约了有限的IP地址资源
减少WEB服务器压力,提高响应速度(缓存功能)
请求的统一控制,包括设置权限、过滤规则等
实现负载均衡
区分动态和静态可缓存内容
模块划分
核心模块:HTTP模块、EVENT模块和MAIL模块
基础模块:HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块,
第三方模块:HTTP Upstream Request Hash模块、Notice模块和HTTP Access Key模块。
从功能上划分:
Core(核心模块):构建nginx基础服务、管理其他模块。
Handlers(处理器模块):此类模块直接处理请求,并进行输出内容和修改headers信息等操作。
Filters (过滤器模块):此类模块主要对其他处理器模块输出的内容进行修改操作,最后由Nginx输出。
Proxies (代理类模块):此类模块是Nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如FastCGI等进行交互,实现服务代理和负载均衡等功能。
负载均衡
1. 轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。此策略适合服务器配置相当,无状态且短平快的服务使用。
2. 指定权重
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
IP哈希法
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
session共享问题
在最简单的一主一备、负载均衡的集群下,比如两台tomcat服务器和一台nginx负载均衡服务器。当用户访问时,nginx分配给tomcat1服务器处理登陆业务,用户登陆成功,在tomcat1记录了其登陆信息,当页面刷新时,nginx将用户请求分配给tomcat2服务器,在tomcat2服务器上没有用户登陆session,这样就需要用户再次登陆,如果足够巧合,刚好再次登陆的请求转到tomcat1服务器,显示用户登陆,再次刷新刚好又分配给tomcat2服务器,又没有登陆,甚至形成既登陆又没有登陆的矛盾局面。这就造成了不好的体验。
一般的解决办法是,tomcat服务器之间开启session共享广播,当tomcat1服务器记录了session数据后,就广播给其他tomcat服务器。但是,tomcat的session共享的节点数是有上限的。当集群中配置的tomcat节点机到达一定数量后(一般是5个),节点内部通信的流量可能被session广播占满,导致无法顺畅的处理其他业务,特别是难以适应高并发的场景。
避免session广播形成节点上限的解决办法是,配置单点登录的session服务器,适应redis缓存模拟session保存登陆信息。
Nginx的Master-Worker模式
启动Nginx后,其实就是在80端口启动了Socket服务进行监听,如图所示,Nginx涉及Master进程和Worker进程。
Master:
读取并验证配置文件nginx.conf;管理worker进程;
接收来自外界的信号
向各worker进程发送信号
监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程
Worker
每一个Worker进程都维护一个线程(避免线程切换),处理连接和请求;注意Worker进程的个数由配置文件决定,一般和CPU个数相关(有利于进程切换),配置几个就有几个Worker进程。
热部署
热部署的原理就是修改nginx.conf后nginx -s reload,master会重新生成新的worker进程,以新的配置处理请求;而老的worker把中间的旧请求处理完毕后kill掉
如何实现高并发的高效处理
Nginx采用了Linux的epoll模型,epoll模型基于事件驱动机制,它可以监控多个事件是否准备完毕,如果OK,那么放入epoll队列中,这个过程是异步的。worker只需要从epoll队列循环处理即可。
Nginx挂了怎么办?(高可用方案)
KeepAlived(主服务器 和 备份服务器 故障时 IP 瞬间无缝交接)
VRRP协议(路由器组,提供虚拟IP,一个master和多个backup,组播消息,选举backup当master)
Nginx+keepalived 双机主主模式(俩公网虚拟IP,负载);双机主从模式(热备服务器)
Nginx既然作为入口网关,很重要,如果出现单点问题,显然是不可接受的。
答案是:Keepalived+Nginx实现高可用。
Keepalived是一个高可用解决方案,主要是用来防止服务器单点发生故障,可以通过和Nginx配合来实现Web服务的高可用。(其实,Keepalived不仅仅可以和Nginx配合,还可以和很多其他服务配合)
Keepalived+Nginx实现高可用的思路:
第一:请求不要直接打到Nginx上,应该先通过Keepalived(这就是所谓虚拟IP VIP)
第二:Keepalived应该能监控Nginx的生命状态(提供一个用户自定义的脚本,定期检查Nginx进程状态,进行权重变化,从而实现Nginx故障切换)
一、Nginx & KeepAlived
Nginx 进程基于Master+Slave(worker)多进程模型,自身具有非常稳定的子进程管理功能。在Master进程分配模式下,Master进程永远不进行业务处理,只是进行任务分发,从而达到Master进程的存活高可靠性,Slave(worker)进程所有的业务信号都 由主进程发出,Slave(worker)进程所有的超时任务都会被Master中止,属于非阻塞式任务模型。
KeepAlived是Linux下面实现VRRP备份路由的高可靠性运行件。基于KeepAlived设计的服务模式能够真正做到主服务器和备份服务器故障时IP瞬间无缝交接。二者结合,可以构架出比较稳定的软件LB(Load Balance)方案。
KeepAlived的作用是检测服务器的状态,如果有一台web服务器宕机,或工作出现故障,KeepAlived将检测到,并将有故障的服务器从系统中剔除,同时使用其他服务器代替该服务器的工作,当服务器工作正常后KeepAlived自动将服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的服务器。
KeepAlived是一个基于VRRP协议来实现的服务高可用方案,可以利用其来避免IP单点故障,类似的工具还有Heartbeat 、Corosync、Pacemaker。但是它一般不会单独出现,而是与其它负载均衡技术(如LVS、Haproxy、Nginx)一起工作来达到集群的高可用。
二、VRRP协议
VRRP全称 Virtual Router Redundancy Protocol,即”虚拟路由冗余协议“。可以认为它是实现路由器高可用的容错协议,即将N台提供相同功能的路由器组成一个路由器组(Router Group),这个组里面有一个master和多个backup,但在外界看来就像一台一样,构成虚拟路由器,拥有一个虚拟IP(VIP - Virtual IP,也就是路由器所在局域网内其他机器的默认路由),占有这个IP的master实际负责ARP相应和转发IP数据包,组中的其它路由器作为备份的角色处于待命状态。master会发组播消息,当backup在超时时间内收不到vrrp包时就认为master宕掉了,这时就需要根据VRRP的优先级来选举一个backup当master,保证路由器的高可用。
在VRRP协议实现里,虚拟路由器使用 00-00-5E-00-01-XX 作为虚拟MAC地址,XX就是唯一的 VRID (Virtual Router IDentifier),这个地址同一时间只有一个物理路由器占用。在虚拟路由器里面的物理路由器组里面通过多播IP地址 224.0.0.18 来定时发送通告消息。每个Router都有一个 1-255之间的优先级别,级别最高的(highest priority)将成为主控(master)路由器。通过降低master的优先权可以让处于backup状态的路由器抢占(pro-empt)主路由器的状态,两个backup优先级相同的IP地址较大者为master,接管虚拟IP。
三、双机高可用解决方案
(1)Nginx+keepalived 双机主从模式:
即前端使用两台服务器,一台主服务器和一台热备服务器,正常情况下,主服务器绑定一个公网虚拟IP,提供负载均衡服务,热备服务器处于空闲状态;当主服务器发生故障时,热备服务器接管主服务器的公网虚拟IP,提供负载均衡服务;但是热备服务器在主机器不出现故障的时候,永远处于浪费状态,对于服务器不多的网站,该方案不经济实惠。
(2)Nginx+keepalived 双机主主模式:
即前端使用两台负载均衡服务器,互为主备,且都处于活动状态,同时各自绑定一个公网虚拟IP,提供负载均衡服务;当其中一台发生故障时,另一台接管发生故障服务器的公网虚拟IP(这时由非故障机器一台负担所有的请求)
惊群现象
定义:惊群效应就是当一个fd的事件被触发时,所有等待这个fd的线程或进程都被唤醒。
Nginx的IO通常使用epoll,epoll函数使用了I/O复用模型。与I/O阻塞模型比较,I/O复用模型的优势在于可以同时等待多个(而不只是一个)套接字描述符就绪。Nginx的epoll工作流程如下:
master进程先建好需要listen的socket后,然后再fork出多个woker进程,这样每个work进程都可以去accept这个socket
当一个client连接到来时,所有accept的work进程都会受到通知,但只有一个进程可以accept成功,其它的则会accept失败,Nginx提供了一把共享锁accept_mutex来保证同一时刻只有一个work进程在accept连接,从而解决惊群问题
当一个worker进程accept这个连接后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,这样一个完成的请求就结束了