第3章:静态网站服务

3.1 虚拟主机配置

虚拟主机(Virtual Host)是Nginx的核心功能之一,允许在单个服务器上托管多个网站。Nginx支持三种类型的虚拟主机配置:

3.1.1 基于域名的虚拟主机

基于域名的虚拟主机是最常用的配置方式,通过不同的域名来区分不同的网站。

配置示例

  1. 创建网站目录结构:

    sudo mkdir -p /var/www/site1
    sudo mkdir -p /var/www/site2
  2. 创建示例网页:

    echo "<h1>Welcome to Site 1</h1>" | sudo tee /var/www/site1/index.html
    echo "<h1>Welcome to Site 2</h1>" | sudo tee /var/www/site2/index.html
  3. 设置目录权限:

    sudo chown -R www-data:www-data /var/www/site1
    sudo chown -R www-data:www-data /var/www/site2
    sudo chmod -R 755 /var/www/site1
    sudo chmod -R 755 /var/www/site2
  4. 创建Nginx配置文件:

    sudo nano /etc/nginx/conf.d/virtual-hosts.conf
  5. 添加以下配置:

    # 第一个虚拟主机 - site1.com
    server {
        listen 80;
        server_name site1.com www.site1.com;
        
        root /var/www/site1;
        index index.html index.htm;
        
        access_log /var/log/nginx/site1.access.log main;
        error_log /var/log/nginx/site1.error.log error;
    }
    
    # 第二个虚拟主机 - site2.com
    server {
        listen 80;
        server_name site2.com www.site2.com;
        
        root /var/www/site2;
        index index.html index.htm;
        
        access_log /var/log/nginx/site2.access.log main;
        error_log /var/log/nginx/site2.error.log error;
    }
  6. 验证配置并重载:

    sudo nginx -t
    sudo systemctl reload nginx
  7. 本地测试(修改hosts文件):

    sudo nano /etc/hosts

    添加:

    127.0.0.1 site1.com www.site1.com
    127.0.0.1 site2.com www.site2.com
  8. 测试访问:

    curl http://site1.com
    curl http://site2.com

3.1.2 基于端口的虚拟主机

基于端口的虚拟主机通过不同的端口来区分不同的网站,适合开发和测试环境。

配置示例

# 基于端口80的站点
server {
    listen 80;
    server_name localhost;
    
    root /var/www/site1;
    index index.html;
}

# 基于端口8080的站点
server {
    listen 8080;
    server_name localhost;
    
    root /var/www/site2;
    index index.html;
}

测试访问

curl http://localhost:80
curl http://localhost:8080

3.1.3 基于IP的虚拟主机

基于IP的虚拟主机通过不同的IP地址来区分不同的网站,需要服务器配置多个IP地址。

配置示例

# 绑定到第一个IP地址
server {
    listen 192.168.1.100:80;
    server_name site1.com;
    
    root /var/www/site1;
    index index.html;
}

# 绑定到第二个IP地址
server {
    listen 192.168.1.101:80;
    server_name site2.com;
    
    root /var/www/site2;
    index index.html;
}

3.2 静态文件服务优化

3.2.1 文件压缩(gzip)

启用gzip压缩可以减小文件大小,提高传输速度,降低带宽消耗。

配置示例

http {
    # 启用gzip压缩
    gzip on;
    
    # 压缩级别(1-9,推荐6)
    gzip_comp_level 6;
    
    # 压缩的最小文件大小
    gzip_min_length 256;
    
    # 压缩的文件类型
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    
    # 对于代理请求,也启用压缩
    gzip_proxied any;
    
    # 为IE6及以下版本禁用gzip
    gzip_disable "MSIE [1-6]\.";
    
    # 添加Vary头,告诉代理缓存压缩和非压缩版本
    gzip_vary on;
}

验证压缩是否生效

curl -I -H "Accept-Encoding: gzip" http://localhost

预期输出(包含以下头信息):

Content-Encoding: gzip
Vary: Accept-Encoding

3.2.2 缓存控制策略

合理的缓存策略可以减少重复请求,提高网站性能。Nginx通过设置Cache-ControlExpires头来控制浏览器缓存。

配置示例

server {
    # ... 其他配置 ...
    
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 30d;
        add_header Cache-Control "public, no-transform";
    }
    
    location ~* \.(html|htm|txt)$ {
        expires 1h;
        add_header Cache-Control "public, must-revalidate";
    }
}

指令说明

  • expires 30d;:设置缓存过期时间为30天
  • add_header Cache-Control &quot;public, no-transform&quot;;:允许公共缓存,禁止转换内容
  • add_header Cache-Control &quot;public, must-revalidate&quot;;:允许公共缓存,但每次请求都必须验证

3.2.3 断点续传与范围请求

断点续传允许客户端从文件的某个位置开始下载,提高大文件下载的可靠性。Nginx默认支持断点续传,只需要确保sendfile指令开启。

配置示例

http {
    # 启用sendfile系统调用
    sendfile on;
    
    # 启用TCP_NOPUSH,提高大文件传输效率
    tcp_nopush on;
    
    # 启用TCP_NODELAY,提高小文件传输效率
    tcp_nodelay on;
}

