1. 项目概述
在当今互联网时代,Web技术已经成为构建在线服务的基础设施。作为一名从业多年的系统工程师,我经常需要为不同业务场景搭建稳定高效的Web环境。Nginx作为目前最流行的Web服务器之一,以其高性能、低资源消耗和灵活的配置特性,成为我的首选工具。
这个项目将带你从零开始,完整部署一个基于Nginx的Web服务器环境。不同于简单的安装教程,我会分享在实际生产环境中积累的配置技巧、性能优化方法和常见问题解决方案。无论你是刚接触Web部署的新手,还是希望优化现有环境的老手,都能从中获得实用价值。
2. 环境准备与基础安装
2.1 系统要求与依赖检查
在开始部署前,我们需要确保系统满足基本要求。我推荐使用Ubuntu 20.04 LTS或CentOS 8作为基础系统,它们都提供了长期支持且稳定性有保障。
首先更新系统软件包:
bash复制# Ubuntu/Debian
sudo apt update && sudo apt upgrade -y
# CentOS/RHEL
sudo yum update -y
检查系统关键依赖:
bash复制# 检查gcc编译器
gcc --version
# 检查make工具
make --version
# 检查PCRE库
pcre-config --version
提示:如果缺少任何依赖项,可以使用系统包管理器安装。例如在Ubuntu上:
sudo apt install build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev
2.2 Nginx安装方式选择
Nginx有三种主要安装方式:
- 系统包管理器安装(最简单):
bash复制# Ubuntu
sudo apt install nginx
# CentOS
sudo yum install nginx
- 官方仓库安装(版本较新):
bash复制# Ubuntu
sudo apt install curl gnupg2 ca-certificates lsb-release
echo "deb http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -
sudo apt update
sudo apt install nginx
# CentOS
sudo yum install yum-utils
sudo yum-config-manager --add-repo https://nginx.org/packages/centos/$releasever/$basearch/
sudo yum install nginx
- 源码编译安装(最灵活):
bash复制wget https://nginx.org/download/nginx-1.21.6.tar.gz
tar zxvf nginx-1.21.6.tar.gz
cd nginx-1.21.6
./configure --prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module
make
sudo make install
经验分享:生产环境我推荐使用官方仓库安装,它提供了稳定的更新渠道,同时避免了源码编译的复杂性。只有在需要特定模块或自定义编译选项时,才选择源码编译方式。
3. Nginx基础配置解析
3.1 核心配置文件结构
Nginx的配置文件通常位于以下路径:
/etc/nginx/nginx.conf(主配置文件)/etc/nginx/conf.d/(额外配置文件目录)/etc/nginx/sites-available/(虚拟主机配置)/etc/nginx/sites-enabled/(启用的虚拟主机链接)
典型的nginx.conf结构如下:
nginx复制user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 1024;
# multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
3.2 虚拟主机配置实战
下面是一个完整的虚拟主机配置示例(/etc/nginx/sites-available/example.com):
nginx复制server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
启用该配置:
bash复制sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t # 测试配置
sudo systemctl reload nginx
3.3 性能优化关键参数
在nginx.conf的http块中添加以下优化参数:
nginx复制sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# 缓冲设置
client_body_buffer_size 10K;
client_header_buffer_size 1k;
client_max_body_size 8m;
large_client_header_buffers 2 1k;
# 压缩设置
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
注意事项:
worker_processes通常设置为CPU核心数,可以使用auto让Nginx自动检测。worker_connections乘以worker_processes不能超过系统的最大文件描述符限制(可通过ulimit -n查看)。
4. 安全加固与SSL配置
4.1 基础安全措施
- 禁用server tokens(隐藏Nginx版本信息):
nginx复制server_tokens off;
- 防止点击劫持:
nginx复制add_header X-Frame-Options "SAMEORIGIN";
- 启用XSS保护:
nginx复制add_header X-XSS-Protection "1; mode=block";
- 内容安全策略(CSP)示例:
nginx复制add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' cdn.example.com; img-src 'self' data:; style-src 'self' 'unsafe-inline'; font-src 'self'; frame-ancestors 'none';";
4.2 Let's Encrypt SSL证书配置
安装Certbot工具:
bash复制# Ubuntu
sudo apt install certbot python3-certbot-nginx
# CentOS
sudo yum install certbot python3-certbot-nginx
获取并安装证书:
bash复制sudo certbot --nginx -d example.com -d www.example.com
Certbot会自动修改Nginx配置,添加类似以下内容:
nginx复制listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
4.3 强化SSL配置
在nginx.conf的http块中添加:
nginx复制ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
实操心得:使用SSL Labs测试工具(https://www.ssllabs.com/ssltest/)可以全面评估SSL配置安全性。我建议至少达到A评级,关键业务系统应追求A+。
5. 高级配置与优化
5.1 负载均衡配置
Nginx作为负载均衡器的基本配置:
nginx复制upstream backend {
least_conn;
server backend1.example.com:8080 weight=3;
server backend2.example.com:8080;
server backend3.example.com:8080 backup;
}
server {
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
负载均衡算法选择:
- 轮询(默认):均匀分配请求
- 最少连接(least_conn):优先分配给当前连接数最少的服务器
- IP哈希(ip_hash):同一客户端IP总是访问同一服务器
- 权重(weight):手动指定服务器权重
5.2 缓存配置优化
静态资源缓存配置示例:
nginx复制location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 365d;
add_header Cache-Control "public, no-transform";
access_log off;
}
代理缓存配置:
nginx复制proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m use_temp_path=off;
server {
location / {
proxy_cache my_cache;
proxy_cache_valid 200 304 12h;
proxy_cache_valid any 5m;
proxy_cache_key "$scheme$request_method$host$request_uri";
add_header X-Proxy-Cache $upstream_cache_status;
}
}
5.3 HTTP/2与性能调优
启用HTTP/2只需在listen指令中添加http2参数:
nginx复制listen 443 ssl http2;
其他性能优化建议:
- 调整worker进程数:
nginx复制worker_processes auto; # 自动检测CPU核心数
- 优化连接处理:
nginx复制events {
worker_connections 4096;
multi_accept on;
use epoll;
}
- 文件描述符限制:
bash复制# 临时设置
ulimit -n 65535
# 永久设置(编辑/etc/security/limits.conf)
* soft nofile 65535
* hard nofile 65535
6. 监控与日志分析
6.1 状态监控模块
启用Nginx状态页:
nginx复制location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
访问状态页将显示类似信息:
code复制Active connections: 3
server accepts handled requests
100 100 100
Reading: 0 Writing: 1 Waiting: 2
6.2 日志配置与分析
自定义日志格式:
nginx复制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;
使用GoAccess进行实时日志分析:
bash复制goaccess /var/log/nginx/access.log --log-format=COMBINED --real-time-html --port=7890
6.3 性能监控指标
关键监控指标包括:
- 请求率(requests/second)
- 连接数(active connections)
- 请求处理时间(request_time)
- 上游响应时间(upstream_response_time)
- 错误率(4xx/5xx响应比例)
可以使用Prometheus + Grafana搭建监控系统,配合nginx-exporter采集指标。
7. 常见问题与解决方案
7.1 启动与配置问题
问题1:Nginx启动失败,报错"bind() to 0.0.0.0:80 failed"
解决方案:
- 检查80端口是否被占用:
sudo lsof -i :80 - 停止占用端口的服务,或修改Nginx监听端口
- 检查是否有其他Nginx进程在运行:
ps aux | grep nginx
问题2:配置测试失败"nginx: [emerg] unknown directive"
解决方案:
- 检查指令拼写是否正确
- 确认该指令是否在正确的位置(如某些指令只能在http、server或location块中使用)
- 如果是第三方模块指令,确认模块是否已正确编译安装
7.2 性能相关问题
问题1:服务器负载高,响应慢
排查步骤:
- 检查Nginx状态页:
curl http://localhost/nginx_status - 分析访问日志:
tail -f /var/log/nginx/access.log - 检查错误日志:
tail -f /var/log/nginx/error.log - 使用top/htop查看系统资源使用情况
- 调整worker_processes和worker_connections参数
问题2:上传大文件失败
解决方案:
nginx复制client_max_body_size 100M; # 在http或server块中设置
client_body_buffer_size 128k;
client_body_temp_path /var/nginx/client_body_temp 1 2;
7.3 安全相关问题
问题1:如何防止DDoS攻击
缓解措施:
nginx复制# 限制连接速率
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
server {
location / {
limit_req zone=one burst=20;
}
}
# 限制并发连接数
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
location / {
limit_conn addr 10;
}
}
问题2:如何防止恶意扫描和爬虫
解决方案:
nginx复制# 屏蔽特定User-Agent
if ($http_user_agent ~* (wget|curl|httrack|nikto|sqlmap) ) {
return 403;
}
# 屏蔽特定IP
deny 192.168.1.1;
allow all;
在实际部署过程中,我发现最常被忽视的是日志轮转配置。默认情况下,Nginx日志会不断增长,最终可能占满磁盘空间。建议设置logrotate:
bash复制# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}