nginx buffer机制
buffer机制,请求缓冲区在nginx处理请求中起着重要作用,接收到请求时,nginx将其写入这些缓冲区,缓冲区数据可作为nginx变量使用。
如果缓冲区大小比请求大小小一些,则将数据存入磁盘文件上,因此将涉及IO操作。
对于来自于FastCGI Server的Response,Nginx将其缓冲到内存中,然后依次发送到客户端浏览器,缓冲区大小可以通过fastcgi_buffers和fastcgi_buffer_size配置。
Buffer size优化
buffer大小时需要调优的重要参数,如果buffer size太小会导致nginx使用文件存储response,会引起磁盘IO,流量越大问题越严重。
client_body_buffer_size处理客户端请求体buffer大小。用来处理post提交数据,上传文件等。client_body_buffer_size需要足够大以容纳需要上传的POST数据。
Fastcgi_buffers,proxy_buffers处理后端响应,如果这个buffer不够大,同样会引起磁盘IO。
共享内存
在linux中为了实现进程间通信方式,一般通过mmap或者shmget系统调用在内存中创建一块连续的线性地址空间,使用munmap或者shmdt系统调用可以释放这块内存。
使用共享内存的好处是:当多个进程使用同一块共享内存时,在任何一个进程中修改了共享内存内容,其他进程通过访问这段共享内存能够得到修改后的内容。
nginx是多进程的,有一些全局变量,nginx希望所有进程都可以共享这些变量,共享变量实现有几种方案:
1. mmap匿名映射
2. 尝试将mmap映射到/dev/zero上
3. 尝试使用共享内存shmget从内存中申请一个内存区域
4. 如果不支持原子操作,使用文件锁实现多进程环境下加锁
从性能考虑,优先使用mmap匿名映射。
nginx如何使用共享内存?
默认情况下,通过fork派生的子进程并不与其父进程共享内存区。但master和worker进程是父子进程,该怎么办呢?
解决方法就是mmap的flags参数,master进程在调用fork之前制定flags为MAP_SHARED来调用mmap,POSIX保证父进程中的内存映射关系时存留到子进程中,父进程对共享内存的所有修改都可以在子进程中看到,反过来也一样。
所以是:
master进程在内存中以MAP_SHARD方式开辟一块共享内存,并映射到自己进程地址空间中的共享内存区
master调用fork,派生出子进程,可以在其自己地址空间内继承这块共享内存区域,解决了问题