这篇不是科普文,是我自己最近在项目里折腾nginx给nacos做反向代理的记录。之前有人在群里问“nginx配置nacos返向代理”怎么写,还有人把“反向代理”打成“返向代理”,我觉得这词儿其实也挺形象的——请求在外面绕一圈再返回到nacos,就是“返向”了嘛。玩笑归玩笑,这个需求在真实环境里出现得特别频繁,尤其是你部署了nacos注册中心、配置中心以后,不可能让它裸奔在公网或者让每个客户端直接改hosts去访问内网节点,这时候就需要nginx在中间做一层统一入口。
我这次把单机版、集群版、HTTPS终止、还有那些踩过的坑全部梳理了一遍,代码都是直接能抄的,抄完按你的实际IP和域名替换就能用。适合刚接触nacos和nginx的读者,也适合已经在用但被各种诡异问题卡住的老哥。
1. 为什么需要给nacos做反向代理
1.1 先说说我遇到的实际场景
我这边的情况是:nacos以集群方式部署在三台内网服务器上,默认端口8848,控制台和客户端请求都得走这个端口。一开始开发环境无所谓,都是内网IP直连,可一旦到了测试环境、预发环境,问题就来了——前端和外部系统根本不知道这三台机器的真实地址,也不应该让它们知道。你不可能在每台业务服务器上写死多个nacos地址,更不可能让外部系统直接访问内部机器。所以最省事、最合理的方案就是:nginx放在前面,对外只暴露一个地址,负载均衡到后面的三台nacos节点。
另一个更常见的场景是安全合规。nacos控制台自带权限认证,但在很多公司流程里,直接把8848端口映射到公网或者办公网是大忌,审计过不去。nginx在前面做四层或七层代理,配合IP白名单、限流、HTTPS卸载,能挡掉一大半的风险。运维同学找你要端口开放清单的时候,你也只需要申请一个443或者80端口,成本低很多。
1.2 反向代理到底解决了什么问题
如果只用一句话总结,那就是:把多个后端节点聚合成一个稳定对外入口,同时把协议、端口、路径这些细节全部封装在nginx这一层。具体拆开有几个比较实际的价值:
统一访问入口和域名绑定。客户端只需要知道一个域名,比如nacos.example.internal,nginx根据这个域名把请求分到对应后端的nacos节点。后端怎么扩容、怎么下线,客户端完全无感。
负载均衡。nacos集群模式下,多节点之前本身有Nacos-Sync或者自身集群同步,但客户端不能只连其中一个节点,否则单点故障直接就挂。nginx用upstream可以配置轮询、最小连接数、IP哈希等策略,把请求均匀分摊到每个nacos节点。
SSL终止。如果公司要求所有链路加密,传统做法是每个nacos节点都得配证书,维护成本翻三倍。nginx统一卸载HTTPS,后端继续走内网HTTP,证书只在nginx上管一份,省心太多了。
安全隔离。nginx层可以做allow/deny、做access_log、做请求体大小限制,这些都是nacos自带的Tomcat容器不太方便做的事情。比如某些不需要暴露给外部的接口,直接在nginx层直接拦掉,比去nacos源码里改逻辑优雅得多。
2. 动手前需要确认的事
2.1 理清你的nacos部署方式是单机还是集群
有的朋友配置半天连不上,不是nginx写错了,而是压根没搞清楚nacos到底是怎么部署的。单机和集群的nginx配置差别很大。
单机nacos,比如你在一台机器上解压了nacos-server-2.2.3.tar.gz,默认就是8848端口,那nginx里只需要一个server块、一个location块就够了。集群nacos,比如用了三台机器部署了集群模式,或者用了Rancher/K8s部署,每台nacos都暴露了不同端口,那nginx里就要写upstream做负载均衡,而且要考虑nacos 2.x的gRPC长连接端口偏移问题,这个后面细说。
一定要先搞清楚一件事:nacos的版本。1.x和2.x在客户端通信方式上差别巨大。nacos 2.x默认开启了gRPC通信,客户端不仅连8848,还会连8848+1000的gRPC端口(也就是9848)。如果你只代理了8848,客户端会出现“注册成功但过一会儿就掉线”的诡异现象,因为gRPC长连接端口不通。这一点我吃过亏,后文会专门说。
2.2 检查nginx的安装情况和关键模块
确认nginx已经装好,并且带上了stream模块(如果是四层代理)和http_sub之类的常用模块。绝大多数发行版编译的nginx都自带--with-stream,你可以用下面命令确认:
nginx -V 2>&1 | grep stream如果输出里有--with-stream,说明四层转发能力没问题。如果一个nginx要同时承担多个web项目(这是热词里经常出现的“nginx部署多个web项目”),建议把nacos代理单独写一个/etc/nginx/conf.d/nacos.conf文件,不要一股脑全塞进主配置文件里,后面维护会想哭。
还有一个细节:nacos的context path默认是/nacos,控制台地址是http://ip:8848/nacos/。这个路径在nginx配置里非常重要,因为你要保证nginx对外路径和后端路径能正确衔接,特别是proxy_pass后面要不要带/nacos/,这直接影响到404问题,我在第三节详细拆解。
2.3 建议先在本机用curl验证nacos可用性
在动nginx之前,先通一通后端服务,这是基本功。我在服务器上执行:
curl http://127.0.0.1:8848/nacos/v1/console/health/readiness如果返回{"status":"UP"},说明nacos本体健康。如果连本机都访问不了,先排查nacos侧问题,别急着折腾nginx,否则你根本分不清故障出在哪一层。这个习惯帮我省下了大量排查时间,强烈建议你养成。
3. nginx反向代理nacos的核心配置
3.1 单实例nacos的最小可用配置
如果你是单机nacos,只需要一个最简配置。这里假设你的nginx对外域名是nacos.example.com,nacos监听内网192.168.1.10:8848。直接新建/etc/nginx/conf.d/nacos.conf:
upstream nacos_server { server 192.168.1.10:8848; } server { listen 80; server_name nacos.example.com; client_max_body_size 50m; location /nacos/ { proxy_pass http://nacos_server/nacos/; 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 / { return 404; } }这个配置看起来简单,但有几个必须注意的点:
proxy_pass http://nacos_server/nacos/;这一行,upstream名字后面加了/nacos/,这代表把原始请求的URI前缀替换掉。什么意思呢?客户端请求http://nacos.example.com/nacos/v1/console/health/readiness,nginx到了upstream这一层时,实际转发给nacos的就是http://192.168.1.10:8848/nacos/v1/console/health/readiness,路径保持完整。如果你在proxy_pass里写成http://nacos_server;而没有带/nacos/,那么nginx会把原始的完整URI直接拼到后端,变成http://192.168.1.10:8848/nacos/v1/...,其实也一样。关键看你的location匹配粒度。
但也有一个经典坑:location /nacos/与proxy_pass http://upstream/nacos/是绝配,而location /nacos不加末尾斜杠时行为会不一样。location /nacos能同时匹配/nacosabc,这会导致不该被代理到nacos的路径也被转发。稳妥做法是location和proxy_pass两边都统一带/,语义清晰,也避免别人接手时产生歧义。
client_max_body_size 50m;是为了防止配置中心的大配置内容、或者上传配置时body超限。nacos默认Tomcat对POST大小限制比较小,nginx默认是1m,如果你通过控制台直接粘贴大段配置,很容易出现413 Request Entity Too Large,这个我后面在问题表里也会提到。
3.2 集群场景下的负载均衡和gRPC支持
如果你有三台nacos节点,那么upstream里写三个地址,这就够了。但要注意,nginx的upstream默认是轮询,这没问题,nacos节点之间是有数据同步的,客户端无论打到哪个节点都能读到配置。不过,nacos 1.x的鉴权和配置推送机制,以及2.x的gRPC长连接,都要求会话尽量固定在同一个节点,否则可能出现“客户端上线后反复重新注册”的现象。
解决办法很简单,给upstream加ip_hash或hash指令。我这边使用的是:
upstream nacos_cluster { ip_hash; server 192.168.1.10:8848 max_fails=2 fail_timeout=30s; server 192.168.1.11:8848 max_fails=2 fail_timeout=30s; server 192.168.1.12:8848 max_fails=2 fail_timeout=30s; keepalive 32; } server { listen 80; server_name nacos.example.com; client_max_body_size 50m; location /nacos/ { proxy_pass http://nacos_cluster/nacos/; proxy_http_version 1.1; proxy_set_header Connection ""; 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; } }ip_hash之后,同一个客户端IP总是被路由到同一台nacos节点,gRPC长连接不会频繁迁移,体验稳定得多。你可能会担心ip_hash造成某台节点压力大,这在nacos场景下问题不大,因为nacos集群本身就是多副本,配置和服务的读写都需要内部一致,单台节点压力不是瓶颈,稳定才是第一位的。
还有一点非常重要:2.x客户端用的gRPC端口是主端口+1000。也就是说8848的gRPC端口是9848。如果你用nginx七层代理做location /nacos/,只代理了8848的HTTP请求,但gRPC长连接绕过nginx直连节点,会有两个问题:一是防火墙只放行了nginx地址,gRPC端口不通,服务频繁掉线;二是你压根没法和“注册中心地址填nginx域名”这个需求兼容,因为gRPC需要的服务发现IP默认是注册时客户端看到的地址,而客户端看到的可能是nginx的IP,但9848端口不通。
简化处理方式有两种:
第一,用nginx的stream模块做四层转发,直接把8848和9848端口都代理了。
stream { upstream nacos_http { server 192.168.1.10:8848; server 192.168.1.11:8848; server 192.168.1.12:8848; } upstream nacos_grpc { server 192.168.1.10:9848; server 192.168.1.11:9848; server 192.168.1.12:9848; } server { listen 8848; proxy_pass nacos_http; } server { listen 9848; proxy_pass nacos_grpc; } }这种方式优点是简单粗暴,客户端完全无感,也不用管路径匹配。但你想在nginx层做域名分发、做HTTPS终止就做不了了,只能做端口转发。
第二,继续用七层HTTP代理,但在nacos端关闭gRPC,或者保证客户端能直通9848端口。
nacos 2.x有参数nacos.server.grpc.port.offset,默认是1000。你可以在application.properties里显式调整偏移。但我不建议关闭gRPC,因为2.x的很多特性依赖它,关了等于把版本退回1.x的体验。最稳妥的做法是:如果网络环境里9848端口无法打通,那就用stream四层方案,把8848和9848都代理到nginx,客户端只认nginx的IP和端口。
3.3 HTTPS终止与SSL配置
公司内部如果强制要求加密,或者你要把这个地址映射出去给外部系统访问,那么直接在nginx上做HTTPS,后面nacos保持HTTP就够了。证书可以用自签名,也可以用内部CA签发的证书。如果你只是内网测试,自签名证书完全够用,但要注意客户端JVM是否信任这个CA,否则Java程序调用nacos会报SSL握手失败。
一个典型的HTTPS配置:
server { listen 443 ssl http2; server_name nacos.example.com; ssl_certificate /etc/nginx/certs/nacos.example.com.crt; ssl_certificate_key /etc/nginx/certs/nacos.example.com.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; access_log /var/log/nginx/nacos_access.log; error_log /var/log/nginx/nacos_error.log; location /nacos/ { proxy_pass http://nacos_cluster/nacos/; proxy_http_version 1.1; proxy_set_header Connection ""; 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; } }这里有个小坑:proxy_set_header Host $host;这行,如果你把Host改成$proxy_host,后端收到的Host就会变成192.168.1.10:8848,nacos控制台里“当前集群节点”的连接地址就会显示成内网IP,跳转的时候可能跳到内网地址,导致浏览器访问不了。所以一定用$host,保持域名透传。
另一个HTTPS坑是重定向。nacos某些接口会返回302重定向,Location头里是http://还是https://,取决于后端拿到的协议。因为nginx做了SSL终止,后端看到的是HTTP,所以Location头可能生成http://nacos.example.com/...,浏览器会自动跳到80端口,造成死循环。解决方式是在nginx里加上:
proxy_redirect http:// https://;或者精确一点:
proxy_redirect http://nacos.example.com/ https://nacos.example.com/;这个我遇到过,当时控制台死活打不开,报“重定向次数过多”,查日志发现全是302,就是这个原因。加了proxy_redirect立刻就好了。
4. 核心机制:代理过程中必须搞懂的细节
4.1 proxy_pass结尾斜杠的一字之差
这个细节我单独拿一节来讲,因为太多人在这里翻车。location /nacos/和proxy_pass http://nacos_cluster/nacos/这两端,末尾斜杠的有无直接决定路径拼接结果:
proxy_pass http://nacos_cluster;不带斜杠,没有URI路径,nginx会将原始URI完整传给后端,适合location精确匹配或根路径代理。proxy_pass http://nacos_cluster/;带斜杠,且URI为空,nginx会把location匹配部分替换为/,比如请求/nacos/v1/console会被变成/v1/console,前后缀对不上,直接404。proxy_pass http://nacos_cluster/nacos/;带路径,nginx会把location匹配部分替换为/nacos/,请求/nacos/v1/console还是/nacos/v1/console,这才是你要的。
用生活类比来说,这就像是快递转寄:地址栏上写“杭州市”和“杭州市/西湖区”,快递员拆包裹后重新打包的方式完全不同。你如果不确认对方收件地址到底接受不带前缀还是带前缀的格式,就会出现包裹发出去但对方拒收——对应到HTTP就是404或502。
我建议的策略是:location带斜杠,proxy_pass也完整复制后端路径,形成一一对应关系。这样最直观,后来接手的同事也不容易误解。
4.2 长连接、超时与会话保持
nacos客户端和配置中心之间有很多依赖长连接的场景:配置变更监听、服务实例心跳、gRPC流式通信。nginx默认的proxy_read_timeout是60秒,如果后端在这段时间内没有返回任何数据,nginx会直接断开连接。nacos的配置监听长轮询通常设计成30秒左右能拿到响应,但如果你的网络稍慢,或者nacos节点恰好卡顿,超过60秒没有数据返回,nginx就会切断连接。客户端重新连接时,如果恰逢注册中心正在做数据同步,就可能报错。
稳妥的做法是适当调大超时时间:
proxy_connect_timeout 10s; proxy_read_timeout 300s; proxy_send_timeout 300s;我这里把proxy_read_timeout调到300秒,是为gRPC长连接留足了余量。如果只是做控制台反向代理,不涉及客户端长连接,60秒默认值问题不大;但如果你有大量微服务通过nginx访问nacos,建议按这个配置来。
另外,如果nginx和nacos之间走HTTP/1.0,每次请求都要新建TCP连接,对高并发场景不友好。我在集群配置里写proxy_http_version 1.1;和proxy_set_header Connection "";,就是让nginx与后端之间启用keepalive,减少握手开销。配合upstream里的keepalive 32,连接复用效果很明显。
4.3 服务注册地址、回源地址的IP/域名问题
这是nacos代理里最容易引发玄学故障的点。微服务客户端通过nginx注册到nacos时,nacos保存的服务实例IP是客户端进程中配置的spring.cloud.nacos.discovery.ip,还是客户端实际握手时的源IP,取决于nacos的识别方式。
默认情况下,nacos识别的是客户端的socket源IP。如果客户端也通过nginx去注册,那么nginx的IP会成为源IP,注册到nacos上的服务地址就变成nginx的IP。如果nginx和微服务在同一台机器或者同一内网,可能还能通;但如果你配置了nginx代理客户端的所有请求到nacos,那么注册到nacos上的服务地址全部是nginx的IP,别的服务调用时就会去连nginx,而不是连实际提供服务的实例,结果就是调用失败或端口不对。
这个问题在“客户端通过nginx访问nacos”时特别明显。解决办法通常是:
在客户端明确指定注册IP。Spring Cloud Alibaba的配置里加上:
spring.cloud.nacos.discovery.ip=实际内网IP spring.cloud.nacos.discovery.port=实际服务端口这样nacos注册表里保存的就是服务真实地址,不走nginx转发。也可以配置spring.cloud.nacos.discovery.net-interface,指定网卡自动获取IP。
另外,X-Forwarded-For和X-Real-IP这些header,主要用于控制台显示客户端真实来源、以及权限日志审计,不能用于修正注册中心的实例地址。这个机制要清楚,别在错误的地方解决问题。
4.4 健康检查与故障转移
nginx upstream自带的被动健康检查(max_fails和fail_timeout)只对“转发时出现连接失败或超时”的请求生效,如果nacos服务保持在但端口异常,或者返回500,nginx默认不会把它摘掉。生产环境要求高的话,建议配合nginx的主动健康检查模块,或者每台nacos上自己挂一个监控脚本,检测到异常直接修改nginx upstream配置文件并reload。
我在配置里写了max_fails=2 fail_timeout=30s,意思是30秒内最多失败2次,就把该节点标记为不可用,不再转发流量。但对nacos这种需要长连接的服务,被动健康检查并不完美,因为很多故障是“连接建立了但响应变慢”,而不是“连接失败”。如果条件允许,用nginx商业版的health_check或者开源模块nginx-upsync配合consul做动态后端发现,体验会好很多。不过对大多数中小团队,被动检查加Cloud Alert已经足够用。
5. 常见问题排查实录
5.1 先放一个速查表
我在排查过程中遇到的问题都整理到了表里,按“症状—原因—解法”来描述,方便你直接对号入座。
| 症状 | 可能原因 | 解决方案 |
|---|---|---|
| 浏览器访问nginx域名返回404 | proxy_pass路径拼接不对,或location匹配到了别的块 | 检查proxy_pass是否完整带/nacos/,location和proxy_pass末尾斜杠保持一致 |
| 控制台能打开,但服务注册不上 | 2.x的gRPC端口9848不通,或注册地址变成nginx IP | 用stream代理8848和9848;客户端显式指定discovery.ip |
| 页面一直302重定向 | nginx做SSL终止后Location头还是http | 加上proxy_redirect http:// https://; |
| 上传/拉取大配置时报413 | nginx默认client_max_body_size只有1m | 在server块里设置client_max_body_size 50m; |
| 配置变更后客户端没有及时刷新 | gRPC长连接被nginx断开,客户端重连慢 | 调大proxy_read_timeout,启用upstream keepalive |
| 登录nacos控制台后跳转到内网IP | Host头传递错误或nacos使用绝对地址拼接 | 设置proxy_set_header Host $host; |
| 集群节点显示全部下线 | 客户端与nacos之间的健康检查IP不通 | 检查nacos节点IP配置,确认注册地址能互通 |
| 同时代理多个web项目时互相干扰 | 多个server_name或location块混在一起 | 每个项目独立conf文件,用server_name区分 |
| CentOS Stream 9上nginx启动失败 | SELinux或依赖库缺失 | 检查nginx -t、journalctl日志、确认libssl等依赖 |
表格里的内容都是我真实遇到的,只有一个“同时代理多个web项目”的问题是我帮同事排查的。他那台nginx上挂了三个项目,其中nacos的location /nacos/写到了默认server里,被其他项目的location /拦截了,导致nacos控制台永远返回404。
5.2 一次“控制台能打开但服务注册不上”的完整排查记录
这个案例我印象最深,因为我花了大半天才定位到问题。现象是:通过nginx域名访问nacos控制台完全正常,登录、配置列表、服务列表都能看到,但新启动的微服务一直注册失败,日志里报currentServerAddr: http://nacos.example.com, err: connect timed out。
一开始我以为是nginx配置问题,反复改了proxy_pass,都没用。后来在微服务所在机器上手动测试:
curl http://nacos.example.com:80/nacos/v1/ns/instance/list?serviceName=test能正常返回。问题在于,服务注册时nacos客户端不仅要发HTTP请求,还要建立gRPC长连接,而客户端的gRPC地址是自动拼接的:它会把spring.cloud.nacos.server-addr=nacos.example.com解析出主机名和端口80,然后推断gRPC端口是80+1000=1080。实际上nacos真实gRPC端口是9848,而1080在nginx上根本没监听,所以一直超时。
找到原因后,解决方案就很清晰了:如果坚持七层HTTP代理,就必须让nacos的gRPC端口也能通。最直接的办法是改nginx监听端口和nacos gRPC端口保持一致。既然nacos主端口是8848,gRPC是9848,我们直接让nginx在8848和9848上做四层stream转发,问题彻底解决。微服务只认一个地址10.0.0.5:8848,nginx把HTTP转发到后端的8848,把gRPC转发到后端的9848。
排查这类的通用思路是:先抓住报错关键字,比如connect timed out、Connection refused、No provider,再逐层测试。我曾经把这些关键字整理成一个脚本,批量检查端口连通性和HTTP响应。最常用的是nc -vz 10.0.0.5 9848,和curl -v看握手过程,基本能定位90%的网络问题。
5.3 nginx日志里的线索怎么看
遇到问题第一件事永远是看日志,而不是瞎改配置。nginx的access log能看到请求进来了没有,error log能看到upstream连接失败的具体原因。
我比较习惯把nacos的请求单独写一个access log,配置里加上:
access_log /var/log/nginx/nacos_access.log; error_log /var/log/nginx/nacos_error.log warn;排错的时候切到日志目录:
tail -f /var/log/nginx/nacos_access.log grep -i "error" /var/log/nginx/nacos_error.log比如你看到access log里有大量499状态码,说明客户端主动断开了连接,大概率是等待时间过长,和proxy_read_timeout有关。如果看到502或504,说明upstream对应的nacos节点连接不上或超时,下一步就用curl直接访问那个节点,确认它是否存活。
记住一点:nginx日志是第一手现场证据,别在没有任何证据的情况下反复reload配置。reload本身不会造成大问题,但你改来改去如果没有确定依据,只会让问题更乱。
6. 几个容易忽略的高级细节
6.1 代理nacos open API时注意body大小和鉴权
如果你在业务系统里直接通过HTTP调用nacos的open API,比如发布配置、查询配置、触发服务心跳,那么nginx的client_max_body_size和鉴权透传就会变得关键。
nacos 2.2.0以后默认开启了鉴权,open API需要在header里带Authorization: Bearer <token>或者用户名密码。如果通过nginx代理,要确保请求头不被篡改,Authorization默认是透传的,问题不大。但如果你在nginx层加了proxy_set_header去覆盖一些不必要的头,极有可能把Authorization也覆盖掉,这时候调open API会一直返回403。
另外,发布大配置时,如果client_max_body_size不够,nginx直接返回413,根本到不了nacos。我在配置里写50m,是因为我们有一个包含大量数据源和路由规则的配置文件,超过了默认的1m。你可以根据自己实际情况调整,但别设太小,也别无脑设成1g,容易造成内存压力。
6.2 日志、监控和告警的小建议
nginx层启日志后,最好用logrotate定期切割,否则/var/log/nginx分区会被打满。可以用现成的logrotate配置,也可以cron里加一行:
/usr/sbin/logrotate /etc/logrotate.d/nginx针对nacos的可用性监控,最简单的做法是cron脚本每分钟curl一次登录页或健康检查接口:
*/1 * * * * curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:80/nacos/v1/console/health/readiness | grep -q "200"如果返回不是200,就触发告警。要注意的是,健康检查接口响应可能不一定是200而是其他状态码,用curl -s看返回内容更可靠。我这边是把检查结果写入Prometheus的自定义exporter,grafana上挂了一个“nacos代理可用性”的仪表盘,效果直观。
6.3 优雅下线与摘流
还有一个小技巧:当nacos节点要做维护升级时,直接在nginx upstream里把这个节点注释掉,然后reload,流量就不会再打过去了。但要注意,reload会导致已有的gRPC长连接断开,如果客户端重连逻辑不健壮,可能造成短暂的服务注册抖动。所以尽量在业务低峰期操作,且一次只摘一个节点,等客户端全部重连稳定后再摘下一个。
举一个实际例子。有一次我们要升级nacos集群的三台节点,我把upstream里第一台注释掉,reload,观察日志,等客户端陆续注册到另外两台,再把这台的nacos进程停掉。整个过程大概花了5分钟,服务无感知。如果一次性三台全部注释,那nacos集群直接没有可用节点,所有依赖配置中心的微服务都会启动失败或拉取配置超时,这就是事故了。
至于下线后的配置同步,nacos集群节点之间会自动处理,不用人工干预。只要保证同一时间至少有一台节点存活,集群就能继续对外提供服务。
7. 最后再分享一个小技巧
做完nginx代理后,可以用openssl或nginx的sub_filter给控制台页面加一些额外响应头,比如X-Content-Type-Options: nosniff、X-Frame-Options: SAMEORIGIN,安全性会更好。虽然不是必需,但在安全扫描的时候能少几个告警。nginx配置里加:
add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always;如果这台nginx只代理nacos,加这些没问题。如果nginx还代理了其他web项目,别全局加,只加到nacos这个server块里,否则某些第三方页面可能因为X-Frame-Options被拦而无法嵌入。
还有个更实用的小技巧,就是nginx里给nacos的/nacos/v1/ns/健康检查路径配置缓存。如果你有很多微服务频繁调用健康检查或心跳接口,而这些接口对实时性要求没那么高,可以用proxy_cache缓存几秒,减少后端压力。但心跳接口不建议缓存,因为nacos需要看到实时的心跳数据,缓存可能导致误判实例下线。配置变更查询接口也不好缓存,会破坏“动态刷新”的效果。能缓存的一般是服务列表查询这类只读接口,实际收益有限,所以不展开。
根据我个人经验,nginx配nacos并不难,难点在于nacos 2.x的gRPC端口和注册IP这两个点,很多配置看起来“通了”但其实只是控制台通了,客户端压根没连上。只要把这两点想清楚,其他都是常规操作。希望这篇记录能让你少走一点弯路。