Nginx
1. Nginx的整体架构
1.1. 主进程
Nginx启动时,会生成两种类型的进程,一个是主进程(master),一个(windows版本的目前只有一个)或多个工作进程(worker)。主进程并不处理网络请求,主要负责调度工作进程,也就是:加载配置、启动工作进程及非停升级。所以,Nginx启动以后,查看操作系统的进程列表,我们就能看到至少有两个Nginx进程。
1.2. 工作进程
服务器实际处理网络请求及响应的是工作进程(worker),在类Lunix系统上,Nginx可以配置多个worker,而每个worker进程都可以同时处理数以千计的网络请求。
1.3. 模块化设计
Nginx的worker进程,包括核心和功能性模块,核心模块负责维持一个运行循环(run-loop),执行网络请求处理的不同阶段的模块功能,比如:网络读写、存储读写、内容传输、外出过滤,以及将请求发往上游服务器等。而其代码的模块化设计,也使得我们可以根据需要对功能模块进行适当的选择和修改,编译成具有特定功能的服务器。
1.4. 事件驱动模型
基于异步及非阻塞的事件驱动模型,可以说是Nginx得以获得高并发、高性能的关键因素,同时也得益于对Linux、Solaris及类BSD等操作系统内核中事件通知及I/O性能增强功能的采用,如kqueue、epoll及event ports。
1.5. 代理(proxy)设计
代理设计,可以说是Nginx深入骨髓的设计,无论是对于HTTP,还是对于FastCGI、Memcache、Redis等的网络请求或响应,本质上都采用了代理机制。所以,Nginx天生就是高性能的代理服务器。
的模块化设计
高度模块化的设计是 Nginx 的架构基础。Nginx服务器被分解为多个模块,每个模块就是一个功能模块,只负责自身的功能,模块之间严格遵循==“高内聚,低耦合”==的原则。
2.1. 核心模块
核心模块是Nginx服务器正常运行必不可少的模块,提供错误日志记录、配置文件解析、事件驱动机制、进程管理等核心功能。
2.2. 标准HTTP模块
标准HTTP模块提供HTTP协议解析相关的功能,比如:端口配置、网页编码设置、HTTP响应头设置等等。
2.3. 可选HTTP模块
可选HTTP模块主要用于扩展标准的HTTP功能,让Nginx能处理一些特殊的服务,比如: Flash多媒体传输、解析GeoIP请求、网络传输压缩、安全协议SSL支持等。
2.4. 邮件服务模块
邮件服务模块主要用于支持Nginx的邮件服务,包括对POP3协议、IMAP协议和SMTP协议的支持。
2.5. 第三方模块
第三方模块是为了扩展Nginx服务器应用,完成开发者自定义功能,比如: Json支持、Lua支持等。
3. Nginx的请求方式处理
Nginx是一个高性能的Web服务器,能够同时处理大量的并发请求。它结合多进程机制和异步机制,异步机制使用的是异步非阻塞方式,接下来就给大家介绍一下Nginx的多线程机制和异步非阻塞机制。
3.1. 多进程机制
服务器每当收到一个客户端时,就有服务器主进程(master process)生成一个子进程( worker process )出来和客户端建立连接进行交互,直到连接断开,该子进程就结束了。
使用进程的好处:是各个进程之间相互独立,不需要加锁,减少了使用锁对性能造成影响,同时降低编程的复杂度,降低开发成本。其次,采用独立的进程,可以让 进程互相之间不会影响,如果一个进程发生异常退出时,其它进程正常工作,master进程则很快启动新的worker进程,确保服务不会中断,从而将风险降到最低。
缺点:是操作系统生成一个子进程需要进行内存复制等操作,在资源和时间上会产生一定的开销。当有大量请求时,会导致系统性能下降。
3.2. 异步非阻塞机制
每个工作进程使用异步非阻塞方式,可以处理多个客户端请求。
当某个工作进程接收到客户端的请求以后,调用IO进行处理,如果不能立即得到结果,就去处理其他请求(即为非阻塞);而客户端在此期间也无需等待响应,可以去处理其他事情(即为异步)。
当IO返回时,就会通知此工作进程;该进程得到通知,暂时挂起当前处理的事务去 响应客户端请求。
4. Nginx事件驱动模型
在Nginx的异步非阻塞机制中,工作进程在调用IO后,就去处理其他的请求,当IO调用返回后,会通知该工作进程。对于这样的系统调用,主要使用Nginx服务器的事件驱动模型来实现。
如上图所示,Nginx的事件驱动模型由事件收集器、事件发送器和事件处理器三部分基本单元组成。
事件收集器:负责收集 worker 进程的各种 IO 请求;
事件发送器:负责将 IO 事件发送到事件处理器 ;
事件处理器:负责各种事件的响应工作 。
事件发送器将每个请求放入一个待处理事件列表,使用非阻塞I/O方式调用事件处理器来处理该请求。其处理方式称为“多路IO复用方法”,常见的包括以下三种:select模型、poll模型、epoll模型。
5.什么是Nginx?有什么用?
1)Nginx 是一个高性能的Web 和反向代理服务器。
作为 Web 服务器:相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效率,这点使 Nginx 尤其受到虚拟主机提供商的欢迎。能够支持高达 50,000 个并发连接数的响应。也可以作为反向代理服务器,解决跨域问题。用于HTTP、HTTPS、SMTP、POP3和IMAP协议。
2)作为负载均衡服务器,实现集群功能:
在许多应用中,负载平衡是一种常用的技术来优化利用资源最大化吞吐量,减少等待时间,并确保容错。可以使用nginx的作为一种非常高效的HTTP负载平衡器,将流量分配到多个应用服务器上提高性能,可扩展性和高可用性。
3)作为邮件代理服务器:
Nginx 同时也是一个非常优秀的邮件代理服务器(最早开发这个产品的目的之一也是作为邮件代理服务器)。
6. Nginx 有哪些优点?
1). 跨平台、配置简单。
2) .非阻塞、高并发连接:处理 2-3 万并发连接数,官方监测能支持 5 万并发。
3).内存消耗小:开启 10 个 Nginx 才占 150M 内存。
4). 成本低廉,且开源。
5). 稳定性高,宕机的概率非常小。
7.为什么 Nginx 不使用多线程?
Apache: 创建多个进程或线程,而每个进程或线程都会为其分配 cpu 和内存(线程要比进程小的多,所以 worker 支持比 perfork 高的并发),并发过大会榨干服务器资源。
Nginx: 采用单线程来异步非阻塞处理请求(管理员可以配置 Nginx 主进程的工作进程的数量)(epoll),不会为每个请求分配 cpu 和内存资源,节省了大量资源,同时也减少了大量的 CPU 的上下文切换。所以才使得 Nginx 支持更高的并发。
是如何实现高并发的
一个主进程,多个工作进程,每个工作进程可以处理多个请求
每进来一个request,会有一个worker进程去处理。但不是全程的处理,处理到可能发生阻塞的地方,比如向上游(后端)服务器转发request,并等待请求返回。那么,这个处理的worker继续处理其他请求,而一旦上游服务器返回了,就会触发这个事件,worker才会来接手,这个request才会接着往下走。
由于web server的工作性质决定了每个request的大部份生命都是在网络传输中,实际上花费在server机器上的时间片不多。这是几个进程就解决高并发的秘密所在。即@skoo所说的webserver刚好属于网络io密集型应用,不算是计算密集型。
常用命令
启动nginx ./sbin/nginx
停止nginx ./sbin/nginx -s stop 或
./sbin/nginx -s quit
重载配置 ./sbin/nginx -s reload(平滑重启) 或 service nginx reload
重载指定配置文件 ./sbin/nginx -c /usr/local/nginx/conf/
查看nginx版本 ./sbin/nginx -v
检查配置文件是否正确 ./sbin/nginx -t
显示帮助信息 ./sbin/nginx -h
状态码
499:服务端处理时间过长,客户端主动关闭了连接。
11.负载均衡
负载均衡即是代理服务器将接收的请求均衡的分发到各服务器中
负载均衡主要解决网络拥塞问题,提高服务器响应速度,服务就近提供,达到更好的访问质量,减少后台服务器大并发压力
12.为什么Nginx性能这么高?
得益于它的事件处理机制:
异步非阻塞事件处理机制:运用了epoll模型,提供了一个队列,排队解决
功能
作为http server(代替apache,对PHP需要FastCGI处理器支持)
1).反向代理服务器: 客户端假设通过HTTP协议访问A网站中的应用服务器,那么网站管理者可在服务器加一个Nginx(也就是所谓的反向代理),让客户端线先请求Nginx,随后Nginx去请求应用服务器,然后将结果返回给客户端。
2).实现负载均衡: 当一个网站访问量特别大的时候,网站的各种速度都会越来越慢,一台服务器肯定是不够用了。这个时候就需要将应用部署在多台服务器上,将请求平摊给多台服务器来处理。这样的好处是,万一某一台服务器GG了,但只要还有其他的服务器正常运行,就不会影响使用。这个时候就可以通过Nginx反向代理来实现负载均衡。
3).虚拟主机: 负载均衡虽然很好用,但并不是适合所有的网站,例如有的网站,访问量较小,所以需要节约成本,这个时候就需要将多个网站放在同一台服务器上。例如将A和B两个网站部署在同一台服务器上,然后将两个域名同时解析到一个IP地址,但是要让用户通过两个域名打开两个完全不同的网站,彼此之间不影响,就像访问两个服务器一样,这个时候就像2个虚拟主机。
虚拟主机的原理是通过HTTP请求头中的Host是否匹配server_name来实现的,另外server_name配置还可以过滤将某些域名指向你主机服务器的恶意行为。
4).FastCGI:Nginx本身不支持PHP等语言,但是它可以通过FastCGI来将请求扔给某些语言或框架处理
14.请解释 Nginx 如何处理 HTTP 请求?
首先,Nginx 在启动时,会解析配置文件,得到需要监听的端口与 IP 地址,然后在 Nginx 的 Master 进程里面先初始化好这个监控的Socket(创建 S ocket,设置 addr、reuse 等选项,绑定到指定的 ip 地址端口,再 listen 监听)。
然后,再 fork(一个现有进程可以调用 fork 函数创建一个新进程。由 fork 创建的新进程被称为子进程 )出多个子进程出来。
之后,子进程会竞争 accept 新的连接。此时,客户端就可以向 nginx 发起连接了。当客户端与nginx进行三次握手,与 nginx 建立好一个连接后。此时,某一个子进程会 accept 成功,得到这个建立好的连接的 Socket ,然后创建 nginx 对连接的封装,即 ngx_connection_t 结构体。
接着,设置读写事件处理函数,并添加读写事件来与客户端进行数据的交换。
最后,Nginx 或客户端来主动关掉连接,到此,一个连接就寿终正寝了。
15.是否有可能将Nginx的错误替换为502错误、503?
502 = 错误网关 503 = 服务器超载
有可能,但是您可以确保fastcgi_intercept_errors被设置为ON,并使用错误页面指令。
16.502错误可能原因
(1).FastCGI进程是否已经启动
(2).FastCGI worker进程数是否不够
(3).FastCGI执行时间过长
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
(4).FastCGI Buffer不够
nginx和apache一样,有前端缓冲限制,可以调整缓冲参数
fastcgi_buffer_size 32k;
fastcgi_buffers 8 32k;
(5). Proxy Buffer不够
如果你用了Proxying,调整
proxy_buffer_size 16k;
proxy_buffers 416k;
(6).php脚本执行时间过长
将的0s的0s改成一个时间
和apache的区别
轻量级,同样起web 服务,比apache 占用更少的内存及资源
抗并发,nginx 处理请求是异步非阻塞的,而apache 则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能
高度模块化的设计,编写模块相对简单
最核心的区别在于apache是同步多进程模型,一个连接对应一个进程;nginx是异步的,多个连接(万级别)可以对应一个进程
与cgi的区别
差别在于是否重复 fork 进程,处理请求。
cgi: web服务器会根据请求的内容,然后会fork一个新进程来运行外部c程序(或perl脚本…), 这个进程会把处理完的数据返回给web服务器,最后web服务器把内容发送给用户,刚才fork的进程也随之退出。 如果下次用户还请求改动态脚本,那么web服务器又再次fork一个新进程,周而复始的进行。
fastcgi: web服务器收到一个请求时,他不会重新fork一个进程(因为这个进程在web服务器启动时就开启了,而且不会退出),web服务器直接把内容传递给这个进程(进程间通信,但fastcgi使用了别的方式,tcp方式通信),这个进程收到请求后进行处理,把结果返回给web服务器,最后自己接着等待下一个请求的到来,而不是退出。
配置
worker_processes 8; | 工作进程个数 |
---|---|
worker_connections 65535; | 每个工作进程能并发处理(发起)的最大连接数(包含所有连接数) |
error_log /data/logs/nginx/; | 错误日志打印地址 |
access_log /data/logs/nginx/; | 进入日志打印地址 |
log_format main ‘$ remote_addr"$ request" ‘’$ status $ upstream_addr “$request_time”’; | 进入日志格式 |
fastcgi_connect_timeout=300; | 连接到后端fastcgi超时时间 |
fastcgi_send_timeout=300; | 向fastcgi请求超时时间(这个指定值已经完成两次握手后向fastcgi传送请求的超时时间) |
fastcgi_rend_timeout=300; | 接收fastcgi应答超时时间,同理也是2次握手后 |
fastcgi_buffer_size=64k; | 读取fastcgi应答第一部分需要多大缓冲区,该值表示使用1个64kb的缓冲区读取应答第一部分(应答头),可以设置为fastcgi_buffers选项缓冲区大小 |
fastcgi_buffers 4 64k; | 指定本地需要多少和多大的缓冲区来缓冲fastcgi应答请求,假设一个php或java脚本所产生页面大小为256kb,那么会为其分配4个64kb的缓冲来缓存 |
fastcgi_cache TEST; | 开启fastcgi缓存并为其指定为TEST名称,降低cpu负载,防止502错误发生 |
Listen 80; | 监听端口 |
server_name ; | 允许域名 |
root /data/release/rrc/web; | 项目根目录 |
index ; | 访问根文件 |
20.在Nginx中,如何使用未定义的服务器名称来阻止处理请求?
只需将请求删除的服务器就可以定义,服务器名被保留为一个空字符串,它将在没有“主机”头字段的情况下匹配请求,而一个特殊的Nginx的非标准代码444被返回,从而终止连接。
21.使用“反向代理服务器”的优点是什么?
反向代理服务器可以隐藏源服务器的存在和特征。它充当互联网云和web服务器之间的中间层。这对于安全方面来说是很好的,特别是当您使用web托管服务时。
22、正向代理----------代理端代理的是客户端
一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端才能使用正向代理
23、反向代理--------代理端代理的是服务端
反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求,发给内部网络上的服务器并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
24.请列举Nginx服务器的最佳用途。
Nginx服务器的最佳用法是在网络上部署动态HTTP内容,使用SCGI、WSGI应用程序服务器、用于脚本的FastCGI处理程序。它还可以作为负载均衡器。
25.请解释Nginx服务器上的Master和Worker进程分别是什么?
Master进程:读取及评估配置和维持
Worker进程:处理请求
26.请解释你如何通过不同于80的端口开启Nginx?
为了通过一个不同的端口开启Nginx,你必须进入/etc/Nginx/sites-enabled/,如果这是默认文件,那么你必须打开名为“default”的文件。编辑文件,并放置在你想要的端口:
Like server { listen 81; }
27.在Nginx中,解释如何在URL中保留双斜线?
要在URL中保留双斜线,就必须使用merge_slashes_off;
语法:merge_slashes [on/off]
默认值: merge_slashes on
环境: http,server
28.请解释ngx_http_upstream_module的作用是什么?
ngx_http_upstream_module用于定义可通过fastcgi传递、proxy传递、uwsgi传递、memcached传递和scgi传递指令来引用的服务器组。
29.请解释什么是C10K问题?
C10K问题是指无法同时处理大量客户端(10,000)的网络套接字。
30.请陈述stub_status和sub_filter指令的作用是什么?
Stub_status指令:该指令用于了解Nginx当前状态的当前状态,如当前的活动连接,接受和处理当前读/写/等待连接的总数
Sub_filter指令:它用于搜索和替换响应中的内容,并快速修复陈旧的数据
31.解释Nginx是否支持将请求压缩到上游?
可以使用Nginx模块gunzip将请求压缩到上游。gunzip模块是一个过滤器,它可以对不支持“gzip”编码方法的客户机或服务器使用“内容编码:gzip”来解压缩响应。
32.解释如何在Nginx中获得当前的时间?
要获得Nginx的当前时间,必须使用SSI模块、
d
a
t
e
g
m
t
和
date_gmt和
dategmt和date_local的变量。
Proxy_set_header THE-TIME $date_gmt;
33.用Nginx服务器解释-s的目的是什么?
用于运行Nginx -s参数的可执行文件。
34.解释如何在Nginx服务器上添加模块?
在编译过程中,必须选择Nginx模块,因为Nginx不支持模块的运行时间选择。
35. 什么是动态资源、静态资源分离?
动态资源、静态资源分离,是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,动静资源做好了拆分以后我们就可以根据静态资源的特点将其做缓存操作,这就是网站静态化处理的核心思路。
动态资源、静态资源分离简单的概括是:动态文件与静态文件的分离。
36.什么叫 CDN 服务?
CDN ,即内容分发网络。
其目的是,通过在现有的 Internet中 增加一层新的网络架构,将网站的内容发布到最接近用户的网络边缘,使用户可就近取得所需的内容,提高用户访问网站的速度。
一般来说,因为现在 CDN 服务比较大众,所以基本所有公司都会使用 CDN 服务。
37.为什么要做动、静分离?
在我们的软件开发中,有些请求是需要后台处理的(如:.jsp,.do 等等),有些请求是不需要经过后台处理的(如:css、html、jpg、js 等等文件),这些不需要经过后台处理的文件称为静态文件,否则为动态文件。
因此我们后台处理忽略静态文件。这会有人又说那我后台忽略静态文件不就完了吗?当然这是可以的,但是这样后台的请求次数就明显增多了。在我们对资源的响应速度有要求的时候,我们应该使用这种动静分离的策略去解决动、静分离将网站静态资源(HTML,JavaScript,CSS,img等文件)与后台应用分开部署,提高用户访问静态代码的速度,降低对后台应用访问
这里我们将静态资源放到 Nginx 中,动态资源转发到 Tomcat 服务器中去。
当然,因为现在七牛、阿里云等 CDN 服务已经很成熟,主流的做法,是把静态资源缓存到 CDN 服务中,从而提升访问速度。
相比本地的 Nginx 来说,CDN 服务器由于在国内有更多的节点,可以实现用户的就近访问。
并且,CDN 服务可以提供更大的带宽,不像我们自己的应用服务,提供的带宽是有限的。
有哪些负载均衡策略?
负载均衡,即是代理服务器将接收的请求均衡的分发到各服务器中。
Nginx 默认提供了 3 种负载均衡策略:
1).轮询(默认)round_robin
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。
2).IP 哈希 ip_hash
每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 共享的问题。
当然,实际场景下,一般不考虑使用 ip_hash 解决 session 共享。
3).最少连接 least_conn
下一个请求将被分派到活动连接数量最少的服务器,通过 Nginx 插件,我们还可以引入 fair、url_hash 等负载均衡策略。另外,我们还可以配置每一个后端节点在负载均衡时的其它配置:
39. Nginx 如何实现后端服务的健康检查?
利用 nginx 自带模块 ngx_http_proxy_module 和 ngx_http_upstream_module 对后端节点做健康检查。