美文网首页
2020-03-23 Nginx虚拟主机配置实战

2020-03-23 Nginx虚拟主机配置实战

作者: 阿丧小威 | 来源:发表于2020-03-23 14:53 被阅读0次

    1. 虚拟主机概念和类型介绍

    1.1 虚拟主机概念

    所谓虚拟主机,在Web服务里就是一个独立的网站站点,这个站点既可以对应独立的域名(也可能是IP或端口),具有独立的程序及资源目录,又可以独立地对外提供服务供用户访问。
    这个独立的站点在配置里是由一定格式的标签段标记,对于Apache软件来说,一个虚拟主机的标签段通常被包含在<VirtualHost></VirtualHost>内,而Nginx软件则使用一个Server{}标签来标示一个虚拟主机,一个Web服务里可以有多个虚拟主机标签对,即同时可以支持多个虚拟主机站点。

    1.2 虚拟主机类型

    (1)基于域名的虚拟主机
    所谓基于域名的虚拟主机,意思就是通过不同的域名区分不同的虚拟主机。基于域名的虚拟主机是企业应用最广的虚拟主机类型,几乎所有对外提供服务的网站都是使用基于域名的虚拟主机,如www.etiantian.org
    (2)基于端口的虚拟主机
    同理,所谓基于端口的虚拟主机,意思就是通过不同的端口来区分不同的虚拟主机,此类虚拟主机对应的企业应用主要为公司内部的网站,如一些不希望直接对外提供用户访问的网站后台等。访问基于端口的虚拟主机地址里要带有端口,如http://etiantian.org:9000
    (3)基于IP的虚拟主机
    同理,所谓基于IP的虚拟主机,意思就是通过不同的IP区分不同的虚拟主机,此类虚拟主机对应的企业应用非常少见。一般不同业务需要使用多IP的场景都会在负载均衡器上进行VIP绑定,而不是在Web上通过绑定IP区分不同的虚拟机。
    三种虚拟主机类型既可独立使用,也可以互相混合一起使用。

    2. 基于域名的虚拟主机配置实战

    2.1 配置基于域名的nginx.conf内容

    这里使用grep过滤命令来生成基础的Nginx主配置文件nginx.conf,然后根据生成的初始配置进行修改,使其成为所需的形式,具体步骤为:

    [root@web01 ~]# cd /application/nginx/conf/
    [root@web01 conf]# diff nginx.conf.default nginx.conf    ---初始时这两个配置文件是一致的
    [root@web01 conf]# egrep -v "#|^$" nginx.conf.default > nginx.conf
    ---过滤包含#号和空行生成新文件
    [root@web01 conf]# cat nginx.conf
    worker_processes  1;
    events {
        worker_connections  1024;
    }
    http {
        include       mime.types;
        default_type  application/octet-stream;
        sendfile        on;
        keepalive_timeout  65;
        server {
            listen       80;
            server_name  localhost;
            location / {
                root   html;
                index  index.html index.htm;
            }
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }
        }
    }
    

    2.2 创建域名对应的站点目录及文件

    此处配置的是基于域名的虚拟主机,即创建对应的域名站点目录及文件。

    [root@web01 conf]# mkdir ../html/www -p    ---创建www站点目录,注意目录层次
    [root@web01 conf]# echo "http://www.etiantian.org" >../html/www/index.html    ---追加内容到首页文件
    [root@web01 conf]# cat ../html/www/index.html 
    http://www.etiantian.org
    

    上述命令的作用是创建了一个/application/nginx/html/www站点目录,对应于虚拟主机配置文件里root根目录的html/www设置(root html/www;)。然后生成一个默认的首页文件index.html,文件的内容是"http://www.etiantian.org"。

    2.3 检查语法并重新加载Nginx

    [root@web01 conf]# nginx -t
    nginx: the configuration file /application/nginx-1.16.0//conf/nginx.conf syntax is ok
    nginx: configuration file /application/nginx-1.16.0//conf/nginx.conf test is successful
    [root@web01 conf]# nginx -s reload    ---平滑重启,重新加载配置文件
    

    再检查Nginx重新加载后的情况,如进程和端口是否OK。

    [root@web01 conf]# netstat -lntup | grep nginx
    tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      9584/nginx: master
    

    最后测试域名站点配置的访问结果。

    [root@web01 conf]# echo "192.168.9.7 www.etiantian.org" >> /etc/hosts
    [root@web01 conf]# tail -1 /etc/hosts
    192.168.9.7 www.etiantian.org
    [root@web01 conf]# ping www.etiantian.org
    PING www.etiantian.org (192.168.9.7) 56(84) bytes of data.
    64 bytes from www.etiantian.org (192.168.9.7): icmp_seq=1 ttl=64 time=0.045 ms    ---hosts解析成功
    ^C
    --- www.etiantian.org ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 2004ms
    rtt min/avg/max/mdev = 0.019/0.030/0.045/0.011 ms
    [root@web01 conf]# curl www.etiantian.org    ---访问测试
    http://www.etiantian.org
    

    2.4 配置多个基于域名的虚拟主机

    (1)增加新域名对应的配置
    前面已经增加了一个www.etiantian.org虚拟主机的配置,下面再增加两个虚拟主机的配置,站点域名分别为bbs.etiantian.orgblog.etiantian.org。增加的配置一定要在nginx.conf的HTTP{}区块内,最好放在www.etiantian.org虚拟主机配置的下面,增加的内容如下图所示。

    Nginx基于域名的虚拟主机图

    在整体格式上,新增域名虚拟主机的配置和前面配置过的www.etiantian.org域名的虚拟主机是一样的,区别就是server_name和root参数的配置不同,此时基于3个域名的完整nginx.conf配置文件内容为:

    [root@web01 conf]# cat -n nginx.conf
         1  worker_processes  1;
         2  events {
         3      worker_connections  1024;
         4  }
         5  http {
         6      include       mime.types;
         7      default_type  application/octet-stream;
         8      sendfile        on;
         9      keepalive_timeout  65;
        10      server {
        11          listen       80;
        12          server_name  www.etiantian.org;
        13          location / {
        14              root   html/www;
        15              index  index.html index.htm;
        16          }
        17          error_page   500 502 503 504  /50x.html;
        18          location = /50x.html {
        19              root   html;
        20          }
        21      }
        22  
        23      server {
        24      listen       80;
        25          server_name  bbs.etiantian.org;
        26          location / {
        27              root   html/bbs;
        28              index  index.html index.htm;
        29          }
        30      }
        31  
        32      server {
        33          listen       80;
        34          server_name  blog.etiantian.org;
        35          location / {
        36              root   html/blog;
        37              index  index.html index.htm;
        38          }
        39      }
        40  }
    

    (2)创建新虚拟主机站点对应的目录和文件
    下面的命令用于创建上述两个新增域名分别对应的站点目录及文件。

    [root@web01 conf]# mkdir ../html/bbs ../html/blog -p
    [root@web01 conf]# echo "http://bbs.etiantian.org" > ../html/bbs/index.html
    [root@web01 conf]# echo "http://blog.etiantian.org" > ../html/blog/index.html
    [root@web01 conf]# cat ../html/bbs/index.html 
    http://bbs.etiantian.org
    [root@web01 conf]# cat ../html/blog/index.html 
    http://blog.etiantian.org
    

    也可以使用Shell脚本一条命令搞掂。

    for n in www blog bbs;
    do
    mkdir -p ../html/$n;
    echo "http://$(n).etiantian.org" > ../html/$n/index.html;
    cat ../html/$n/index.html;
    done
    

    检查html站点的目录结构:

    [root@web01 conf]# tree ../html/
    ../html/
    ├── 50x.html
    ├── bbs
    │   └── index.html
    ├── blog
    │   └── index.html
    ├── index.html
    └── www
        └── index.html
    3 directories, 5 files
    

    (3)重新加载Nginx配置
    每次更改Nginx的配置都需要管理员重新加载,使配置生效,这是因为Nginx在启动时已把所有配置信息都加载到内存中了,若更改了磁盘上的nginx.conf配置文件,需要把新配置重新加载到内存中生效。这样设计的目的是可以大幅度提升Nginx服务访问性能。

    [root@web01 conf]# nginx -t
    nginx: the configuration file /application/nginx-1.16.0//conf/nginx.conf syntax is ok
    nginx: configuration file /application/nginx-1.16.0//conf/nginx.conf test is successful
    [root@web01 conf]# nginx -s reload
    

    (4)在客户端测试

    [root@web01 conf]# vi /etc/hosts    ---增加两个域名的解析
    192.168.9.7 www.etiantian.org bbs.etiantian.org blog.etiantian.org
    [root@web01 conf]# curl www.etiantian.org
    http://www.etiantian.org
    [root@web01 conf]# curl bbs.etiantian.org
    http://bbs.etiantian.org
    [root@web01 conf]# curl blog.etiantian.org
    http://blog.etiantian.org
    

    3. 基于域名的虚拟主机通信原理介绍

    Nginx客户端发起请求过程如下
    1)浏览器输入www.etiantian.org回车。
    2)浏览器请求LDNS,通过LDNS最终找到授权DNS获取IP。
    3)请求Web服务器发起TCP三次握手。
    4)建立HTTP请求(192.168.9.7的80端口)。
    5)发起HTTP请求报文(请求头里携带:host www.etiantian.org字段)。
    Nginx服务端处理请求过程如下
    1)监听本地所有网卡对80端口的请求。
    2)读取接收到的HTTP报文里的信息。
    3)读取Nginx配置文件虚拟主机Server标签。
    4)先匹配Server标签中请求的端口号。
    5)相同端口再去匹配Server标签对应server_name指定的域名(和读取请求头里host字段比对)。
    6)把对应域名下面站点目录下的首页文件(index.xx)发给客户端。
    7)如果没有匹配的域名,就把排在第一个顺序Server标签虚拟机对应内容发给客户端。
    基于域名的虚拟主机通信原理如下图所示。

    基于域名的虚拟主机通信原理图

    4. 基于端口的虚拟主机配置实战

    基于端口的虚拟主机在生产环境中不多见,仅偶尔会用到,一般是为公司内部人员提供访问的,如OA系统/网站程序的后台、CMS发布后台、MySQL的Web客户端phpmyadmin等,使用特殊端口多是从安全上考虑的。

    4.1 配置虚拟主机监听的端口

    如果要配置基于端口的虚拟主机,就需要每个虚拟主机配置有不同的端口。编辑nginx.conf主配置文件,然后把每隔虚拟主机的“listen 80;”的配置行的80数字端口部分分别修改掉,内容见下文,注意server_name域名位置可以不做任何变更,哪怕是相同域名也可以,因为,基于端口的虚拟主机就是通过端口来唯一区别不同的虚拟主机的,只要端口不同就是不同的虚拟主机。

    4.2 修改虚拟主机配置

    [root@web01 conf]# cat -n nginx.conf
         1  worker_processes  1;
         2  events {
         3      worker_connections  1024;
         4  }
         5  http {
         6      include       mime.types;
         7      default_type  application/octet-stream;
         8      sendfile        on;
         9      keepalive_timeout  65;
        10      server {
        11          listen       80;
        12          server_name  www.etiantian.org;
        13          location / {
        14              root   html/www;
        15              index  index.html index.htm;
        16          }
        17          error_page   500 502 503 504  /50x.html;
        18          location = /50x.html {
        19              root   html;
        20          }
        21      }
        22  
        23      server {
        24      listen       81;    ---由80端口改成81端口
        25          server_name  bbs.etiantian.org;
        26          location / {
        27              root   html/bbs;
        28              index  index.html index.htm;
        29          }
        30      }
        31  
        32      server {
        33          listen       82;    ---由80端口改成82端口
        34          server_name  blog.etiantian.org;
        35          location / {
        36              root   html/blog;
        37              index  index.html index.htm;
        38          }
        39      }
        40  }
    

    4.3 检查语法重新加载配置生效

    [root@web01 conf]# nginx -t
    nginx: the configuration file /application/nginx-1.16.0//conf/nginx.conf syntax is ok
    nginx: configuration file /application/nginx-1.16.0//conf/nginx.conf test is successful
    [root@web01 conf]# nginx -s reload
    [root@web01 conf]# netstat -lntup|grep nginx
    tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      9584/nginx: master  
    tcp        0      0 0.0.0.0:81              0.0.0.0:*               LISTEN      9584/nginx: master  
    tcp        0      0 0.0.0.0:82              0.0.0.0:*               LISTEN      9584/nginx: master
    

    4.4 测试不同端口的访问结果

    [root@web01 conf]# curl http://www.etiantian.org:80
    http://www.etiantian.org
    [root@web01 conf]# curl http://bbs.etiantian.org:81
    http://bbs.etiantian.org
    [root@web01 conf]# curl http://blog.etiantian.org:82
    http://blog.etiantian.org
    

    4.5 基于IP的虚拟主机配置实战

    4.5.1 在服务器网卡上增加多个IP

    临时增加2个不同的IP

    [root@web01 conf]# ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host 
           valid_lft forever preferred_lft forever
    2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 00:50:56:33:39:23 brd ff:ff:ff:ff:ff:ff
        inet 192.168.9.7/24 brd 192.168.9.255 scope global dynamic ens33
           valid_lft 5403165sec preferred_lft 5403165sec
        inet6 fe80::250:56ff:fe33:3923/64 scope link 
           valid_lft forever preferred_lft forever
    [root@web01 conf]# ip addr add 192.168.9.208/24 dev ens33 label ens33:1    ---临时添加IP
    [root@web01 conf]# ip addr add 192.168.9.209/24 dev ens33 label ens33:2    ---临时添加IP
    
    [root@web01 conf]# ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host 
           valid_lft forever preferred_lft forever
    2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 00:50:56:33:39:23 brd ff:ff:ff:ff:ff:ff
        inet 192.168.9.7/24 brd 192.168.9.255 scope global dynamic ens33
           valid_lft 5403085sec preferred_lft 5403085sec
        inet 192.168.9.208/24 scope global secondary ens33:1
           valid_lft forever preferred_lft forever
        inet 192.168.9.209/24 scope global secondary ens33:2
           valid_lft forever preferred_lft forever
        inet6 fe80::250:56ff:fe33:3923/64 scope link 
           valid_lft forever preferred_lft forever
    [root@web01 conf]# ping 192.168.9.208    ---ping检查
    PING 192.168.9.208 (192.168.9.208) 56(84) bytes of data.
    64 bytes from 192.168.9.208: icmp_seq=1 ttl=64 time=0.017 ms
    ^C
    --- 192.168.9.208 ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 0.017/0.017/0.017/0.000 ms
    [root@web01 conf]# ping 192.168.9.209    ---ping检查
    PING 192.168.9.209 (192.168.9.209) 56(84) bytes of data.
    64 bytes from 192.168.9.209: icmp_seq=1 ttl=64 time=0.011 ms
    64 bytes from 192.168.9.209: icmp_seq=2 ttl=64 time=0.019 ms
    ^C
    --- 192.168.9.209 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1000ms
    rtt min/avg/max/mdev = 0.011/0.015/0.019/0.004 ms
    
    4.5.2 增加虚拟主机配置

    基于IP的虚拟主机实际配置示例如下。这是一个端口和IP混合的虚拟主机示例,可以自行修改,使其仅仅基于IP,即每个虚拟主机的server_name字段都换成IP地址。

    [root@web01 conf]# cat -n nginx.conf
         1  worker_processes  1;
         2  events {
         3      worker_connections  1024;
         4  }
         5  http {
         6      include       mime.types;
         7      default_type  application/octet-stream;
         8      sendfile        on;
         9      keepalive_timeout  65;
        10      server {
        11          listen       192.168.9.7:80;
        12          server_name  www.etiantian.org;    ---此处也可以换成对应IP192.168.9.7
        13          location / {
        14              root   html/www;
        15              index  index.html index.htm;
        16          }
        17          error_page   500 502 503 504  /50x.html;
        18          location = /50x.html {
        19              root   html;
        20          }
        21      }
        22  
        23      server {
        24      listen       192.168.9.208:80;
        25          server_name  bbs.etiantian.org;    ---此处也可以换成对应IP192.168.9.208
        26          location / {
        27              root   html/bbs;
        28              index  index.html index.htm;
        29          }
        30      }
        31  
        32      server {
        33          listen       192.168.9.209:80;
        34          server_name  blog.etiantian.org;    ---此处也可以换成对应IP192.168.9.209
        35          location / {
        36              root   html/blog;
        37              index  index.html index.htm;
        38          }
        39      }
        40  }
    

    重新加载Nginx服务使得修改的配置生效。

    [root@web01 conf]# nginx -t
    nginx: the configuration file /application/nginx-1.16.0//conf/nginx.conf syntax is ok
    nginx: configuration file /application/nginx-1.16.0//conf/nginx.conf test is successful
    [root@web01 conf]# nginx -s reload    ---平滑加载配置不生效
    [root@web01 conf]# netstat -lntup|grep nginx
    tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      9584/nginx: master  
    tcp        0      0 0.0.0.0:81              0.0.0.0:*               LISTEN      9584/nginx: master  
    tcp        0      0 0.0.0.0:82              0.0.0.0:*               LISTEN      9584/nginx: master  
    [root@web01 conf]# nginx -s stop    ---必须先停止nginx服务
    [root@web01 conf]# nginx    ---再开启服务
    [root@web01 conf]# netstat -lntup|grep nginx
    tcp        0      0 192.168.9.209:80        0.0.0.0:*               LISTEN      14376/nginx: master 
    tcp        0      0 192.168.9.208:80        0.0.0.0:*               LISTEN      14376/nginx: master 
    tcp        0      0 192.168.9.7:80          0.0.0.0:*               LISTEN      14376/nginx: master 
    
    4.5.3 Linux客户端中的访问结果
    [root@web01 conf]# curl 192.168.9.7
    http://www.etiantian.org
    [root@web01 conf]# curl 192.168.9.208
    http://bbs.etiantian.org
    [root@web01 conf]# curl 192.168.9.209
    http://blog.etiantian.org
    

    5. Nginx配置虚拟主机的步骤

    1)增加一个完整的Server标签段到结尾处。注意,要放在HTTP的结束大括号前,也就是将Server标签段放入HTTP标签。
    2)更改server_name及对应网页的root根目录,如果需要其他参数,可以增加或修改。
    3)创建server_name域名对应网页的根目录,并且建立测试文件,如果没有index首页,访问会出现403错误。
    4)检查Nginx配置文件语法,平滑重启Nginx服务,快速检查启动结果。
    5)在客户端对server_name处配置的域名做host解析或DNS配置,并检查(ping域名看返回的IP对不对)。
    6)在Win32浏览器中输入地址访问,或者在Linux客户端做hosts解析,用wget或curl接地址访问。

    7. 企业场景中重启Nginx后的检测策略

    在企业运维实战场景中,每一个配置操作处理完毕后都应该进行快速有效的检查,这是一个合格运维人员的良好习惯。在大型企业中,在启动Nginx的同时,还会调用脚本通过获取header信息或模拟用户访问指定URL(wget等方式)来自动检查Nginx的启动是不是真的正常,最大限度地保证服务重启后,能迅速确定网站情况,而无须收工敲命令查看。这样,如果配置有问题(非语法问题,语法问题已经用-t参数检查过了),就可以迅速使用上一版备份的配置文件覆盖回来,使得影响用户的时间最短。
    下面是一个重启Nginx服务后,检查启动是否正常的脚本,可以把它包含在Nginx启动脚本(需要另外开发)内部的start等启动位置。

    [root@web01 conf]# cat -n check_url.sh 
         1  #!/bin/bash
         2  #--------function split--------
         3  . /etc/rc.d/init.d/functions
         4  function checkURL()
         5  {
         6      checkUrl=$1
         7      echo 'check url start ...'
         8      judge=($(curl -I -s --connect-timeout 2 ${checkUrl}|head -1 | tr " " "\n"))
         9      if [[ "${judge[1]}" == '200' && "${judge[2]}" == 'OK' ]]
        10          then
        11              action "${checkUrl}" /bin/true
        12          else
        13              action "${checkUrl}" /bin/false
        14              echo -n "retrying again...";sleep 3;
        15              judgeagain=($(curl -I -s --connect-timeout 2 ${checkUrl}| head -1| tr "\r" "\n"))
        16              if [[ "${judgeagain[1]}" == '200' && "${judgeagain[2]}" == 'OK' ]]
        17              then
        18                  action "${checkUrl}, retried again" /bin/true 
        19              else    
        20                  action "${checkUrl}, retried again" /bin/false
        21              fi
        22      fi
        23      sleep 1;
        24  }
        25  # usage method
        26  checkURL http://www.etiantian.org
    [root@web01 conf]# sh check_url.sh 
    check url start ...
    http://www.etiantian.org                                   [失败]
    retrying again...http://www.etiantian.org, retried again   [  确定  ]
    

    此脚本功能是检测访问WWW网站时相应header是否返回200,以及状态是否为OK。当检测失败时,3秒后再检测一次,然后,格式化检测结果输出,如果有多个域名可以对上述命令传参的不同域名循环检查。检测方法可以是端口、URI、相应header等,具体将根据业务需求进行选择。

    相关文章

      网友评论

          本文标题:2020-03-23 Nginx虚拟主机配置实战

          本文链接:https://www.haomeiwen.com/subject/mzjiyhtx.html