实现虚拟主机有三种方式:基于端口,基于ip,基于FQDN。
基于端口:因为不是默认的80端口,所以客户端访问时需要指明指定的端口
基于ip: 每个虚拟主机都需要一个不同的ip
基于FQDN:每个虚拟主机都有一个不同的域名来标识
[root@localhost ~]#vim /etc/nginx/conf.d/vhost.conf
server {
listen 80;
server_name node1.kej.io;
root /data/node1;
location / {
index index.html;
}
}
server {
listen 80;
server_name node2.kej.io;
location / {
index index.html;
root /data/node2;
}
}
server {
listen 80;
server_name *.kej.io;
root /data/node;
location / {
index index.html;
}
}
location匹配url,支持正则表达式。
location = / { #精确匹配
[ configuration A ]
}
location / { #不带符号
[ configuration B ]
}
location /documents/ {
[ configuration C ]
}
location ^~ /images/ { #^~正则表达式,从URI左侧开始匹配,不区分大小写。
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ { #~*正则表达式,不区分大小写。~区分大小写
[ configuration E ]
}
优先级:= > ^~ > ~|~* > 不带符号
“/”匹配configuration A
“/index.html”匹配configuration B
“/documents/document.html”匹配configuration C
“/images/1.gif”匹配configuration D
“/documents/1.jpg”匹配configuration E
隐藏错误页面和响应报文头部中的nginx版本信息
Syntax: server_tokens on | off | build | string;
Default: server_tokens on;
Context: http, server, location
定义客户端请求的配置:
保持链接的超时时长
Syntax: keepalive_timeout timeout [header_timeout];
Default: keepalive_timeout 75s;
Context: http, server, location
一次保持链接中最多请求次数
Syntax: keepalive_requests number;
Default: keepalive_requests 100;
Context: http, server, location
This directive appeared in version 0.8.0.
发送响应报文给客户端的超时时间,如果客户端在规定时间中没有收到任何东西,链接断开
Syntax: send_timeout time;
Default: send_timeout 60s;
Context: http, server, location
用于接收客户端请求报文的body部分缓冲区大小,默认16K,超出时放在client_body_temp_path定义的位置
Syntax: client_body_buffer_size size;
Default: client_body_buffer_size 8k|16k;
Context: http, server, location
设定用于储存客户端报文的body部分的临时存储路径及目录结构和数量 例如 2 1 1
Syntax: client_body_temp_path path [level1 [level2 [level3]]];
Default: client_body_temp_path client_body_temp;
Context: http, server, location
例如
client_body_temp_path /spool/nginx/client_temp 1 2;
/spool/nginx/client_temp/7/45/00000123457
Syntax: tcp_nodelay on | off;
Default: tcp_nodelay on; #keepalive启用才有效
Context: http, server, location
Syntax: tcp_nopush on | off;
Default: tcp_nopush off; #sendfile启用时才有效
Context: http, server, location
Syntax: sendfile on | off;
Default: sendfile off;
Context: http, server, location, if in location
事例
location /video/ {
sendfile on;
tcp_nopush on;
aio on;
}
文件操作优化配置
是否启动文件系统的异步传输功能
Syntax: aio on | off | threads[=pool];
Default: aio off;
Context: http, server, location
This directive appeared in version 0.8.11.
Syntax: directio size | off;
Default: directio off;
Context: http, server, location
This directive appeared in version 0.7.7.
Syntax: open_file_cache off;
open_file_cache max=N [inactive=time]; #缓存项上限和缓存时间。LRU算法清理
Default: open_file_cache off;
Context: http, server, location
例子
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
是否缓存文件查找错误
Syntax: open_file_cache_errors on | off;
Default: open_file_cache_errors off;
Context: http, server, location
在缓存时间中最少访问次数
Syntax: open_file_cache_min_uses number;
Default: open_file_cache_min_uses 1;
Context: http, server, location
缓存检查频率
Syntax: open_file_cache_valid time;
Default: open_file_cache_valid 60s;
Context: http, server, location
对客户端限制的配置
Syntax: limit_rate rate; #单位字节/每秒
Default: limit_rate 0; #默认不限制
Context: http, server, location, if in location
Syntax: limit_except method ... { ... } #method:GET, HEAD, POST, PUT, DELETE, MKCOL, COPY, MOVE, OPTIONS, PROPFIND, PROPPATCH, LOCK, UNLOCK, or PATCH.
Default: —
Context: location
例子
limit_except GET {
allow 192.168.1.0/32;
deny all;
}
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 / {
deny 192.168.1.1;
allow 192.168.1.0/24;
allow 10.1.1.0/16;
allow 2001:0db8::/32;
deny all;
}
访问权限管理,生效顺序从上到下
用户登陆身份验证模块
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
例子
location / {
auth_basic "closed site";
auth_basic_user_file conf/htpasswd;
}
nginx状态页模块
ngx_http_stub_status_module
Syntax: stub_status;
Default: —
Context: server, location
例子
location = /basic_status {
stub_status;
}
实验:给nginx状态页添加用户登陆验证
location /ngxstatus {
auth_basic "closed site";
auth_basic_user_file /etc/nginx/user;
stub_status;
}
[root@localhost /etc/nginx]#yum install -y httpd-tools
[root@localhost /etc/nginx]#htpasswd -cm /etc/nginx/user kej
输入用户名和密码
Active connections
The current number of active client connections including Waiting connections.
accepts
The total number of accepted client connections.
handled
The total number of handled connections. Generally, the parameter value is the same as accepts unless some resource limits have been reached (for example, the worker_connections limit).
requests
The total number of client requests.
Reading
The current number of connections where nginx is reading the request header.
Writing
The current number of connections where nginx is writing the response back to the client.
Waiting
The current number of idle client connections waiting for a request.
日志模块
ngx_http_log_module
Syntax: access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
access_log off;
Default: access_log logs/access.log combined; #默认为主配置文件,combined格式
Context: http, server, location, if in location, limit_except #每个代码段下都可以单独定义日志
可以使用syslog工具保存日志,使用gzip会压缩日志文件,压缩等级1-9,用zcat查看日志
例子
access_log /path/to/log.gz combined gzip flush=5m;
Syntax: log_format name [escape=default|json|none] string ...;
Default: log_format combined "...";
Context: http
例子
log_format compression '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" "$gzip_ratio"';
access_log /spool/logs/nginx-access.log compression buffer=32k;
Syntax: open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
open_log_file_cache off;
Default: open_log_file_cache off;
Context: http, server, location
max:设置缓存中文件描述符的最大数量,超过数量用LRU算法清理
inactive:非活动时长,默认10秒
valid:检查频率,默认60秒
min_uses:在inactive定义的时间中最少使用次数
ngx_http_gzip_module
Syntax: gzip on | off;
Default: gzip off;
Context: http, server, location, if in location
Syntax: gzip_buffers number size;
Default: gzip_buffers 32 4k|16 8k;
Context: http, server, location
Syntax: gzip_comp_level level;
Default: gzip_comp_level 1; #1-9
Context: http, server, location
Syntax: gzip_min_length length;
Default: gzip_min_length 20;
Context: http, server, location
响应报文头部“Content-Length”的值超过定义的值才会被压缩
Syntax: gzip_types mime-type ...;
Default: gzip_types text/html;
Context: http, server, location
是否压缩MIME中的文件类型。*表示全都压缩。
cat /etc/nginx/mime.types #查看所有MIME的文件类型
Syntax: gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any ...;
Default: gzip_proxied off;
Context: http, server, location
off
disables compression for all proxied requests, ignoring other parameters;
expired
enables compression if a response header includes the “Expires” field with a value that disables caching;
no-cache
enables compression if a response header includes the “Cache-Control” field with the “no-cache” parameter;
no-store
enables compression if a response header includes the “Cache-Control” field with the “no-store” parameter;
private
enables compression if a response header includes the “Cache-Control” field with the “private” parameter;
no_last_modified
enables compression if a response header does not include the “Last-Modified” field;
no_etag
enables compression if a response header does not include the “ETag” field;
auth
enables compression if a request header includes the “Authorization” field;
any
enables compression for all proxied requests.
ngx_http_rewrite_module
Syntax: rewrite regex replacement [flag]; #flag:last,break,redirect,permanent
Default: —
Context: server, location, if
URL重定向; “http://”, “https://”, “$scheme”会把结果直接返回给客户端
last:跳出当前循环并且重新开始循环 #可能造成死循环,最多循环10次
break:跳出所有循环 #推荐使用
redirect:返回302的响应码,临时重定向
permanent:返回301的响应码,永久重定向
例子
server {
...
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last;
return 403;
...
}
location /download/ {
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break; #此处用last会造成死循环
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;
return 403;
}
实验:实现URL重定向
[root@localhost /etc/nginx]#vim conf.d/vhost.conf
server {
listen 80;
server_name www.kej.com;
root /data;
location /data {
rewrite ^/data/(.*)$ /app/$1 last;
}
}
[root@localhost ~]#tree /data/
/data/
├── app
│ └── index.html
└── index.html
[root@localhost ~]#curl http://www.kej.com/ #当访问/时,/data/index.html会响应
/data/index
[root@localhost ~]#curl http://www.kej.com/data/index.html #当访问/data/index.html时,会被重定向到/data/app/index.html
/data/app/index
[root@localhost /etc/nginx]#vim conf.d/vhost.conf
server {
server_name www.kej.com;
root /data;
location /data {
rewrite ^/data/(.*)$ /app/$1 redirect;
}
}
[root@localhost ~]#curl http://www.kej.com/data/
<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center> #返回302响应码
<hr><center>nginx/1.12.2</center>
</body>
</html>
[root@localhost /etc/nginx]#vim conf.d/vhost.conf
server {
server_name www.kej.com;
root /data;
location /data {
rewrite ^/data/(.*)$ /app/$1 permanent;
}
}
[root@localhost ~]#curl -Li http://www.kej.com/data/ #L:跳转 i:显示头部信息
HTTP/1.1 301 Moved Permanently #响应301
Server: nginx/1.12.2
Date: Tue, 28 May 2019 04:08:24 GMT
Content-Type: text/html
Content-Length: 185
Location: http://www.kej.com/app/
Connection: keep-alive
HTTP/1.1 200 OK #重定向后,客户端会再次访问新的URL
Server: nginx/1.12.2
Date: Tue, 28 May 2019 04:08:24 GMT
Content-Type: text/html
Content-Length: 16
Last-Modified: Tue, 28 May 2019 03:49:18 GMT
Connection: keep-alive
ETag: "5cecafbe-10"
Accept-Ranges: bytes
/data/app/index #页面信息
用来阻塞请求报文头部中“Referer”为invalid_referer的值
ngx_http_referer_module
Syntax: valid_referers none | blocked | server_names | string ...;
Default: —
Context: server, location
例子
valid_referers none blocked server_names #定义有效值
*.example.com example.* www.example.org/galleries/
~\.google\.; #正则表达式或通配符
if ($invalid_referer) { #无效值
return 403; #可以返回URL
}
ngx_http_proxy_module #反向代理模块
Syntax: proxy_pass URL; #URL可以是域名或者IP+port. 可以是http或者https协议
Default: —
Context: location, if in location, limit_except
例子
proxy_pass http://localhost:8000/uri/;
实验:实现nginx反代
在前端nginx
[root@localhost /etc/nginx]#vim conf.d/vhost.conf
server {
listen 80;
server_name www.kej.com;
root /data;
location /app {
proxy_pass http://www.kej.io; #注意,IP后面的"/"是否存在会造成反代结果不一样
}
}
在后端nginx
[root@centos7 ~]#vim /etc/nginx/conf.d/vhost.conf
server {
listen 80;
server_name www.kej.io;
root /myapp/;
}
[root@centos7 ~]#tree /myapp/
/myapp/
├── app
│ └── index.html #/myapp/app/index
└── index.html #/myapp/index
找另一台主机测试:需要在/etc/hosts解析域名
[root@localhost ~]#curl -L http://www.kej.com/app/
/myapp/app/index
在后端nginx上查看日志
192.168.91.139 - - [28/May/2019:15:41:05 +0800] "GET /app/ HTTP/1.0" 200 17 "-" "curl/7.29.0" "-"
可以看到客户端地址为前端nginx
在前端nginx上查看日志
192.168.91.137 - - [28/May/2019:15:41:05 +0800] "GET /app/ HTTP/1.1" 200 17 "-" "curl/7.29.0" "-"
可以看到客户端地址为真正的客户端地址
[root@localhost /etc/nginx]#vim conf.d/vhost.conf
server {
listen 80;
server_name www.kej.com;
root /data;
location /app {
proxy_pass http://www.kej.io/;
}
}
[root@localhost ~]#curl -L http://www.kej.com/app/
/myapp/index
总结:proxy_pass后的URL有“/”存在时,直接反代到后端web服务的根目录下
“/”不存在时,反带到后端web服务的根目录下由location指定的某个目录下
当location使用正则表达式时,不能有“/”
Syntax: proxy_set_header field value;
Default: proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
Context: http, server, location
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
192.168.91.139 - - [28/May/2019:16:33:31 +0800] "GET / HTTP/1.0" 200 28 "-" "curl/7.29.0" "192.168.91.137"
实验:nginx反代php
注意:nginx不支持php模块化。使用php-fpm
在php主机上
[root@centos7 ~]#yum install -y php-fpm
[root@centos7 ~]#vim /etc/php-fpm.d/www.conf
listen = 0.0.0.0:9000 #监听所有网卡
listen.allowed_clients = 192.168.91.139 #允许nginx主机访问
[root@centos7 ~]#systemctl start php-fpm
[root@centos7 ~]#ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:9000 *:*
[root@centos7 ~]#vim /app/php/index.php
<?php
phpinfo();
?>
在nginx主机
[root@localhost /etc/nginx]#vim nginx.conf
location ~ \.php$ {
fastcgi_pass 192.168.91.132:9000; #php主机地址和端口
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /app/php$fastcgi_script_name; #php文件位置;/app/php/
include fastcgi_params;
}
浏览器访问192.168.91.139/index.php(nginx主机)
实验:php状态页面
在192.168.91.132上安装php-fpm
[root@centos7 ~]#yum install -y php-fpm
[root@centos7 ~]#vim /etc/php-fpm.d/www.conf
listen = 0.0.0.0:9000 #监听所有网卡
listen.allowed_clients = 192.168.91.139 #允许nginx主机访问
pm.status_path = /status
ping.path = /ping
ping.response = pong
在nginx主机
[root@localhost /etc/nginx]#vim nginx.conf
location ~* ^/(status|ping)$ {
fastcgi_pass 192.168.91.132:9000;
fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
include fastcgi_params;
}
实验:nginx实现动静分离
注意:proxy_pass似乎不能把请求反代到自己的虚拟主机上,只能代理到其他的虚拟主机。不过我并不确定
[root@localhost /etc/nginx]#vim conf.d/vhost.conf
server {
listen 80;
server_name www.kej.com;
root /data;
index index.html index.php;
location ~\.php$ {
fastcgi_pass 192.168.91.132:9000;
fastcgi_param SCRIPT_FILENAME /app/php$fastcgi_script_name;
include fastcgi_params;
}
location / {
proxy_pass http://127.0.0.1; #当把地址改为www.kej.com时。访问静态资源无反应,这里用的是nginx的默认主机
}
}
在192.168.91.132上配置php-fpm,前面有写
ngx_http_upstream_module #定义后端服务器组,可以被proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, memcached_pass, and grpc_pass引用
例子:
upstream backend { #backend为后端服务器组的名字,不同的组名字不能一样
server backend1.example.com weight=5; #定义每个组的成员
server backend2.example.com:8080;
server unix:/tmp/backend3;
server backup1.example.com:8080 backup; #sorry server
server backup2.example.com:8080 backup;
}
server {
location / {
proxy_pass http://backend; #引用组
}
}
resolver 10.0.0.1;
upstream dynamic {
zone upstream_dynamic 64k;
server backend1.example.com weight=5;
server backend2.example.com:8080 fail_timeout=5s slow_start=30s;
server 192.0.2.1 max_fails=3;
server backend3.example.com resolve;
server backend4.example.com service=http resolve;
server backup1.example.com:8080 backup;
server backup2.example.com:8080 backup;
}
server {
location / {
proxy_pass http://dynamic;
health_check;
}
}
Syntax: upstream name { ... }
Default: —
Context: http
例子:
upstream backend {
server backend1.example.com weight=5;
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
server backup1.example.com backup;
}
Syntax: server address [parameters];
Default: —
Context: upstream
paramters:
weight=number默认为1
max_conns=number反代给后端主机最大的活动连接数,默认0,不限制
max_fails=number与后端服务器连接失败次数。默认为1
fail_timeout=time与后端服务器连接超时时长。默认10s
backup备用服务器。当其他服务器不可用时自动启用
down禁用服务器
resolve监测服务器的域名对应的IP地址的变化,并且在不重启Nginx的情况下应用这些变化。这功能可以通过resolver指令实现,该指令必须放在http块里,还有服务器组里server指令的resolve参数必须指定。
例子:
http {
resolver 10.0.0.1;
upstream u {
zone ...;
...
server example.com resolve;
}
}
Syntax: hash key [consistent];
Default: —
Context: upstream
This directive appeared in version 1.7.2.
例子:
hash $request_uri consistent #一致性hash
Syntax: ip_hash; #源ip地址hash
Default: —
Context: upstream
如果后端服务器需要临时移除,应该标记为down状态,防止继续被访问
例子:
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com down;
server backend4.example.com;
}
Syntax: keepalive connections;
Default: —
Context: upstream
This directive appeared in version 1.1.4.
每个worker进程上的最大空闲的持久连接数量,超过时使用LRU算法清理
例子:针对memcached
upstream memcached_backend {
server 127.0.0.1:11211;
server 10.0.0.2:11211;
keepalive 32;
}
server {
...
location /memcached/ {
set $memcached_key $uri;
memcached_pass memcached_backend;
}
}
例子:针对http
upstream http_backend {
server 127.0.0.1:8080;
keepalive 16;
}
server {
...
location /http/ {
proxy_pass http://http_backend;
proxy_http_version 1.1; #http协议版本
proxy_set_header Connection ""; #头部信息connection段为空
...
}
}
例子:针对fastcgi协议
upstream fastcgi_backend {
server 127.0.0.1:9000;
keepalive 8;
}
server {
...
location /fastcgi/ {
fastcgi_pass fastcgi_backend;
fastcgi_keep_conn on;
...
}
}
Syntax: keepalive_timeout timeout;
Default: keepalive_timeout 60s;
Context: upstream
This directive appeared in version 1.15.3.
保持连接时长。默认60s
Syntax: least_conn;
Default: —
Context: upstream
This directive appeared in versions 1.3.1 and 1.2.2.
最少连接调度算法。与权重有关
Syntax: least_time header | last_byte [inflight];
Default: —
Context: upstream
This directive appeared in version 1.7.10.
最少平均响应时间调度算法。与权重有关
Syntax: sticky cookie name [expires=time] [domain=domain] [httponly] [secure] [path=path];
sticky route $variable ...;
sticky learn create=$variable lookup=$variable zone=name:size [timeout=time] [header] [sync];
Default: —
Context: upstream
This directive appeared in version 1.5.7.