Nginx基础学习

Nginx基础学习

_

Nginx基础学习
环境准备

1. 安装Nginx(macOS)

# 使用Homebrew安装
brew install nginx

# 查看Nginx版本
nginx -v

# 查看编译参数
nginx -V

2. 基本目录结构

/usr/local/etc/nginx/          # 配置文件目录
├── nginx.conf                 # 主配置文件
├── servers/                   # 虚拟主机配置目录
└── conf.d/                    # 额外配置目录

/usr/local/var/www/            # 默认网站根目录
/usr/local/var/log/nginx/      # 日志目录

3. 实验1:基础静态网站

a. 步骤1:创建测试网站

# 创建网站目录
sudo mkdir -p /usr/local/var/www/test-site

# 创建测试HTML文件
cat > /usr/local/var/www/test-site/index.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
    <title>Nginx测试网站</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 40px; }
        .container { max-width: 800px; margin: 0 auto; }
        .success { color: green; }
    </style>
</head>
<body>
    <div class="container">
        <h1 class="success">🎉 Nginx配置成功!</h1>
        <p>这是您的第一个Nginx静态网站</p>
        <ul>
            <li>服务器时间:<span id="time"></span></li>
            <li>当前路径:/</li>
        </ul>
    </div>
    <script>
        document.getElementById('time').textContent = new Date().toLocaleString();
    </script>
</body>
</html>
EOF

b. 步骤2:配置虚拟主机

# 创建虚拟主机配置
cat > /usr/local/etc/nginx/servers/test-site.conf << 'EOF'
server {
    listen 8080;
    server_name localhost;
    
    root /usr/local/var/www/test-site;
    index index.html;
    
    access_log /usr/local/var/log/nginx/test-site.access.log;
    error_log /usr/local/var/log/nginx/test-site.error.log;
    
    location / {
        try_files $uri $uri/ =404;
    }
}
EOF

c. 步骤3:测试配置

# 检查配置语法
nginx -t

# 重新加载配置
nginx -s reload

# 测试访问
curl http://localhost:8080

# 在浏览器中打开
open http://localhost:8080

4. 实验2:反向代理

a. 步骤1:创建后端服务

# 创建一个简单的Node.js后端服务
cat > /tmp/backend-server.js << 'EOF'
const http = require('http');
const url = require('url');

const server = http.createServer((req, res) => {
    const parsedUrl = url.parse(req.url, true);
    
    res.setHeader('Content-Type', 'application/json');
    res.setHeader('Access-Control-Allow-Origin', '*');
    
    const response = {
        method: req.method,
        url: req.url,
        headers: req.headers,
        query: parsedUrl.query,
        timestamp: new Date().toISOString(),
        server: 'Backend Server',
        port: process.env.PORT || 3000
    };
    
    if (parsedUrl.pathname === '/health') {
        response.status = 'healthy';
    } else if (parsedUrl.pathname === '/api/users') {
        response.data = [
            { id: 1, name: 'Alice' },
            { id: 2, name: 'Bob' }
        ];
    }
    
    res.end(JSON.stringify(response, null, 2));
});

const port = process.env.PORT || 3000;
server.listen(port, () => {
    console.log(`Backend server running on port ${port}`);
});
EOF

# 启动后端服务
node /tmp/backend-server.js &

b. 步骤2:配置反向代理

cat > /usr/local/etc/nginx/servers/proxy-test.conf << 'EOF'
upstream backend {
    server 127.0.0.1:3000;
}

