Nginx基础学习
环境准备
1. 安装Nginx(macOS)
# 使用Homebrew安装
brew install nginx
# 查看Nginx版本
nginx -v
# 查看编译参数
nginx -V2. 基本目录结构
/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>
EOFb. 步骤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;
}
}
EOFc. 步骤3:测试配置
# 检查配置语法
nginx -t
# 重新加载配置
nginx -s reload
# 测试访问
curl http://localhost:8080
# 在浏览器中打开
open http://localhost:80804. 实验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/health5. 实验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 ""
donec. 实验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.crta. 步骤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:84437. 实验5:缓存配置
a. 步骤1:创建缓存目录
sudo mkdir -p /usr/local/var/cache/nginx
sudo chown -R $(whoami) /usr/local/var/cache/nginxb. 步骤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/usersc. 实验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 -109. 实验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
EOF10. 实验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.txt11. 深入学习
深入学习模块:了解更多Nginx模块(如auth_basic、limit_req等)
生产环境配置:学习生产环境的安全和性能配置
与其他工具集成:学习与Docker、Kubernetes的集成
日志分析工具:使用ELK Stack分析Nginx日志
自动化部署:使用Ansible、Terraform等工具自动化Nginx配置
通过这些实验,您可以逐步掌握Nginx的各种功能和配置技巧!
Nginx实战项目示例
本目录包含了基于您当前前端项目的Nginx配置示例,展示如何为实际的前端应用配置Nginx。
项目背景
根据您的项目结构,这是一个基于Lerna的多包前端项目,包含:
● front:基础前端包
● front-demo:DemoApp前端应用
● module-a、module-b、module-c:其他前端模块
配置方案开发环境配置 (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;
}
}生产环境配置 (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;
}
}多子域名配置 (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/;
# ... 代理配置
}
}
# 其他子应用类似配置...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
fidocker-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;
}
}