大纲
一、环境准备
二、编译安装Nginx
三、Nginx相关理论知识
四、相关模块与指令介绍
一、环境准备
系统环境
CentOS5.8 x86_64
软件包
nginx-1.8.0.tar.gz(源码包)
拓扑图
1、时间同步
[root@soysauce ~]# ntpdate s2c.time.edu.cn 18 Jan 12:44:37 ntpdate[25250]: adjust time server 202.112.10.36 offset -0.007795 sec
2、关闭iptables和selinux
[root@soysauce ~]# sed -r -i "s/^(SELINUX=).*/\1permissive/g" /etc/sysconfig/selinux [root@soysauce ~]# setenforce 0 [root@soysauce ~]# getenforce Permissive
二、编译安装Nginx
1、下载源码包
[root@soysauce ~]# wget http://nginx.org/download/nginx-1.8.0.tar.gz
2、解决依赖关系和创建nginx用户和组
[root@soysauce ~]# yum groupinstall -y "Development Tools" "Development Libraries" [root@soysauce ~]# yum install openssl-devel pcre-devel [root@soysauce ~]# groupadd -r nginx [root@soysauce ~]# useradd -r -g nginx nginx
3、编译安装
[root@soysauce ~]# tar xf nginx-1.8.0.tar.gz [root@soysauce ~]# cd nginx-1.8.0 [root@soysauce nginx-1.8.0]# ls auto CHANGES CHANGES.ru conf configure contrib html LICENSE Makefile man objs README src [root@soysauce nginx-1.8.0]# ./configure \ --prefix=/usr \ --sbin-path=/usr/sbin/nginx \ --conf-path=/etc/nginx/nginx.conf \ --error-log-path=/var/log/nginx/error.log \ --http-log-path=/var/log/nginx/access.log \ --pid-path=/var/run/nginx/nginx.pid \ --lock-path=/var/lock/nginx.lock \ --user=nginx \ --group=nginx \ --with-http_ssl_module \ --with-http_flv_module \ --with-http_stub_status_module \ --with-http_gzip_static_module \ --http-client-body-temp-path=/var/tmp/nginx/client/ \ --http-proxy-temp-path=/var/tmp/nginx/proxy/ \ --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ \ --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \ --http-scgi-temp-path=/var/tmp/nginx/scgi \ --with-pcre 显示我们自定义的配置信息和编译选项 Configuration summary + using system PCRE library + using system OpenSSL library + md5: using OpenSSL library + sha1: using OpenSSL library + using system zlib library nginx path prefix: "/usr" nginx binary file: "/usr/sbin/nginx" nginx configuration prefix: "/etc/nginx" nginx configuration file: "/etc/nginx/nginx.conf" nginx pid file: "/var/run/nginx/nginx.pid" nginx error log file: "/var/log/nginx/error.log" nginx http access log file: "/var/log/nginx/access.log" nginx http client request body temporary files: "/var/tmp/nginx/client/" nginx http proxy temporary files: "/var/tmp/nginx/proxy/" nginx http fastcgi temporary files: "/var/tmp/nginx/fcgi/" nginx http uwsgi temporary files: "/var/tmp/nginx/uwsgi" nginx http scgi temporary files: "/var/tmp/nginx/scgi" 编译安装 [root@soysauce nginx-1.8.0]# make && make install 补充: Nginx可以使用Tmalloc(快速、多线程的malloc库及优秀性能分析工具)来加速内存分配 使用此功能需要事先安装gperftools,而后在编译nginx添加--with-google_perftools_module选项即可
4、为nginx提供SysV init脚本
[root@soysauce nginx-1.8.0]# vim /etc/rc.d/init.d/nginx #!/bin/sh # # nginx - this script starts and stops the nginx daemon # # chkconfig: - 85 15 # description: Nginx is an HTTP(S) server, HTTP(S) reverse \ # proxy and IMAP/POP3 proxy server # processname: nginx # config: /etc/nginx/nginx.conf # config: /etc/sysconfig/nginx # pidfile: /var/run/nginx.pid # Source function library. . /etc/rc.d/init.d/functions # Source networking configuration. . /etc/sysconfig/network # Check that networking is up. [ "$NETWORKING" = "no" ] && exit 0 nginx="/usr/sbin/nginx" prog=$(basename $nginx) NGINX_CONF_FILE="/etc/nginx/nginx.conf" [ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx lockfile=/var/lock/subsys/nginx make_dirs() { # make required directories user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -` options=`$nginx -V 2>&1 | grep 'configure arguments:'` for opt in $options; do if [ `echo $opt | grep '.*-temp-path'` ]; then value=`echo $opt | cut -d "=" -f 2` if [ ! -d "$value" ]; then # echo "creating" $value mkdir -p $value && chown -R $user $value fi fi done } start() { [ -x $nginx ] || exit 5 [ -f $NGINX_CONF_FILE ] || exit 6 make_dirs echo -n $"Starting $prog: " daemon $nginx -c $NGINX_CONF_FILE retval=$? echo [ $retval -eq 0 ] && touch $lockfile return $retval } stop() { echo -n $"Stopping $prog: " killproc $prog -QUIT retval=$? echo [ $retval -eq 0 ] && rm -f $lockfile return $retval } restart() { configtest || return $? stop sleep 1 start } reload() { configtest || return $? echo -n $"Reloading $prog: " killproc $nginx -HUP RETVAL=$? echo } force_reload() { restart } configtest() { $nginx -t -c $NGINX_CONF_FILE } rh_status() { status $prog } rh_status_q() { rh_status >/dev/null 2>&1 } case "$1" in start) rh_status_q && exit 0 $1 ;; stop) rh_status_q || exit 0 $1 ;; restart|configtest) $1 ;; reload) rh_status_q || exit 7 $1 ;; force-reload) force_reload ;; status) rh_status ;; condrestart|try-restart) rh_status_q || exit 0 ;; *) echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}" exit 2 esac 添加执行权限,并加入到服务列表中 [root@soysauce nginx-1.8.0]# chmod +x /etc/rc.d/init.d/nginx [root@soysauce nginx-1.8.0]# chkconfig --add nginx [root@soysauce nginx-1.8.0]# chkconfig nginx on [root@soysauce nginx-1.8.0]# chkconfig --list nginx nginx 0:off 1:off 2:on 3:on 4:on 5:on 6:off
5、启动Nginx服务,并测试能否访问主页
[root@soysauce nginx-1.8.0]# service nginx start Starting nginx: [ OK ] 查看80端口是否处于监听状态 [root@soysauce nginx-1.8.0]# netstat -tnlp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 2820/portmap tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 30414/nginx tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 25126/sshd tcp 0 0 0.0.0.0:922 0.0.0.0:* LISTEN 2860/rpc.statd tcp 0 0 127.0.0.1:6011 0.0.0.0:* LISTEN 24814/sshd tcp 0 0 :::22 :::* LISTEN 25126/sshd tcp 0 0 ::1:6011 :::* LISTEN 24814/sshd
打开浏览器访问一下
可以看到是能够正常访问的
三、Nginx相关理论知识
传统上基于进程或线程模型架构的web服务通过每进程或每线程处理并发连接请求,这势必会在网络和I/O操作时产生阻塞,其另一个必然结果则是对内存或CPU的利用率低下。生成一个新的进程/线程需要事先备好其运行时环境,这包括为其分配堆内存和栈内存,以及为其创建新的执行上下文等。这些操作都需要占用CPU,而且过多的进程/线程还会带来线程抖动或频繁的上下文切换,系统性能也会由此进一步下降。 在设计的最初阶段,nginx的主要着眼点就是其高性能以及对物理计算资源的高密度利用,因此其采用了不同的架构模型。受启发于多种操作系统设计中基于“事件”的高级处理机制,nginx采用了模块化、事件驱动、异步、单线程及非阻塞的架构,并大量采用了多路复用及事件通知机制。在nginx中,连接请求由为数不多的几个仅包含一个线程的进程worker以高效的回环(run-loop)机制进行处理,而每个worker可以并行处理数千个的并发连接及请求。 如果负载以CPU密集型应用为主,如SSL或压缩应用,则worker数应与CPU数相同;如果负载以IO密集型为主,如响应大量内容给客户端,则worker数应该为CPU个数的1.5或2倍。 Nginx会按需同时运行多个进程:一个主进程(master)和几个工作进程(worker),配置了缓存时还会有缓存加载器进程(cache loader)和缓存管理器进程(cache manager)等。所有进程均是仅含有一个线程,并主要通过“共享内存”的机制实现进程间通信。主进程以root用户身份运行,而worker、cache loader和cache manager均应以非特权用户身份运行。 主进程主要完成如下工作: 1. 读取并验正配置信息; 2. 创建、绑定及关闭套接字; 3. 启动、终止及维护worker进程的个数; 4. 无须中止服务而重新配置工作特性; 5. 控制非中断式程序升级,启用新的二进制程序并在需要时回滚至老版本; 6. 重新打开日志文件,实现日志滚动; 7. 编译嵌入式perl脚本; worker进程主要完成的任务包括: 1. 接收、传入并处理来自客户端的连接; 2. 提供反向代理及过滤功能; 3. nginx任何能完成的其它任务; cache loader进程主要完成的任务包括: 1. 检查缓存存储中的缓存对象; 2. 使用缓存元数据建立内存数据库; cache manager进程的主要任务: 1. 缓存的失效及过期检验; Nginx的配置有着几个不同的上下文:main、http、server、upstream和location(还有实现邮件服务反向代理的mail)。配置语法的格式和定义方式遵循所谓的C风格,因此支持嵌套,还有着逻辑清晰并易于创建、阅读和维护等优势。 Nginx的代码是由一个核心和一系列的模块组成, 核心主要用于提供Web Server的基本功能,以及Web和Mail反向代理的功能;还用于启用网络协议,创建必要的运行时环境以及确保不同的模块之间平滑地进行交互。不过,大多跟协议相关的功能和某应用特有的功能都是由nginx的模块实现的。这些功能模块大致可以分为事件模块、阶段性处理器、输出过滤器、变量处理器、协议、upstream和负载均衡几个类别,这些共同组成了nginx的http功能。事件模块主要用于提供OS独立的(不同操作系统的事件机制有所不同)事件通知机制如kqueue或epoll等。协议模块则负责实现nginx通过http、tls/ssl、smtp、pop3以及imap与对应的客户端建立会话。 在nginx内部,进程间的通信是通过模块的pipeline或chain实现的;换句话说,每一个功能或操作都由一个模块来实现。例如,压缩、通过FastCGI或uwsgi协议与upstream服务器通信,以及与memcached建立会话等。
四、相关模块与指令介绍
1、http核心模块:ngx_http_core_module
(1)、error_page
syntax:error_page code ... [=[response]] uri; default:— context:http, server, location, if in location Example Configuration location / { root /web/html; index index.html index.htm; error_page 404 /404.html; error_page 500 502 503 504 /50x.html; }
(2)、location
syntax: location [ = | ~ | ~* | ^~ ] uri { ... } location @name { ... } default:- context: server, location location 匹配优先级 1、Directives with the = prefix that match the query exactly. If found, searching stops. 2、All remaining directives with conventional strings, longest match first. If this match used the ^~ prefix, searching stops. 3、Regular expressions, in order of definition in the configuration file. 4、If #3 yielded a match, that result is used. Else the match from #2 is used. =前缀的指令严格匹配这个查询。如果找到,停止搜索;即 = 优先级最高 所有剩下的常规字符串,最长的匹配。如果这个匹配使用^~前缀,搜索停止;接着是^~ 正则表达式,在配置文件中定义的顺序;接着是~和~* 如果第3条规则产生匹配的话,结果被使用。否则,如同从第2条规则被使用。 Examples: location = / { # matches the query / only. [ configuration A ] } location / { # matches any query, since all queries begin with /, but regular # expressions and any longer conventional blocks will be # matched first. [ configuration B ] } location ^~ /p_w_picpaths/ { # matches any query beginning with /p_w_picpaths/ and halts searching, # so regular expressions will not be checked. [ configuration C ] } location ~* ".(gif|jpg|jpeg)$ { # matches any request ending in gif, jpg, or jpeg. However, all # requests to the /p_w_picpaths/ directory will be handled by # Configuration C. [ configuration D ] } The “/” request will match configuration A the “/index.html” request will match configuration B the “/documents/document.html” request will match configuration C the “/p_w_picpaths/1.gif” request will match configuration D, and the “/documents/1.jpg” request will match configuration E.
(3)、server
Syntax: server { ... } Default: — Context: http Example Configuration server { listen 80; server_name www.a.org; location / { root /web/a.org; index index.html; } } server { listen 80; server_name www.b.net; location / { root /web/b.net; index index.html; } } 准备两个站点的网页文件存放目录及主页文件 [root@soysauce nginx]# mkdir /web/{a.org,b.net} [root@soysauce nginx]# echo "a.org
" > /web/a.org/index.html [root@soysauce nginx]# echo "a.org
" > /web/b/index.html bbs/ b.net/ [root@soysauce nginx]# echo "b.net
" > /web/b.net/index.html 测试语法是否有错误,没有则重启nginx服务 [root@soysauce nginx]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [root@soysauce nginx]# service nginx restart nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful Stopping nginx: [ OK ] Starting nginx: [ OK ] 这两个域名是做测试的,所以本地改下hosts解析 [root@soysauce nginx]# vim /etc/hosts [root@soysauce nginx]# tail -2 /etc/hosts 172.16.1.101 www.a.org 172.16.1.101 www.b.net 访问测试两个虚拟主机 [root@soysauce nginx]# curl http://www.a.org/index.htmla.org
[root@soysauce nginx]# curl http://www.b.net/index.htmlb.net
2、http访问控制模块:ngx_http_access_module
Syntax: allow address | CIDR | unix: | all; Default: — Context: http, server, location, limit_except Syntax: deny address | CIDR | unix: | all; Default: — Context: http, server, location, limit_except 如想只允许特定主机或网段,则使用如下配置 location URI { allow 172.16.1.106; # 仅允许特定主机 allow 172.16.0.0/16; # 仅允许特定网段 deny all; } 如想只拒绝定网段访问,则使用如下配置 location URI { deny 172.16.1.100; # 仅拒绝172.16.1.106访问,其他则可以正常访问 deny 172.16.0.0/16; # 仅拒绝172.16网段访问,其他则可以正常访问 allow all; # 此行不写也行,因为默认规则为allow all }
3、http基本认证模块:ngx_http_auth_basic_module
Syntax: auth_basic string | off; Default: auth_basic off; Context: http, server, location, limit_except Syntax: auth_basic_user_file file; Default: — Context: http, server, location, limit_except 如想实现基于用户的访问认证,则需借助htpasswd,而htpasswd工具是由httpd提供 首先在nginx中定义两个指令 auth_basic 和auth_basic_user_file location /bbs { root /web; index index.html index.htm; auth_basic "Resticted Area..."; auth_basic_user_file "/etc/nginx/.htpasswd"; } 安装httpd并生成认证用户和密码 [root@soysauce ~]# yum install -y httpd [root@soysauce nginx]# htpasswd -c -m /etc/nginx/.htpasswd tom New password: Re-type new password: Adding password for user tom [root@soysauce nginx]# htpasswd -m /etc/nginx/.htpasswd jerry New password: Re-type new password: Adding password for user jerry [root@soysauce nginx]# cat /etc/nginx/.htpasswd tom:$apr1$bUDII/..$Nt1lO/TeUH4ic5DJhJ2w.0 jerry:$apr1$Rn6sB/..$hD2s/euOa/ge4hzQUo3dv. 重新载入nginx并测试访问 [root@soysauce nginx]# service nginx reload nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful Reloading nginx: [ OK ]
4、http目录列表自动生成模块:ngx_http_autoindex_module
Syntax: autoindex on | off; Default: autoindex off; Context: http, server, location 是否使用自动目录列表 Syntax: autoindex_exact_size on | off; Default: autoindex_exact_size on; Context: http, server, location 设置目录中列出的文件是显示精确大小,还是对KB,MB,GB进行四舍五入 Syntax: autoindex_format html | xml | json | jsonp; Default: autoindex_format html; Context: http, server, location This directive appeared in version 1.7.9. 设置目录列表的格式,当使用JSONP格式,回调函数的名称设置回调请求参数。如果参数丢失或为空值则使用JSON格式 Syntax: autoindex_localtime on | off; Default: autoindex_localtime off; Context: http, server, location 设置目录中列出文件的时间是本地时间还是UTC时间 Example Configuration location /bbs { root /web; autoindex on; index index.html index.htm; }
5、http状态统计模块:ngx_http_stub_status_module
Syntax: stub_status; Default: — Context: server, location Example Configuration location /status { stub_status on; access_log off; allow 172.16.1.101; deny all; } 状态统计信息官方示例 Active connections: 291 server accepts handled requests 16630948 16630948 31070465 Reading: 6 Writing: 179 Waiting: 106 active connections -- 当前处于活动状态的连接,包括处于wait状态的连接 server accepts handled requests -- nginx已经接受并处理16630948个连接,31070465个请求(每个连接1.8个请求) reading -- 正在读取请求首部的个数。 writing -- 正在读取请求主体的个数、正在处理请求主体的个数或者正向客户端发送响应的个数 waiting -- 长连接模式的保持的连接个数,数值等于active - (reading + writing)
6、http的SSL模块:ngx_http_ssl_module
Example Configuration server { listen 443; server_name localhost; ssl on; ssl_certificate /etc/nginx/ssl/nginx.crt; ssl_certificate_key /etc/nginx/ssl/nginx.key; ssl_session_timeout 5m; ssl_protocols SSLv2 SSLv3 TLSv1; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; location / { root /web/ssl; index index.html index.htm; } } 1、编辑nginx配置,定义如上一个server 2、CA编辑openssl的配置文件,修改如下一项 [root@soysauce nginx]# vim /etc/pki/tls/openssl.cnf dir = /etc/pki/CA 3、CA上创建两个目录,并生成CA自己的私钥 [root@soysauce nginx]# cd /etc/pki/CA/ [root@soysauce CA]# ls private [root@soysauce CA]# mkdir certs crl newcerts [root@soysauce CA]# (umask 077; openssl genrsa 2048 > private/cakey.pem) Generating RSA private key, 2048 bit long modulus ........................................+++ ........................+++ e is 65537 (0x10001) 4、CA生成自签署证书 [root@soysauce CA]# openssl req -new -x509 -key private/cakey.pem -out cacert.pem You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [GB]:CN State or Province Name (full name) [Berkshire]:HB Locality Name (eg, city) [Newbury]:HG Organization Name (eg, company) [My Company Ltd]:soysauce Organizational Unit Name (eg, section) []:Tech Common Name (eg, your name or your server's hostname) []:ca.soysauce.com Email Address []:[email protected] [root@soysauce CA]# ls cacert.pem certs crl newcerts private [root@soysauce CA]# echo 01 > serial [root@soysauce CA]# touch index.txt 5、nginx服务器生成自己的私钥 [root@soysauce CA]# cd /etc/nginx/ [root@soysauce nginx]# mkdir ssl [root@soysauce nginx]# cd ssl [root@soysauce ssl]# (umask 077; openssl genrsa 2048 > nginx.key) Generating RSA private key, 2048 bit long modulus ..+++ .....................+++ e is 65537 (0x10001) 6、nginx服务器生成证书签署请求 [root@soysauce ssl]# openssl req -new -key nginx.key -out nginx.csr You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [GB]:CN State or Province Name (full name) [Berkshire]:HB Locality Name (eg, city) [Newbury]:HG Organization Name (eg, company) [My Company Ltd]:soysauce Organizational Unit Name (eg, section) []:Tech Common Name (eg, your name or your server's hostname) []:www.soysauce.com Email Address []:[email protected] Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: 7、CA签署nginx的证书签署请求 [root@soysauce ssl]# openssl ca -in nginx.csr -out nginx.crt -days 3650 Using configuration from /etc/pki/tls/openssl.cnf Check that the request matches the signature Signature ok Certificate Details: Serial Number: 1 (0x1) Validity Not Before: Jan 18 13:57:30 2016 GMT Not After : Jan 15 13:57:30 2026 GMT Subject: countryName = CN stateOrProvinceName = HB organizationName = soysauce organizationalUnitName = Tech commonName = www.soysauce.com emailAddress = [email protected] X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: ED:5E:71:91:18:C5:AC:D2:8C:55:80:E8:90:69:29:B5:B3:13:FD:9D X509v3 Authority Key Identifier: keyid:B4:C9:06:73:2B:D9:40:2C:00:59:99:08:7D:FC:6E:40:28:18:77:BD Certificate is to be certified until Jan 15 13:57:30 2026 GMT (3650 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated 8、重启nginx服务,查看监听端口,并进行访问测试 [root@soysauce ssl]# service nginx restart nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful Stopping nginx: [ OK ] Starting nginx: [ OK ] [root@soysauce ssl]# netstat -tnlp | grep "nginx" tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1469/nginx tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 1469/nginx [root@soysauce nginx]# curl -k https://172.16.1.101SSL Page