验证断点续传

curl -r 0-1023 -o partial.txt http://localhost/large-file.zip

预期输出

  • 只下载文件的前1024字节
  • 状态码为206 Partial Content

3.2.4 日志配置与分析

Nginx提供了灵活的日志配置选项,可以自定义日志格式,便于分析网站访问情况。

配置示例

http {
    # 定义自定义日志格式
    log_format detailed '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" '
                      'rt=$request_time uct="$upstream_connect_time" uht="$upstream_header_time" urt="$upstream_response_time"';
    
    # 访问日志使用自定义格式
    access_log /var/log/nginx/access.log detailed;
    
    # 错误日志级别为warn
    error_log /var/log/nginx/error.log warn;
}

常用日志分析命令

  1. 查看访问量最高的IP:

    awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
  2. 查看访问量最高的URL:

    awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
  3. 查看状态码分布:

    awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr
  4. 查看请求时间最长的10个请求:

    awk '{print $NF, $0}' /var/log/nginx/access.log | sort -nr | head -10

3.3 实战项目1:搭建个人博客静态站点

在这个实战项目中,我们将使用Nginx搭建一个基于Hexo的个人博客静态站点。

3.3.1 项目准备

1. 安装Node.js和npm

# Ubuntu/Debian
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs

# CentOS/RHEL
sudo yum install -y nodejs

2. 安装Hexo

npm install -g hexo-cli

3.3.2 初始化Hexo博客

# 创建博客目录
mkdir ~/my-blog
cd ~/my-blog

# 初始化Hexo
hexo init

# 安装依赖
npm install

# 生成静态文件
hexo generate

3. 查看生成的静态文件

ls -la ~/my-blog/public

3.3.3 配置Nginx服务

  1. 创建网站目录

    sudo mkdir -p /var/www/my-blog
  2. 复制静态文件

    sudo cp -r ~/my-blog/public/* /var/www/my-blog/
  3. 设置权限

    sudo chown -R www-data:www-data /var/www/my-blog
    sudo chmod -R 755 /var/www/my-blog
  4. 创建Nginx配置文件

    sudo nano /etc/nginx/conf.d/my-blog.conf

    内容:

    server {
        listen 80;
        server_name my-blog.com www.my-blog.com;
        
        root /var/www/my-blog;
        index index.html index.htm;
        
        # 配置静态文件缓存
        location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|eot)$ {
            expires 30d;
            add_header Cache-Control "public, no-transform";
        }
        
        # 配置gzip压缩
        gzip on;
        gzip_comp_level 6;
        gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
        
        # 访问日志
        access_log /var/log/nginx/my-blog.access.log main;
        error_log /var/log/nginx/my-blog.error.log error;
    }
  5. 验证配置并重载

    sudo nginx -t
    sudo systemctl reload nginx
  6. 本地测试配置

    sudo nano /etc/hosts

    添加:

    127.0.0.1 my-blog.com www.my-blog.com
  7. 访问博客

    • 通过浏览器访问:http://my-blog.com
    • 或通过命令行测试:
      curl -I http://my-blog.com

3.3.4 博客更新流程

当博客内容更新后,需要重新生成静态文件并同步到网站目录:

# 进入博客目录
cd ~/my-blog

# 创建新文章
hexo new "我的第一篇博客文章"

# 编辑文章(使用你喜欢的编辑器)
nano source/_posts/我的第一篇博客文章.md

# 生成静态文件
hexo generate

# 同步到网站目录
sudo cp -r public/* /var/www/my-blog/

3.3.5 常见问题与解决方案

问题1:403 Forbidden错误

解决方案

  1. 检查文件权限:

    sudo chown -R www-data:www-data /var/www/my-blog
    sudo chmod -R 755 /var/www/my-blog
  2. 检查selinux设置(CentOS/RHEL):

    sudo setenforce 0

    或永久关闭:

    sudo nano /etc/selinux/config

    SELINUX=enforcing改为SELINUX=disabled

问题2:CSS和JS文件无法加载

解决方案

  1. 检查文件路径是否正确
  2. 检查Nginx配置中的root指令是否正确
  3. 检查浏览器控制台的错误信息

章节总结

在本章中,我们学习了:

  1. 虚拟主机配置

    • 基于域名的虚拟主机配置
    • 基于端口的虚拟主机配置
    • 基于IP的虚拟主机配置
  2. 静态文件服务优化

    • 启用gzip压缩减小文件大小
    • 配置合理的缓存策略
    • 支持断点续传和范围请求
    • 自定义日志格式和日志分析
  3. 实战项目

    • 使用Hexo创建静态博客
    • 配置Nginx服务静态博客
    • 实现博客更新流程
    • 解决常见问题

实践练习

  1. 配置两个基于域名的虚拟主机
  2. 为静态资源启用gzip压缩和缓存
  3. 使用Hexo创建一个个人博客并部署到Nginx
  4. 分析Nginx访问日志,找出访问量最高的页面
  5. 配置自定义日志格式,包含请求时间信息

延伸阅读


下一章第4章:反向代理与负载均衡

« 上一篇 核心概念理解 下一篇 » 反向代理与负载均衡