vscode调试nginx源码
clone源码
- bash
1 | git clone https://github.com/nginx/nginx |
除了官方的nginx,也可以考虑用阿里的Tengine或OpenResty。
这两个发行版添加了各自的三方module。
编译运行
修改 /auto/cc/conf 文件,将ngx_compile_opt=”-c” 修改为 ngx_compile_opt=”-c -g”
-g
用来生成调试信息:详见gcc文档执行 sudo ./auto/configure –prefix=nginx工程目录 ,如果遇到错误 “the HTTP rewrite module requires the PCRE library”,说明少了用来匹配正则表达式的
pcre
依赖包,可以自行根据平台进行安装- Debein
- MacOS
- CentOS
1
apt install pcre2-utils
执行 sudo make
执行 ./objs/nginx,打开浏览器访问下 127.0.0.1,没问题的话就可以看到Nginx的欢迎界面了。
具体源码编译内容可以参考nginx文档
Nginx的多进程架构
nginx是多进程架构:一个Master进程,若干个Worker进程。
Master进程负责管理 Worker 进程,处理nginx命令行指令
Worker进程负责接收处理客户端请求
Worker进程数通常设置成CPU核数,worker_processes: auto;
可以自动检查CPU设置成核心数。
Worker进程和redis类似使用单线程+IO多路复用实现高并发处理IO请求。
Master进程调试
修改
/conf/nginx.conf
- nginx
1
2
3
4# 关闭Master守护进程的功能
daemon off;
# 便于调试只启动一个Worker进程
worker_processes 1;daemon默认都是
on
,开发阶段关闭添加VSCODE调试配置
- JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/objs/nginx",
"args": [
"-c",
"${workspaceFolder}/conf/nginx.conf"
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}如果是MacOS,不愿意装
gdb
,也可以用llvm的lldb
进行调试。具体配置可以参考vscode文档打断点,Debug起来
调试Worker进程
查看 Worker 进程pid
- bash
1
ps aux | grep nginx
编辑
launch.json
,Attach到worker进程- json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15{
"version": "0.2.0",
"configurations": [
/* ... */
{
"name": "(gdb) Attach Worker",
"type": "cppdbg",
"request": "attach",
"program": "${workspaceFolder}/objs/nginx",
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb",
"processId": "9133"
}
]
}这里的进程id填进去就行了
切换到
Attach Worker
接受请求的地方打个断点,浏览器重新刷新一下,请求就进来了
从函数堆栈中,可以看到请求的处理过程
关闭Nginx多进程模式
启动两个进程的方式debug确实挺麻烦的,nginx提供了配置关闭多进程架构,这样就可以在一个进程里对nginx的整个流程进行debug了,避免上面繁琐的配置。
只需要在nginx.conf
文件中把daemon
和master_process
设成off
即可。
- nginx
1 | # 关闭Master守护进程的功能 |
ReadMore: https://github.com/agile6v/awesome-nginx