共计 2975 个字符,预计需要花费 8 分钟才能阅读完成。
nginx 是什么?
nginx 是一个强大的 web 服务器软件,用于处理高并发的 http 请求和作为反向代理服务器做负载均衡。具有高性能、轻量级、内存消耗少,强大的负载均衡能力等优势。
nginx 架构?
如上官方示意图所示,nginx 启动以后,会在系统中以 daemon 的方式在后台运行,其中包括一个 master 进程,n(n>=1)个 worker 进程。
其中,master 进程用于接收来自外界的信号,并给 worker 进程发送信号,同时监控 worker 进程的工作状态。
worker 进程则是外部请求真正的处理者,每个 worker 请求相互独立且平等的竞争来自客户端的请求。请求只能在一个 worker 进程中被处理,且一个 worker 进程只有一个主线程,所以同时只能处理一个请求。那么问题来了,一个 worker 进程只有一个主线程,只能同时处理一个请求,nginx 对高并发请求强大的处理能力是如何保证的呢?答案是 nginx 采用异步非阻塞的方式来处理请求,即单线程、非阻塞、异步 IO 的工作模型。对比 apache 的异步非阻塞版本的工作模式,apache 会为每一个请求新建一个线程去处理请求,线程进行上下文切换,会造成内存和 CPU 的浪费。反看 nginx 的异步非阻塞 io 模式,实用操作系统提供的 io 多路复用技术(epoll),在一个线程中处理所有请求,当一个 io 操作开始的时候,nginx 不会等待其完成就回去处理下一个请求,等到 io 操作完成后,nginx 再回来处理这一次请求 io 操作的后续工作。相比 apache,nginx 省去了线程上下文切换带来的资源开销。
那么 nginx 如何确定哪个 worker 来处理请求呢?首先,每个 worker 进程都是从 master 进程 fork 过来,在 master 进程里面,先建立好需要 listen 的 socket(listenfd)之后,然后再 fork 出多个 worker 进程。所有 worker 进程的 listenfd 会在新连接到来时变得可读,为保证只有一个进程处理该连接,所有 worker 进程在注册 listenfd 读事件前抢 accept_mutex,抢到互斥锁的那个进程注册 listenfd 读事件,在读事件里调用 accept 接受该连接。当一个 worker 进程在 accept 这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,这样一个完整的请求就是这样的了。这样,一个请求,完全由 worker 进程来处理,而且只在一个 worker 进程中处理。
nginx 性能?
这里援引网上搜索到的 nginx 的测试数据:10000 个非活跃的 HTTP keep-alive 连接仅占用约 2.5MB 内存。三万并发连接下,10 个 Nginx 进程,消耗内存 150M。淘宝 tengine 团队说测试结果是“24G 内存机器上,处理并发请求可达 200 万”。
nginx 负载均衡?
通信协议支持:nginx 负载均衡主要是对七层网络通信模型中的第七层应用层上的 http、https 进行支持。同时 nginx 更新版本也在逐步对 Websocket、SPDY 等协议作出支持。
nginx 是以反向代理的方式进行负载均衡的。反向代理(Reverse Proxy)方式是指以代理服务器来接受 Internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 Internet 上请求连接的客户端,此时代理服务器对外就表现为一个服务器。(为了理解反向代理,这里插播一条什么是正向代理:正向代理指的是,一个位于客户端和原始服务器之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。)
这里再插播一条实现负载均衡的技术的方式有哪些:硬件层面有 F5 负载均衡器,网络层层面有 LVS(Linux Virtual Server),应用层层面就是 nginx、Haproxy 等。
nginx 实现负载均衡的分配策略有很多,被编进 nginx 内核的策略有轮询和 ip_hash,第三方的有 fair、url_hash 等。这里主要对内核策略进行介绍。
1. 轮询
a)none(默认轮询):upstream 按照轮询(默认)方式进行负载,每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。虽然这种方式简便、成本低廉。但缺点是:可靠性低和负载分配不均衡。
b)weight(按权重轮询): 指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况。
server 192.168.61.22 weight = 6; # 60% 请求
server 192.168.61.23 weight = 4; # 40% 请求
2.ip_hash
每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。配置只需要在 upstream 中加入 ”ip_hash;” 即可。
upstream tomcats {
ip_hash;
server 127.0.0.1:9001;
server 127.0.0.1:9002;
}
3.fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。与 weight 分配策略类似。
upstream tomcats {
server 127.0.0.1:9001;
server 127.0.0.1:9002;
fair;
}
4.url_hash(第三方)
和 IP 哈希类似,只不过针对请求的 url 进行 hash(基于缓存的 server,页面静态化)。
更多 Nginx 负载均衡配置 相关教程见以下内容:
Nginx 负载均衡配置说明 http://www.linuxidc.com/Linux/2016-03/129424.htm
Linux 下 Nginx+Tomcat 负载均衡和动静分离配置要点 http://www.linuxidc.com/Linux/2016-01/127255.htm
Docker+Nginx+Tomcat7 配置简单的负载均衡 http://www.linuxidc.com/Linux/2015-12/125907.htm
Nginx 负载均衡(主备)+Keepalived http://www.linuxidc.com/Linux/2015-12/126865.htm
使用 Nginx 作为负载均衡器 http://www.linuxidc.com/Linux/2015-12/125789.htm
使用 Nginx 简单实现负载均衡 http://www.linuxidc.com/Linux/2016-08/134443.htm
Nginx 负载均衡与高可用的实现 http://www.linuxidc.com/Linux/2016-04/130350.htm
初学 Nginx 实现 Web 负载均衡 http://www.linuxidc.com/Linux/2016-10/136116.htm
Nginx 的详细介绍:请点这里
Nginx 的下载地址:请点这里
本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-11/137111.htm