尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Spring Boot 集成 Nacos 与 OpenFeign 高可用方案

发布时间:2026/9/25 20:02:02

资讯中心
01
ARTICLE

Spring Boot 集成 Nacos 与 OpenFeign 高可用方案

Spring Boot 集成 Nacos 与 OpenFeign 高可用方案
先说点实在的。微服务拆完之后最头疼的问题就是服务之间怎么互相找。服务数量少的时候我们可以把对方的 IP 写死在配置文件里但一旦搞起弹性伸缩Pod 随时可能被销毁重建虚拟机也可能迁移手写地址这种玩法直接废了。所以我们需要一个注册中心让服务启动的时候自己报个到别人来查名单就行。注册中心都干啥说白了就三件事服务注册启动时把 IP、端口、健康状态这些信息交给注册中心。服务发现调用方从注册中心拉一份目标服务的实例列表选一个能用的发起请求。健康检查注册中心盯着这些实例有没有挂挂了的从列表里踢掉。在 Spring Cloud 里常见的就是 Eureka、Consul、Nacos。这个选型怎么说呢看你项目背景和运维能力。选型Nacos 为什么我用得最多Eureka 当年是 Netflix 家的一代网红但 2.0 早就停了Spring Cloud Netflix 也进入维护状态新项目再选它确实不合适。Eureka 本身是 AP 模型保证服务可用但数据可能不一致而且它只是个注册中心配置管理还得另找。Consul 走的是 CPRaft 协议保证强一致服务状态准确但网络分区时为了保一致性会牺牲可用性。它的主动健康检查做得挺细HTTP/TCP/gRPC 都支持。如果你在 Consul 的生态里配合 Consul Template 和 Vault 做动态配置和密钥管理其实也是条不错的路。但 Consul 的配置管理不算核心能力要折腾的东西不少。Nacos 最大的优势是把服务发现和配置管理放一起了。它可以切换 AP 和 CP 两种模式临时实例走心跳AP持久实例走服务端主动探测CP。另外它还内置了配置中心这样就不需要再单独部署一个配置管理组件运维省事。如果你们技术栈是 Spring Cloud Alibaba基本就是无脑选 Nacos。就算不用 Alibaba 全家桶Nacos 独立用也顺。搭建 Nacos ServerNacos Server 可以直接用 Docker 跑本地调试开单机模式就行。dockerrun-d--namenacos-server\-p8848:8848-p9848:9848\-eMODEstandalone\nacos/nacos-server:v2.3.2注意9848是 gRPC 的通信端口Nacos 2.x 客户端默认走 gRPC这个端口漏了服务注册不上去。启动完打开http://localhost:8848/nacos账号密码默认都是nacos。要是拿到生产环境建议用 MySQL 存配置和元数据然后起至少三个节点做成集群。Nacos Server 自己的配置在conf/application.properties里类似这样spring.datasource.platformmysql db.num1 db.url.0jdbc:mysql://xxx:3306/nacos?characterEncodingutf8serverTimezoneUTC db.userroot db.passwordxxx启动集群时每个节点用NACOS_SERVERS环境变量把其他节点地址带上同时MODEcluster比如dockerrun-d--namenacos-server\-p8848:8848-p9848:9848\-eMODEcluster\-eNACOS_SERVERS10.0.0.1:8848,10.0.0.2:8848,10.0.0.3:8848\nacos/nacos-server:v2.3.2Spring Boot 集成 Nacos注册和发现依赖版本我用的是 Spring Boot 2.7.18Spring Cloud Alibaba 2021.0.5.0。spring-cloud.version用 2021.0.8 没毛病但主要是靠这两个 BOM 把依赖版本管住parentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.7.18/version/parentdependencyManagementdependenciesdependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-dependencies/artifactIdversion2021.0.8/versiontypepom/typescopeimport/scope/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-alibaba-dependencies/artifactIdversion2021.0.5.0/versiontypepom/typescopeimport/scope/dependency/dependencies/dependencyManagement服务提供者和消费者都要加spring-cloud-starter-alibaba-nacos-discovery和spring-boot-starter-web。配置注册信息在application.yml里配置应用名和 Nacos 地址spring:application:name:product-servicecloud:nacos:discovery:server-addr:localhost:8848namespace:publicgroup:DEFAULT_GROUPmetadata:version:v1.0author:dev-team# 多网卡机器上注册 IP 可能不对手动指定ip:192.168.1.100port:8080metadata很实用你可以塞版本号、环境、负责人这些信息后面做灰度路由或者监控都能用上。健康检查的两种姿势Nacos 对临时实例默认采用客户端心跳每 5 秒发一次15 秒没收到就标不健康30 秒后移除。临时实例适合动态扩缩容的场景比如 K8s 里的 Pod。持久实例则相反服务端主动用 HTTP 或 TCP 探测你设置ephemeral: false就切过去了。持久实例主要给那些不适合心跳的长生命周期服务用比如数据库代理。看一眼服务发现怎么用Spring Cloud 的DiscoveryClient是标准接口用起来很简单RestControllerpublicclassDiscoveryController{AutowiredprivateDiscoveryClientdiscoveryClient;GetMapping(/instances)publicListServiceInstanceinstances(RequestParamStringserviceId){returndiscoveryClient.getInstances(serviceId);}}但这个只能查着玩实际上不会直接用它发起调用。要调服务还是用 OpenFeign 靠谱。OpenFeign 声明式调用引入依赖调用方服务需要加 OpenFeign 和 LoadBalancerdependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId/dependencydependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-loadbalancer/artifactId/dependency然后在启动类上加EnableFeignClients就可以开始写接口了。写一个 FeignClientFeignClient(nameproduct-service,fallbackProductFallback.class)publicinterfaceProductClient{GetMapping(/product/{id})ProductDTOgetProduct(PathVariable(id)Longid);}name是目标服务名OpenFeign 会拿着这个名字去找 Nacos 要实例列表然后通过 LoadBalancer 选一个。负载均衡Spring Cloud 2020 之后 Ribbon 退休了默认是 Spring Cloud LoadBalancer。如果你不加额外配置它默认用轮询。想切换策略可以通过自定义ServiceInstanceListSupplier来实现比如基于权重的BeanpublicServiceInstanceListSupplierserviceInstanceListSupplier(ObjectProviderLoadBalancerClientFactoryfactory){returnServiceInstanceListSupplier.builder().withDiscoveryClient().withWeighted().build(factory.getIfUnique());}不过说实话大多数场景轮询够用了别为了炫技去搞复杂策略。超时与重试Feign 默认的连接超时是 10 秒读取超时是 60 秒。对线上接口来说太长容易把线程池拖死一般要调短spring:cloud:openfeign:client:config:default:connect-timeout:2000read-timeout:3000product-service:connect-timeout:1000read-timeout:5000可以针对每个服务单独配置。重试默认是不开的因为重试天然带来重复请求除非接口幂等。如果一定要开自定义一个RetryerBeanpublicRetryerfeignRetryer(){// 间隔 100ms 起最长 1000ms最多 3 次returnnewRetryer.Default(100,1000,3);}这里我提醒一句重试和熔断必须搭配着来不然服务已经挂了重试只会加重负担产生“重试风暴”。Sentinel 让 Feign 有熔断降级能力如果商品服务异常我们不希望调用方一直傻等。给 Feign 加上 Sentinel 可以快速失败。开启 Sentinel 适配引入依赖dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-sentinel/artifactId/dependency配置feign:sentinel:enabled:true然后通过fallback或fallbackFactory指定降级逻辑。Fallback 和 FallbackFactoryfallback是简单的降级方法不需要知道具体异常ComponentpublicclassProductFallbackimplementsProductClient{OverridepublicProductDTOgetProduct(Longid){returnProductDTO.builder().id(id).name(默认商品).price(0.0).build();}}注意这个类需要交给 Spring 管理加上Component否则 Feign 找不到它。如果你要记录日志或者根据异常做不同处理就用FallbackFactorySlf4jComponentpublicclassProductFallbackFactoryimplementsFallbackFactoryProductClient{OverridepublicProductClientcreate(Throwablecause){returnnewProductClient(){OverridepublicProductDTOgetProduct(Longid){log.error(调用 product-service 失败降级,cause);returnProductDTO.builder().id(id).name(降级商品).build();}};}}然后在FeignClient里指定fallbackFactory ProductFallbackFactory.class。熔断规则可以用控制台或代码配置。代码里定义一条“慢调用比例”的降级规则PostConstructpublicvoidinitDegradeRule(){DegradeRulerulenewDegradeRule();rule.setResource(GET:http://product-service/product/{id});rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);rule.setCount(500);// 最大响应时间 500msrule.setTimeWindow(10);// 熔断 10 秒rule.setSlowRatioThreshold(0.5);// 慢调用比例阈值 0.5DegradeRuleManager.loadRules(Collections.singletonList(rule));}当这资源在统计周期内慢调用比例超过 50%Sentinel 就会熔断 10 秒期间直接走降级方法把故障隔离在单次调用之内。Nacos 多环境隔离和服务列表管理命名空间环境隔离最简单的方式就是建命名空间开发、测试、生产各一个相互看不见。每个服务注册时指定 namespacespring:cloud:nacos:discovery:namespace:dev-namespace-id分组同一个命名空间内还能用分组再拆比如同一个环境里有两个团队都用了order-service这个服务名可以用不同的 group 分开互相不发现。但 OpenFeign 默认只找DEFAULT_GROUP如果服务在别的组消费者也要把 group 配成一样的。控制台里那些事Nacos 控制台能做的细节管理不少。实例上下线上线一个实例后可以让它先不接流量等确认正常了再上线相当于优雅发布。反过来下线实例前先把流量摘了就不会影响线上。权重设置实例权重就能控制流入流量比例。新版本先给个 1观察没问题再往上加比直接切全量稳得多。保护阈值这个默认是 0我建议设成 0.6 到 0.8。当健康实例比例低于这个阈值时Nacos 会把不健康的实例也返回给调用方虽然调用可能失败但能防止流量全压到少数健康实例上造成雪崩。集群在配置里指定cluster-name比如SH消费者也配同样的cluster-name那么它去 Nacos 拿服务列表时就只拿到同一个集群下的实例相当于强制同集群路由。这个不是通过 LoadBalancer 过滤是 Nacos discovery 层直接做的。元数据建议至少写版本号、Git 提交号、负责人出了线上问题能快速定位是哪个版本在跑。相比 Spring Cloud Kubernetes怎么选如果你的应用已经跑在 K8s 上K8s 自带 Service 和 DNS 已经解决了服务发现问题Pod 有探针配置有 ConfigMap。Spring Cloud Kubernetes 这个项目提供了 DiscoveryClient 和 LoadBalancer 适配你可以在 Spring Cloud 里直接用DiscoveryClient拿到后端实例。这种情况下其实不需要引入 Nacos 这种注册中心K8s 已经帮你做了服务发现的活而且少维护一套系统更省心。但 K8s 原生的服务发现能力偏向底层流量管理、灰度权重这些细粒度控制需要配合 Istio 这类服务网格才能做配置管理也是零散的 ConfigMap。如果是传统的虚拟机部署或者需要精细的服务治理比如多环境配置、灰度、服务权重Nacos 的优势就很明显。Nacos 本身就是为服务治理设计的而且配置中心集成了开发体验更统一。实际操作里也有两边都用的服务注册走 Nacos配置管理走 ConfigMap或者反过来看团队习惯。没有绝对的对错能降低运维负担就成。最后聊两句这一套组合拳Nacos OpenFeign Sentinel不是银弹但确实是 Spring Cloud Alibaba 生态里最顺手的一套。注册中心解决“找得到”负载均衡解决“分得均”超时和重试解决“扛得住”熔断降级解决“断了别传染”。每个环节都做好服务才算有了一点点“高可用”的样子。再说一句这一套只是基础线上的高可用还得看监控告警、限流降级这些配套是否跟上。别指望用了 Nacos 就高枕无忧了。 福利时间如果你正在备战面试或者想要学习其他知识给大家推荐一个宝藏知识库作者整理了一些列 Java 程序员需要掌握的核心知识有需要的自取不谢。知识库地址https://farerboy.com/
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。