1. nginx的负载均衡算法有哪些?
Nginx的upstream模块支持6种方式的负载均衡策略(算法):轮询(默认方式)、weight(权重方式)、ip_hash(依据ip分配方式)、least_conn(最少连接方式)、fair(第三方提供的响应时间方式)、url_hash(第三方通过的依据URL分配方式)。
2. ngxin的作用
web 服务.
负载均衡 (反向代理)
web cache(web 缓存)
动静分离
3. nginx的优点:
模块化、事件驱动、异步、非阻塞、多进程单线程
高并发。静态小文件
占用资源少。2万并发、10个线程,内存消耗几百M。
功能种类比较多。web,cache,proxy。每一个功能都不是特别强。
支持epoll模型,使得nginx可以支持高并发。
nginx 配合动态服务和Apache有区别。(FASTCGI 接口)
利用nginx可以对IP限速,可以限制连接数。
配置简单,更灵活。
4. nginx为什么抗高并发
Nginx的高并发得益于其采用了epoll模型
nginx采用epoll模型,异步非阻塞。对于Nginx来说,把一个完整的连接请求处理都划分成了事件,一个一个的事件。比如accept(), recv(),磁盘I/O,send()等,每部分都有相应的模块去处理,一个完整的请求可能是由几百个模块去处理。真正核心的就是事件收集和分发模块,这就是管理所有模块的核心。只有核心模块的调度才能让对应的模块占用CPU资源,从而处理请求。拿一个HTTP请求来说,首先在事件收集分发模块注册感兴趣的监听事件,注册好之后不阻塞直接返回,接下来就不需要再管了,等待有连接来了内核会通知你(epoll的轮询会告诉进程),cpu就可以处理其他事情去了。一旦有请求来,那么对整个请求分配相应的上下文(其实已经预先分配好),这时候再注册新的感兴趣的事件(read函数),同样客户端数据来了内核会自动通知进程可以去读数据了,读了数据之后就是解析,解析完后去磁盘找资源(I/O),一旦I/O完成会通知进程,进程开始给客户端发回数据send(),这时候也不是阻塞的,调用后就等内核发回通知发送的结果就行。整个下来把一个请求分成了很多个阶段,每个阶段都到很多模块去注册,然后处理,都是异步非阻塞。异步这里指的就是做一个事情,不需要等返回结果,做好了会自动通知你。
5. 为什么nginx的总体性能比Apache高?
nginx使用最新的epoll和kqueue网络IO模型,而Apache使用传统的select模式。
目前Linux下能够承受高并发访问的squid、Memcached 都采用的是epoll网络IO模型。
6. nginx如何处理请求?
nginx在启动时会以daemon形式在后台运行,采用多进程+异步非阻塞IO事件模型来处理各种连接请求。多进程模型包括一个master进程,多个worker进程,一般worker进程个数是根据服务器CPU核数来决定的。master进程负责管理Nginx本身和其他worker进程
在nginx多进程中,每个worker都是平等的,因此每个进程处理外部请求的机会权重都是一致的。
Master进程读取并验证配置文件nginx.conf;管理worker进程;而每一个Worker进程都维护一个线程(避免线程切换),处理连接和请求;注意Worker进程的个数由配置文件决定,一般和CPU个数相关(有利于进程切换),配置几个就有几个Worker进程。worker进程中有一个ngx_worker_process_cycle()函数,执行无限循环,不断处理收到的来自客户端的请求,并进行处理,那就要讲讲多进程模型的处理流程了。
7. nginx多进程模式的处理流程
首先,master进程一开始就会根据我们的配置,来建立需要listen的网络socket fd,然后fork出多个worker进程。
其次,根据进程的特性,新建立的worker进程,也会和master进程一样,具有相同的设置。因此,其也会去监听相同ip端口的套接字socket fd。
然后,这个时候有多个worker进程都在监听同样设置的socket fd,意味着当有一个请求进来的时候,所有的worker都会感知到。这样就会产生所谓的“惊群现象”。为了保证只会有一个进程成功注册到listenfd的读事件,nginx中实现了一个“accept_mutex”类似互斥锁,只有获取到这个锁的进程,才可以去注册读事件。其他进程全部accept 失败。
最后,监听成功的worker进程,读取请求,解析处理,响应数据返回给客户端,断开连接,结束。因此,一个request请求,只需要worker进程就可以完成。
多进程模型的好处是进程之间独立,有一个worker坏了也不会影响逼得worker瘫痪
nginx还会将进程和cpu某一个核绑定,避免因为进程切换带来的缓存失效
8. 为什么要采用异步非阻塞?
多进程模型+异步非阻塞模型才是胜出的方案。单纯的多进程模型会导致连接并发数量的降低,而采用异步非阻塞IO模型很好的解决了这个问题;并且还因此避免的多线程的上下文切换导致的性能损失。
9. 如何避免所有的请求都被一个worker进程给竞争获取了
Nginx采用了一个是否打开accept_mutex选项的值,ngx_accept_disabled标识控制一个worker进程是否需要去竞争获取accept_mutex选项,进而获取accept事件
ngx_accept_disabled值:nginx单进程的所有连接总数的八分之一,减去剩下的空闲连接数量,得到的这个ngx_accept_disabled。
当ngx_accept_disabled大于0时,不会去尝试获取accept_mutex锁,并且将ngx_accept_disabled减1,于是,每次执行到此处时,都会去减1,直到小于0。不去获取accept_mutex锁,就是等于让出获取连接的机会,很显然可以看出,当空闲连接越少时,ngx_accept_disable越大,于是让出的机会就越多,这样其它进程获取锁的机会也就越大。不去accept,自己的连接就控制下来了,其它进程的连接池就会得到利用,这样,nginx就控制了多进程间连接的平衡了。
10. nginx挂了怎么办?
Keepalived+Nginx实现高可用,Keepalived是一个高可用解决方案,主要是用来防止服务器单点发生故障,可以通过和Nginx配合来实现Web服务的高可用。
第一:请求不要直接打到Nginx上,应该先通过Keepalived(这就是所谓虚拟IP,VIP)
第二:Keepalived应该能监控Nginx的生命状态(提供一个用户自定义的脚本,定期检查Nginx进程状态,进行权重变化,,从而实现Nginx故障切换)
修改配置文件nginx.conf后,重新生成新的worker进程,当然会以新的配置进行处理请求,而且新的请求必须都交给新的worker进程,至于老的worker进程,等把那些以前的请求处理完毕后,kill掉即可。