前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何configure定制出属于你的Nginx?

如何configure定制出属于你的Nginx?

作者头像
陶辉
发布2020-12-23 15:10:34
1.2K0
发布2020-12-23 15:10:34
举报
文章被收录于专栏:陶辉笔记陶辉笔记

上一篇文章中,我介绍了Nginx的特性,如何获取Nginx源代码,以及源代码中各目录的含义。本文将介绍如何定制化编译、安装、运行Nginx。

当你用yum或者apt-get命令安装、启动Nginx后,通过nginx -t命令你会发现,nginx.conf配置文件可能在/etc/目录中。而运行基于源码安装的Nginx时,nginx.conf文件又可能位于/usr/local/nginx/conf/目录,运行OpenResty时, nginx.conf又被放在了/usr/local/openresty/nginx/conf/目录。这些奇怪的现象都源于编译Nginx前,configure脚本设置的–prefix或者–conf-path选项

Nginx的所有功能都来自于官方及第三方模块,如果你不知道如何使用configure添加需要的模块,相当于放弃了Nginx诞生16年来累积出的丰富生态。而且,很多高性能特性默认是关闭的,如果你习惯于使用应用市场中编译好的二进制文件,也无法获得性能最优化的Nginx。

本文将会介绍定制Nginx过程中,configure脚本的用法。其中对于定制模块的选项,会从模块的分类讲起,带你系统的掌握如何添加Nginx模块。同时,也会介绍configure执行后生成的objs目录,以及Makefile文件的用法。这也是Nginx开源社区基础培训系列课程第一季,即6月11日晚第2次视频直播课前半部分的文字总结。

configure脚本有哪些选项?

在Linux系统(包括各种类Unix操作系统)下,编译复杂的C语言软件工程是由Makefile文件完成的。你一定注意到Nginx源码中并没有Makefile文件,这是因为Makefile是由configure脚本即时生成的。接下来我们看看,configure脚本悄悄的做了哪些事,这些工作又会对Nginx产生哪些影响。

configure脚本支持很多选项,掌握它们就可以灵活的定制Nginx。为了方便理解,从功能上我把它们分为5类:

  • 改变Nginx编译、运行时各类资源的默认存取路径

configure既可以设置Nginx运行时各类资源的默认访问路径,也可以设置编译期生成的临时文件存放路径。比如:

  • –error-log-path=定义了运行期出现错误信息时写入log日志文件的路径。
  • –http-log-path=定义了运行期处理完HTTP请求后,将执行结果写入log日志文件的路径。
  • –http-client-body-temp-path=定义了运行期Nginx接收客户端的HTTP请求时,存放包体的磁盘路径。
  • –http-proxy-temp-path=定义了运行期负载均衡使用的Nginx,临时存放上游返回HTTP包体的磁盘路径。
  • –builddir=定义了编译期生成的脚本、源代码、目标文件存放的路径。

等等。

对于已经编译好的Nginx,可以通过nginx -V命令查看设置的路径。如果没有显式的设置选项,Nginx便会使用默认值,例如官方Nginx将–prefix的默认值设为/usr/local/nginx,而OpenResty的configure脚本则将–prefix的默认值设为/usr/local/openresty/nginx

  • 改变编译器选项

Nginx由C语言开发,因此默认使用的C编译器,由于C++向前兼容C语言,如果你使用了C++编写的Nginx模块,可以通过–cc-opt等选项,将C编译器修改为C++编译器,这就可以支持C++语言了。

Nginx编译时使用的优化选项是-O,如果你觉得这样优化还不够,可以调大优化级别,比如OpenResty就将gcc的优化调整为-O2。当某些模块依赖其他软件库才能实现需求时,也可以通过–with-ld-opt选项链接其他库文件。

  • 修改编译时依赖的中间件

Nginx执行时,会依赖pcre、openssl、zlib等中间件,实现诸如正则表达式解析、TLS/SSL协议处理、解压缩等功能。通常,编译器会自动寻找系统默认路径中的软件库,但当系统中含有多个版本的中间件时,就可以人为地通过路径来指定版本。比如当我们需要使用最新的TLS1.3时,可以下载最新的openssl源码包,再通过–with-openssl=选项指定源码目录,让Makefile使用它去编译Nginx。

  • 选择编译进Nginx的模块

