您的位置:首页 > 运维架构 > Nginx

nginx学习

2017-03-31 18:12 37 查看
1 nginx在启动后,会有一个master进程和多个worker进程。master进程主要用来管理worker进程

2 master进程:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。

3 worker进程:基本的网络事件处理。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的

注:worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致,这里面的原因与nginx的进程模型以及事件处理模型是分不开的

nginx模型

 

4 操作nginx:[/b]

操作nginx实际上就是操作master,master来管理worker进程,只需要与master进程通信,master进程会接收来自外界发来的信号,再根据信号做不同的事情

[/b]

5
 运行机制[/b]:

master机制:

重启nginx(重新加载配置):kill -HUP
pid(服务不中断)

流程(服务不中断原因):master接收命令---->重新加载配置----->启动新的worker进程----->向老的worker进程发送停止信号---->处理完老的请求退出

 
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
|____接受新的请求

nginx
0.8之后新增命令:

重启nginx:./nginx -s
reload

流程:启动一个新的nginx进程---->由reload明白重新加载配置----->发送信号到master------>同上

worker机制:

worker都是由master进程fork而来,在http请求发送过来前会建立好需要listen的socket(listenfd),然后fork出多个worker,然后各个worker抢互斥锁(accept_mutex)(保证只有一个进程处理该连接)抢到互斥锁后,worker进程在accept这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接

6
优点[/b]

1)每个worker进程独立,不需要加锁,在编程以及问题查找时,也会方便很多,节省时间

2) 采用独立的进程,可以让互相之间不会影响,服务不会中断,降低了风险

7
处理请求方式[/b]

nginx采用了异步非阻塞的方式来处理请求

apache的常用工作方式(apache也有异步非阻塞版本,但因其与自带某些模块冲突,所以不常用),每个请求会独占一个工作线程,当并发数上到几千时,就同时有几千的线程在处理请求了。这对操作系统来说,是个不小的挑战,线程带来的内存占用非常大,线程的上下文切换带来的cpu开销很大,自然性能就上不去了,而这些开销完全是没有意义的。

ngnix高效率原因:首先,请求过来,要建立连接,然后再接收数据,接收数据后,再发送数据。具体到系统底层,就是读写事件,而当读写事件没有准备好时,必然不可操作,如果不用非阻塞的方式来调用,那就得阻塞调用了,事件没有准备好,那就只能等了,等事件准备好了,你再继续吧。阻塞调用会进入内核等待,cpu就会让出去给别人用了,对单线程的worker来说,显然不合适,当网络事件越多时,大家都在等待呢,cpu空闲下来没人用,cpu利用率自然上不去了,更别谈高并发了。好吧,你说加进程数,这跟apache的线程模型有什么区别,注意,别增加无谓的上下文切换。所以,在nginx里面,最忌讳阻塞的系统调用了。不要阻塞,那就非阻塞喽。非阻塞就是,事件没有准备好,马上返回EAGAIN,告诉你,事件还没准备好呢,你慌什么,过会再来吧。好吧,你过一会,再来检查一下事件,直到事件准备好了为止,在这期间,你就可以先去做其它事情,然后再来看看事件好了没。虽然不阻塞了,但你得不时地过来检查一下事件的状态,你可以做更多的事情了,但带来的开销也是不小的。所以,才会有了异步非阻塞的事件处理机制,具体到系统调用就是像select/poll/epoll/kqueue这样的系统调用。它们提供了一种机制,让你可以同时监控多个事件,调用他们是阻塞的,但可以设置超时时间,在超时时间之内,如果有事件准备好了,就返回。这种机制正好解决了我们上面的两个问题,拿epoll为例(在后面的例子中,我们多以epoll为例子,以代表这一类函数),当事件没准备好时,放到epoll里面,事件准备好了,我们就去读写,当读写返回EAGAIN时,我们将它再次加入到epoll里面。这样,只要有事件准备好了,我们就去处理它,只有当所有事件都没准备好时,才在epoll里面等着。这样,我们就可以并发处理大量的并发了,当然,这里的并发请求,是指未处理完的请求,线程只有一个,所以同时能处理的请求当然只有一个了,只是在请求间进行不断地切换而已,切换也是因为异步事件未准备好,而主动让出的。这里的切换是没有任何代价,你可以理解为循环处理多个准备好的事件,事实上就是这样的。与多线程相比,这种事件处理方式是有很大的优势的,不需要创建线程,每个请求占用的内存也很少,没有上下文切换,事件处理非常的轻量级。并发数再多也不会导致无谓的资源浪费(上下文切换)。更多的并发数,只是会占用更多的内存而已。
我之前有对连接数进行过测试,在24G内存的机器上,处理的并发请求数达到过200万。现在的网络服务器基本都采用这种方式,这也是nginx性能高效的主要原因

8 cpu亲缘性的绑定[/b]

设置worker的个数为cpu的核数,更多的worker数,只会导致进程来竞争cpu资源从而带来不必要的上下文切换。cpu亲缘性的绑定:将某一个进程绑定在某一个核上,这样就不会因为进程的切换带来cache的失效

小优化eg:

nginx在做4个字节的字符串比较时,会将4个字符转换成一个int型,再作比较,以减少cpu的指令数

9
安装常见问题[/b]

命令:fuser

10
跳转方式[/b]

1)rewrite

2)proxy(可以增加参数,进行基本的过滤筛选,可以自定义return页面)

3)return

11 反向代理[/b]

1)加快访问(缓存机制)

2)实现负载均衡(master--worker)

3)

12 正向代理[/b]

[/b]

13 集群服务器[/b]

weight
权重(总数是所有服务器数量)

(摘自官方文档)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: