Nginx基础知识点总结和优化项
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Nginx基础知识点总结和优化项
1.什么是Nginx?
Nginx是⼀个⾼性能的HTTP和反向代理服务器,常⽤于做负载均衡服务器
2.为什么要⽤Nginx?
跨平台、配置简单
⾮阻塞、⾼并发连接:
处理2-3万并发连接数,官⽅监测能⽀持5万并发
内存消耗⼩:
开启10个nginx才占150M内存,Nginx采取了分阶段资源分配技术
nginx处理静态⽂件好,耗费内存少
内置的健康检查功能:
如果有⼀个服务器宕机,会做⼀个健康检查,再发送的请求就不会发送到宕机的服务器了。
重新将请求提交到其他的节点上。
节省宽带:
⽀持GZIP压缩,可以添加浏览器本地缓存
稳定性⾼:
宕机的概率⾮常⼩
master/worker结构:
⼀个master进程,⽣成⼀个或者多个worker进程
接收⽤户请求是异步的:
浏览器将请求发送到nginx服务器,它先将⽤户请求全部接收下来,再⼀次性发送给后端web服务器,极⼤减轻了web服务器的压⼒,⼀边接收web服务器的返回数据,⼀边发送给浏览器客户端
⽹络依赖性⽐较低,只要ping通就可以负载均衡
可以有多台nginx服务器
3.为什么Nginx性能这么⾼?
得益于它的事件处理机制:
异步⾮阻塞事件处理机制:运⽤了epoll模型,提供了⼀个队列,排队解决
4、为什么不使⽤多线程?
Apache Tomcat: 创建多个进程或线程,⽽每个进程或线程都会为其分配cpu和内存(线程要⽐进程⼩的多,所以worker⽀持⽐perfork⾼的并发),并发过⼤会榨⼲服务器资源。
Nginx: 采⽤单线程来异步⾮阻塞处理请求(管理员可以配置Nginx主进程的⼯作进程的数量)(epoll),不会为每个请求分配cpu和内存资源,节省了⼤量资源,同时也减少了⼤量的CPU的上下⽂切换。
所以才使得Nginx⽀持更⾼的并发。
下⾯说⼀下Nginx是如何处理⼀个请求的呢?
⾸先,nginx在启动时,会解析配置⽂件,得到需要监听的端⼝与ip地址,然后在nginx的master进程⾥⾯
先初始化好这个监控的socket(创建socket,设置addrreuse等选项,绑定到指定的ip地址端⼝,再listen)
然后再fork(⼀个现有进程可以调⽤fork函数创建⼀个新进程。
由fork创建的新进程被称为⼦进程 )出多个⼦进程出来
然后⼦进程会竞争accept新的连接。
此时,客户端就可以向nginx发起连接了。
当客户端与nginx进⾏三次握⼿,与nginx建⽴好⼀个连接后
此时,某⼀个⼦进程会accept成功,得到这个建⽴好的连接的socket,然后创建nginx对连接的封装,即ngx_connection_t结构体
为什么nginx可以采⽤异步⾮阻塞的⽅式来处理?
看看⼀个请求的完整过程:⾸先,请求过来,要建⽴连接,然后再接收数据,接收数据后,再发送数据。
具体到系统底层,就是读写事件,⽽当读写事件没有准备好时,必然不可操作,如果不⽤⾮阻塞的⽅式来调⽤,那就得阻塞调⽤了,事件没有准备好,那就只能等了,等事件准备好了,你再继续吧。
阻塞调⽤会进⼊内核等待,cpu就会让出去给别⼈⽤了,对单线程的worker来说,显然不合适,当⽹络事件越多时,⼤家都在等待呢,cpu空闲下来没⼈⽤,cpu利⽤率⾃然上不去了,更别谈⾼并发了。
好吧,你说加进程数,这跟apache的线程模型有什么区别,注意,别增加⽆谓的上下⽂切换。
所以,在nginx⾥⾯,最忌讳阻塞的系统调⽤了。
不要阻塞,那就⾮阻塞喽。
⾮阻塞就是,事件没有准备好,马上返回EAGAIN,告诉你,事件还没准备好呢,你慌什么,过会再来吧。
好吧,你过⼀会,再来检查⼀下事件,直到事件准备好了为⽌,在这期间,你就可以先去做其它事情,然后再来看看事件好了没。
虽然不阻塞了,但你得不时地过来检查⼀下事件的状态,你可以做更多的事情了,但带来的开销也是不⼩的。
nginx⽀持的事件模型?
Nginx⽀持如下处理连接的⽅法(I/O复⽤⽅法),这些⽅法可以通过use指令指定。
● select– 标准⽅法。
如果当前平台没有更有效的⽅法,它是编译时默认的⽅法。
你可以使⽤配置参数 –with-select_module 和 –without-select_module 来启⽤或禁⽤这个模块。
● poll– 标准⽅法。
如果当前平台没有更有效的⽅法,它是编译时默认的⽅法。
你可以使⽤配置参数 –with-poll_module 和 –without-
poll_module 来启⽤或禁⽤这个模块。
● kqueue– ⾼效的⽅法,使⽤于 FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X. 使⽤双处理器的MacOS X系统使⽤kqueue可能会造成内核崩溃。
● epoll – ⾼效的⽅法,使⽤于Linux内核2.6版本及以后的系统。
在某些发⾏版本中,如SuSE 8.2, 有让2.4版本的内核⽀持epoll的补丁。
● rtsig – 可执⾏的实时信号,使⽤于Linux内核版本2.2.19以后的系统。
默认情况下整个系统中不能出现⼤于1024个POSIX实时(排队)信号。
这种情况对于⾼负载的服务器来说是低效的;所以有必要通过调节内核参数 /proc/sys/kernel/rtsig-max 来增加队列的⼤⼩。
可是从Linux内
核版本2.6.6-mm2开始,这个参数就不再使⽤了,并且对于每个进程有⼀个独⽴的信号队列,这个队列的⼤⼩可以⽤
RLIMIT_SIGPENDING 参数调节。
当这个队列过于拥塞,nginx就放弃它并且开始使⽤ poll ⽅法来处理连接直到恢复正常。
● /dev/poll – ⾼效的⽅法,使⽤于 Solaris 7 11/99+, HP/UX 11.22+ (eventport), IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+.
● eventport – ⾼效的⽅法,使⽤于 Solaris 10. 为了防⽌出现内核崩溃的问题,有必要安装这个安全补丁。
在linux下⾯,只有epoll是⾼效的⽅法,epoll到底是如何⾼效的
Epoll是Linux内核为处理⼤批量句柄⽽作了改进的poll。
要使⽤epoll只需要这三个系统调⽤:epoll_create(2), epoll_ctl(2),
epoll_wait(2)。
它是在2.5.44内核中被引进的(epoll(4) is a new API introduced in Linux kernel 2.5.44),在2.6内核中得到⼴泛应⽤。
epoll的优点?
●⽀持⼀个进程打开⼤数⽬的socket描述符(FD)
select 最不能忍受的是⼀个进程所打开的FD是有⼀定限制的,由FD_SETSIZE设置,默认值是2048。
对于那些需要⽀持的上万连接数⽬的IM服务器来说显然太少了。
这时候你⼀是可以选择修改这个宏然后重新编译内核,不过资料也同时指出这样会带来⽹络效率的下降,⼆是可以选择多进程的解决⽅案(传统的 Apache⽅案),不过虽然linux上⾯创建进程的代价⽐较⼩,但仍旧是不可忽视的,加上进程间数据同步远⽐不上线程间同步的⾼效,所以也不是⼀种完美的⽅案。
不过 epoll则没有这个限制,它所⽀持的FD上限是最⼤可以打开⽂件的数⽬,这个数字⼀般远⼤于2048,举个例⼦,在1GB内存的机器上⼤约是10万左右,具体数⽬可以cat /proc/sys/fs/file-max察看,⼀般来说这个数⽬和系统内存关系很⼤。
● IO效率不随FD数⽬增加⽽线性下降
传统的select/poll另⼀个致命弱点就是当你拥有⼀个很⼤的socket集合,不过由于⽹络延时,任⼀时间只有部分的socket是”活跃”的,但是select/poll每次调⽤都会线性扫描全部的集合,导致效率呈现线性下降。
但是epoll不存在这个问题,它只会对”活跃”的socket进⾏操作—这是因为在内核实现中epoll是根据每个fd上⾯的callback函数实现的。
那么,只有”活跃”的socket才会主动的去调⽤ callback函数,其他idle状态socket则不会,在这点上,epoll实现了⼀个”伪”AIO,因为这时候推动⼒在os内核。
在⼀些 benchmark中,如果所有的socket基本上都是活跃的—⽐如⼀个⾼速LAN环境,epoll并不⽐select/poll有什么效率,相反,如果过多使⽤epoll_ctl,效率相⽐还有稍微的下降。
但是⼀旦使⽤idle connections模拟WAN环境,epoll的效率就远在select/poll之上了。
●使⽤mmap加速内核与⽤户空间的消息传递。
这点实际上涉及到epoll的具体实现了。
⽆论是select,poll还是epoll都需要内核把FD消息通知给⽤户空间,如何避免不必要的内存拷贝就很重要,在这点上,epoll是通过内核于⽤户空间mmap同⼀块内存实现的。
⽽如果你想我⼀样从2.5内核就关注epoll的话,⼀定不会忘记⼿⼯mmap这⼀步的。
●内核微调
这⼀点其实不算epoll的优点了,⽽是整个linux平台的优点。
也许你可以怀疑linux平台,但是你⽆法回避linux平台赋予你微调内核的能⼒。
⽐如,内核TCP/IP协议栈使⽤内存池管理sk_buff结构,那么可以在运⾏时期动态调整这个内存pool(skb_head_pool)的⼤⼩— 通过echo XXXX>/proc/sys/net/core/hot_list_length完成。
再⽐如listen函数的第2个参数(TCP完成3次握⼿的数据包队列长度),也可以根据你平台内存⼤⼩动态调整。
更甚⾄在⼀个数据包⾯数⽬巨⼤但同时每个数据包本⾝⼤⼩却很⼩的特殊系统上尝试最新的NAPI⽹卡驱动架构。
(epoll内容,参考epoll_互动百科)
推荐设置worker的个数为cpu的核数,在这⾥就很容易理解了,更多的worker数,只会导致进程来竞争cpu资源了,从⽽带来不必要的上下⽂切换。
⽽且,nginx为了更好的利⽤多核特性,提供了cpu亲缘性的绑定选项,我们可以将某⼀个进程绑定在某⼀个核上,这样就不会因为进程的切换带来cache的失效。
像这种⼩的优化在nginx中⾮常常见,同时也说明了nginx作者的苦⼼孤诣。
⽐如,nginx在做4个字节的字符串⽐较时,会将4个字符转换成⼀个int型,再作⽐较,以减少cpu的指令数等等。
5、Nginx是如何处理⼀个请求的呢?
⾸先,nginx在启动时,会解析配置⽂件,得到需要监听的端⼝与ip地址,然后在nginx的master进程⾥⾯,先初始化好这个监控的socket,再进⾏listen,然后再fork出多个⼦进程出来, ⼦进程会竞争accept新的连接。
此时,客户端就可以向nginx发起连接了。
当客户端与nginx进⾏三次握⼿,与nginx建⽴好⼀个连接后,某⼀个⼦进程会accept成功,然后创建nginx对连接的封装,即ngx_connection_t结构体,根据事件调⽤相应的事件处理模块,如http模块与客户端进⾏数据的交换。
最后,nginx或客户端来主动关掉连接,到此,⼀个连接就寿终正寝了
6. 正向代理,反向代理
正向代理总结就⼀句话:代理端代理的是客户端
⽐如,国内访问google会被墙挡住,但是可以通过访问其他国家的服务器,达到访问Google的结果
如果是正向代理的话,就是其他国家的服务器解决了墙的问题,将你的访问直接转发到Google上⾯
⼀个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送⼀个请求并指定⽬标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。
客户端才能使⽤正向代理
反向代理总结就⼀句话:代理端代理的是服务端
反向代理就是你压根就不知道你要访问的地址是哪⾥,但是⼀去访问⼀个服务器,但是这个服务器其实是去访问其他的服务器,得到数据后返回给你,你甚⾄不知道数据来源
反向代理(Reverse Proxy)⽅式是指以代理服务器来接受internet上的连接请求,然后将请求,发给内部⽹络上的服务器并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为⼀个反向代理服务器
7.动静态分离
动态资源、静态资源分离是让动态⽹站⾥的动态⽹页根据⼀定规则把不变的资源和经常变的资源区分开来,动静资源做好了拆分以后,我们就可以根据静态资源的特点将其做缓存操作,这就是⽹站静态化处理的核⼼思路
动态资源、静态资源分离简单的概括是:动态⽂件与静态⽂件的分离
location ~.(png|jpg|css|js|htm|html){
root /home
}
8.为什么要做动、静分离?
在我们的软件开发中,有些请求是需要后台处理的(如:.jsp,.do等等),有些请求是不需要经过后台处理的(如:css、html、jpg、js等等⽂件)
这些不需要经过后台处理的⽂件称为静态⽂件,否则动态⽂件。
因此我们后台处理忽略静态⽂件。
这会有⼈⼜说那我后台忽略静态⽂件不就完了吗
当然这是可以的,但是这样后台的请求次数就明显增多了。
在我们对资源的响应速度有要求的时候,我们应该使⽤这种动静分离的策略去解决动、静分离将⽹站静态资源(HTML,JavaScript,CSS,img等⽂件)与后台应⽤分开部署,提⾼⽤户访问静态代码的速度,降低对后台应⽤访问
这⾥我们将静态资源放到nginx中,动态资源转发到tomcat服务器中,毕竟Tomcat的优势是处理动态请求
9.负载均衡
负载均衡即是代理服务器将接收的请求均衡的分发到各服务器中
负载均衡主要解决⽹络拥塞问题,提⾼服务器响应速度,服务就近提供,达到更好的访问质量,减少后台服务器⼤并发压⼒
tomcatlist{
ip+port[weigth=3],
ip+port[weigth=1],
…
}
location /{
pass_proxy tomcat
}
10.nginx和apache的区别
轻量级,同样起web 服务,⽐apache 占⽤更少的内存及资源
抗并发,nginx 处理请求是异步⾮阻塞的,⽽apache 则是阻塞型的,在⾼并发下nginx 能保持低资源低消耗⾼性能
⾼度模块化的设计,编写模块相对简单
最核⼼的区别在于apache是同步多进程模型,⼀个连接对应⼀个进程;nginx是异步的,多个连接(万级别)可以对应⼀个进程
nginx 优化选项有哪些?
nginx常⽤优化内容主要包括如下内容:
1.隐藏版本信息
2.隐藏nginx要修改的源代码
3.更改nginx服务的默认⽤户
4.降权启动nginx
5.优化nginx进程个数
6.绑定不同的nginx进程到不同的CPU上
7.Nginx事件处理模型优化
8.调整nginx单个进程允许的客户端最⼤连接数
9.配置nginx worker进程对打打开⽂件数
10.开启⾼效⽂件传输模式
11.Nginx gzip压缩实现性能优化
12.编写脚本实现⽇志轮询
13.不记录不需要的⽇志
14.访问⽇志的权限设置
15.根据扩展名限制程序和⽂件访问
16.禁⽌访问指定⽬录下的所有⽂件和⽬录
17.限制⽹站来源的IP访问
18.配置nginx禁⽌⾮法域名解析访问企业⽹站
19.nginx防爬⾍优化
20.控制nginx并发连接数量。