准备写一系列nginx教程,从基础编译配置开始,到源码解析。之前陆陆续续学了点nginx相关的知识,源码也学过一点,但是没有系统学习,所以这次要系统学习一下。
目前先以备忘录的方式写,没有什么结构,根据自己的学习方式来以日记的方式完成,这个可以在后面有结构学习的时候知道我当时是怎么学习怎么想的。就像数学公式,一个公式并不是凭空出现的,而是有灵感和不断的实验尝试得到的。
写本类文档,我会先自己学习测试,会遇到无数失败,最后成功后删去多余的操作记录下来,让文档显得精炼真实。文章中会有“应该”这样的词,表示我的猜测,但不一定是正确的,需要以后学习源码时确认。好了,下面开始学习nginx。
首先说一下我的环境,我的系统是ubuntu18.04,所以如果你是windows,那么编译安装方面你可能需要自己查询相关教程,但是后面配置相关应该是可以参考本文档的。
1
2
3
4
liuxu:nginx$ pwd
/home/liuxu/learn/nginx
liuxu:nginx$ ls -l
-rw-r--r-- 1 liuxu liuxu 1016272 4月 17 23:35 nginx-1.14.0.tar.gz
然后我们解压源码:
1
2
3
4
liuxu:nginx$ tar -xvf nginx-1.14.0.tar.gz
liuxu:nginx$ ls -l
drwxr-xr-x 8 liuxu liuxu 4096 4月 17 23:22 nginx-1.14.0
-rw-r--r-- 1 liuxu liuxu 1016272 4月 17 23:35 nginx-1.14.0.tar.gz
好了,源码我们拿到了,先看看源码里面有啥:
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
liuxu:nginx$ tree -L 2 nginx-1.14.0/
nginx-1.14.0/
├── auto
│ ├── cc
│ ├── define
│ ├── endianness
│ ├── feature
│ ├── have
│ ├── have_headers
│ ├── headers
│ ├── include
│ ├── init
│ ├── install
│ ├── lib
│ ├── make
│ ├── module
│ ├── modules
│ ├── nohave
│ ├── options
│ ├── os
│ ├── sources
│ ├── stubs
│ ├── summary
│ ├── threads
│ ├── types
│ └── unix
├── CHANGES
├── CHANGES.ru
├── conf
│ ├── fastcgi.conf
│ ├── fastcgi_params
│ ├── koi-utf
│ ├── koi-win
│ ├── mime.types
│ ├── nginx.conf
│ ├── scgi_params
│ ├── uwsgi_params
│ └── win-utf
├── configure
├── contrib
│ ├── geo2nginx.pl
│ ├── README
│ ├── unicode2nginx
│ └── vim
├── html
│ ├── 50x.html
│ └── index.html
├── LICENSE
├── man
│ └── nginx.8
├── README
└── src
├── core
├── event
├── http
├── mail
├── misc
├── os
└── stream
19 directories, 38 files
从这个输出看,auto
里应该是编译时自动执行的东西,CHANGES
和CHANGES.ru
是此版本代码和上一版本有啥改变,conf
里应该是nginx的配置文件,configure
就是所有代码基本会有的自动生成Makefile
的工具啦,contrib
里是一些工具,例如那个vim
里就是vim外观配置文件,html
里是nginx默认的html页面,LICENSE
是开源代码的使用协议,man
里是可由linuxman
命令输出的帮助内容,README
就是在使用该源码应该先看看的文件,src
里就是nginx源码了。
先看一下README
文件是正确的操作:
1
2
3
liuxu:nginx-1.14.0$ cat README
Documentation is available at http://nginx.org
恩。。告诉我们文档得去nginx官网。
好吧,那就去官网看文档,看看怎么安装。
看看这个文档,安装、编译、配置、管理啥都有,那个“nginx for Windows”是windows用户们可以参考的文档。
从安装文档看,有直接通过yum或apt配置源后直接安装的方式,也可以自己手动编译,我们这里就看怎么手动编译安装。
编译安装文档里面先给了所有编译参数的解释,最后给了一个编译安装的例子。看着这么多编译选项,其实学习起来很简单,除了前面十来个特殊选项,后面的全部都是“–with-…”和“–without-…”,因为nginx从源码到逻辑功能都是模块化的,所以编译时需要用“–with-…”选择需要的模块来编译进nginx。nginx也有默认需要编译的模块,如果不需要这些默认的,可以用“–without-…”去掉。
既然是从零开始学nginx,那么就不要任何编译参数编译吧,ubuntu用户可能需要先安装编译工具:
1
liuxu:nginx-1.14.0$ sudo apt install build-essential
然后我们开始编译nginx:
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
liuxu:nginx-1.14.0$ pwd
/home/liuxu/learn/nginx/nginx-1.14.0
liuxu:nginx-1.14.0$ ls
auto CHANGES CHANGES.ru conf configure contrib html LICENSE man README src
liuxu:nginx-1.14.0$ ./configure
checking for OS
+ Linux 4.15.0-20-generic x86_64
checking for C compiler ... found
+ using GNU C compiler
+ gcc version: 7.3.0 (Ubuntu 7.3.0-16ubuntu3)
checking for gcc -pipe switch ... found
...
...
checking for sysconf(_SC_NPROCESSORS_ONLN) ... found
checking for sysconf(_SC_LEVEL1_DCACHE_LINESIZE) ... found
checking for openat(), fstatat() ... found
checking for getaddrinfo() ... found
checking for PCRE library ... not found
checking for PCRE library in /usr/local/ ... not found
checking for PCRE library in /usr/include/pcre/ ... not found
checking for PCRE library in /usr/pkg/ ... not found
checking for PCRE library in /opt/local/ ... not found
./configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using --with-pcre=<path> option.
好吧,出错了,看看“error”前后的输出,是PCRE library
没有,可以用--without-http_rewrite_module
去掉http_write_module
,这个参数就是--without-...
里面的,从这个可以知道http_rewrite_module
是nginx默认会安装的模块,它依赖PCRE library
。但是系统里没找到,所有如果需要这个模块的话,就需要用后面的参数--with-pcre=<path>
,为了保证nginx的默认选项,我们选方案二,加入pcre包。
在文档里看看这个选项:
1
2
--with-pcre=path
sets the path to the sources of the PCRE library. The library distribution (version 4.4 — 8.41) needs to be downloaded from the PCRE site and extracted. The rest is done by nginx’s ./configure and make. The library is required for regular expressions support in the location directive and for the ngx_http_rewrite_module module.
这个选项用户设置PCRE library
目录位置,它的版本需要是4.4-8.41
,加入这个选项后再用./configure
重新编译即可。这个包是给ngx_http_rewrite_module
模块的正则表达式给予支持。
我们现在来现在这个包,PCRE library官网里找到下载目录并下载,可以看见,有很多版本,但既然nginx文档说需要的版本是4.4-8.41
,那就下载pcre-8.41.tar.bz2
吧,其他的.tar.gz
等等只是压缩格式不同,代码都是一样的,.sig
是验证文件,我也懒得验证了,但严格操作是需要验证的。
下载后解压,并在编译选项中包含:
1
2
3
4
5
6
7
8
9
10
11
12
13
liuxu:nginx$ pwd
/home/liuxu/learn/nginx
liuxu:nginx$ tar -xvf pcre-8.41.tar.bz2
liuxu:nginx$ ls -al
total 2540
drwxr-xr-x 4 liuxu liuxu 4096 5月 28 15:38 .
drwxr-xr-x 3 liuxu liuxu 4096 5月 28 14:30 ..
drwxr-xr-x 9 liuxu liuxu 4096 5月 28 15:06 nginx-1.14.0
-rw-r--r-- 1 liuxu liuxu 1016272 4月 17 23:35 nginx-1.14.0.tar.gz
drwxr-xr-x 7 liuxu liuxu 4096 7月 5 2017 pcre-8.41
-rw-r--r-- 1 liuxu liuxu 1561874 7月 5 2017 pcre-8.41.tar.bz2
liuxu:nginx$ cd nginx-1.14.0/
liuxu:nginx-1.14.0$ ./configure --with-pcre=../pcre-8.41
看看./configure --with-pcre=../pcre-8.41
,就是包含上级目录的pcre
包。然后一阵输出,Makefile
生成成功。
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
28
29
30
31
liuxu:nginx-1.14.0$ ./configure --with-pcre=../pcre-8.41
checking for OS
+ Linux 4.15.0-20-generic x86_64
checking for C compiler ... found
+ using GNU C compiler
+ gcc version: 7.3.0 (Ubuntu 7.3.0-16ubuntu3)
checking for gcc -pipe switch ... found
checking for -Wl,-E switch ... found
...
...
checking for zlib library ... found
creating objs/Makefile
Configuration summary
+ using PCRE library: ../pcre-8.41
+ OpenSSL library is not used
+ using system zlib library
nginx path prefix: "/usr/local/nginx"
nginx binary file: "/usr/local/nginx/sbin/nginx"
nginx modules path: "/usr/local/nginx/modules"
nginx configuration prefix: "/usr/local/nginx/conf"
nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
nginx pid file: "/usr/local/nginx/logs/nginx.pid"
nginx error log file: "/usr/local/nginx/logs/error.log"
nginx http access log file: "/usr/local/nginx/logs/access.log"
nginx http client request body temporary files: "client_body_temp"
nginx http proxy temporary files: "proxy_temp"
nginx http fastcgi temporary files: "fastcgi_temp"
nginx http uwsgi temporary files: "uwsgi_temp"
nginx http scgi temporary files: "scgi_temp"
看下面的Configuration summary
输出,里边包括了pcre使用了我们设置的目录,openssl没有使用,它应该是给https用的,zlib用的系统的,它应该是给nginx压缩支持。然后一堆nginx默认选项,例如默认配置文件位置,默认日志文件位置。
好了,既然Makefile
已经有了,可以开始编译:
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
liuxu:nginx-1.14.0$ ls
auto CHANGES CHANGES.ru conf configure contrib html LICENSE Makefile man objs README src
liuxu:nginx-1.14.0$ make
make -f objs/Makefile
make[1]: Entering directory '/home/liuxu/learn/nginx/nginx-1.14.0'
cd ../pcre-8.41 \
&& if [ -f Makefile ]; then make distclean; fi \
&& CC="cc" CFLAGS="-O2 -fomit-frame-pointer -pipe " \
./configure --disable-shared
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... no
...
...
objs/src/http/modules/ngx_http_upstream_keepalive_module.o \
objs/src/http/modules/ngx_http_upstream_zone_module.o \
objs/ngx_modules.o \
-ldl -lpthread -lcrypt ../pcre-8.41/.libs/libpcre.a -lz \
-Wl,-E
sed -e "s|%%PREFIX%%|/usr/local/nginx|" \
-e "s|%%PID_PATH%%|/usr/local/nginx/logs/nginx.pid|" \
-e "s|%%CONF_PATH%%|/usr/local/nginx/conf/nginx.conf|" \
-e "s|%%ERROR_LOG_PATH%%|/usr/local/nginx/logs/error.log|" \
< man/nginx.8 > objs/nginx.8
make[1]: Leaving directory '/home/liuxu/learn/nginx/nginx-1.14.0'
编译很快,一会就成功了:
1
2
3
4
liuxu:nginx-1.14.0$ ls
auto CHANGES CHANGES.ru conf configure contrib html LICENSE Makefile man objs README src
liuxu:nginx-1.14.0$ ls objs/
autoconf.err Makefile nginx nginx.8 ngx_auto_config.h ngx_auto_headers.h ngx_modules.c ngx_modules.o src
objs
目录下的nginx
就是编译好的文件,好了,我们把它复制到一个新目录:
1
2
3
4
5
liuxu:test$ pwd
/home/liuxu/learn/nginx/test
liuxu:test$ ls -l
total 4616
-rwxr-xr-x 1 liuxu liuxu 4726472 5月 28 15:59 nginx
好了,接下来就是从这个可执行文件开始学习nginx了。