server {
    listen 8081;
    server_name localhost;
    
    access_log /usr/local/var/log/nginx/proxy-test.access.log;
    
    location / {
        return 200 "Nginx Proxy Server\nTry /api/ or /health";
        add_header Content-Type text/plain;
    }
    
    location /api/ {
        proxy_pass http://backend/api/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    
    location /health {
        proxy_pass http://backend/health;
        proxy_set_header Host $host;
    }
}
EOF

# 重新加载配置
nginx -s reload

# 测试代理
curl http://localhost:8081/api/users
curl http://localhost:8081/health

5. 实验3:负载均衡

a. 步骤1:启动多个后端服务

# 启动第二个后端服务
PORT=3001 node /tmp/backend-server.js &

# 启动第三个后端服务
PORT=3002 node /tmp/backend-server.js &

b. 步骤2:配置负载均衡

cat > /usr/local/etc/nginx/servers/load-balance.conf << 'EOF'
upstream backend_cluster {
    # 默认轮询算法
    server 127.0.0.1:3000 weight=3;
    server 127.0.0.1:3001 weight=2;
    server 127.0.0.1:3002 weight=1;
}

server {
    listen 8082;
    server_name localhost;
    
    location / {
        proxy_pass http://backend_cluster;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
EOF

# 重新加载配置
nginx -s reload

# 测试负载均衡(多次请求观察不同的端口)
for i in {1..6}; do
    echo "Request $i:"
    curl -s http://localhost:8082/health | grep '"port"'
    echo ""
done

c. 实验4:SSL/HTTPS配置

6. 步骤1:生成自签名证书

# 创建SSL目录
sudo mkdir -p /usr/local/etc/nginx/ssl

# 生成私钥
openssl genrsa -out /usr/local/etc/nginx/ssl/test.key 2048

# 生成证书签名请求
openssl req -new -key /usr/local/etc/nginx/ssl/test.key -out /usr/local/etc/nginx/ssl/test.csr -subj "/C=CN/ST=Beijing/L=Beijing/O=Test/CN=localhost"

# 生成自签名证书
openssl x509 -req -days 365 -in /usr/local/etc/nginx/ssl/test.csr -signkey /usr/local/etc/nginx/ssl/test.key -out /usr/local/etc/nginx/ssl/test.crt

a. 步骤2:配置HTTPS

cat > /usr/local/etc/nginx/servers/https-test.conf << 'EOF'
# HTTP重定向到HTTPS
server {
    listen 8083;
    server_name localhost;
    return 301 https://$server_name:8443$request_uri;
}

# HTTPS服务器
server {
    listen 8443 ssl;
    server_name localhost;
    
    ssl_certificate /usr/local/etc/nginx/ssl/test.crt;
    ssl_certificate_key /usr/local/etc/nginx/ssl/test.key;
    
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    
    root /usr/local/var/www/test-site;
    index index.html;
    
    location / {
        try_files $uri $uri/ =404;
    }
}
EOF

# 重新加载配置
nginx -s reload

# 测试HTTPS(忽略证书警告)
curl -k https://localhost:8443

7. 实验5:缓存配置

a. 步骤1:创建缓存目录

sudo mkdir -p /usr/local/var/cache/nginx
sudo chown -R $(whoami) /usr/local/var/cache/nginx

b. 步骤2:配置缓存

cat > /usr/local/etc/nginx/servers/cache-test.conf << 'EOF'
# 定义缓存路径
proxy_cache_path /usr/local/var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;

server {
    listen 8084;
    server_name localhost;
    
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_cache my_cache;
        proxy_cache_valid 200 304 10m;
        proxy_cache_valid 404 1m;
        
        # 添加缓存状态头部
        add_header X-Cache-Status $upstream_cache_status;
        
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
    
    # 缓存清理端点
    location /cache/purge/ {
        proxy_cache_purge my_cache $host$request_uri;
    }
}
EOF

# 重新加载配置
nginx -s reload

# 测试缓存
echo "第一次请求(MISS):"
curl -I http://localhost:8084/api/users

echo "第二次请求(HIT):"
curl -I http://localhost:8084/api/users

c. 实验6:日志分析

8. 查看访问日志

# 实时查看访问日志
tail -f /usr/local/var/log/nginx/access.log

# 分析最常访问的页面
awk '{print $7}' /usr/local/var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10

# 分析状态码分布
awk '{print $9}' /usr/local/var/log/nginx/access.log | sort | uniq -c | sort -nr

# 分析IP访问频率
awk '{print $1}' /usr/local/var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10

9. 实验7:性能测试


使用ApacheBench测试

# 安装ApacheBench(如果没有)
# macOS上通常已经包含

# 基础性能测试
ab -n 1000 -c 10 http://localhost:8080/

# 测试负载均衡性能
ab -n 1000 -c 50 http://localhost:8082/

# 测试缓存性能
ab -n 1000 -c 20 http://localhost:8084/api/users

使用curl进行基准测试

# 测试响应时间
curl -w "@curl-format.txt" -o /dev/null -s http://localhost:8080/

# 创建curl格式文件
cat > curl-format.txt << 'EOF'
     time_namelookup:  %{time_namelookup}\n
        time_connect:  %{time_connect}\n
     time_appconnect:  %{time_appconnect}\n
    time_pretransfer:  %{time_pretransfer}\n
       time_redirect:  %{time_redirect}\n
  time_starttransfer:  %{time_starttransfer}\n
                     ----------\n
          time_total:  %{time_total}\n
EOF

10. 实验8:监控和调试

启用状态页面

cat > /usr/local/etc/nginx/servers/monitoring.conf << 'EOF'
server {
    listen 8085;
    server_name localhost;
    
    location /nginx_status {
        stub_status on;
        access_log off;
        allow 127.0.0.1;
        deny all;
    }
    
    location /info {
        return 200 "Nginx Monitoring\nVersion: $nginx_version\nBuilt: $nginx_built_date";
        add_header Content-Type text/plain;
    }
}
EOF

# 重新加载配置
nginx -s reload

# 查看状态信息
curl http://localhost:8085/nginx_status
curl http://localhost:8085/info

调试配置

# 检查配置文件语法
nginx -t

# 查看配置文件内容
nginx -T

# 查看错误日志
tail -f /usr/local/var/log/nginx/error.log

# 增加调试信息
# 在nginx.conf中添加:error_log /path/to/log debug;

清理实验环境

# 停止所有Node.js后端服务
pkill -f "node /tmp/backend-server.js"

# 删除测试配置文件
rm -f /usr/local/etc/nginx/servers/*-test.conf
rm -f /usr/local/etc/nginx/servers/load-balance.conf
rm -f /usr/local/etc/nginx/servers/cache-test.conf
rm -f /usr/local/etc/nginx/servers/monitoring.conf

# 重新加载配置
nginx -s reload

# 清理缓存
rm -rf /usr/local/var/cache/nginx/*

# 清理测试文件
rm -f /tmp/backend-server.js
rm -f curl-format.txt

11. 深入学习

  1. 深入学习模块:了解更多Nginx模块(如auth_basic、limit_req等)

  2. 生产环境配置:学习生产环境的安全和性能配置

  3. 与其他工具集成:学习与Docker、Kubernetes的集成

  4. 日志分析工具:使用ELK Stack分析Nginx日志

  5. 自动化部署:使用Ansible、Terraform等工具自动化Nginx配置
    通过这些实验,您可以逐步掌握Nginx的各种功能和配置技巧!
    Nginx实战项目示例
    本目录包含了基于您当前前端项目的Nginx配置示例,展示如何为实际的前端应用配置Nginx。
    项目背景
    根据您的项目结构,这是一个基于Lerna的多包前端项目,包含:
    ● front:基础前端包
    ● front-demo:DemoApp前端应用
    ● module-a、module-b、module-c:其他前端模块
    配置方案

  6. 开发环境配置 (development.conf)

# 开发环境 - 支持热重载和开发工具
server {
    listen 80;
    server_name dev.example.local front-dev.example.local;
    
    # 代理到开发服务器
    location / {
        proxy_pass http://localhost:8000;  # UmiJS开发服务器
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
        
        # 支持WebSocket(用于热重载)
        proxy_read_timeout 86400;
    }
    
    # API代理到后端服务
    location /api/ {
        proxy_pass http://localhost:7001/api/;  # Egg.js后端服务
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
  1. 生产环境配置 (production.conf)

# 生产环境 - 优化性能和安全
upstream front_servers {
    server 127.0.0.1:3000;
    server 127.0.0.1:3001 backup;
}

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
    
    # SSL配置
    ssl_certificate /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    
    # 前端静态文件目录
    root /var/www/demo-app/dist;
    index index.html;
    
    # 日志
    access_log /var/log/nginx/demo-app.access.log;
    error_log /var/log/nginx/demo-app.error.log;
    
    # 安全头部
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    
    # 主应用路由(SPA)
    location / {
        try_files $uri $uri/ /index.html;
        
        # HTML文件不缓存
        location ~* \.html$ {
            add_header Cache-Control "no-cache, no-store, must-revalidate";
            expires 0;
        }
    }
    
    # 静态资源缓存
    location /static/ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        access_log off;
        
        # Gzip压缩
        gzip_static on;
    }
    
    # UmiJS构建的静态资源
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        access_log off;
        
        # 防盗链
        valid_referers none blocked example.com *.example.com;
        if ($invalid_referer) {
            return 403;
        }
    }
    
    # API代理
    location /api/ {
        proxy_pass http://front_servers/api/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # 超时设置
        proxy_connect_timeout 30s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
        
        # 错误重试
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
        proxy_next_upstream_tries 3;
    }
    
    # 健康检查
    location /health {
        access_log off;
        return 200 "healthy";
        add_header Content-Type text/plain;
    }
}
  1. 多子域名配置 (subdomains.conf)

# 前端子应用配置
server {
    listen 443 ssl http2;
    server_name front.example.com;
    
    ssl_certificate /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;
    
    root /var/www/demo-app/packages/front/dist;
    index index.html;
    
    location / {
        try_files $uri $uri/ /index.html;
    }
    
    location /api/ {
        proxy_pass http://front_servers/api/;
        # ... 代理配置
    }
}

# DemoApp主应用
server {
    listen 443 ssl http2;
    server_name app.example.com;
    
    ssl_certificate /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;
    
    root /var/www/demo-app/packages/front-demo/dist;
    index index.html;
    
    location / {
        try_files $uri $uri/ /index.html;
    }
    
    location /api/ {
        proxy_pass http://front_servers/api/;
        # ... 代理配置
    }
}

# 其他子应用类似配置...
  1. Docker部署配置 (docker.conf)

# 用于Docker容器化部署
server {
    listen 80;
    server_name _;
    
    # 容器内的静态文件路径
    root /app/dist;
    index index.html;
    
    # 健康检查
    location /health {
        access_log off;
        return 200 "healthy";
        add_header Content-Type text/plain;
    }
    
    # 主应用
    location / {
        try_files $uri $uri/ /index.html;
    }
    
    # API代理到后端容器
    location /api/ {
        proxy_pass http://backend:3000/api/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    
    # 静态资源
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 30d;
        add_header Cache-Control "public";
        access_log off;
    }
}

部署脚本
deploy.sh

#!/bin/bash

# 前端构建和部署脚本

set -e

# 配置变量
BUILD_DIR="/tmp/demo-app-build"
DEPLOY_DIR="/var/www/demo-app"
NGINX_CONFIG_DIR="/etc/nginx/sites-available"
BACKUP_DIR="/var/backups/demo-app"

echo "开始部署前端应用..."

# 1. 创建备份
echo "创建备份..."
sudo mkdir -p $BACKUP_DIR
if [ -d "$DEPLOY_DIR" ]; then
    sudo cp -r $DEPLOY_DIR $BACKUP_DIR/$(date +%Y%m%d_%H%M%S)
fi

# 2. 构建应用
echo "构建应用..."
rm -rf $BUILD_DIR
git clone https://github.com/your-repo/frontend-monorepo.git $BUILD_DIR
cd $BUILD_DIR

# 安装依赖
pnpm install

# 构建所有包
pnpm run build

# 3. 部署静态文件
echo "部署静态文件..."
sudo mkdir -p $DEPLOY_DIR
sudo cp -r dist/* $DEPLOY_DIR/
sudo cp -r packages/*/dist $DEPLOY_DIR/packages/
sudo chown -R nginx:nginx $DEPLOY_DIR

# 4. 更新Nginx配置
echo "更新Nginx配置..."
sudo cp nginx-config/production.conf $NGINX_CONFIG_DIR/demo-app.conf
sudo ln -sf $NGINX_CONFIG_DIR/demo-app.conf /etc/nginx/sites-enabled/

# 5. 测试配置
echo "测试Nginx配置..."
sudo nginx -t

# 6. 重新加载Nginx
echo "重新加载Nginx..."
sudo systemctl reload nginx

echo "部署完成!"

# 7. 健康检查
echo "进行健康检查..."
sleep 2
if curl -f http://localhost/health; then
    echo "健康检查通过!"
else
    echo "健康检查失败,正在回滚..."
    # 回滚逻辑
    latest_backup=$(ls -t $BACKUP_DIR | head -1)
    sudo cp -r $BACKUP_DIR/$latest_backup/* $DEPLOY_DIR/
    sudo systemctl reload nginx
    exit 1
fi

docker-compose.yml

version: '3.8'

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./conf.d:/etc/nginx/conf.d
      - ./dist:/app/dist
      - ./ssl:/etc/nginx/ssl
    depends_on:
      - frontend
      - backend
    restart: unless-stopped

  frontend:
    build:
      context: .
      dockerfile: docker/Dockerfile
    volumes:
      - ./dist:/app/dist
    environment:
      - NODE_ENV=production
    restart: unless-stopped

  backend:
    image: your-backend-image:latest
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
    restart: unless-stopped

监控配置
nginx-monitoring.conf

# Nginx监控配置
server {
    listen 8080;
    server_name localhost;
    
    # 限制访问
    allow 127.0.0.1;
    allow 10.0.0.0/8;
    allow 172.16.0.0/12;
    allow 192.168.0.0/16;
    deny all;
    
    # 状态页面
    location /nginx_status {
        stub_status on;
        access_log off;
    }
    
    # 访问日志分析
    location /log_analysis {
        alias /var/log/nginx/;
        autoindex on;
    }
    
    # 配置文件查看
    location /config {
        alias /etc/nginx/;
        autoindex on;
    }
}

@react-three/fiber的useThree 2025-12-30
IndexedDB详解 2025-12-30

评论区