在现代 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服务器的资料请关注代码网其它相关文章!
发表评论