网站首页 > 技术教程 正文
Nginx是一个高性能的静态HTTP服务器和反向代理服务器,Nginx本身不支持现在流行的 JSP、ASP、PHP等动态页面,但是它可以通过反向代理将请求发送到后端的服务器,例如 Tomcat、Apache等来完成动态页面的请求处理。
结合Nginx开发从入门到精通一书和Nginx源码学习服务器的高并发处理。
服务器的架构大同小异,而性能的差异主要来自对数据的处理方式上,也即进程模型和事件模型上。一个客户端请求的数据如何进行接收、存储、解析、返回是服务器做的最主要的工作。
##源码文件结构 源码位于src目录下,分为七个部分。
├── core #core module代码,nginx服务入口 ├── event #事件处理逻辑的封装 ├── http #作为web/http/proxy server运行时核心模块 ├── mail #作为pop3/imap/smtp proxy server核心模块 ├── misc #一些utils,定义test个profiler外围模块逻辑 ├── os #对各个平台抽象逻辑的封装 └── stream #
最基础的数据结构
C++之所以不被用来写网站是因为,网站的核心是处理字符串。而C++的字符串处理实在比较弱,还要不断惦记GC和内存泄漏。
而Nginx首先封装了一下字符串的数据结构和API。定义位于nginx/src/core/nginx_string.h中。
typedef struct { size_t len; u_char *data; } ngx_str_t;
Nginx中一个字符串被表示为指针data指示首地址+len指示长度的方式,这种方式唯一定位一个字符串。和标准的glibc API用\0的方式标识字符串结束不同,它有很多好处。
- 通过长度表示字符串长度,减少计算字符串长度的步骤
- 可以重复引用一段字符串内存,减少不必要的内存分配
这样的表示是不是似曾相识?在Redis的sds中有类似的处理。
struct sdshdr { unsigned int len; unsigned int free; char buf[]; };
再看看它的API,API以宏的方式定义。
#define ngx_string(str) { sizeof(str) - 1, (u_char *) str }
#define ngx_null_string { 0, NULL }
#define ngx_str_set(str, text) \
(str)->len = sizeof(text) - 1; (str)->data = (u_char *) text
#define ngx_str_null(str) (str)->len = 0; (str)->data = NULL
第一个宏定义一个nginx的字符串,用法是
int main() { ngx_str_t stringA = ngx_string("Stop"); printf("len: %d \n", stringA.len); printf("address: %p \n", stringA.data); char* p = (char*)("HELLO WORLD"); printf("address: %p \n", p); printf("string %s \n", p); return 0; }
这里直接是宏展开,对结构体进行赋值。先生成了一个临时变量"stop",然后把临时变量的长度和地址赋值给结构体。ngx_string与ngx_null_string是{,}格式的,而结构体只能在初始化时进行整体赋值,因而API只能用于赋值时初始化。还需要注意str必须是常量字符串,因为sizeof是以\0为结束标志的。
打印结果
len: 4 address: 0x8048530 address: 0x804854d string HELLO WORLD
内存管理池ngx_pool_t
ngx_pool_t是一个资源管理池。它提供一种机制帮助管理一系列的资源(如内存、文件等),接管这些资源的所有权,负责资源的使用和释放。类似于C++中的shared_ptr智能指针。
ngx_pool_t定义在文件nginx/src/core/ngx_palloc.h中,相关的内存分配函数(如ngx_alloc)定义在nginx/src/os/unix/ngx_alloc.h中。
typedef struct ngx_pool_s ngx_pool_t; //core.h中 struct ngx_pool_s { ngx_pool_data_t d; size_t max; ngx_pool_t *current; ngx_chain_t *chain; ngx_pool_large_t *large; ngx_pool_cleanup_t *cleanup; ngx_log_t *log; };
ngx_pool_data_t指示资源池数据块的位置信息。
size_t是数据块的最大值
整个内存管理如图所示:
再看一下相关的API函数。
- ngx_alloc使用malloc进行内存分配,同时把错误信息写到log文件。
void * ngx_alloc(size_t size, ngx_log_t *log) { void *p; p = malloc(size); if (p == NULL) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "malloc(%uz) failed", size); } ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, log, 0, "malloc: %p:%uz", p, size); return p; }
- ngx_create_pool使用posix_memalign()申请大小为NGX_POOL_ALIGNMENT字节对其的内存。
ngx_pool_t * ngx_create_pool(size_t size, ngx_log_t *log) { ngx_pool_t *p; p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log); if (p == NULL) { return NULL; } p->d.last = (u_char *) p + sizeof(ngx_pool_t); p->d.end = (u_char *) p + size; p->d.next = NULL; p->d.failed = 0; size = size - sizeof(ngx_pool_t); p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? \ size : NGX_MAX_ALLOC_FROM_POOL; p->current = p; p->chain = NULL; p->large = NULL; p->cleanup = NULL; p->log = log; return p; }
p->d.last位移ngx_pool_t大小指向数据区段未使用部分的开始。
p->d.last指向数据区段未使用部分的结束。
可见分配的size大小的内存一部分要分给ngx_pool_t结构。
p->max表示分配的最大内存为NGX_MAX_ALLOC_FROM_POOL。
#define NGX_MAX_ALLOC_FROM_POOL (ngx_pagesize -1) ngx_pagesize = getpagesize();
最大限制为一个分页大小,在x86上其返回值应为4096Bytes = 4KB。
零声学院专门整理了《互联网后端架构师技术大纲》,有兴趣的同学可以关注私信我!更多免费学习资料等你来取。欢迎大家点赞、转发、关注!
猜你喜欢
- 2024-10-12 推荐一个计算机电子书免费下载开源项目
- 2024-10-12 「妙手数评」给数据工程师推荐5本书
- 2024-10-12 故宫订票系统崩了,7本书告诉你怎样让网站挺住
- 2024-10-12 Java工程师成神之路:程序员的学习路线规划以及书籍推荐
- 2024-10-12 Java工程师成神之路:进阶架构师的学习路线规划以及书籍推荐
- 2024-10-12 书籍管理系统源代码及开发文档和演示视频JavaEE框架与应用开发课
- 2024-10-12 推荐10部嵌入式Linux开发有关的电子书
- 2024-10-12 周日福利!分享一本nginx宝典:Nginx教程从入门到精通
- 2024-10-12 Java架构师进阶必看书单:JVM+Redis+Nginx+Tomact+Spring
- 2024-10-12 Java相关免费编程书籍推荐(都是PDF版)
你 发表评论:
欢迎- 最近发表
-
- Win10 TH2正式版官方ESD映像转换ISO镜像方法详解
- 使用iso镜像升级到Windows 10的步骤
- macOS Ventura 13.2 (22D49) Boot ISO 原版可引导镜像
- 安利一个用ISO镜像文件制作引导U盘的的小工具RUFUS
- CentOS 7使用ISO镜像配置本地yum源
- 用于x86平台的安卓9.0 ISO镜像发布下载:通吃I/A/N、完全免费
- AlmaLinux 9.6发布:升级工具、初步支持IBM Power虚拟化技术
- Rufus写入工具简洁介绍与教程(写入模式)
- 新硬件也能安装使用了,Edge版Linux Mint 21.3镜像发布
- 开源工程师:Ubuntu应该抛弃32位ISO镜像
- 标签列表
-
- 下划线是什么 (87)
- 精美网站 (58)
- qq登录界面 (90)
- nginx 命令 (82)
- nginx .http (73)
- nginx lua (70)
- nginx 重定向 (68)
- Nginx超时 (65)
- nginx 监控 (57)
- odbc (59)
- rar密码破解工具 (62)
- annotation (71)
- 红黑树 (57)
- 智力题 (62)
- php空间申请 (61)
- 按键精灵 注册码 (69)
- 软件测试报告 (59)
- ntcreatefile (64)
- 闪动文字 (56)
- guid (66)
- abap (63)
- mpeg 2 (65)
- column (63)
- dreamweaver教程 (57)
- excel行列转换 (56)
本文暂时没有评论,来添加一个吧(●'◡'●)