游客发表
nginx处理http代理的方式,本质上是一张“路由表”加上一套“搬运工”逻辑。它不像squid那样把文件缓存到硬盘,也不像haproxy那样只盯着四层端口。nginx代理的是完整的http会话——包括请求头、响应体、keep-alive连接,甚至升级后的websocket协议。
我见过最典型的误用,是把nginx反代当成负载均衡器来配,结果忽略了它真正强大的地方:在http层改写流量。比如,你可以在location块里用proxy_set_header随意修改发往上游的请求头。有个真实案例,某公司内部老系统强制校验Host头必须等于“internal.server.com”,但用户访问的域名是“www.example.com”。nginx一行配置就解决了:proxy_set_header Host internal.server.com;。这种精细控制,纯四层方案根本做不到。
配置的核心就两个指令:proxy_pass和proxy_set_header。前者定义上游地址,后者控制转发时的头信息。但坑也藏在这里。proxy_pass结尾有没有斜杠,行为完全不同。写成proxy_pass http://backend;,nginx会把原始URI原样转发;写成proxy_pass http://backend/;,location匹配的部分会被替换掉。这个差异害过不少人——我亲眼见过同事排查了半天,最后发现是斜杠导致上游接口404。
还有超时设置。默认的proxy_read_timeout是60秒,这对大部分API够用,但碰上导出报表或者批量计算的接口,60秒就是定时炸弹。调大它很容易,proxy_read_timeout 300s;一行搞定。但别忘了proxy_send_timeout——上游处理慢,客户端上传大文件也可能触发超时。这两个参数最好一起调。
连接复用是另一个容易忽略的点。nginx默认对上游开启keep-alive,但前提是你得显式配置:
upstream backend { server 192.168.1.10:8080; keepalive 32; } server { location /api/ { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Connection ""; } } 这段配置里proxy_http_version 1.1和空的Connection头缺一不可。少了任何一个,nginx都会退化为短连接,每次请求都重新建TCP握手。高并发下,这会让上游服务器CPU飙到80%以上,而nginx本身却闲得发慌。
调试代理问题时,最实用的工具是curl -v加上nginx的access log。日志格式里加上$upstream_addr和$upstream_response_time,能立刻看出请求打到了哪台机器、上游花了多久。我曾经靠这两字段定位出一个诡异现象:所有请求都集中在一台上游节点,其他节点空闲——原因是nginx的upstream默认轮询,但有个节点配置了down状态,而健康检查又没开,导致流量全被甩给剩余节点。
最后说个主观判断:nginx做http代理,强项在“边缘”——也就是入口处的请求清洗、改写和分发。真要处理复杂路由规则(比如按请求体内容分流),它不如专门的网关(如apisix)。但论简单直接、资源占用低、生态成熟度,nginx依然是首选。它就像瑞士军刀,不花哨,但关键时刻总有一款功能能用上。
友情链接