WEB服务与NGINX(4)-NGINX实现虚拟主机
1 http基础配置参数详解
[root@nginx01 ~]# cat /etc/nginx/nginx.conf
......
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
[root@nginx01 ~]# cat /etc/nginx/conf.d/default.conf
server {
listen 80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
......
}
web相关的配置都放置在http语句块中,在http语句块中可以定义一些站点全局的配置,每一个站点是定义在一个server语句块中的,上面的主要配置意义如下:
-
server
server语句块用于配置一个虚拟主机,有基于端口,IP,server_name三种形式的虚拟主机。
-
listen
虚拟主机听端口,可以直接写端口,也可以指定服务器IP:端口,还可以监听本地套接字
支持环境: server
语法
-
listen address[:port];
- listen port;
- listen address[:port] [default_server] [ssl] [http2 | spdy] [backlog=number] [rcvbuf=size] [sndbuf=size];
可以只指端口不指地址表示默认监听本机上的所有地址,也可以只指地址不指端口表示默认监听在80端口。
参数
-
default_server:设定为默认虚拟主机
-
ssl:限制仅能够通过ssl连接提供服务,当配置为listen 80 ssl;时表示使用80端口监听ssl服务。
-
backlog=number:超过并发连接数后,新请求进入后援队列的长度
-
rcvbuf=size: 接收缓冲区大小
-
sndbuf=size: 发送缓冲区大小
-
-
include /etc/nginx/mime.types;
表示支持的文件后缀类型,在/etc/nginx/mime.types文件中定义。
[root@nginx01 ~]# cat /etc/nginx/mime.types types { text/html html htm shtml; text/css css; text/xml xml; image/gif gif; image/jpeg jpeg jpg; application/javascript js; ......
-
default_type application/octet-stream;
对于nginx不支持的文件后缀类型,会直接以把该文件下载的形式返回给客户端。
-
server_name
虚拟主机的主机名称,后可跟多个主机名,由空白字符分隔的字符串
支持环境:server
语法
-
支持*通配任意长度的任意字符 server_name *.abc.com www.abc.* ;
-
支持~起始的字符做正则表达式模式匹配,性能原因慎用 server_name ~^b.*.a.com$;
匹配优先级机制从高到低
- 首先是字符串精确匹配 如:www.a.com;
- 左侧*通配符 如:*.a.com;
- 右侧*通配符 如:www.a.*;
- 正则表达式 如: ~^.*.magedu.com$;
- default_server;
- 若默认服务器未定义,那就自上而下找第一个server来匹配。
-
-
tcp_nodelay on | off;
是否对长连接使用TCP_NODELAY选项,仅对长连接有效;
一般来讲,如果想提高用户体验的话,让用户一请求立即就能得到响应,我们还是应该启用tcp_nodelay,不让它延迟,每个包都单独发送,无论它有多小。
tcp是一种开销比较大的连接类型,因为任何一次数据发送之前都要先三次握手而后要四次断开。如果很不幸的是,某一个连接恰好它所发送的数据量非常小,访问这个页面下一共也只有几个字节或者十几个字节而已,如果我们请求网站上的资源很多都是这很小的资源的话,会发现每一个包单独封装而且没有使用长连接结果是大量的资源开销被浪费掉了,那为了避免这么一种浪费,TCP在它的拥塞避免算法中有一种解决方案是它把多次请求的小资源合并成一次大的响应过去,比如请求了很多东西每一个都很小,把多个小的请求合并成一个响应报文响应过去了。这样子可以节约带宽,可以节约请求次数。但是这样一来会有问题,对于Web站点来讲,用户请求一个资源半天还没响应,因为它在等待跟其他包合并呢,这是无法接受的,所以在有些本来就拥有很多小资源的Web站点上,我们不应该启用tcp_delay的功能,所以我们把tcp延迟功能关闭,tcp_nodelay就表示tcp是不延迟发送,on就可以。
-
tcp_nopush on|off;
在sendfile模式下,合并请求统一发送给客户端,tcp_nopush即为TCP_CORK功能;默认不启用。
TCP_CORK选项的功能类似于在发送数据管道出口处插入一个“塞子”,使得发送数据全部被阻塞,直到取消TCP_CORK选项(即拔去塞子)或被阻塞数据长度已超过MSS才将其发送出去。
假设应用程序使用sendfile()函数来转移大量数据。应用协议通常要求发送某些信息来预先解释数据,这些信息其实就是报头内容。
典型情况下报头很小,而且套接字上设置了TCP_NODELAY。有报头的包将被立即传输,在某些情况下(取决于内部的包计数器),因为这个包成功地被对方收到后需要请求对方确认,这样,大量数据的传输就会被推迟而且产生了不必要的网络流量交换。但是,如果我们在套接字上设置了TCP_CORK(可以比喻为在管道上插入“塞子”)选项,具有报头的包就会填补大量的数据,所有的数据都根据大小自动地通过包传输出去。
总而言之,如果你肯定能一起发送多个数据集合(例如HTTP响应的头和正文),那么建议你设置TCP_CORK选项,这样在这些数据之间不存在延迟。
开启后能极大地有益于WWW、FTP以及文件服务器的性能。
-
sendfile on | off;
是否启用sendfile功能,在内核中封装报文直接发送,默认Off(回应报文时不需要送到用户空间来封装,减少I/O次数,提高性能)
建议和tcp_nopush参数同时启用。
在发送一系列当作单一消息的数据之前设置TCP_CORK,而且在发送应立即发出的短消息之前设置TCP_NODELAY。
如果需要提高网络的传输效率,应该减少小包的传输,使用TCP_CORK来做汇总传输,在利用sendfile来提高效率;
但如果是交互性的业务,那应该让任意小包可以快速传输,关闭Nagle算法,提高包的传输效率。
-
index file ...;
指定默认网页文件,可以跟多个文件,默认为index.html。此指令由ngx_http_index_module模块提供
支持环境:server, location
-
send_timeout time;
向客户端发送响应报文的超时时长,此处是指两次写操作之间的间隔时长(报文重传间隔),而非整个响应过程的传输时长,默认60s。
支持环境:http, server, location
-
client_body_buffer_size size;
用于接收每个客户端请求报文的body部分的缓冲区大小;默认为16k;超出此大小时,其将被暂存到磁盘上的由下面client_body_temp_path指令所定义的位置。
一般只有在需要客户端执行put或post方法时才会用到,例如论坛,博客等需要上传大文件的场景中。
支持环境:http, server, location
-
client_body_temp_path path [level1 [level2 [level3]]];
设定存储客户端请求报文的body部分的临时存储路径及子目录结构和数量
支持环境:http, server, location
示例:
#1、配置文件设置格式,表示设置三级目录, 1 2 2表示三级目录每级所占位数 client_body_temp_path /var/tmp/client_body 1 2 2 #2、假设缓存数据为index.html,其哈希结果如下所示 [root@nginx01 ~]# md5sum index.html 0d6a914877e53e2957172f5e46bb5755 index.html #3、存放目录为3级目录,共有16*256*256=1048576个目录 一级目录取最后一位5(一级目录占一个16位数,范围在0-f) 二级目录取倒数2-3位75(二级目录占两个16位数,范围在00-ff) 三级目录取倒数4-5位b5(三级目录占两个16位数,范围在00-ff)
-
limit_except method ... { ... },
仅用于location
限制客户端使用除了指定的请求方法之外的其它方法
支持环境:location
示例:除了GET 之外其它方法仅允许192.168.1.0/24网段主机使用
location / { limit_except GET { allow 192.168.1.0/24; deny all; } }
-
aio on | off | threads[=pool];
是否启用异步文件I/O功能,默认关闭。
支持环境:http, server, location
-
directio size | off;
操作和aio相反,aio是读取文件而directio是写文件。当文件大于等于给定大小时,例如directio 4m,同步(直接)写磁盘,而非写缓存
支持环境:http, server, location
-
**open_file_cache off; **
-
open_file_cache max=N [inactive=time];
是否开启文件缓存功能,默认关闭。
支持环境:http, server, location
nginx可以缓存以下三种信息:
1.文件元数据:文件的描述符、文件大小和最近一次的修改时间
2.打开的目录结构
3.没有找到的或者没有权限访问的文件的相关信息
参数描述
max=N
可缓存的缓存项上限;达到上限后会使用LRU(最近最少使用)算法实现管理
inactive=time
缓存项的非活动时长,在此处指定的时长内未被命中的或命中的次数少于open_file_cache_min_uses指令所指定的次数的缓存项即为非活动项,将被删除
off:表示禁用
示例:
open_file_cache max=1000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on;
-
open_file_cache_errors on | off;
是否缓存查找时发生错误的文件一类的信息,默认值为off
支持环境:http, server, location
-
open_file_cache_min_uses number;
open_file_cache指令的inactive参数指定的时长内,至少被命中此处指定的次数方可被归类为活动项,默认值为1
支持环境:http, server, location
-
open_file_cache_valid time;
缓存项有效性的检查频率,默认值为60s
支持环境:http, server, location
-
server_tokens off;
支持环境:http
隐藏nginx server版本信息,默认为on开启。
2 搭建虚拟主机
通常生产中会有存在多个业务系统,这些业务系统可以部署在不同的web服务器上,也可以部署在一台web服务器上。
nginx的虚拟主机功能可以实现在一台nginx服务器上搭建多套网站,这些网站时相互独立的。
nginx的虚拟主机有三种实现方式:
- 基于不同ip的虚拟主机;
- 基于不同端口的虚拟主机;
- 基于不同域名的虚拟主机,通过请求报文中首部HOST字段标识;
2.1 基于ip的虚拟主机
场景:为两个不同的虚拟主机配置不同的ip地址,需要在主机上存在两个不同的ip地址,地址为192.168.20.20和192.168.20.21
#1.创建网站工作目录和主页文件
[root@nginx01 web2]# mkdir -pv /data/nginx/html/web{1,2}
[root@nginx01 web2]# chown -R nginx:nginx /data/nginx/
[root@nginx01 web1]# echo "<h1>192.168.20.20</h1>" > /data/nginx/html/web1/index.html
[root@nginx01 web2]# echo "<h1>192.168.20.21</h1>" > /data/nginx/html/web2/index.html
#2.配置ip地址
[root@nginx01 web2]# ip add add 192.168.20.21/24 dev eth1
[root@nginx01 web2]# ip add show eth1
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:21:9d:5c brd ff:ff:ff:ff:ff:ff
inet 192.168.20.20/24 brd 192.168.20.255 scope global noprefixroute eth1
valid_lft forever preferred_lft forever
inet 192.168.20.21/24 scope global secondary eth1
valid_lft forever preferred_lft forever
inet6 fe80::52b0:737b:a3cb:c6a5/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@nginx01 web2]# vim /etc/nginx/conf.d/virtualhost_ip.conf
#3.编译虚拟主机配置文件
[root@nginx01 web2]# vim /etc/nginx/conf.d/virtualhost.conf
server {
listen 192.168.20.20;
location / {
root /data/nginx/html/web1;
index index.html;
}
}
server {
listen 192.168.20.21;
location / {
root /data/nginx/html/web2;
index index.html;
}
}
#4.重启服务生效
[root@nginx01 web2]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx01 web2]# systemctl reload nginx.service
#5.客户端测试
[root@xuzhichao ~]# curl http://192.168.20.21
<h1>192.168.20.21</h1>
[root@xuzhichao ~]# curl http://192.168.20.20
<h1>192.168.20.20</h1>
2.2 基于端口的虚拟主机
场景:为同一个ip地址设置不同的端口,使用80和8080端口分别对应一个站点。
注意:使用的端口不能被其他应用程序占用。
#1.修改配置文件
[root@nginx01 web2]# vim /etc/nginx/conf.d/virtualhost.conf
server {
listen 192.168.20.20:80;
location / {
root /data/nginx/html/web1;
index index.html;
}
}
server {
listen 192.168.20.20:8080;
location / {
root /data/nginx/html/web2;
index index.html;
}
}
#2.修改主页文件内容
[root@nginx01 web2]# echo "192.168.20.20:80" > /data/nginx/html/web1/index.html
[root@nginx01 web2]# echo "192.168.20.20:8080" > /data/nginx/html/web2/index.html
#3.重启服务生效
[root@nginx01 web2]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx01 web2]# systemctl reload nginx.service
#4.客户端测试
[root@xuzhichao ~]# curl http://192.168.20.20:80
192.168.20.20:80
[root@xuzhichao ~]# curl http://192.168.20.20:8080
192.168.20.20:8080
2.3 基于域名的虚拟主机
场景:实现两个虚拟主机,域名分别为www.nginx01.com和www.nginx02.com。
#1.修改虚拟主机配置文件
[root@nginx01 web2]# vim /etc/nginx/conf.d/virtualhost.conf
server {
listen 192.168.20.20:80;
location / {
root /data/nginx/html/web1;
index index.html;
}
}
server {
listen 192.168.20.20:8080;
location / {
root /data/nginx/html/web2;
index index.html;
}
}
#2.修改主页文件内容
[root@nginx01 web2]# echo "www.nginx02.com" > /data/nginx/html/web2/index.html
[root@nginx01 web2]# echo "www.nginx01.com" > /data/nginx/html/web1/index.html
##3.重启服务生效
[root@nginx01 web2]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx01 web2]# systemctl reload nginx.service
#4.客户端修改hosts文件进行域名解析
[root@xuzhichao ~]# vim /etc/hosts
192.168.20.20 www.nginx01.com www.nginx02.com
#5.客户端测试
[root@xuzhichao ~]# curl http://www.nginx01.com
www.nginx01.com
[root@xuzhichao ~]# curl http://www.nginx02.com
www.nginx02.com