前言
在部署Web项目时,你是否注意到过这样的访问方式差异?
- 方式一:
http://192.168.1.100:8080 - 方式二:
http://192.168.1.100/myapp
这两种方式有什么区别?又该如何实现呢?本文将为你详细解答。
一、两种访问方式的本质区别
1.1 端口号 + IP 形式
这种形式通常用于访问多个独立服务,每个服务占用一个端口。
http://192.168.1.100:8080 # 服务A
http://192.168.1.100:8081 # 服务B
http://192.168.1.100:3000 # 服务C
特点:
- 每个端口对应一个独立的应用
- 端口号必须显式输入
- 常用于开发环境或内部服务
1.2 端口号 + IP + 目录形式
这种形式通常使用80端口(HTTP)或443端口(HTTPS),通过URL路径区分不同的应用。
http://192.168.1.100/ # 主站
http://192.168.1.100/myapp # 应用1
http://192.168.1.100/api # API服务
http://192.168.1.100/blog # 博客系统
特点:
- 只需输入IP即可访问(端口80/443可省略)
- 同一个端口下运行多个应用
- 便于统一管理和配置SSL证书
二、为什么目录形式通常使用80端口?
这是一个约定俗成的规则:
| 端口 | 协议 | 用途 |
|---|---|---|
| 80 | HTTP | Web服务默认端口,浏览器自动省略 |
| 443 | HTTPS | 安全Web服务默认端口 |
| 其他 | 自定义 | 需要手动指定端口 |
当使用目录形式时,实际上是通过反向代理 将不同路径的请求转发到对应的后端服务。80/443端口作为"入口",扮演着网关的角色。
三、实现方式详解
3.1 方式一:直接使用端口访问
这是最简单的方式,直接启动服务并指定端口。
Node.js 示例:
javascript
const http = require('http');
const server = http.createServer((req, res) => {
res.end('Hello from port 8080!');
});
server.listen(8080, () => {
console.log('Server running on port 8080');
});
Python Flask 示例:
python
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello from port 5000!'
if __name__ == '__main__':
app.run(port=5000)
Java Spring Boot 示例:
yaml
# application.yml
server:
port: 8080
访问地址:http://192.168.1.100:8080
3.2 方式二:Nginx反向代理配置目录形式
这是生产环境最常用的方案,通过Nginx实现路径转发。
场景一:单应用部署在根路径
nginx
server {
listen 80;
server_name 192.168.1.100;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
访问:http://192.168.1.100/ → 转发到 http://127.0.0.1:8080
场景二:多应用部署在不同目录
nginx
server {
listen 80;
server_name 192.168.1.100;
# 主站
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
}
# MyApp应用 - 访问 /myapp 时转发到 8081 端口
location /myapp/ {
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;
}
# API服务 - 访问 /api 时转发到 8082 端口
location /api/ {
proxy_pass http://127.0.0.1:8082/;
proxy_set_header Host $host;
}
# 静态文件服务
location /static/ {
alias /var/www/static/;
}
}
访问效果:
http://192.168.1.100/→ 8080端口http://192.168.1.100/myapp/→ 8081端口http://192.168.1.100/api/→ 8082端口
场景三:处理静态资源与API分离
nginx
server {
listen 80;
server_name 192.168.1.100;
# 前端静态文件
location / {
root /var/www/myapp/dist;
index index.html;
try_files $uri $uri/ /index.html;
}
# 后端API
location /api/ {
proxy_pass http://127.0.0.1:8080/api/;
proxy_set_header Host $host;
}
# 图片资源
location /images/ {
alias /var/www/images/;
expires 30d;
}
}
3.3 方式三:使用Apache配置
如果你使用的是Apache服务器,可以通过.htaccess或配置文件实现:
apache
<VirtualHost *:80>
ServerName 192.168.1.100
# 主应用
DocumentRoot "/var/www/main-app"
# 子目录代理
ProxyPass /myapp http://127.0.0.1:8081
ProxyPassReverse /myapp http://127.0.0.1:8081
# API代理
ProxyPass /api http://127.0.0.1:8080/api
ProxyPassReverse /api http://127.0.0.1:8080/api
</VirtualHost>
3.4 方式四:Docker容器部署
使用Docker时,也可以通过Nginx容器作为反向代理:
yaml
# docker-compose.yml
version: '3'
services:
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app1
- app2
app1:
image: myapp1:latest
expose:
- "3000"
app2:
image: myapp2:latest
expose:
- "4000"
对应的Nginx配置:
nginx
server {
listen 80;
location / {
proxy_pass http://app1:3000;
}
location /app2/ {
proxy_pass http://app2:4000/;
}
}
四、实战:完整的部署方案
假设你有一个服务器,需要部署以下服务:
| 服务 | 后端端口 | 访问路径 |
|---|---|---|
| 前端Vue应用 | 3000 | / |
| 后端API | 8080 | /api |
| 管理后台 | 3001 | /admin |
| 文档服务 | 5000 | /docs |
Nginx完整配置:
nginx
upstream frontend {
server 127.0.0.1:3000;
}
upstream api {
server 127.0.0.1:8080;
}
upstream admin {
server 127.0.0.1:3001;
}
upstream docs {
server 127.0.0.1:5000;
}
server {
listen 80;
server_name 192.168.1.100;
# 前端应用
location / {
proxy_pass http://frontend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# API服务
location /api/ {
proxy_pass http://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;
}
# 管理后台
location /admin/ {
proxy_pass http://admin/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 文档服务
location /docs/ {
proxy_pass http://docs/;
proxy_set_header Host $host;
}
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 7d;
add_header Cache-Control "public, immutable";
}
}
五、注意事项与最佳实践
5.1 路径匹配细节
Nginx的location匹配规则需要注意:
nginx
# 精确匹配
location = /api { }
# 区分大小写的正则匹配
location ~ /api/\d+ { }
# 不区分大小写的正则匹配
location ~* \.(jpg|png)$ { }
# 前缀匹配(最常用)
location /api/ { }
5.2 常见问题解决
问题1:静态资源404
nginx
# 确保正确设置root或alias
location /static/ {
alias /path/to/static/files/; # 注意末尾斜杠
}
问题2:接口请求跨域
nginx
location /api/ {
proxy_pass http://backend:8080/;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
}
问题3:WebSocket支持
nginx
location /ws/ {
proxy_pass http://websocket:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
5.3 安全建议
- 使用HTTPS:通过Let's Encrypt免费获取SSL证书
- 限制访问 :使用Nginx的
allow/deny限制IP访问 - 配置WAF:使用Nginx + ModSecurity防护Web攻击
- 日志审计:定期检查访问日志和错误日志
总结
| 部署方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 端口直接访问 | 开发环境、微服务 | 简单直观 | 端口不易记忆 |
| 目录形式(80端口) | 生产环境、多应用 | 统一入口、便于管理 | 配置复杂 |
| 混合方案 | 复杂架构 | 灵活可控 | 维护成本高 |
核心要点:
- 端口+IP形式:直接启动服务,指定端口即可
- 目录形式:通过反向代理(Nginx/Apache)实现路径转发
- 80端口是Web服务的默认端口,浏览器会自动省略
- 使用目录形式更专业,便于SSL配置和统一管理
希望这篇文章能帮助你更好地理解Web服务的部署方式。如果有其他问题,欢迎在评论区留言讨论!