nginx配置解析之缓冲区管理
nginx服务器的master进程在解析nginx.conf时,会使用一个4k大小的缓存区存放部分配置文件信息。nginx会从配置文件中读取4k大小的内容到缓冲区,之后对缓冲区中的内容进行逐个字符扫描,从而解析出配置项、配置值。例如server_name 127.0.0.1; 则逐个字符扫描得到配置项server_name, 配置值127.0.0.1。当然nginx不会每次都去读取文件,而是读取4k大小的内容到缓冲区中,然后对缓冲区的内容进行解析。如果缓冲区的内容都解析完了,才会从配置文件中重新读取4k大小的内容到缓冲区中。
因此这个缓冲区可以被重复利用。那为什么不一次性读取配置文件中的所有内容到缓冲区,然后对缓冲区的内容进行解析呢? 因为在极端情况下,如果nginx.conf内容非常大,例如超过1G,则把这1G内容一次性读取到内容缓冲区中,太占用内存资源。因此为了解决配置文件过大问题,使用一个4K的缓冲区进行管理,限制每次读取到缓冲区数据大小。 以下是缓冲区可能存在的几种状态。
一、开始解析配置时,ngx_conf_parse函数会从配置中读取4K大小的内容内容到缓冲(前提是nginx.conf配置文件大小超过4k)。函数调用后内存布局如下,缓冲区的数据全部为待解析数据,pos,start指向缓冲区的开始位置;last,end指向缓冲区的结束位置。接下里nginx会对这个缓冲区中的数据进行解析,从而获取到配置项、配置值。
二、当nginx解析完一部分数据后,一部分数据已经解析成“配置项 配置值;"了,另一部分数据则已经扫描到了,但不足以组装成一行数据(也就是配置项 配置值;); 还有一部分则表示完全没有扫描到。
已解析数据: 这部分的数据表示已经能够组装成一各个独立行数据,也就是("配置项 配置值;")格式。例如:
work_process 2;
error_log logs/error.log;
这部分已解析数据已经保存到了ngx_conf_s结构中的args数组中了,因此这部分空间可以被重新利用。
已扫描数据: 这部分数据表示不能够组装成一个个独立行数据,也就是("配置项 配置值;")格式。例如:本来一个完整的行格式为:worker_connections 1024;
但实际上只解析到了worker_conectio这一小部分数据,因此不能构成一个完整的格式。这部分数据称为已扫描数据,还不能被删除。nginx使用了局部变量start,start与pos之间的这部分数据就是已扫描数据。
未扫描数据: 这部分数据表示nginx还没有解析到这部分数据,pos与last之间的这部分数据称为未扫描数据。
三、当缓冲区里的字符都处理完成时,需要从配置文件中读取新的内容到缓冲区中,此时的临界状态为:
四、已解析的数据已经保存到数组中了,在缓存中没有意义了。这部分数据可以被删除。而start与pos之间这部分数据,由于还不能为组装成一个完成的格式,因此还不能被删除。但由于缓冲期已经解析完了,因此需要从配置文件中读取新的数据到缓冲区中。此时需要把这部分已经扫描的数据移动到缓冲区最开始的位置。然后从配置文件中读取新数据到这个已扫描缓冲区之后。
如果配置文件剩余数据没有4K大小,也就是读取后的内容不能填满整个缓冲区。那这种场景下缓冲区布局如下,此时空白空域表示缓冲区未满。
以上是在解析nginx.conf配置文件时,可能存在的5种缓冲区状态。在理清了配置文件在缓冲区中的内存布局后,接下来分析nginx如何解析配置文件就相对容易些了。ngx_conf_parse函数是解析配置文件的入口,内部会调用ngx_conf_read_token函数,这个函数负责从配置文件中读取数据到缓冲区,以及对缓冲区中的数据进行扫描得到完整的"配置项 配置值;"格式的内容;以下代码片段就是上面5种可能的缓冲区内存布局的代码实现。
ngx_int_t ngx_conf_read_token(ngx_conf_t *cf)
{for(;;){//是否需要从配置文件读取配置到缓冲区条件。也就是缓冲区的所有内容都已经被扫描到了。//一部分数据已经解析为配置项配置值格式。 另一部分扫描到了,但还没解析为配置项配置值格式。//说明缓冲区内容已经不能够组装完整的配置项配置值内容格式,需要从文件中读取数据到缓冲区if (b->pos >= b->last) {if (cf->conf_file->file.offset >= file_size) {//如果文件已经读取完成,但数组中参数个数不为0,说明配置文件格式错误。//因为每解析完一行配置,会把数组中的参数保存到内容结构中。之后会把这个参数数组元素清空。//以便存放下一行解析出的参数信息。文件都结束了,但数组元素还存在,说明配置有误if (cf->args->nelts > 0) {if (cf->conf_file->file.fd == NGX_INVALID_FILE) {return NGX_ERROR;}return NGX_ERROR;}return NGX_CONF_FILE_DONE;}//len长度的空间表示已经扫描完成,但没有解析成一个个配置项配置值格式//start为局部变量(pos与start之间的数据为已扫描数据)len = b->pos - start;//已经扫描但未组装成一个配置项配置值格式的内容。说明这一行长度太大了。配置有问题if (len == NGX_CONF_BUFFER) {cf->conf_file->line = start_line;return NGX_ERROR;}//len表示上一次读取后,还有多少内容未解析。并将这些未解析的内容移动到缓冲区头部//下一次读取的内容就可以放到缓冲区的len长度后面if (len) {ngx_memmove(b->start, start, len);}//计算配置文件剩余大小size = (ssize_t) (file_size - cf->conf_file->file.offset);//每一次最多读取多少字节内容,如果文件很大,大于缓冲区4096大小,则每次最多//从文件中读取4096字节的内容if (size > b->end - (b->start + len)) {size = b->end - (b->start + len);}//从文件中读取数据到缓冲区n = ngx_read_file(&cf->conf_file->file, b->start + len, size,cf->conf_file->file.offset);b->pos = b->start + len;b->last = b->pos + n;start = b->start;}}
}
nginx配置解析之缓冲区管理相关推荐
- nginx配置解析流程
上一篇文章分析了nginx配置文件缓冲区的管理,接下来将详细分析nginx是如何解析配置文件的.包含模块上下文结构的创建.core核心模块的解析.event事件模块的解析.http模块的解析. 一.模 ...
- nginx配置解析之配置合并
上一篇文章分析了nginx.conf配置解析流程,解析完成后会把各个配置项存放到各个模块的上下文结构中.但此时还没有对http模块.server模块.location模块公共部分进行合并处理.所谓的合 ...
- Linux之Nginx配置解析PHP
location ~ \.php${include fastcgi_params;fastcgi_pass unix:/tmp/php-fcgi.sock;fastcgi_index index.ph ...
- nginx html解析插件,nginx配置信息的解析流程
nginx配置信息的解析流程 2011年9月9日 1,744 次浏览 请关注最新修正合订: 这一系列的文章还是在09年写的,存在电脑里很久了,现在贴出来.顺序也不记得了,看到那个就发那个吧,最近都会发 ...
- Nginx 配置实现web解析php代码 过程记录
[Nginx配置] Nginx本身不支持对php的解析,需要将php代码转发到php-fpm 进程管理器来交给php解析器解析代码. 重要的配置注意注释位置: user www www; # 用户 用 ...
- 三、nginx服务的nginx.conf的参数配置解析
前一篇:二.nginx服务的nginx.conf配置参数解析 后一篇:四.nginx服务器的参数配置解析 目录 一.虚拟主机设定模块 1.upstream模块配置样式 1.1.默认配置 1.2.wei ...
- nginx配置防止域名恶意解析
前几发生一件事情,就是通过nginx日志发现有一个域名恶意指向到了我的服务器,大家可以去查查域名恶意解析可能会造成的危害.由于我是用的nginx配置了一个反向代理,所以直接配置nginx就可以实现域名 ...
- Nginx配置后无法解析PHP问题
配置Nginx服务器之后,打开域名,是直接下载而不是直接打开网页,是因为配置的Nginx无法解析PHP的原因. 根据我出现的问题,我的解决办法如下: 1.打开nginx.conf配置文件, 那个127 ...
- Nginx 配置中一个不起眼字符 “/“ 的巨大作用
Nginx作为一个轻量级的,高性能的web服务软件,因其占有内存少,并发能力强的特点,而广受欢迎和使用.国内很多大型互联网公司也对Nginx很是青睐.像BAT(百度,阿里和腾讯),TMD(头条,美团和 ...
最新文章
- 3、Spring Cloud - Eureka(高可用Eureka Server集群)
- 爬取百度百科上中国所有城市的信息
- python工程师-Python工程师必看的面试问题与解答(中)
- axi ps读写pl_PL读写DDR:Datamover能干什么
- js正则限制字符串长度_正则笔记(3)万字长文,慎点。
- 2019.8.15几道练习题
- android 导入modoule_android studio如何创建一个子module并引入主工程
- 对项目的总结以及对这种教学方式的看法
- 扩展NameValueCollection
- 微信小程序开发常见的错误
- MATLAB中将数字转换成罗马数字
- [置顶] 而立之年——三线城市程序员的年终告白
- ESP8266-Arduino编程实例-OPT3001数字环境光传感器
- MTK 使用iptable 命令来完成网络路由(android WIFI/4G分享网络)
- web前端开发人员要求,css设置背景图片自适应
- 【Arduino+ESP32专题】PlatformIO串口监视器的默认波特率修改
- 10 EPC与物联网
- Postman工具的简单介绍
- PNG序列帧转webm格式视频播放时有白边问题
- 【ffmpeg】最全简单实用教程|安装音频视频剪切融合拼接抽帧等