吃透 Nginx 编译安装过程

编译出适合自己的 Nginx
Nginx 的安装方式
安装 Nginx 有两种方法,除了编译以外,还可以直接用操作系统上自带的一些工具,比如 yum、apt-get
但是直接安装 Nginx 的二进制文件会有个问题,因为 Nginx 的二进制文件会把模块直接编译进来。Nginx 的官方模块,并不是每一个都默认开启的,如果你想添加第三方的 Nginx 模块,你必须通过编译 Nginx 这种方式才能把第三方的模块添加到 Nginx 中
编译安装 Nginx 过程
下载 Nginx
进入官网之后,点击右下角的 download

可以发现 Nginx 有两类版本,一个是 Mainline version(最新版本)、一个是 Stable version(稳定版本)。我们通常会选择下载稳定版本(这里最新的是 1.18.0)

选择一个稳定版本,复制下载链接,通过 wget 的方式下载下来即可,下载下来之后是一个压缩包,通过下边命令解压即可
各目录介绍
进入解压之后的源码目录中,可以看到如下结构

auto 目录

cc 目录是用于编译的,还有 lib 库,os 目录是对所有的操作系统进行判断的。其它的文件都是为了在 configure 脚本执行的时候,去判定 Nginx 支持哪些模块,当前操作系统有什么样的特性可以供 Nginx 使用
CHANGES 文件
CHANGES 文件记录的是每个 Nginx 版本中提供了哪些特性和 bugfix,部分内容截图

CHANGES.ru 文件
因为 Nginx 作者是一个俄罗斯人,所以这是一个俄罗斯语言的 CHANGES 文件
conf 目录

一个示例目录,就是把 Nginx 安装完成以后,为了方便运维去配置,会把 conf 中的示例文件拷贝到安装目录
configure 脚本
configure 脚本是一个用来生成中间文件,执行编译前的必备动作
contrib 目录

供了两个脚本和 vim 的一个工具,比如在没有使用它提供的 vim 工具时打开 Nginx 的配置文件,会发现色彩没什么变化(可以看到 Nginx 配置文件的语法,没有在 vim 中高亮的显示)

然后现在将 contrib 目录中下的所有 vim 文件拷贝到本地安装的 vim 目录中
然后再打开 Nginx 的配置文件

html 目录

录中提供了两个标准的 html 文件,一个是发现 500 错误的时候可以重定向到 50x.html 文件,另外一个是默认的 Nginx 欢迎界面
man 目录
man 目录是 linux 对 Nginx 的帮助文件(打开命令:man ./nginx.8)

src 目录

c 目录是 Nginx 的源代码目录
Configure 编译
编译之前,可以看一下 Configure 支持哪些参数

它的参数里边主要分为几个大块:
第一类,确定 Nginx 执行中,它会去找哪些目录下的文件作为它的辅助文件。比如需要动态模块,此时 --modules-path=PATH 就会产生作用。如果没有任何变动的话,只需要指定 --prefix=PATH 这个参数就可以了,所有的其它的文件都会在 prefix 指定的目录下面建相应的文件夹
第二类,主要是确定使用和不使用哪些模块,它的前缀通常是 --with- 和 --without- 。比如说 --with-http_ssl_module 、 --with-http_v2_module,通常需要我们主动加--with 模块的时候,意味着该模块默认是不会被编译进来的。而编译中需要使用 --without- ,意味着默认它会被编译进 Nginx,如果你不加这个参数,他是会被编译进去,如果加了--without- ,它就不会被编译进去
第三类,指定了 Nginx 编译中需要的一些特殊的参数,比如用 gcc 编译的时候,需要加一些什么样的优化参数,或者说需要打印 dubug 级别的日志

下边就使用默认参数编译一下 Nginx,下边指定了 Nginx 的安装目录
如果在执行的过程中没有报错,就意味着 Nginx 编译成功了。此时 Nginx 所有配置的特性,以及运行时的目录都会列在最下边

在上边编译完成之后,会生成一些中间文件
中间文件介绍
编译完成之后,生成的中间文件,会放在解压之后的 nginx 目录下的 objs 目录下

objs 目录下文件结构

这里边最重要的是会生成一个文件叫 ngx_modules.c,它决定了接下来执行编译的时候,有哪些模块会被编译进 Nginx

每一行 extern ngx_module_t 后边就是一个 ngxin 模块,所有会被编译进当前 Nginx 中的模块,都会被列在上边,他们最终会形成一个叫 *ngx_modules[]的指针数组
然后就可以执行 make 编译了。编译完成之后,会生成大量的中间文件,以及最终运行的 Nginx 二进制文件,可以在 objs 目录中看到

为什么需要知道 Nginx 的目标文件是放在这里的?
因为如果我们要做 Nginx 版本升级,此时不能执行 make install,而是从这里把目标文件拷贝到安装目录中
C 语言编译时生成的所有中间文件都会放在 objs 下的 src 目录下,如果我们使用了动态模块,编译时会生成动态文件,这个动态文件也会放在 objs 目录下。接下来就可以执行 make install(首次安装时执行该命令)
执行完之后,就可以在--prefix 执行的路径下看到如下结构

这里边最主要的 Nginx 二进制文件就在 sbin 目录下,决定 Nginx 功能的配置文件在 conf 目录下
可以看到在 conf 目录下,所有的文件就是在源代码中那个 conf 目录下所有文件 copy 过来了一份,内容也是一模一样的
以上便是 Nginx 的全部编译安装过程
Nginx 配置文件通用语法介绍
Nginx 配置文件中,已经指定了它包含了哪些模块,但每一个模块都提供独一无二的配置语法,这些所有的配置语法,会遵循同样的语法规则
配置文件由指令与指令块构成
每条指令以;分号结尾,指令与参数间以空格分隔
指令块以{}大括号将多条指令组织在一起
include 语句允许组合多个配置文件以提升可维护性
使用 #符合添加注释,提高可读性
使用 $符号使用变量
部分指令的参数支持正则表达式

在 http 这个指令块下,通常有四个块:
http
server
location
upstream
http 大括号下边就表示,里边所有的指令,都是由 http 模块去解析执行的,一个非 http 模块是没办法解析这里边的指令的。upstream 则是表示上游服务,当 Nginx 需要与 tomcat 等其它服务交互的时候,可以定义一个 upstream。server 则是对应一个域名,或者一组域名。location 则是一个 url 表达式
版权声明: 本文为 InfoQ 作者【书旅】的原创文章。
原文链接:【http://xie.infoq.cn/article/6c4214dddfdc259c01e0c11e4】。文章转载请联系作者。
评论