Nginx中虛擬主機(jī)的三種配置方式詳解
在現(xiàn)代 Web 架構(gòu)中,單一服務(wù)器承載多個(gè)網(wǎng)站已成為常態(tài)。無論是小型創(chuàng)業(yè)公司還是大型企業(yè),都希望在有限的硬件資源下最大化服務(wù)效率。Nginx 作為高性能、輕量級(jí)的反向代理與 Web 服務(wù)器,憑借其出色的并發(fā)處理能力與靈活的虛擬主機(jī)配置機(jī)制,成為眾多開發(fā)者的首選。本文將深入探討如何通過 Nginx 實(shí)現(xiàn)基于域名、端口、IP 地址的多站點(diǎn)部署,覆蓋從基礎(chǔ)配置到高階實(shí)戰(zhàn)的完整路徑,并結(jié)合 Java 應(yīng)用場景提供可運(yùn)行的示例代碼,幫助你構(gòu)建一個(gè)穩(wěn)定、可擴(kuò)展、安全的多站點(diǎn)服務(wù)架構(gòu)。

什么是虛擬主機(jī)(Virtual Host)?
虛擬主機(jī)(Virtual Host)是 Web 服務(wù)器通過單一 IP 地址或端口,為多個(gè)不同域名或站點(diǎn)提供服務(wù)的技術(shù)。它允許你在一臺(tái)服務(wù)器上運(yùn)行多個(gè)網(wǎng)站,每個(gè)網(wǎng)站擁有獨(dú)立的根目錄、配置文件、SSL 證書和訪問日志,對(duì)用戶而言,就像各自運(yùn)行在獨(dú)立的物理服務(wù)器上一樣。
Nginx 的虛擬主機(jī)機(jī)制基于 server 塊定義,每個(gè) server 塊代表一個(gè)獨(dú)立的站點(diǎn)。Nginx 通過解析客戶端請(qǐng)求中的 Host 頭、目標(biāo)端口和綁定 IP 地址,匹配最合適的 server 塊進(jìn)行響應(yīng)。
小知識(shí):Apache 也有類似機(jī)制,稱為“Name-based Virtual Hosts”,但 Nginx 在高并發(fā)場景下的內(nèi)存占用與響應(yīng)速度更具優(yōu)勢,尤其適合現(xiàn)代微服務(wù)架構(gòu)。
Nginx 配置文件結(jié)構(gòu)概覽
在開始配置之前,我們先了解 Nginx 的核心配置文件結(jié)構(gòu)。通常,Nginx 的主配置文件位于:
- Linux 系統(tǒng):
/etc/nginx/nginx.conf - macOS (Homebrew):
/usr/local/etc/nginx/nginx.conf - Windows:
C:\nginx\conf\nginx.conf
主配置文件中,通常包含以下關(guān)鍵部分:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
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;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
關(guān)鍵點(diǎn):include /etc/nginx/conf.d/*.conf; 表示 Nginx 會(huì)加載 conf.d 目錄下所有 .conf 文件,這是推薦的多站點(diǎn)管理方式,便于模塊化與版本控制。
我們將在 conf.d 目錄下為每個(gè)站點(diǎn)創(chuàng)建獨(dú)立的配置文件,如:
site1.example.com.confapi.example.com:8080.confapp1.192.168.1.10.conf
基于域名的虛擬主機(jī)(Name-based Virtual Host)
這是最常見的虛擬主機(jī)類型。多個(gè)域名共享同一個(gè) IP 地址和端口(通常是 80 或 443),Nginx 通過 Host 請(qǐng)求頭區(qū)分請(qǐng)求屬于哪個(gè)站點(diǎn)。
場景說明
假設(shè)你有一臺(tái)服務(wù)器,IP 為 192.168.1.10,你想部署三個(gè)網(wǎng)站:
www.example.com—— 公司官網(wǎng)blog.example.com—— 博客系統(tǒng)shop.example.com—— 電商前端
它們都監(jiān)聽 80 端口,但內(nèi)容完全不同。
配置文件示例
在 /etc/nginx/conf.d/ 下創(chuàng)建三個(gè)文件:
1.www.example.com.conf
server {
listen 80;
server_name www.example.com example.com;
root /var/www/www.example.com/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
access_log /var/log/nginx/www.example.com.access.log;
error_log /var/log/nginx/www.example.com.error.log;
}
2.blog.example.com.conf
server {
listen 80;
server_name blog.example.com;
root /var/www/blog.example.com/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
}
access_log /var/log/nginx/blog.example.com.access.log;
error_log /var/log/nginx/blog.example.com.error.log;
}
3.shop.example.com.conf
server {
listen 80;
server_name shop.example.com;
root /var/www/shop.example.com/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
# 靜態(tài)資源緩存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
access_log /var/log/nginx/shop.example.com.access.log;
error_log /var/log/nginx/shop.example.com.error.log;
}
Java 應(yīng)用集成示例
雖然 Nginx 本身是靜態(tài)服務(wù)器,但常作為 Java Web 應(yīng)用(如 Spring Boot)的反向代理。我們來模擬一個(gè)場景:
你有一個(gè) Spring Boot 應(yīng)用,運(yùn)行在 localhost:8081,希望通過 api.example.com 訪問。
Java 代碼:Spring Boot REST API
package com.example.apiserver;
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;
import java.util.HashMap;
import java.util.Map;
@SpringBootApplication
@RestController
public class ApiServerApplication {
public static void main(String[] args) {
SpringApplication.run(ApiServerApplication.class, args);
}
@GetMapping("/health")
public Map<String, Object> healthCheck() {
Map<String, Object> response = new HashMap<>();
response.put("status", "UP");
response.put("service", "API Server v1.2");
response.put("timestamp", System.currentTimeMillis());
response.put("message", "? Nginx + Java integration working!");
return response;
}
@GetMapping("/user/{id}")
public Map<String, Object> getUser(@PathVariable("id") Long id) {
Map<String, Object> user = new HashMap<>();
user.put("id", id);
user.put("name", "張三");
user.put("email", "zhangsan@example.com");
user.put("role", "admin");
return user;
}
}Nginx 配置:反向代理到 Java 應(yīng)用
在 /etc/nginx/conf.d/api.example.com.conf 中:
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://127.0.0.1:8081;
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;
# 超時(shí)設(shè)置
proxy_connect_timeout 5s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
access_log /var/log/nginx/api.example.com.access.log;
error_log /var/log/nginx/api.example.com.error.log;
}
重啟 Nginx 后,訪問 http://api.example.com/health 將返回 Java 應(yīng)用的 JSON 響應(yīng)。
DNS 與本地測試
為了在本地測試,你需要修改 /etc/hosts(Linux/macOS)或 C:\Windows\System32\drivers\etc\hosts(Windows):
192.168.1.10 www.example.com 192.168.1.10 blog.example.com 192.168.1.10 shop.example.com 192.168.1.10 api.example.com
然后在瀏覽器中訪問:
http://www.example.comhttp://blog.example.comhttp://shop.example.comhttp://api.example.com/health
提示:若你使用 Docker,可將 Java 應(yīng)用部署在容器中,Nginx 通過 proxy_pass http://app-container:8081; 進(jìn)行代理,實(shí)現(xiàn)真正的隔離部署。
基于端口的虛擬主機(jī)(Port-based Virtual Host)
當(dāng)多個(gè)站點(diǎn)需要共享同一個(gè)域名,但提供不同服務(wù)時(shí),端口綁定成為理想方案。例如:
example.com:80→ 網(wǎng)站首頁example.com:8080→ 管理后臺(tái)example.com:9000→ API 網(wǎng)關(guān)
這種配置常用于內(nèi)部系統(tǒng)、測試環(huán)境或微服務(wù)架構(gòu)中。
場景說明
假設(shè)你有一個(gè)主站 example.com,同時(shí)部署了:
- 管理后臺(tái)(運(yùn)行在 8080)
- Swagger 文檔接口(運(yùn)行在 9000)
- 前端靜態(tài)資源(運(yùn)行在 80)
配置文件示例
1. 主站(端口 80)
server {
listen 80;
server_name example.com;
root /var/www/example.com/main;
index index.html;
location / {
try_files $uri $uri/ =404;
}
access_log /var/log/nginx/example.com-main.access.log;
error_log /var/log/nginx/example.com-main.error.log;
}
2. 管理后臺(tái)(端口 8080)
server {
listen 8080;
server_name example.com;
root /var/www/example.com/admin;
index index.html;
location / {
try_files $uri $uri/ =404;
}
# 限制訪問來源(僅允許內(nèi)網(wǎng))
allow 192.168.1.0/24;
deny all;
access_log /var/log/nginx/example.com-admin.access.log;
error_log /var/log/nginx/example.com-admin.error.log;
}
3. Swagger API 文檔(端口 9000)
server {
listen 9000;
server_name example.com;
root /var/www/example.com/swagger;
index index.html;
location / {
try_files $uri $uri/ =404;
}
# 允許跨域訪問(前端調(diào)用)
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization";
access_log /var/log/nginx/example.com-swagger.access.log;
error_log /var/log/nginx/example.com-swagger.error.log;
}
Java 應(yīng)用:部署 Swagger UI
如果你使用 Spring Boot,只需引入依賴:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.3.0</version>
</dependency>然后啟動(dòng)應(yīng)用,監(jiān)聽 8081 端口:
@SpringBootApplication
public class SwaggerApp {
public static void main(String[] args) {
System.setProperty("server.port", "8081");
SpringApplication.run(SwaggerApp.class, args);
}
}
Nginx 反向代理配置:
server {
listen 9000;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:8081/v3/api-docs;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /swagger-ui/ {
proxy_pass http://127.0.0.1:8081/swagger-ui/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
access_log /var/log/nginx/example.com-swagger.access.log;
error_log /var/log/nginx/example.com-swagger.error.log;
}
注意事項(xiàng)
- 端口必須在防火墻中開放(如
ufw allow 8080) - 瀏覽器地址欄會(huì)顯示端口號(hào),不夠“優(yōu)雅”
- 適合內(nèi)網(wǎng)或測試環(huán)境,生產(chǎn)環(huán)境建議使用域名 + SSL + 80/443
- 多端口部署會(huì)增加運(yùn)維復(fù)雜度,建議配合 Docker Compose 管理
基于 IP 的虛擬主機(jī)(IP-based Virtual Host)
當(dāng)多個(gè)站點(diǎn)使用相同域名和端口,但需要綁定不同 IP 地址時(shí),使用 IP-based 虛擬主機(jī)。這在以下場景非常有用:
- 服務(wù)器擁有多個(gè)公網(wǎng) IP
- 某些站點(diǎn)需要獨(dú)立 SSL 證書(舊版客戶端不支持 SNI)
- 安全隔離需求(如金融系統(tǒng) vs 公共網(wǎng)站)
場景說明
你有兩塊網(wǎng)卡,或通過 VLAN 分配了兩個(gè) IP:
192.168.1.10→ 對(duì)外官網(wǎng)192.168.1.11→ 內(nèi)部管理后臺(tái)(不對(duì)外暴露)
兩個(gè)站點(diǎn)都使用 example.com,但通過不同 IP 訪問。
配置文件示例
1. 外網(wǎng)官網(wǎng)(IP: 192.168.1.10)
server {
listen 192.168.1.10:80;
server_name example.com;
root /var/www/public-site;
index index.html;
location / {
try_files $uri $uri/ =404;
}
access_log /var/log/nginx/public-site.access.log;
error_log /var/log/nginx/public-site.error.log;
}
2. 內(nèi)部后臺(tái)(IP: 192.168.1.11)
server {
listen 192.168.1.11:80;
server_name example.com;
root /var/www/internal-admin;
index index.html;
location / {
try_files $uri $uri/ =404;
}
# 僅允許內(nèi)網(wǎng)訪問
allow 192.168.1.0/24;
deny all;
access_log /var/log/nginx/internal-admin.access.log;
error_log /var/log/nginx/internal-admin.error.log;
}
如何測試
在客戶端機(jī)器上,分別訪問:
http://192.168.1.10→ 顯示官網(wǎng)http://192.168.1.11→ 顯示后臺(tái)
若你在瀏覽器中訪問 http://example.com,Nginx 會(huì)匹配 server_name example.com,但不會(huì)區(qū)分 IP,除非你顯式綁定 IP。
安全建議
- 使用
listen 192.168.1.11:80可避免外部直接訪問內(nèi)部服務(wù) - 結(jié)合防火墻規(guī)則(如 iptables)進(jìn)一步加固
- 對(duì)敏感后臺(tái)啟用 Basic Auth:
location / {
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd;
try_files $uri $uri/ =404;
}
生成密碼文件:
sudo apt install apache2-utils htpasswd -c /etc/nginx/.htpasswd admin
多種方式組合:高級(jí)虛擬主機(jī)策略
現(xiàn)實(shí)世界中,很少只使用單一方式。優(yōu)秀的架構(gòu)往往是域名 + 端口 + IP的組合策略。
案例:企業(yè)級(jí)多租戶系統(tǒng)
你是一家 SaaS 平臺(tái)提供商,為多個(gè)客戶(客戶A、客戶B)提供獨(dú)立子域名服務(wù),同時(shí):
- 客戶A 使用
customerA.yourcompany.com - 客戶B 使用
customerB.yourcompany.com - 所有客戶后臺(tái)通過
admin.yourcompany.com:8081訪問 - 你有兩臺(tái)服務(wù)器:
192.168.1.10(對(duì)外)、192.168.1.11(數(shù)據(jù)庫/緩存)
架構(gòu)如下:
| 服務(wù)類型 | 域名 | 端口 | IP | 說明 |
|---|---|---|---|---|
| 客戶前端 | customerA.yourcompany.com | 80 | 192.168.1.10 | 靜態(tài) HTML + JS |
| 客戶前端 | customerB.yourcompany.com | 80 | 192.168.1.10 | 靜態(tài) HTML + JS |
| 管理后臺(tái) | admin.yourcompany.com | 8081 | 192.168.1.10 | Java Spring Boot |
| 內(nèi)部服務(wù) | internal.yourcompany.com | 80 | 192.168.1.11 | 僅限內(nèi)網(wǎng)訪問 |
Nginx 配置文件集合
customerA.yourcompany.com.conf
server {
listen 80;
server_name customerA.yourcompany.com;
root /var/www/customers/customerA;
index index.html;
location / {
try_files $uri $uri/ =404;
}
# 緩存靜態(tài)資源
location ~* \.(css|js|png|jpg|jpeg|gif|ico)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
access_log /var/log/nginx/customerA.access.log;
error_log /var/log/nginx/customerA.error.log;
}
customerB.yourcompany.com.conf
server {
listen 80;
server_name customerB.yourcompany.com;
root /var/www/customers/customerB;
index index.html;
location / {
try_files $uri $uri/ =404;
}
# 自定義響應(yīng)頭(用于客戶品牌識(shí)別)
add_header X-Customer-ID "B-2024";
access_log /var/log/nginx/customerB.access.log;
error_log /var/log/nginx/customerB.error.log;
}
admin.yourcompany.com.conf
server {
listen 8081;
server_name admin.yourcompany.com;
location / {
proxy_pass http://127.0.0.1:8082;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# 限制僅公司內(nèi)網(wǎng)訪問
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
access_log /var/log/nginx/admin.access.log;
error_log /var/log/nginx/admin.error.log;
}
internal.yourcompany.com.conf
server {
listen 192.168.1.11:80;
server_name internal.yourcompany.com;
root /var/www/internal;
index index.html;
location / {
try_files $uri $uri/ =404;
}
# 禁止外部訪問
deny all;
access_log /var/log/nginx/internal.access.log;
error_log /var/log/nginx/internal.error.log;
}
Mermaid 架構(gòu)圖:多租戶系統(tǒng)拓?fù)?/h3>

此圖清晰展示了流量如何根據(jù)域名、端口、IP 被路由到不同后端服務(wù)。在實(shí)際運(yùn)維中,這種拓?fù)浣Y(jié)構(gòu)能極大提升系統(tǒng)彈性與安全性。
SSL/TLS 加密:HTTPS 虛擬主機(jī)配置
安全是現(xiàn)代 Web 的基石。為每個(gè)虛擬主機(jī)配置 HTTPS,不僅能保護(hù)用戶數(shù)據(jù),還能提升 SEO 排名。
使用 Let’s Encrypt 免費(fèi)證書
我們使用 certbot 自動(dòng)申請(qǐng)證書(以 Ubuntu 22.04 為例):
sudo apt update sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d www.example.com -d blog.example.com -d shop.example.com
Certbot 會(huì)自動(dòng)修改 Nginx 配置,添加 SSL 監(jiān)聽與證書路徑。
生成的 HTTPS 配置示例
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
ssl_prefer_server_ciphers off;
root /var/www/www.example.com/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
access_log /var/log/nginx/www.example.com.ssl.access.log;
error_log /var/log/nginx/www.example.com.ssl.error.log;
}
# 強(qiáng)制 HTTP 跳轉(zhuǎn) HTTPS
server {
listen 80;
server_name www.example.com;
return 301 https://$host$request_uri;
}
Java 應(yīng)用 HTTPS 集成
如果你的 Java 應(yīng)用也啟用 HTTPS(如 Spring Boot),你需要:
生成 keystore:
keytool -genkey -alias tomcat -keyalg RSA -keystore keystore.jks
在 application.properties 中配置:
server.port=8443 server.ssl.key-store=classpath:keystore.jks server.ssl.key-store-password=changeit server.ssl.key-password=changeit server.ssl.key-store-type=JKS
Nginx 反向代理:
server {
listen 443 ssl;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
location / {
proxy_pass https://127.0.0.1:8443;
proxy_ssl_verify off; # 僅在自簽名證書時(shí)使用,生產(chǎn)環(huán)境請(qǐng)開啟
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
重要提示:生產(chǎn)環(huán)境請(qǐng)關(guān)閉 proxy_ssl_verify off,并配置 proxy_ssl_trusted_certificate 指向 CA 證書鏈。
性能優(yōu)化與最佳實(shí)踐
1.啟用 Gzip 壓縮
gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
2.緩存靜態(tài)資源
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
3.限制請(qǐng)求速率(防刷)
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;
}
}
4.啟用 HTTP/2
listen 443 ssl http2;
HTTP/2 支持多路復(fù)用,顯著提升頁面加載速度,尤其適合多資源站點(diǎn)。
5.日志分離與輪轉(zhuǎn)
為每個(gè)站點(diǎn)配置獨(dú)立日志,便于排查問題:
# 編輯 /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
}
Java + Nginx + Docker 實(shí)戰(zhàn)演練
我們構(gòu)建一個(gè)完整的多站點(diǎn) Docker 環(huán)境,包含:
- Nginx(反向代理)
- Spring Boot API(Java)
- 靜態(tài)網(wǎng)站(HTML)
- Redis 緩存
項(xiàng)目結(jié)構(gòu)
nginx-multi-site/
├── nginx/
│ ├── nginx.conf
│ └── sites-available/
│ ├── frontend.conf
│ └── api.conf
├── java-api/
│ ├── src/
│ │ └── main/java/com/example/ApiApplication.java
│ └── Dockerfile
├── frontend/
│ ├── index.html
│ └── Dockerfile
└── docker-compose.yml
docker-compose.yml
version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/sites-available:/etc/nginx/conf.d
- ./frontend:/var/www/frontend
depends_on:
- java-api
restart: unless-stopped
java-api:
build: ./java-api
ports:
- "8081:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
restart: unless-stopped
frontend:
build: ./frontend
ports:
- "8082:80"
restart: unless-stoppedjava-api/Dockerfile
FROM openjdk:17-jre-slim WORKDIR /app COPY target/api-1.0.jar app.jar EXPOSE 8080 ENTRYPOINT ["java","-jar","app.jar"]
frontend/Dockerfile
FROM nginx:alpine COPY index.html /usr/share/nginx/html/index.html COPY index.html /usr/share/nginx/html/404.html EXPOSE 80
frontend/index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>前端站點(diǎn)</title>
</head>
<body>
<h1>?? 歡迎訪問前端站點(diǎn)</h1>
<p>調(diào)用 API:<a href="http://localhost/api/health" rel="external nofollow" >/api/health</a></p>
<script>
fetch('http://nginx/api/health')
.then(r => r.json())
.then(data => console.log('API 響應(yīng):', data))
.catch(e => console.error('調(diào)用失敗:', e));
</script>
</body>
</html>nginx/sites-available/frontend.conf
server {
listen 80;
server_name frontend.example.com;
root /var/www/frontend;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
nginx/sites-available/api.conf
server {
listen 80;
server_name api.example.com;
location /api/ {
proxy_pass http://java-api:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
啟動(dòng)服務(wù)
cd nginx-multi-site docker-compose up --build
訪問:
http://localhost→ 前端頁面http://localhost/api/health→ Java API 響應(yīng)- 修改
/etc/hosts,綁定127.0.0.1 frontend.example.com api.example.com,即可用域名訪問
這是一個(gè)完整可運(yùn)行的多站點(diǎn)架構(gòu),支持未來擴(kuò)展:添加數(shù)據(jù)庫、緩存、負(fù)載均衡器等。
常見錯(cuò)誤與調(diào)試技巧
| 問題 | 原因 | 解決方案 |
|---|---|---|
404 Not Found | root 路徑錯(cuò)誤或文件不存在 | 使用 ls -la /var/www/site 檢查文件是否存在 |
502 Bad Gateway | Java 應(yīng)用未啟動(dòng)或端口錯(cuò)誤 | curl http://localhost:8081/health 測試后端 |
SSL_ERROR_BAD_CERT_DOMAIN | 證書域名不匹配 | 使用 openssl x509 -in cert.pem -text -noout 查看證書域名 |
nginx: [emerg] bind() to 0.0.0.0:80 failed | 端口被占用 | sudo lsof -i :80,sudo kill -9 <PID> |
server_name 不生效 | 缺少 listen 或域名拼寫錯(cuò)誤 | 檢查大小寫、是否包含 www、是否用通配符 *.example.com |
調(diào)試命令
# 檢查配置語法 sudo nginx -t # 重載配置(不中斷服務(wù)) sudo nginx -s reload # 查看正在監(jiān)聽的端口 sudo ss -tuln | grep nginx # 查看訪問日志實(shí)時(shí)流 tail -f /var/log/nginx/www.example.com.access.log # 模擬請(qǐng)求測試 curl -H "Host: blog.example.com" http://192.168.1.10
監(jiān)控與自動(dòng)化
使用 Prometheus + Grafana 監(jiān)控 Nginx
在 Nginx 中啟用 stub_status:
location /nginx_status {
stub_status;
allow 127.0.0.1;
deny all;
}
然后使用 nginx-prometheus-exporter 導(dǎo)出指標(biāo):
# docker-compose.yml 添加
nginx-exporter:
image: nginx/nginx-prometheus-exporter:0.10.0
ports:
- "9113:9113"
command: -nginx.scrape-uri=http://nginx/nginx_status
depends_on:
- nginx
在 Grafana 中導(dǎo)入 Nginx Dashboard 即可可視化 QPS、連接數(shù)、響應(yīng)時(shí)間。
與其他技術(shù)的對(duì)比
| 方案 | 優(yōu)點(diǎn) | 缺點(diǎn) | 適用場景 |
|---|---|---|---|
| Nginx 虛擬主機(jī) | 高性能、低內(nèi)存、配置靈活 | 無內(nèi)置負(fù)載均衡(需 upstream) | 多站點(diǎn)、靜態(tài)資源、反向代理 |
| Apache VirtualHost | 模塊豐富、.htaccess 支持 | 內(nèi)存占用高、線程模型效率低 | 傳統(tǒng) PHP 網(wǎng)站、共享主機(jī) |
| Traefik | 自動(dòng)發(fā)現(xiàn)、Docker 集成好 | 配置復(fù)雜、學(xué)習(xí)曲線陡峭 | 微服務(wù)、Kubernetes |
| HAProxy | 專業(yè)負(fù)載均衡、TCP/HTTP 代理 | 無靜態(tài)文件服務(wù)能力 | 高并發(fā) API 網(wǎng)關(guān)、TCP 轉(zhuǎn)發(fā) |
推薦:中小型項(xiàng)目用 Nginx,大型微服務(wù)用 Traefik + Nginx 組合。
未來趨勢:云原生與 Nginx Ingress
隨著 Kubernetes 的普及,Nginx Ingress Controller 成為標(biāo)準(zhǔn)組件。它本質(zhì)上是 Nginx 的 Kubernetes 插件,支持:
- 自動(dòng)域名綁定(Ingress Rule)
- 自動(dòng) TLS 證書(Cert-Manager)
- 金絲雀發(fā)布、灰度發(fā)布
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-site-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: frontend.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080未來你將不再手動(dòng)寫 Nginx 配置,而是通過 YAML 定義路由策略,實(shí)現(xiàn)“聲明式運(yùn)維”。
總結(jié):構(gòu)建你的多站點(diǎn)架構(gòu)藍(lán)圖
| 維度 | 推薦實(shí)踐 |
|---|---|
| 域名 | 使用 server_name 匹配,支持通配符 *.example.com |
| 端口 | 生產(chǎn)環(huán)境盡量使用 80/443,內(nèi)部服務(wù)可開放 8080/9000 |
| IP | 用于安全隔離,如內(nèi)網(wǎng)管理后臺(tái) |
| Java 集成 | Nginx 反向代理 Spring Boot,避免暴露端口 |
| HTTPS | 強(qiáng)制使用 Let’s Encrypt,開啟 HSTS |
| 性能 | 啟用 Gzip、緩存、HTTP/2、限制速率 |
| 監(jiān)控 | 日志分離 + Prometheus + Grafana |
| 自動(dòng)化 | 使用 Docker + docker-compose 管理多服務(wù) |
| 擴(kuò)展性 | 未來遷移到 Kubernetes + Ingress |
結(jié)語:架構(gòu)之美在于簡單與可擴(kuò)展
Nginx 的虛擬主機(jī)配置看似簡單,實(shí)則蘊(yùn)含了網(wǎng)絡(luò)架構(gòu)的精髓:分而治之,按需路由。無論是為個(gè)人博客搭建獨(dú)立站點(diǎn),還是為企業(yè)構(gòu)建千級(jí)租戶的 SaaS 平臺(tái),這套機(jī)制始終穩(wěn)定可靠。
當(dāng)你在深夜調(diào)試一個(gè) 502 錯(cuò)誤時(shí),當(dāng)你看到 curl -I 返回 200 OK 時(shí),當(dāng)你在 Grafana 圖表上看到 QPS 穩(wěn)定上升時(shí)——你會(huì)明白,這不僅是配置文件,更是你親手搭建的數(shù)字世界基石。
以上就是Nginx中虛擬主機(jī)的三種配置方式詳解的詳細(xì)內(nèi)容,更多關(guān)于Nginx虛擬主機(jī)配置的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
當(dāng) Nginx 出現(xiàn) 504 錯(cuò)誤的完美解決方法
Nginx是一款流行的Web服務(wù)器和反向代理服務(wù)器,但有時(shí)會(huì)遇到504網(wǎng)關(guān)超時(shí)錯(cuò)誤,這種錯(cuò)誤通常是由后端服務(wù)器響應(yīng)緩慢、Nginx配置不當(dāng)或網(wǎng)絡(luò)問題導(dǎo)致的,下面給大家分享Nginx 出現(xiàn) 504 錯(cuò)誤的完美解決方法,一起看看吧2024-09-09
記錄Nginx服務(wù)器的Split Clients模塊配置過程
這篇文章主要介紹了Nginx服務(wù)器的Split Clients模塊的配置過程記錄,ngx-http-split-clients模塊用于切分客戶端連接,需要的朋友可以參考下2016-01-01
503 service unavailable錯(cuò)誤解決方案講解
這篇文章主要介紹了503 service unavailable錯(cuò)誤解決方案講解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08
Nginx rewrite和proxy_pass的區(qū)別及說明
這篇文章主要介紹了Nginx rewrite和proxy_pass的區(qū)別及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06
nginx安裝并轉(zhuǎn)發(fā)socket服務(wù)實(shí)現(xiàn)方式
文章指導(dǎo)如何安裝編譯工具、PCRE和Nginx,并通過修改配置文件添加stream塊實(shí)現(xiàn)端口轉(zhuǎn)發(fā),將9999/801端口分別映射至9988/1557端口2025-07-07