Nginx是由少量的框架代码、大量的C语言模块构成的。当你根据业务需求,需要通过某个模块实现相应的功能时,必须先通过configure脚本将它编译进Nginx(Nginx被设计为按需添加模块的架构),之后你才能在nginx.conf配置文件中启用它们。下一小节我会详细介绍这部分内容。

  • 其他选项

还有些不属于上述4个类别的选项,包括:

  • 定位问题时,最方便的是通过log查看DEBUG级别日志,而打开调试日志的前提,是在configure时加入–with-debug选项。
  • HTTP服务是默认打开的,如果你想禁用HTTP或者HTTP缓存服务,可以使用–without-http和–without-http-cache选项。
  • 大文件读写磁盘时,并不适宜使用正常的read/write系统调用,因为文件内容会写入PageCache磁盘高速缓存。由于PageCache空间有限,而大文件会迅速将可能高频命中缓存的小文件淘汰出PageCache,同时大文件自身又很难享受到缓存的好处。因此,在Linux系统中,可以通过异步IO、直接IO来处理文件。但开启Linux原生异步IO的前提,是在configure时加入–with-file-aio选项。
  • 开启IPv6功能时,需要加入–with-ipv6选项。
  • 生产环境中,需要使用master/worker多进程模式运行Nginx。master是权限更高的管理进程,而worker则是处理请求的工作线程,它的权限相对较低。通过–user=和–group=选项可以指定worker进程所属的用户及用户组,当然,你也可以在conf中通过user和group指令修改它。

在大致了解configure提供的选项后,下面我们重点看下如何定制Nginx模块。

如何添加Nginx模块?

编译Nginx前,我们需要决定添加哪些模块。在定制化模块前,只有分清了模块的类别才能系统的掌握它们。Nginx通常可以分为6类模块,包括:

  • 核心模块:有限的7个模块定义了Nginx最基本的功能。需要注意,核心模块并不是默认一定编译进Nginx,例如只有在configure时加入–with-http_ssl_module或者–with-stream_ssl_modul选项时,ngx_openssl_module核心模块才会编译进Nginx。
  • 配置模块:仅包括ngx_conf_module这一个模块,负责解析conf配置文件。
  • 事件模块:Nginx采用事件驱动的异步框架来处理网络报文,它支持epoll、poll、select等多种事件驱动方式。目前,epoll是主流的事件驱动方式,选择事件驱动针对的是古董操作系统。
  • HTTP模块:作为Web服务器及七层负载均衡,Nginx最复杂的功能都由HTTP模块实现,稍后我们再来看如何定制HTTP模块。
  • STREAM模块:负责实现四层负载功能,默认不会编译进Nginx。你可以通过–with-stream启用STREAM模块。
  • MAIL模块:Nginx也可以作为邮件服务器的负载均衡,通过–with-mail选项启用。

在上图中,HTTP模块又可以再次细分为3类模块:

  • 请求处理模块:Nginx接收、解析完HTTP报文后,会将请求交给各个HTTP模块处理。比如读取磁盘文件并发送到客户端的静态资源功能,就是由ngx_http_static_module模块实现的。为了方便各模块间协同配合,Nginx将HTTP请求的处理过程分为11个阶段,如下图所示:
  • 响应过滤模块:当上面的请求处理模块生成合法的HTTP响应后,将会由各个响应过滤模块依次对HTTP头部、包体做加工处理。比如返回HTML、JS、CSS等文本文件时,若配置了gzip on;指令,就可以添加content-encoding: gzip头部,并使用zlib库压缩包体。
  • upstream负载均衡模块:当Nginx作为反向代理连接上游服务时,允许各类upstream模块提供不同的路由策略,比如ngx_http_upstream_hash_module模块提供了哈希路由,而ngx_http_upstream_keepalive_module模块则允许复用TCP连接,降低握手、慢启动等动作提升的网络时延。

对于这3类模块,你可以从模块名中识别,比如模块中出现filter和http字样,通常就是过滤模块,比如ngx_http_gzip_filter_module。如果模块中出现upstream和http字样,就是负载均衡模块。

