Nginx高性能WEB服务器详解
第一章 初探
- Nginx 编译安装以及参数详解
-
Nginx安装 # wget http://nginx.org/download/nginx-1.10.2.tar.gz # tar xvf nginx-1.10.2.tar.gz -C /usr/local/src # yum groupinstall "Development too # yum -y install gcc wget gcc-c++ automake autoconf \ -- libtool libxml2-devel libxslt-devel perl-devel \ --perl-ExtUtils-Embed pcre-devel openssl-devel # cd /usr/local/src/nginx-1.10.2 # ./configure \ --prefix=/usr/local/nginx \ 指向安装目录 --sbin-path=/usr/sbin/nginx \ 指向(执行)程序文件(nginx) --conf-path=/etc/nginx/nginx.conf \ 指向配置文件(nginx.conf) --error-log-path=/var/log/nginx/error.log \ 指向错误日志目录 --http-log-path=/var/log/nginx/access.log \ --pid-path=/var/run/nginx.pid \ 指向pid文件(nginx.pid) --lock-path=/var/run/nginx.lock \ 指向lock文件(nginx.lock)(安装文件锁定,防止安装文件被别人利用,或自己误操作。) --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 \ --user=nginx \ 指定程序运行时的非特权用户 --group=nginx \ 指定程序运行时的非特权用户组 --with-pcre \ 启用pcre库 --with-http_v2_module \ --with-http_ssl_module \ 启用ngx_http_ssl_module支持(使支持https请求,需已安装openssl) --with-http_realip_module \ 启用ngx_http_realip_module支持(这个模块允许从请求标头更改客户端的IP地址值,默认为关) --with-http_addition_module \ --with-http_sub_module \ 启用ngx_http_sub_module支持(允许用一些其他文本替换nginx响应中的一些文本) --with-http_dav_module \ 启用ngx_http_dav_module支持(增加PUT,DELETE,MKCOL:创建集合,COPY和MOVE方法)默认情况下为关闭,需编译开启 --with-http_flv_module \ 启用ngx_http_flv_module支持(提供寻求内存使用基于时间的偏移量文件) --with-http_mp4_module \ --with-http_gunzip_module \ 禁用ngx_http_gzip_module支持(该模块同-with-http_gzip_static_module功能一样) --with-http_gzip_static_module \ 启用ngx_http_gzip_static_module支持(在线实时压缩输出数据流) --with-http_random_index_module \ 启用ngx_http_random_index_module支持(从目录中随机挑选一个目录索引) --with-http_secure_link_module \ 启用ngx_http_secure_link_module支持(计算和检查要求所需的安全链接网址) --with-http_stub_status_module \ 启用ngx_http_stub_status_module支持(获取nginx自上次启动以来的工作状态) --with-http_auth_request_module \ 禁用ngx_http_auth_basic_module(该模块是可以使用用户名和密码基于http基本认证方法来保护你的站点或其部分内容) -–without-http_access_module 禁用ngx_http_access_module支持(该模块提供了一个简单的基于主机的访问控制。允许/拒绝基于ip地址) –-without-http_autoindex_module 禁用disable ngx_http_autoindex_module支持(该模块用于自动生成目录列表,只在ngx_http_index_module模块未找到索引文件时发出请求。) –-without-http_geo_module 禁用ngx_http_geo_module支持(创建一些变量,其值依赖于客户端的IP地址 -–without-http_map_module 禁用ngx_http_map_module支持(使用任意的键/值对设置配置变量) –-without-http_split_clients_module 禁用ngx_http_split_clients_module支持(该模块用来基于某些条件划分用户。条件如:ip地址、报头、cookies等等) –-without-http_referer_module 禁用disable ngx_http_referer_module支持(该模块用来过滤请求,拒绝报头中Referer值不正确的请求) –-without-http_rewrite_module 禁用ngx_http_rewrite_module支持(该模块允许使用正则表达式改变URI,并且根据变量来转向以及选择配置 –-without-http_proxy_module 禁用ngx_http_proxy_module支持(有关代理服务器) -–without-http_fastcgi_module 禁用ngx_http_fastcgi_module支持(该模块允许Nginx 与FastCGI 进程交互,并通过传递参数来控制FastCGI 进程工作。 )FastCGI一个常驻型的公共网关接口。 –-without-http_upstream_ip_hash_module 禁用ngx_http_upstream_ip_hash_module支持(该模块用于简单的负载均衡) -–with-http_perl_module 启用ngx_http_perl_module支持(该模块使nginx可以直接使用perl或通过ssi调用perl) –-with-perl_modules_path= 设定perl模块路径 -–with-perl= 设定perl库文件路径 -–http-log-path= 设定access log路径 -–http-client-body-temp-path= 设定http客户端请求临时文件路径 -–http-proxy-temp-path= 设定http代理临时文件路径 -–http-fastcgi-temp-path= 设定http fastcgi临时文件路径 -–http-uwsgi-temp-path= 设定http uwsgi临时文件路径 –-http-scgi-temp-path= 设定http scgi临时文件路径 --without-http 禁用http server功能 -–without-http-cache 禁用http cache功能 -–with-mail 启用POP3/IMAP4/SMTP代理模块支持 -–with-mail_ssl_module 启用ngx_mail_ssl_module支持 -–without-mail_pop3_module 禁用pop3协议 --with-file-aio \ --with-ipv6 \ 启用ipv6支持 --with-http_v2_module \ --with-threads \ --with-stream \ -–with-libatomic= 指向libatomic_ops安装目录 -–with-openssl= 指向openssl安装目录 -–with-openssl-opt 在编译时为openssl设置附加参数 --with-debug 启用debug日志 --with-stream_ssl_module --add-module=/home/tinywan/nchan-1.1.3/ # make && make install # mkdir -pv /var/tmp/nginx/client 启动关闭重置Nginx 启动:直接执行以下命令,nginx就启动了,不需要改任何配置文件 /usr/local/nginx -1.5.1/sbin/nginx 关闭 /usr/local/nginx -1.5.1/sbin/nginx -s stop 重启 /usr/local/nginx -1.5.1/sbin/nginx -s reload C:\Program Files\Git\bin nginx root&alias文件路径配置 nginx指定文件路径有两种方式root和alias,这两者的用法区别,使用方法总结了下,方便大家在应用过程中,快速响应。root与alias主要区别在于nginx如何解释location后面的uri,这会使两者分别以不同的方式将请求映射到服务器文件上。 location /abc/ { alias /home/html/def/; } alias会把location后面配置的路径丢弃掉,把当前匹配到的目录指向到指定的目录。如果一个请求的URI是/abc/a.ttlsa.com/favicon.jgp时,web服务器将会返回服务器上的/home/html/def/a.ttlsa.com/favicon.jgp的文件。 alias注意要点 1.使用alias时,目录名后面一定要加”/”`。 2.alias可以指定任何名称。 3.alias在使用正则匹配时,必须捕捉要匹配的内容并在指定的内容处使用。 4.alias只能位于location块中
- NGINX变量详解
-
set 指令 属于 ngx_rewrite 模块 set 指令(以及前面提到的 geo 指令)不仅有赋值的功能 set 指令 还有创建 Nginx 变量的副作用,即当作为赋值对象的变量尚不存在时,它会自动创建该变量 Nginx 变量的创建只能发生在 Nginx 配置加载的时候,或者说 Nginx 启动的时候 赋值操作则只会发生在请求实际处理的时候 变量插值:通过已有的 Nginx 变量 $a 的值,来构造变量 $b 的值,这种技术在 Perl 世界里被称为“变量插值” set $a hello; set $b "$a, $a"; echo 指令 属于 ngx_echo 模块 geo 指令 属于 ngx_geo模块,ngx_geo 模块最常规的用法是根据客户端的 IP 地址对指定的 Nginx 变量进行赋值 Nginx 变量一旦创建,其变量名的可见范围就是整个 Nginx 配置,甚至可以跨越不同虚拟主机的 server 配置块 用户变量未赋值就输出的话,得到的便是空字符串 Nginx 变量名的可见范围虽然是整个配置,但每个请求都有所有变量的独立副本,或者说都有各变量用来存放值的容器的独立副本,彼此互不干扰 事实上,Nginx 变量的生命期是不可能跨越请求边界的 echo_exec 指令属于 ngx_echo 模块,发起到 location 的内部跳转 内部跳转 就是在处理请求的过程中,于服务器内部,从一个 location 跳转到另一个 location 的过程 外部跳转 set 指令 还有创建 Nginx 变量的副作用,即当作为赋值对象的变量尚不存在时,它会自动创建该变量 利用 HTTP 状态码 301 和 302 所进行的“外部跳转”,因为由 HTTP 客户端配合进行跳转的,而且在客户端,用户可以通过浏览器地址栏这样的界面,看到请求的 URL 地址发生了变化 标准 ngx_rewrite 模块的 rewrite 配置指令其实也可以发起“内部跳转” server { listen 8080; location /foo { set $a hello; rewrite ^ /bar; } location /bar { echo "a = [$a]"; } } rewrite 发起 301 和 302 这样的“外部跳转” Nginx 模块提供的“预定义变量”,或者说“内建变量”(builtin variables) 变量 $uri 属于 ngx_http_core 模块,可以用来获取当前请求的 URI(经过解码,并且不含请求参数) 变量 $request_uri 用来获取请求最原始的 URI (未经解码,并且包含请求参数) 案例 location /test { echo "uri = $uri"; echo "request_uri = $request_uri"; } 测试结果 $ curl 'http://localhost:8080/test' uri = /test request_uri = /test $ curl 'http://localhost:8080/test?a=3&b=4' uri = /test request_uri = /test?a=3&b=4 $ curl 'http://localhost:8080/test/hello%20world?a=3&b=4' uri = /test/hello world request_uri = /test/hello%20world?a=3&b=4 内建变量其实并不是单独一个变量,而是有无限多变种的一群变量,即名字以 arg_ 开头的所有变量,我们估且称之为 $arg_XXX 变量群 Nginx 会在匹配参数名之前,自动把原始请求中的参数名调整为全部小写的形式 set_unescape_uri 配置指令属于 ngx_set_misc 模块,对 URI 参数值中的 %XX 这样的编码序列进行解码 取 cookie 值的 $cookie_XXX 变量群 用来取请求头的 $http_XXX 变量群 用来取响应头的 $sent_http_XXX 变量群
- Nginx指令执行顺序
第二章 安装部署
- 启动错误:
Nginx [emerg]: bind() to 0.0.0.0:80 failed (98: Address already in use)
,执行:sudo fuser -k 80/tcp
- 基于域名、IP的虚拟主机配置
- 完整、标准配置实际示列
- 日志文件配置与切割
- alias 和 root 在location 下的应用
- 通过alias 实现别名功能
location /live { alias /home/tinywan/HLS/; }
- 通过alias 实现别名功能
- curl 请求结果
tinywan@tinywan:~/HLS$ cat index.html alias /home/tinywan/HLS/index.html tinywan@tinywan:~/HLS$ curl http://127.0.0.1/live/index.html alias /home/tinywan/HLS/index.html
- 结论:
- cul 请求
/live/index.html
,那么Nginx将会在服务器上查找/home/tinywan/HLS/index.html
文件 - 请求的
url
中的location
后面的部分会被追加到alias
指定的目录后面,而location
后面的/live
路径将会别自动抛弃
- cul 请求
- 类似案例[2]:
- config配置信息
location ~ ^/live/(.*)$ { alias /home/tinywan/HLS/$1; }
- curl 请求结果
tinywan@tinywan:~/HLS$ pwd /home/tinywan/HLS tinywan@tinywan:~/HLS$ cat txt.txt txt file tinywan@tinywan:~/HLS$ curl http://127.0.0.1/live/txt.txt txt file
- 如果url请求
/live/txt.txt
那么Nginx将会在服务器上查找/home/tinywan/HLS/txt.txt
文件
- config配置信息
- 与root 功能的差别:
- config配置信息,注意:一下的
alias
换成root
location ~ ^/live/(.*)$ { root /home/tinywan/HLS/$1; }
- curl 请求结果
tinywan@tinywan:~/HLS$ curl http://127.0.0.1/live/txt.txt <html> <head><title>404 Not Found</title></head> <body bgcolor="white"> <center><h1>404 Not Found</h1></center> <hr><center>openresty/1.11.2.1</center> </body> </html>
- 日志文件信息(打开Nginx的rewrite日志:rewrite_log on;):
/home/tinywan/HLS/txt.txt/live/txt.txt
- 二者的区别
alias
指定的目录是当前目录root
指定的是根目录- 一般建议的
location /
中通过root
命令配置目录,其他目录匹配的位置使用alias
命令
- 一般建议的
- config配置信息,注意:一下的
- 案例[3]:
- config配置信息
location ~ ^/live/(\w+)/(.*) { alias /home/tinywan/HLS/live/$1/$2; }
- curl 请求结果
tinywan@tinywan:~/HLS/live/stream123$ pwd /home/tinywan/HLS/live/stream123 tinywan@tinywan:~/HLS/live/stream123$ cat index.m3u8 12312312312 tinywan@tinywan:~/HLS/live/stream123$ curl "http://127.0.0.1/live/stream123/index.m3u8?token=1234&api=009132" 12312312312
- config配置信息
第三章 架构初探
第四章 高级配置
-
基本语法:location [=||*|^~] /uri/ { … }
=
:严格匹配。如果这个查询匹配,那么将停止搜索并立即处理此请求。~
:为区分大小写匹配(可用正则表达式)!~
:为区分大小写不匹配!~*
:为不区分大小写不匹配^~
:如果把这个前缀用于一个常规字符串,那么告诉nginx 如果路径匹配那么不测试正则表达式
-
正则中需要转义的特殊字符小结
- [1]
$
匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 也匹配‘\n′或‘\r′。要匹配也匹配‘\n′或‘\r′。要匹配 字符本身,请使用 $。 - [2]
( )
标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 和。 - [3]
*
匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 *。 - [4]
+
匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +。 - [5]
.
匹配除换行符 \n之外的任何单字符。要匹配 .,请使用 \。 - [6]
[ ]
标记一个中括号表达式的开始。要匹配 [,请使用 [。 - [7]
?
匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 ?。 - [8]
\
将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, ‘n' 匹配字符 ‘n'。'\n' 匹配换行符。序列 ‘\' 匹配 “\”,而 ‘(' 则匹配 “(”。 - [9]
^
匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用 ^。 - [10]
{ }
标记限定符表达式的开始。要匹配 {,请使用 {。 - [11]
|
指明两项之间的一个选择。要匹配 |,请使用 |。
- [1]
-
正则表达式 (Regular expression) 匹配location
- [1]
location ~* \.(gif|jpg|jpeg)$ { }
:匹配所有以 gif,jpg或jpeg 结尾的请求 - [2]
location ~ /documents/Abc { }
:匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索 - [3] 目录匹配:
- 可以匹配静态文件目录
(static/lib)
- HLS直播目录
(/home/HLS/stream123/index.m3u8)
- HLS/MP4/FLV点播视频目录
(/home/HLS/stream123.m3u8)
- 匹配URL地址:
http://127.0.0.1/live/stream123/index.m3u8
- nginx.conf 配置信息
# 匹配任何以/live/ 开头的任何查询并且停止搜索。任何正则表达式将不会被测试 location ^~ /live/ { root /home/tinywan/HLS/; } # 以上匹配成功后的组合:/home/tinywan/HLS/live/....
- 可以匹配静态文件目录
- [1]
-
后缀匹配
- 匹配任何后缀文件名
gif|jpg|jpeg|png|css|js|ico|m3u8|ts
结尾的请求 - TS 文件匹配
http://127.0.0.1/live/stream123/11.ts
- M3U8 文件匹配
http://127.0.0.1/live/stream123/index.m3u8
- 匹配URL地址:
http://127.0.0.1/hls/123.m3u8
- nginx.conf 配置信息
location ~* \.(gif|jpg|jpeg|png|css|js|ico|m3u8|ts)$ { root /home/tinywan/HLS/; }
- 匹配任何后缀文件名
-
HSL直播目录匹配实际案例(请测试上线)
- 可以后缀文件名:
http://127.0.0.1/live/stream123/index.m3u8
location ^~ /live/ { root /home/tinywan/HLS/; }
- 可以后缀文件名:
第五章 Gzip压缩
第六章 Rewrite 功能
-
Rewrite 常用全局变量
- 请求案例:
curl -G -d "name=Tinywan&age=24" http://127.0.0.1/rewrite_var/1192/index.m3u8
- 接受结果:
变量 值 描述 $args name=Tinywan&age=24 存放URL 请求的指令 $content_length 0 请求头中的Content-length字段 $content_type 0 请求头中的Content-Type字段 $document_root /opt/openresty/nginx/html 当前请求在root指令中指定的值 $document_uri /rewrite_var/1192/index.m3u8 与$uri相同 $host 127.0.0.1 请求主机头字段,否则为服务器名称 $http_user_agent curl/7.47.0 客户端agent信息 $http_cookie 0 COOKIE变量的值 $limit_rate 0 限制连接速率 $request_body_file null 客户端请求主体信息的临时文件名 $request_method GET 客户端请求的动作,通常为GET或POST $remote_addr 127.0.0.1 客户端的IP地址 $remote_port 33516 客户端端口 $remote_user 0 已经经过Auth Basic Module验证的用户名 $request_filename /opt/openresty/nginx/html/rewrite_var/1192/index.m3u8 当前请求的文件路径 $request_uri /rewrite_var/1192/index.m3u8?name=Tinywan&age=24 包含请求参数的原始URI,不包含主机名 $query_string name=Tinywan&age=24 与$args相同 $scheme http HTTP方法(如http,https $server_protocol HTTP/1.1 请求使用的协议,通常是HTTP/1.0或HTTP/1.1 $server_addr 127.0.0.1 服务器地址 $server_name localhost 服务器名称 $server_port 80 请求到达服务器的端口号 $uri /rewrite_var/1192/index.m3u8 不带请求参数的当前URI $binary_remote_addr 乱码 二进制格式的客户端地址 - uri 介绍 (Nginx中的URI是相对的URI)
- URL:
https://github.com/Tinywan/Lua-Nginx-Redis/blob/master/Nginx/config.md
- 绝对URI:
https://github.com/Tinywan/Lua-Nginx-Redis/blob/master/Nginx/config.md
- 相对URI:
/Tinywan/Lua-Nginx-Redis/blob/master/Nginx/config.md
- URL:
- 请求案例:
-
Rewrite 正则匹配
uri
参数接收- 请求案例:
curl http://192.168.18.143/live/tinywan123/index.m3u8
- Nginx.conf配置文件
location ~* ^/live/(\w+)/(\D+)\.(m3u8|ts)$ { set $num $2; set $arg1 $1; echo "args === ${arg1}"; echo "1==$1 2==$2 3==$3"; echo "Total_numbser :: $num"; echo "URI $uri"; }
- 输出结果
args === tinywan123 $1==tinywan123 $2==index $3==m3u8 Total_numbser :: index URI /live/tinywan123/index.m3u8 Total_numbser ::
- $1为正则匹配多个英文字母或数字的字符串
(\w+)
$2 为正则匹配多个非数字(\D+)
$3 为正则匹配的第一个值(m3u8|ts)
.
需要用转义字符转义\.
- 请求案例:
第七章 代理服务
- 正向代理和反向代理的概念
- 正向代理服务
- 反向代理的服务
- Nginx日志服务
- 负载均衡
- HTTP负载均衡
- TCP负载均衡
- proxy_pass 代理的URL总结
- 在nginx中配置proxy_pass时,当在后面的url加上了/,相当于是绝对根路径,则nginx不会把location中匹配的路径部分代理走;如果没有/,则会把匹配的路径部分也给代理走。
- 将url中以/wap/开头的请求转发到后台对应的某台server上,注意最后的?$args,表明把原始url最后的get参数也给代理到后台
location ~* /wap/(\d+)/(.+) { proxy_pass http://mx$1.test.com:6601/$2?$args; }
- 第一种配置,访问:
http://127.0.0.1/proxy/index.html
会被代理到:http://127.0.0.1:8000/index.html
location /proxy/ { proxy_pass http://127.0.0.1:8000/; }
- 第二种配置,访问:
http://127.0.0.1/proxy/index.html
会被代理到:http://127.0.0.1:8000/proxy/index.html
location /proxy/ { proxy_pass http://127.0.0.1:8000; }
- 第三种配置,访问:
http://127.0.0.1/proxy/index.html
会被代理到:http://127.0.0.1:8000/video/index.html
location /proxy/ { proxy_pass http://127.0.0.1:8000/video/; }
- 第四种配置,访问:
http://127.0.0.1/proxy/index.html
会被代理到:http://127.0.0.1:8000/videoindex.html
location /proxy/ { proxy_pass http://127.0.0.1:8000/video; }
- location 直接访问:
- 以下配置,当访问:
http://127.0.0.1:8000/proxy/index.html
会被匹配到:/usr/local/nginx/html/proxy/index.html
location /proxy/ { root /usr/local/nginx/html; index index.html index.htm; }
- 以下配置,当访问: