Linux搭建Nginx反向代理服务器的实战指南
在现代 Web 架构中,Nginx 作为高性能的反向代理服务器,早已成为互联网基础设施的重要组成部分。它不仅能够高效处理静态资源、负载均衡和缓存加速,还能灵活地将请求转发至后端多个服务实例,实现高可用与弹性伸缩。本篇博客将从零开始,带你一步步在 Linux 系统上搭建一个完整的 Nginx 反向代理环境,并结合 Java 后端服务进行实际演示,让你真正掌握企业级部署的核心技能。
为什么选择 Nginx?
Nginx(发音为 “engine-x”)是一款轻量级、高性能的 HTTP 和反向代理服务器,同时支持 IMAP/POP3/SMTP 协议。它最初由俄罗斯程序员 Igor Sysoev 开发,目的是解决 C10K 问题(即单机并发处理一万个连接)。如今,Nginx 已广泛应用于全球各大网站,包括 Netflix、Dropbox、WordPress.com 等知名平台。
Nginx 的核心优势:
- 高并发性能:采用事件驱动架构,异步非阻塞模型,轻松应对数万并发连接。
- 低内存消耗:相比传统 Apache,Nginx 在同等负载下内存占用更低。
- 模块化设计:支持动态加载模块,扩展性强。
- 热部署能力:配置文件修改后无需重启服务即可生效。
- 强大的反向代理与负载均衡功能:支持轮询、权重、IP哈希等多种策略。
- SSL/TLS 支持完善:轻松配置 HTTPS,支持 HTTP/2、HTTP/3。
- 日志与监控友好:提供详细的访问日志和错误日志,便于运维分析。
准备工作:Linux 环境初始化
我们以 Ubuntu 22.04 LTS 为例(其他发行版如 CentOS、Debian 也可类比操作),首先确保你的系统已更新并安装了基础工具。
sudo apt update && sudo apt upgrade -y sudo apt install curl wget vim net-tools -y
确认系统信息:
lsb_release -a uname -r
输出示例:
Distributor ID: Ubuntu Description: Ubuntu 22.04.3 LTS Release: 22.04 Codename: jammy 5.15.0-86-generic
安装 Nginx
Ubuntu 官方仓库已包含 Nginx,直接使用 apt 安装即可:
sudo apt install nginx -y
安装完成后,启动并设置开机自启:
sudo systemctl start nginx sudo systemctl enable nginx
检查状态:
sudo systemctl status nginx
你应该看到类似如下输出:
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2024-06-03 10:00:00 UTC; 1min ago
测试是否成功:打开浏览器访问服务器 IP 地址(如 http://your-server-ip),应看到 Nginx 欢迎页面:“Welcome to nginx!”
Nginx 基础配置结构解析
Nginx 的主配置文件位于 /etc/nginx/nginx.conf,而站点配置通常放在 /etc/nginx/sites-available/ 目录下,通过软链接激活到 /etc/nginx/sites-enabled/。
查看默认配置:
cat /etc/nginx/sites-available/default
关键结构说明:
server {
listen 80; # 监听端口
server_name localhost; # 主机名或域名
location / { # 匹配根路径
root /var/www/html; # 静态文件根目录
index index.html; # 默认首页
}
}每次修改配置后,务必先测试语法是否正确:
sudo nginx -t
若无报错,重载配置:
sudo systemctl reload nginx
配置第一个反向代理:代理本地 Java 服务
假设你有一个运行在 localhost:8080 的 Java Spring Boot 应用,现在你想通过 Nginx 将外部 80 端口的请求转发给它。
Step 1:创建新的站点配置
sudo vim /etc/nginx/sites-available/my-java-app
写入以下内容:
server {
listen 80;
server_name your-domain.com; # 或者写 IP,如 192.168.1.100
location / {
proxy_pass http://localhost:8080;
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;
}
}Step 2:启用配置
sudo ln -s /etc/nginx/sites-available/my-java-app /etc/nginx/sites-enabled/
Step 3:测试并重载
sudo nginx -t sudo systemctl reload nginx
现在,访问 http://your-server-ip 就会看到 Java 应用的内容!
编写一个简单的 Java Spring Boot 示例应用
为了演示完整流程,我们来快速构建一个最简化的 Spring Boot 项目。
创建 Maven 项目pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>nginx-demo-app</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.5</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>创建主启动类Application.java
package com.example.nginxdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@RestController
static class HelloController {
@GetMapping("/")
public String hello() {
return "Hello from Java Spring Boot via Nginx Reverse Proxy! 🚀";
}
@GetMapping("/health")
public String health() {
return "{\"status\": \"UP\", \"message\": \"Service is healthy\"}";
}
}
}编译打包并运行
mvn clean package java -jar target/nginx-demo-app-1.0.0.jar
默认监听 8080 端口。你可以先本地测试:
curl http://localhost:8080/ # 输出:Hello from Java Spring Boot via Nginx Reverse Proxy! 🚀
多实例负载均衡配置
真实生产环境中,我们通常部署多个 Java 实例以提高可用性和吞吐量。Nginx 可以轻松实现负载均衡。
修改 Nginx 配置,定义 upstream
upstream backend_servers {
server 127.0.0.1:8080 weight=3; # 权重3
server 127.0.0.1:8081; # 权重1(默认)
server 127.0.0.1:8082; # 权重1
}
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://backend_servers;
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;
}
}weight 表示权重,数值越大分配请求越多;默认为 1。
启动多个 Java 实例
由于端口冲突,我们需要让每个实例监听不同端口:
# 终端1 java -jar target/nginx-demo-app-1.0.0.jar --server.port=8080 # 终端2 java -jar target/nginx-demo-app-1.0.0.jar --server.port=8081 # 终端3 java -jar target/nginx-demo-app-1.0.0.jar --server.port=8082
或者使用脚本批量启动:
#!/bin/bash
for port in 8080 8081 8082; do
java -jar target/nginx-demo-app-1.0.0.jar --server.port=$port > /dev/null 2>&1 &
echo "Started instance on port $port with PID $!"
done保存为 start-all.sh 并执行:
chmod +x start-all.sh ./start-all.sh
现在刷新浏览器多次访问,你会发现请求被轮流分发到不同端口 —— 这就是轮询负载均衡!
使用 Mermaid 图表展示请求流转
让我们用 Mermaid 图形化展示整个反向代理 + 负载均衡的架构:

该图清晰展示了客户端请求如何经由 Nginx 分发到后端多个 Java 实例,所有实例共享同一数据源(如 MySQL、Redis)。
配置 HTTPS(SSL/TLS)
现代 Web 应用必须支持 HTTPS。我们可以使用免费的 Let’s Encrypt 证书,或自签名证书用于测试。
自签名证书生成(仅用于开发)
sudo mkdir -p /etc/nginx/ssl
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/nginx/ssl/selfsigned.key \
-out /etc/nginx/ssl/selfsigned.crt
填写信息时,Common Name 建议填你的域名或 IP。
修改 Nginx 配置支持 HTTPS
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri; # 强制跳转 HTTPS
}
server {
listen 443 ssl;
server_name your-domain.com;
ssl_certificate /etc/nginx/ssl/selfsigned.crt;
ssl_certificate_key /etc/nginx/ssl/selfsigned.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://backend_servers;
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;
}
}
重载配置:
sudo nginx -t && sudo systemctl reload nginx
现在访问 https://your-server-ip(忽略浏览器警告),即可看到加密连接下的 Java 应用!
健康检查与故障转移
Nginx 支持对后端服务进行健康检查,自动剔除不可用节点。
配置主动健康检查(需商业版或使用开源模块)
标准开源版不支持主动探测,但我们可以通过被动方式(如超时失败)实现简单容错。
upstream backend_servers {
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server 127.0.0.1:8081 max_fails=3 fail_timeout=30s;
server 127.0.0.1:8082 max_fails=3 fail_timeout=30s;
}含义:如果某节点连续 3 次失败,则在 30 秒内不再分配请求给它。
Java 端增加健康检查接口
修改之前的 HelloController:
@GetMapping("/health")
public ResponseEntity<Map<String, Object>> healthCheck() {
Map<String, Object> body = new HashMap<>();
body.put("status", "UP");
body.put("timestamp", System.currentTimeMillis());
body.put("hostname", getHostName());
return ResponseEntity.ok(body);
}
private String getHostName() {
try {
return InetAddress.getLocalHost().getHostName();
} catch (Exception e) {
return "unknown";
}
}这样你就可以通过访问 /health 判断服务是否存活。
限流与安全防护
Nginx 内置多种安全机制,防止恶意攻击或突发流量压垮后端。
基于 IP 的访问限制
location /admin {
allow 192.168.1.0/24;
deny all;
proxy_pass http://backend_servers;
}请求速率限制(漏桶算法)
http {
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
server {
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://backend_servers;
}
}
}解释:
rate=10r/s:每秒最多 10 个请求burst=20:允许突发 20 个请求nodelay:突发请求立即处理,不延迟
日志分析与监控
Nginx 默认记录访问日志和错误日志:
- 访问日志:
/var/log/nginx/access.log - 错误日志:
/var/log/nginx/error.log
你可以自定义日志格式:
log_format detailed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time" uht="$upstream_header_time" urt="$upstream_response_time"';
access_log /var/log/nginx/detailed.log detailed;实时查看日志:
tail -f /var/log/nginx/access.log
配合 ELK(Elasticsearch + Logstash + Kibana)或 Grafana Loki,可实现可视化监控。
高级功能:WebSocket 代理支持
如果你的 Java 应用使用 WebSocket(如聊天室、实时通知),需要特殊配置:
location /ws/ {
proxy_pass http://backend_servers;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}Java 端示例(Spring WebSocket):
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("/app");
}
}前端连接:
const socket = new SockJS('/ws');
const stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
console.log('Connected: ' + frame);
});缓存静态资源提升性能
虽然我们主要代理动态 Java 应用,但也可以让 Nginx 缓存部分响应,减轻后端压力。
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;
server {
location /api/data {
proxy_cache my_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_pass http://backend_servers;
}
}Java 端控制缓存头:
@GetMapping("/api/data")
public ResponseEntity<String> getData(HttpServletResponse response) {
response.setHeader("Cache-Control", "max-age=600, public");
return ResponseEntity.ok("Cached data from Java backend");
}性能调优建议
1. 调整 Worker 进程数
根据 CPU 核心数设置:
worker_processes auto; # 或具体数字,如 4
2. 优化连接队列
events {
worker_connections 1024;
use epoll; # Linux 高效 I/O 模型
multi_accept on;
}3. 启用 Gzip 压缩
gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml; gzip_min_length 1024;
4. 文件描述符限制
编辑 /etc/security/limits.conf:
nginx soft nofile 65536 nginx hard nofile 65536
然后重启 Nginx。
自动化部署脚本示例
编写 Shell 脚本一键部署:
#!/bin/bash
# deploy-nginx-java.sh
echo "🔄 正在停止旧 Java 进程..."
pkill -f nginx-demo-app
echo "📦 正在启动三个 Java 实例..."
for port in 8080 8081 8082; do
nohup java -jar target/nginx-demo-app-1.0.0.jar --server.port=$port > /tmp/app-$port.log 2>&1 &
echo "✅ 启动端口 $port,PID: $!"
done
echo "🛠️ 正在重载 Nginx 配置..."
sudo nginx -t && sudo systemctl reload nginx
echo "🚀 部署完成!访问 http://localhost 查看效果"赋予执行权限并运行:
chmod +x deploy-nginx-java.sh ./deploy-nginx-java.sh
故障排查技巧
常见错误及解决方案:
502 Bad Gateway
- 后端 Java 服务未启动 →
netstat -tuln | grep 8080 - 防火墙阻止 →
sudo ufw allow 8080 - proxy_pass 地址错误 → 检查是否拼写错误
403 Forbidden
- 文件权限不足 →
chmod -R 755 /var/www/html - SELinux 限制(CentOS)→
setsebool -P httpd_can_network_connect 1
404 Not Found
- location 匹配规则错误 → 检查路径正则表达式
- root 或 alias 设置错误 → 确认文件物理路径
Nginx 启动失败
- 端口被占用 →
sudo lsof -i :80 - 配置语法错误 →
sudo nginx -t仔细阅读报错行
结语:拥抱现代化 Web 架构
通过本篇教程,你已经掌握了在 Linux 上搭建 Nginx 反向代理服务器的全流程,并成功将其与 Java 后端服务集成。无论是单实例代理、多节点负载均衡,还是 HTTPS 加密、限流防护、WebSocket 支持,Nginx 都能游刃有余地胜任。
更重要的是,这套架构具备极强的扩展性 —— 你可以轻松接入 Redis 缓存、MySQL 数据库、消息队列 Kafka、容器编排 Kubernetes……构建属于你自己的云原生应用体系。
记住,技术没有终点,只有不断演进的过程。愿你在 DevOps 与云架构的道路上越走越远,成为真正的全栈工程师!
附录:完整 Nginx 配置文件示例(含注释)
# /etc/nginx/sites-available/full-config
upstream backend_servers {
server 127.0.0.1:8080 weight=3 max_fails=3 fail_timeout=30s;
server 127.0.0.1:8081 max_fails=3 fail_timeout=30s;
server 127.0.0.1:8082 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/selfsigned.crt;
ssl_certificate_key /etc/nginx/ssl/selfsigned.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# Gzip 压缩
gzip on;
gzip_types text/plain text/css application/json application/javascript;
# 缓存配置
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m;
# 健康检查页面
location /health {
access_log off;
return 200 'OK\n';
add_header Content-Type text/plain;
}
# API 限流
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://backend_servers;
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;
}
# WebSocket 支持
location /ws/ {
proxy_pass http://backend_servers;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# 默认代理
location / {
proxy_pass http://backend_servers;
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;
}
# 自定义错误页
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}希望这篇详尽的指南能为你在 Linux 上部署 Nginx + Java 架构打下坚实基础。动手实践是掌握技术的最佳途径 —— 不妨现在就打开终端,开始你的第一行配置吧。
以上就是Linux搭建Nginx反向代理服务器的实战指南的详细内容,更多关于Linux搭建Nginx服务器的资料请关注脚本之家其它相关文章!
相关文章
Nginx 配置 proxy_hide_header 隐藏后端 Server&n
Nginx反向代理场景中,后端服务常会在响应头中暴露版本信息,使用proxy_hide_header指令可以在Nginx层将其过滤掉,本文就来详细的介绍一下Nginx隐藏后端 Server 的版本信息的实现,感兴趣的可以了解一下2026-04-04


最新评论