我们可以使用–with-模块名,将其编译进Nginx,也可以通–without-模块名,从Nginx中移出该模块。需要注意的是,当你通过configure –help帮助中看到–with-打头的选项,都是默认不编译进Nginx的模块,反之,–without-打头的选项,则是默认就编译进Nginx的模块。

还有一些HTTP模块并不属于上述3个类别,比如–with-http_v2_module是加入支持HTTP2协议的模块。当你需要添加第三方模块时,则可以通过–add-module=或者–add-dynamic-module=(动态模块将在后续文章中再介绍)选项指定模块源码目录,这样就可以将它编译进Nginx

如何安装并运行Nginx?

当configure脚本根据指定的选项执行时,会自动检测体系架构、系统特性、编译器、依赖软件等环境信息,并基于它们生成编译Nginx工程的Makefile文件。同时,还会生成objs目录,我们先来看看objs目录中有些什么:

代码语言:javascript
复制
objs
|-- autoconf.err            #configure自动检测环境时的执行纪录
|-- Makefile                 #编译C代码用到的脚本
|-- ngx_auto_config.h   #以宏的方式,存放configure指定的配置,供安装时使用
|-- ngx_auto_headers.h#存放编译时包含的头文件中默认生成的宏
|-- ngx_modules.c        #根据configure时加入的模块,生成ngx_modules数组
`-- src                          #存放编译时的目标文件
    |-- core                #存放核心模块及框架代码生成的目标文件
    |-- event               #存放事件模块生成的目标文件
    |-- http                 #存放HTTP模块生成的目标文件
    |-- mail                 #存放MAIL模块生成的目标文件
    |-- misc                #存放ngx_google_perftools_module模块生成的目标文件
    |-- os                   #存放与操作系统关联的源代码生成的目标文件
    `-- stream             #存放STREAM模块生成的目标文件

接着,执行make命令就可以基于Makefile文件编译Nginx了。make命令可以携带4种参数:

  • build:编译Nginx,这也是make不携带参数时的默认动作。它会在objs目录中生成可执行的二进制文件nginx。
  • clean:通过删除Makefile文件和objs目录,将configure、make的执行结果清除,方便重新编译。
  • install:将Nginx安装到configure时指定的路径中,注意install只针对从头安装Nginx,如果是升级正在运行的服务,请使用upgrade参数。
  • upgrade:替换可执行文件nginx,同时热升级运行中的Nginx进程。

因此,当我们首次安装Nginx时,只需要先执行make命令编译出可执行文件,再执行make install安装到目标路径即可。

启动Nginx也很简单,进入Nginx目录后(比如/usr/local/nginx),在sbin目录下执行nginx程序即可,Nginx默认会启用Daemon守护者模式(参见daemon on;指令),这样shell命令行不会被nginx程序阻塞。

至此,Nginx已经编译、安装完成,并成功运行。

小结

最后做个小结,本文介绍了定制化编译、安装及运行Nginx的方法。

如果你想定制符合自己业务特点的Nginx,那就必须学会使用configure脚本,它会根据输入选项、系统环境生成差异化的编译环境,最终编译出功能、性能都不一样的Nginx。configure支持的选项分为5类,它允许用户修改资源路径、编译参数、依赖软件等,最重要的是可以选择加入哪些官方及第三方模块。

定制模块前,先要掌握模块的类别。Nginx模块分为6类,作为Web服务器使用时,其中最复杂、强大的自然就是HTTP模块,它又可以再次细分为3小类:请求处理模块、响应过滤模块、负载均衡模块。我们可以使用–with或者–without选项增删官方模块,也可以通过–add-module或者–add-dynamic-module添加第三方模块。

configure会生成源代码、脚本、存放目标文件的临时目录,以及编译C工程的Makefile文件。其中,Makefile支持4个选项,允许我们编译、安装、升级Nginx。由于Nginx支持Daemon模式,启动它时直接运行程序即可。

下一篇将会介绍nginx.conf的配置语法,以及使用命令行或者免费的可视化工具分析access.log日志文件的方法。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020年12月22日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • configure脚本有哪些选项?
  • 如何添加Nginx模块?
  • 如何安装并运行Nginx?
  • 小结
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档