nginx源代码分析

nginx使用epoll来处理accept事件,所有会有epoll惊群问题,


ngx_accept_disabled = ngx_cycle-connection_n / 8 - ngx_cycle-free_connection_n; 这个变量是禁用accept,就是现在的连接数比较多
ngx_use_accept_mutex全局变量为1,才开启避免惊群的现象

ngx_use_accept_mutex = 1;的条件是ccf-master ccf-worker_processes 1 ecf-accept_mutex
对应的配置是在event block下面accept_mutex on;

在ngx_event_process_init函数中如果ngx_use_accept_mutex开启,则不会将fd加入本worker进程的epoll
在worker进程的大循环,ngx_process_events_and_timers函数在,如果ngx_use_accept_mutex开启,则所有进程都会去得到ngx_accept_mutex
得到的把listen的fd加到本进程的epoll中,其他的都移除。

这个锁是放在共享内存上的
cl = 128;/* cl should be equal to or greater than cache line size */
size = cl            /* ngx_accept_mutex */
           + cl          /* ngx_connection_counter */
           + cl;         /* ngx_temp_number */

NGX_HAVE_MAP_ANON
shm-addr = (u_char *) mmap(NULL, shm-size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0);
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

全局变量ngx_accept_mutex_ptr保存了这一地址,这是个内核地址,所有进程都可以访问,也就成共享内存了
ngx_shmtx_sh_t只有16字节,却分配了128字节
全局变量ngx_accept_mutex-lock = addr-lock
全局变量是指每个进程的,但是每个进程的这个变量都指向内核同一地址
(gdb) p  ngx_accept_mutex-lock
$1 = (ngx_atomic_t *) 0x7ffff7ff5000
(gdb) p  *ngx_accept_mutex-lock
$2 = 0

(void) ngx_atomic_cmp_set(ngx_connection_counter, 0, 1); 设置ngx_connection_counter = 1
           
锁的名字/home/liuwb/Desktop/code/nginx-code/logs/nginx.lock.accept
*mtx-lock == 0 ngx_atomic_cmp_set(mtx-lock, 0, ngx_pid) 如果mtx-lock == 0,将mtx-lock的值设为ngx_pid,返回1
将ngx_pid的值设在mtx-lock中,是这个worker的pid

ngx_accept_events = 0;
ngx_accept_mutex_held = 1;表示该进程不会拿到锁


最新回复(0)
/jishuY933jiy0CAJLM7w4Vr_2Fybnoel0GPnxAJ5jrgeQ8FjEc_3D4794559
8 简首页