nginx 编译运行
对 nginx 有一定了解之后,接下来把 nginx 运行环境搭建起来,以便我们更好地学习和理解。
nginx 的安装方式有很多,可以通过 apt
或 yum
方式直接安装对应的包程序。有时我们需要使用更新的版本,或需要更丰富的特性或配置,这种方式就满足不了。
对于想深入理解 nginx 的开发者来说,编译安装的方式可以让我们深入代码层面,学习理解会更加高效和透彻。
编译安装
系统环境
- 系统:
ubuntu 22.04.03
- 架构:
x64
安装依赖
- 安装编译工具
1 | apt-get update |
- 安装依赖包
1 | # 正则表达式库,用于处理 HTTP 请求 |
通过上述命令,可以安装 nginx 所需要的基本依赖包,安装完这些依赖包后,接下来就可以通过源码编译的方式进行安装了
编译安装
- 下载 nginx 源代码
1 | # 从官方下载源码包 |
- 执行编译配置
1 | ./configure --prefix=/usr/local/nginx \ |
--prefix
:指定安装目录--with-http_ssl_module
:支持 HTTPS--with-stream_ssl_module
:支持 TLS
- 执行编译和安装
1 | # 编译并安装 |
编译过程可能需要较长时间,请耐心等待,如果编译成功会看到如下信息
1 | nginx path prefix: "/usr/local/nginx" |
运行验证
安装完毕后,可以先看下 nginx 的版本信息,如果安装正常的话,可以看到如下信息
1 | $ /usr/local/nginx/sbin/nginx -v |
可以看到版本信息,接下来可以启动 nginx 了
1 | $ /usr/local/nginx/sbin/nginx |
执行 nginx 命令后,就启动了 nginx,确认 nginx 是否正常启动
1 | # 查看 nginx 进程 |
至此 nginx 成功安装
编译选项
在执行 make
命令时,首先执行了 configure
脚本,该脚本其实做了很多工作,其中一项就是编译选项和配置参数的设置。
configure
脚本支持很多选项,可以通过 --help
来查看,下面尝试总结梳理一些重要的选项参数:
路径相关参数
参数名称 | 意义 | 默认值 |
---|---|---|
–prefix=PATH | Nginx安装部署后的根目录 | /usr/local/nginx |
–sbin-path=PATH | 可执行文件的放置路径 | ${prefix}/sbin/nginx |
–conf-path=PATH | 配置文件的放置路径 | ${prefix}/conf/nginx.conf |
–error-log-path=PATH | 错误日志放置路径 | ${prefix}/logs/error.log |
–pid-path=PATH | pid文件的存放路径 | ${prefix}/logs/nginx.pid |
–lock-path=PATH | lock文件路径 | ${prefix}/logs/nginx.lock |
–builddir=DIR | 编译期间临时文件目录 | src/objs |
–http-log-path=PATH | 访问日志放置的位置 | ${prefix}/logs/access.log |
–http-client-body-temp-path=PATH | 请求缓存临时磁盘文件路径 | ${prefix}/client_body_temp |
–http-proxy-temp-path=PATH | 上游服务器产生临时存放磁盘位置 | ${prefix}/proxy_temp |
编译相关参数
编译参数 | 意义 |
---|---|
–with-cc=PATH | C 编译器的路径 |
–with-cpp=PATH | C++ 编译器的路径 |
–with-cc-opt=OPTIONS | 编译期增加编译选项,如指定宏或使用 -I 加入某些包含目录 |
–with-ld-opt=OPTIONS | 加入链接参数 |
–with-cpu-opt=CPU | 指定CPU处理架构 |
依赖软件参数
–without-pcre | –with-pcre=DIR |
---|---|
–with-pcre | –with-pcre-opt=OPTIONS |
–with-openssl=DIR | –with-openssl-opt=OPTIONS |
–with-libatomic | –with-libatomic=DIR |
–with-MD5=DIR | –with-MD5-opt=OPTIONS |
… | … |
模块相关参数
- 事件模块
--with-poll_module
--with-aio_module
... ...
- 默认编译进 nginx 的 http 模块
--without-http_gzip_module
--without-http_access_module
--without-http_auth_basic_module
--without-http_rewrite_module
... ...
- 默认不会编译进 nginx 的 http 模块
--with-http_ssl_module
--with-http_geoip_module
--with-http_gzip_static_module
... ...
- 邮件代理服务器相关的 mail 模块
--with-mail
--with-mail_ssl_module
... ...
- 其它参数
--with-debug
:开启调试选项--add-module=PATH
:指定三方模块--without-http
:关闭 http 功能--with-ipv6
:开启 IPv6
编译流程
make
命令根据 configure 命令生成的 Makefile 文件编译 nginx 工程,并生成目标文件、最终的二进制文件。
其实 configure
做了大量的幕后工作,包括检测操作系统内核和已经安装的软件,参数的解析,中间目录的生成以及根据各种参数生成一些 C 源码文件、Makefile 文件等。
. auto/options
处理 configure 命令的参数,options 脚本会定义后续工作将要用到的变量,根据本次参数以及默认值设置这些变量
. auto/init
脚本初始化后续将产生的文件路径,比如 Makefile、ngx_module.c 等文件默认情况下将会在 objs
. auto/sources
脚本将分析 nginx 源码结构,这样才能构造后续的 Makefile 文件
test -d $NGX_OBJS || mkdir $NGX_OBJS
编译过程中所有目标文件生成的路径由 –builddir=DIR 参数指定,默认情况下为 objs 此时这个目录将会被创建
- 创建必要编译文件
1 | echo > $NGX_AUTO_HEADERS_H |
开始准备建立 ngx_auto_headers.h、autoconf.err 等必要的编译文件
- 向
objs/ngx_auto_config.h
写入命令行带的参数
1 | echo "#define NGX_CONFIGURE \"$NGX_CONFIGURE\"" > $NGX_AUTO_CONFIG_H |
- 判断 DEBUG 标志,如果有向
objs/ngx_auto_config.h
文件写入 DEBUG 宏
1 | if [ $NGX_DEBUG = YES ]; then |
- 检查操作系统参数是否支持后续编译
1 | if test -z "$NGX_PLATFORM"; then |
. auto/cc/conf
检查并设置编译器,如 GCC 是否安装、GCC 版本是否支持后续编译 nginx
. auto/headers
对非 windows 操作系统定义一些必要的头文件,并检查其是否存在,以此决定 configure 后续步骤是否可以成功
. auto/os/conf
对于当前操作系统,定义一些特定的操作系统相关的方法并检查当前环境是否支持。例如,对于 Linux,在这里使用 sched_setaffinity 设置进程优先级,使用 Linux 特有的 sendfile 系统调用来加速向网络中发送文件块
. auto/unix
定义类 UNIX 操作系统中通用的头文件和系统调用等,并检查当前环境是否支持
. auto/modules
将会生成 ngx_module.c 文件,它定义了 ngx_modules 数组,会被编译进 nginx 中。
ngx_modules 指明 nginx 运行期间有哪些模块会参与到请求处理中,它对数组元素的顺序非常敏感。
另外,在 –add-module= 参数加入的第三方模块也在此步骤写入到 ngx_module.c 文件中了。
. auto/lib/conf
用来检查 nginx 在链接期间需要链接的第三方静态库、动态库或目标文件是否存在
- 处理 nginx 安装后的路径
1 | case ".$NGX_PREFIX" in |
- 处理 nginx 安装后的文件路径
1 | if [ ".$NGX_CONF_PREFIX" != "." ]; then |
. auto/make
创建编译时使用的 objs/Makefiel 文件
. auto/lib/make
为 objs/Makefile 加入需要连接的第三方静态库、动态库或目标文件
. auto/install
为 objs/Makefile 加入 install 功能
. auto/stubs
在 ngx_auto_config.h 文件中加入 NGX_SUPPRESS_WARN 宏、NGX_SMP 宏
. auto/summary
显示 configure 执行的结果,如果失败,则给出原因
- 执行 configure 成功后的文件与目录
1 | ├── configure # 编译配置脚本 |
其中 ngx_modules.c 是一个关键文件,默认配置下生成的 ngx_modules.c 文件内容如下:
1 |
|
ngx_modules 数组非常关键,它指明了每个模块在 nginx 中的优先级,对于 HTTP 模块而言,在 ngx_modules 数组中越是靠后的模块反而会首先处理 HTTP 响应
磁盘目录
make install
命令根据 configure 执行时的参数将 nginx 部署到指定的安装目录,包括相关目录的建立和二进制文件、配置文件的复制。
我们通过简单的方式对 nginx 进行了编译,下面我们来学习相关目录的作用
源代码目录
1 | ├── auto # configure脚本执行时,通过shell检测系统环境 |
中间文件目录
执行 make
编译命令后,在当前目录生成 objs
目录
1 | ├── autoconf.err # 记录自动检查过程中的错误 |
部署目录
在执行 ./configure
脚本时,指定了 --prefix=/usr/local/nginx
参数,是希望 nginx 将此目录作为主工作目录,也就是安装的目录。
在执行 make install
命令之后,脚本会将相关的编译产物和配置文件拷贝到 /usr/local/nginx
目录
1 | ├── conf # 配置目录 |
日志目录
在我们这个环境中,nginx 日志目录是 ${prefix}/logs
,$prefix
是 /usr/local/nginx
。
如果在编译时不指定 --prefix
选项,nginx 默认将 /var/log/nginx/logs
作为日志目录。
在运行中,访问日志、错误日志、pid 文件等会存放在该目录中。
命令操作
在 Linux 中,可以行来控制 nginx 服务器的启动与停止、重载配置文件、回滚日志文件、平滑升级等行为。
启动运行
- 直接启动
1 | /usr/local/nginx/sbin/nginx |
- 启动时指定配置文件
1 | /usr/local/nginx/sbin/nginx -c /tmp/nginx.conf |
- 启动时指定主目录(安装目录)
1 | /usr/local/nginx/sbin/nginx -p /usr/local/nginx |
- 启动时指定全局配置项
1 | /usr/local/nginx/sbin/nginx -g "pid /var/nginx/test.pid;" |
配置测试
测试配置文件是否存在错误
1 | /usr/local/nginx/sbin/nginx -t |
打印信息
- 显示版本信息
1 | /usr/local/nginx/sbin/nginx -v |
- 显示编译阶段参数
1 | $ /usr/local/nginx/sbin/nginx -V |
停止服务
- 快速地停止服务
1 | /usr/local/nginx/sbin/nginx -s stop |
- 优雅地停止服务
1 | /usr/local/nginx/sbin/nginx -s quit |
配置重载
1 | /usr/local/nginx/sbin/nginx -s reload |
日志回滚
1 | /usr/local/nginx/sbin/nginx -s reopen |
平滑升级
- 通知旧版 nginx 准备升级
1 | kill -s SIGUSR2 <nginx master pid> |
启动新版本的 nginx
通过 kill 命令向旧版本 master 进程发送 SIGQUIT 信号,以优雅的方式关闭旧版本的 nginx