Apache 在 127.0.100.2 上,而 Nginx 在 127.0.100.3 上,流量控制执行从前者到后者的 DNAT(对于源 127.0.0.1)以及从后者到前者的 SNAT(对于目标 127.0.0.1):
tc qdisc add dev lo root handle 1:0 prio
tc filter add dev lo parent 1:0 protocol ip prio 1 u32 \
match ip src 127.0.0.1 match ip dst 127.0.100.2 \
action nat ingress 127.0.100.2 127.0.100.3
tc filter add dev lo parent 1:0 protocol ip prio 1 u32 \
match ip src 127.0.100.3 match ip dst 127.0.0.1 \
action nat egress 127.0.100.3 127.0.100.2
缓存命中有效,未命中无效,我理解:一旦发生缓存未命中,内容将由 Apache † 传送,但 NAT 会阻止这种情况。应该使用什么配置?
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 {
listen 127.0.100.3;
location / {
proxy_cache my_cache;
proxy_pass http://127.0.100.2;
}
}
† 附加问题:从技术上讲,Nginx 如何处理缓存未命中?Wireshark 没有显示任何明显的信息:我看到 127.0.0.1 和 127.0.100.3 之间的 SYN;SYN、ACK;ACK;HTTP HEAD;ACK,然后是 127.0.0.1 和 127.0.100.2 之间的类似 TCP 握手,然后是 HTTP GET 和有效负载传递。据推测,127.0.0.1 和 127.0.100.3 之间的最终 ACK 正在做一些聪明的事情,但是什么呢?
答案1
应该使用什么配置?
通常这取决于您的具体情况。但显然,如果您不想让 NAT 介入 Nginx 和 Apache 之间,Nginx 应该使用不同的目标或源地址连接到 Apache。例如,您可以为 Apache 分配第二个 IP 来监听并指向proxy_pass
那里,或者让 Nginx 使用不同的传出 IP 进行连接。这有点生硬,但应该可以做到。
由于 tc 的 NAT 是无状态的,其他选项(例如处理 TCP 的 SYN/ACK)有点麻烦。
答案2
我认为您希望 nginx 与 apache 的连接来自 127.0.100.3,因为您已将 nginx 配置为监听该 IP。
监听(传入)套接字的地址绑定不适用于传出连接。使用当前配置,从 nginx 到 apache 的连接应来自 127.0.0.1,因为这是绑定到环回接口的主要 IP,因此也是使用该接口的传出连接的默认 IP。
您可以使用 proxy_bind 来覆盖默认值并为 nginx 传出连接绑定特定的源地址。docs.nginx.com 上的相关文档
proxy_bind 127.0.100.3;
我相信您将通过添加配置来实现您期望的行为location / { ... }
。
此外,我建议您考虑使用 127.0.100.4 作为您的 proxy_bind,以简化您的过滤规则。