当前位置:首页 > 综合

nginx代理端口转发

nginx做端口转发,理端说白了就是口转让nginx当一个听话的交通警察。你访问80端口,理端它把你引到8080去,口转访问443,理端它又把你塞给某个内网服务。口转这事儿在开发环境里天天用,理端生产环境里也少不了。口转

我见过最典型的理端场景:后端服务起了三个,分别监听3000、口转3001、理端3002,口转前端只认80。理端没有nginx,口转你得在代码里写死端口,理端或者让用户记一串带冒号的地址——谁记啊。nginx一行配置就能解决:

server {  listen 80; location / {  proxy_pass http://127.0.0.1:3000; } }

就这么简单。但别急着高兴,真正的坑往往藏在细节里。

比如WebSocket。你按普通HTTP转发配好了,结果前端连不上socket,报错101切换协议失败。原因在于nginx默认只转发HTTP头,升级协议的头没带上。你得手动加两行:

proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";

这事儿我踩过两次,第一次查了半天文档才明白,第二次长记性了。

再说说路径问题。你有个API服务挂在 /api 下,后端代码里写的是 /api/users,可你转发时把路径剥掉了,后端就404。这时候得用 rewrite 或者明确指定 URI:

location /api/ {  proxy_pass http://127.0.0.1:8080/; }

注意最后那个斜杠——有斜杠表示把 /api/ 前缀去掉再转发,没斜杠就是原样转发。这种细节,配置时一个不留神,线上就给你颜色看。

还有负载均衡。nginx不只是单条转发,它能配 upstream 组,把请求分发给多个后端节点:

upstream backend {  server 10.0.0.1:8080 weight=3; server 10.0.0.2:8080 weight=1; } server {  location / {  proxy_pass http://backend; } }

weight 参数控制流量比例,权重高的多承担些请求。这比在应用层自己搞负载均衡省事多了,而且nginx处理并发的能力相当强悍,一台机器扛几万连接不是问题。

不过,转发时有个隐患常被忽略:客户端真实IP。后端看到的IP全是127.0.0.1,日志里查不到访客来源,限流也没法按IP做。解决办法是加个头:

proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

后端代码里读 X-Real-IP 就行。但注意,如果nginx前面还套了一层CDN,那 $remote_addr 是CDN的IP,你得让CDN传真实的过来,否则就被伪造了。这种链路上的信任问题,得根据实际架构仔细设计。

最后说个性能相关的点。转发时默认nginx会缓冲后端响应,先收完再发给客户端。对大文件下载没问题,但对实时性要求高的接口——比如SSE推送——缓冲会导致客户端迟迟收不到数据。这时候要关掉缓冲:

proxy_buffering off;

代价是nginx和后端之间的连接会持续占用,并发高时可能撑不住。取舍之间,看你业务怎么权衡。

nginx端口转发就是个手艺活,配置简单,但每个参数背后都有实际场景。别光背配置,动手试试不同组合,踩几个坑就真懂了。

分享到: