nginx 为什么这么快

秒速五厘米 2022-11-09 12:43 391阅读 0赞

nginx 架构1介绍及常见的问题
nginx 架构2
nginx 架构3

上面三篇讲的都可以。

问题

  1. 为什么不采用多线程模型管理连接?

无状态服务,无需共享进程内存
采用独立的进程,可以让互相之间不会影响。一个进程异常崩溃,其他进程的服务不会中断,提升了架构的可靠性。
进程之间不共享资源,不需要加锁,所以省掉了锁带来的开销。

  1. 为什么不采用多线程处理逻辑业务?

进程数已经等于核心数,再新建线程处理任务,只会抢占现有进程,增加切换代价。
作为接入层,基本上都是数据转发业务,网络IO任务的等待耗时部分,已经被处理为非阻塞/全异步/事件驱动模式,在没有更多CPU的情况下,再利用多线程处理,意义不大。并且如果进程中有阻塞的处理逻辑,应该由各个业务进行解决,比如openResty中利用了Lua协程,对阻塞业务进行了优化。

  1. 惊群是什么? nginx是如何处理的?

由于worker都是由master进程fork产生,所以worker都会监听相同端口。这样多个子进程在accept建立连接时会发生争抢,带来著名的“惊群”问题。

解决方法:

1)将连接事件与读写事件进行分离。连接事件存放为ngx_posted_accept_events,读写事件存放为ngx_posted_events。

2)设置ngx_accept_mutex锁,只有获得锁的进程,才可以处理连接事件。

配置文件中开启或者关闭

events {
accept_mutex off;
}

为什么关闭?

  1. OS may wake all processes waiting on accept() and select(), this is called thundering herd problem.
  2. This is a problem if you have a lot of workers as in Apache (hundreds and more), but this insensible
  3. if you have just several workers as nginx usually has. Therefore turning accept_mutex off is as
  4. scheduling incoming connection by OS via select/kqueue/epoll/etc (but not accept()).

简单点说:Apache动辄就会启动成百上千的进程,如果发生惊群问题的话,影响相对较大;但是对Nginx而言,一般来说,worker_processes会设置成CPU个数,所以最多也就几十个,即便发生惊群问题的话,影响相对也较小。

另:高版本的Linux中,accept不存在惊群问题,不过epoll_wait等操作还有。

  1. 负载均衡什么时候触发?

Worker间的负载关键在于各自接入了多少连接,其中接入连接抢锁的前置条件是ngx_accept_disabled > 0,所以ngx_accept_disabled就是负载均衡机制实现的关键阈值。

  1. ngx_int_t ngx_accept_disabled;
  2. ngx_accept_disabled = ngx_cycle->connection_n / 8 - ngx_cycle->free_connection_n;

connection_n : 为nginx配置文件中最大连接数
free_connection_n : 未连接数

因此,在nginx启动时,ngx_accept_disabled的值就是一个负数,其值为连接总数的7/8。当该进程的连接数达到总连接数的7/8时,该进程就不会再处理新的连接了。

同时每次调用ngx_process_events_and_timers时,将ngx_accept_disabled减1,直到其值低于阈值时,才试图重新处理新的连接。

因此,nginx各worker子进程间的负载均衡仅在某个worker进程处理的连接数达到它最大处理总数的7/8时才会触发,其负载均衡并不是在任意条件都满足

发表评论

表情:
评论列表 (有 0 条评论,391人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Kafka为什么这么

    Kafka 是一个基于发布-订阅模式的消息系统,它可以在多个生产者和消费者之间传递大量的数据。Kafka 的一个显著特点是它的高吞吐率,即每秒可以处理百万级别的消息。那么 Ka

    相关 Redis为什么这么

    Redis为什么这么快 1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是