Spring Cloud 微服务项目实战
姚秋辰(姚半仙)
PayPal 研发经理
15862 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 38 讲
结束语 (1讲)
Spring Cloud 微服务项目实战
15
15
1.0x
00:00/00:00
登录|注册

10 | 集成 Nacos:如何通过服务发现机制向服务提供者发起调用?

你好,我是姚秋辰。
在上一课里,我们对 coupon-template-serv 和 coupon-calculation-serv 这两个服务做了微服务化改造,通过服务注册流程将它们注册到了 Nacos Server。这两个服务是以服务提供者的身份注册的,它们之间不会发生相互调用。为了发起一次完整的服务调用请求,我们还需要构建一个服务消费者去访问 Nacos 上的已注册服务。
coupon-customer-serv 就扮演了服务消费者的角色,它需要调用 coupon-template-serv 和 coupon-calculation-serv 完成自己的业务流程。今天我们就来动手改造 coupon-customer-serv 服务,借助 Nacos 的服务发现功能从注册中心获取可供调用的服务列表,并发起一个远程服务调用。
通过今天的内容,你可以了解如何使用 Webflux 发起远程调用,并熟练掌握如何搭建一套基于 Nacos 的服务治理方案。

添加 Nacos 依赖项和配置信息

在开始写代码之前,你需要将以下依赖项添加到 customer-customer-impl 子模块的 pom.xml 文件中。
<!-- Nacos服务发现组件 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 负载均衡组件 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- webflux服务调用 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
第一个依赖项你一定很熟悉了,它是 Nacos 服务治理的组件,我们在上一节课程中也添加了同款依赖项到 coupon-template-impl 和 coupon-calculation-impl 两个模块。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Nacos服务发现与远程调用技术总结 本文深入介绍了Nacos服务发现机制及其在微服务化改造中的应用。通过注册到Nacos Server,服务提供者可以实现服务发现和注册,为构建完整的服务调用请求提供支持。文章详细介绍了在coupon-customer-serv服务中如何利用Nacos的服务发现功能获取可供调用的服务列表,并发起远程服务调用。涉及添加Nacos依赖项和配置信息、清理门户、删除实现层依赖、添加接口层依赖以及在项目的application.yml文件中添加Nacos的配置项等步骤。此外,还介绍了使用Webflux发起远程调用以及搭建基于Nacos的服务治理方案的方法。最后,文章详细介绍了如何添加WebClient对象,并在业务类中注入WebClient对象,并发起服务调用。通过本文,读者可以全面了解Nacos服务治理改造的流程和原理,为深入学习和应用提供了良好的基础。文章还介绍了Nacos服务发现的底层实现,通过UpdateTask类实现了服务端注册表的底层原理。整体而言,本文内容涵盖了微服务化改造、Nacos服务发现功能、Webflux服务调用等技术特点,对读者快速了解文章概览有很好的帮助。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Spring Cloud 微服务项目实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(18)

  • 最新
  • 精选
  • ~
    回答一下调用链路的问题: 首先在 spring.factory 文件中配置了 NacosDiscoveryClientConfiguration 类,用于 springboot 的初始化时的自动装配。在 NacosDiscoveryClientConfiguration 类中会向 spring 容器中添加 NacosWatch 这个 bean。顺着 NacosWatch 的 start 方法一路往下,就能看到:NacosWatch#start ->NacosNamingService#subscribe -> HostReactor#subscribe -> HostReactor#addTask;UpdateTask 就是作为 task 添加到定时执行队列里的。

    作者回复: 非常棒!

    2022-01-10
    2
    27
  • Lee KouKuKing
    【分享】nacos的“订阅者列表”中的多块网卡地址问题,以及应用名为unknown的问题: customer服务向nacos注册后,在nacos web的“订阅者列表”菜单中,发现订阅者的地址是我的第二块网卡的地址(我在笔记本上装过virtualbox,有一个虚拟网卡。说明:我是在win10上运行了3个nacos进程组成的集群。),并且应用名是:unknown。这样看着很别扭,我就想修改一下,于是在application.yml添加了spring.cloud.nacos.discovery.ip,但是发现不生效。最后通过源码发现在UpdateTask中请求所有服务器列表时:/instance/list,请求的clientIP是这样获取的: String ip = System.getProperty("com.alibaba.nacos.client.naming.local.ip",InetAddress.getLocalHost().getHostAddress()); 使用System.getProperty获取系统变量,而不是从application.yml中获取,如过获取不到就查找本机的网卡,由于本机有两块网卡,所有就选中了那块虚拟网卡的ip了。 同时/instance/list请求的app参数也是System.getProperty("project.name");这样获取的,由于没有获取到"project.name",所以就默认应用名是:unknown,然后我就在java启动服务加了这俩参数进行解决的。 不只为什么这俩参数不在application.yml中配置呢?这俩参数在application.yml中配置这样多方便呀。 java -D"com.alibaba.nacos.client.naming.local.ip"="192.168.18.8" -D"project.name"="customer" -jar coupon-customer-impl-1.0-SNAPSHOT.jar

    作者回复: 使用虚拟机或者多网卡的同学可以参考上面的的解决方案哦

    2022-02-03
    6
  • Avalon
    老师,我有两个疑问: 1、为什么依赖注入的是 WebClient.Builder,而不直接注入 WebClient? 2、bodyToMono 的返回值类型 Mono,“Mono”是什么意思?

    作者回复: 注入builder的一个比较方便的原因是,你在使用webclient的时候就能利用builder的链式构建风格来注入参数。Mono可以理解为一个元素的发布者(publisher),像Mono和Flux都是响应式编程的一个概念,mono表示发布了empty或1个对象,同学也可以通过一些响应式编程的教程了解更多的应用方式。

    2022-01-04
    3
  • Geek_e93c48
    老师,我发现UpdateTask通过当前类addTask()方法进行任务调度,顺着藤蔓一直摸上去:addTask()->scheduleUpdateIfAbsent()->NamingClientProxyDelegate.subscribe()->NacosNamingService.getAllInstances()->NamingFactory->App启动类加载时调用。

    作者回复: 同学摸到了一个大瓜!非常不错,读源码就这么顺藤摸瓜,从启动入口正着摸,从结果处反着摸,反正一通十八Mo之后就都整明白了

    2022-01-04
    3
  • alex_lai
    根据目前项目里的service discovery setup 所有在一个group里的service都可以互相调用? customer service 也可以被另外两个子项目调用?所以nacos有可以设置service topo的相关设置么? 大厂里PP也是有这个专门的architect和team 去review和维护吧

    作者回复: customer service可以被任何子项目调用,可以用k8s中的service topo来管理,不过如果做topo的目的单纯为了实现集群优先的策略,直接定制本地负载均衡策略就好了, nacos的cluster属性会在服务发现的过程中封装到metadata节点,client端可以根据这个属性做routing定制 PP确实有冗长的review process,服务之间相互调用也要通过arch review,但这是一家技术基建很差劲的公司,被国内互联网大厂完爆的渣都不剩,没啥可借鉴的

    2022-01-21
    3
    2
  • so long
    nacos服务发现正向顺藤摸瓜:主要靠NacosWatch实现SmartLifecycle,在spring容器初始化后开始进行服务发现 NacosDiscoveryClientConfiguration->NacosWatch.start()->NamingService. subscribe(String serviceName, String groupName, List<String> clusters, EventListener listener)->HostReactor. subscribe(String serviceName, String clusters, EventListener eventListener)

    作者回复: 同学摸瓜水平越来越高了。Nacos在watch机制上有了一个比较大的改变,如果查看nacos老版本的源码你会发现nacosServicesWatch这个方法里简直一顿操作猛如虎,但是新版本里,nacosServicesWatch只做一件事就是发布心跳事件了,所以这个watch机制做了一个比较大的减法,没老版本那么牛逼的服务发现了

    2022-01-05
    2
  • 6点无痛早起学习的和尚
    2 个问题: 1. 项目 customer 上的注解:@LoadBalancerClient(value = "coupon-template-serv", configuration = CanaryRuleConfiguration.class),没有说明是啥作用 2. 运行 customer 这个项目的时候会报错,Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set, Google 解决方式:加入spring:jpa:database-platform: org.hibernate.dialect.MySQLDialect

    作者回复: Loadbalancer注解是spring cloud loadbalancer的内容,在Nacos讲完之后紧接着一课里会讲到。如果项目版本和MySQL版本都保持和源码一致的话(在环境准备篇里有版本信息),那么新版里database-platform不用显式配置,默认auto-detect后会自动在日志里打印这一行 org.hibernate.dialect.Dialect: HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect

    2022-01-03
    2
  • 王鸿轩
    老师,以下这段代码似乎有问题(CouponCustomerServiceImpl -> findCoupon): Map<Long, CouponTemplateInfo> templateMap = webClientBuilder.build().get() .uri("http://coupon-template-serv/template/getBatch?ids=" + templateIds) .retrieve() .bodyToMono(new ParameterizedTypeReference<Map<Long, CouponTemplateInfo>>() {}) .block(); 好像不能在查询参数上直接拼接一个数组,要转化成xx=1,2,3...这样的形式

    作者回复: templateIds这个参数是拼装好的1,2,3格式

    2022-02-15
    2
    1
  • 摊牌
    咨询老师个阅读源码的思路与技巧,比如nacos的服务发现,如何从应用的角度追溯到UpdateTask这个类呢,想了解nacos的服务发现底层逻辑,最繁琐的办法是得从头来,搭建nacos的调试环境,下载源码跟踪分析,有没有办法在应用的时候作为切入点去分析局部的底层逻辑呢

    作者回复: 其实有个简单的方法,就是从log追溯。因为大部分同学的习惯是下载下来代码,然后慢慢啃,我的习惯可能特殊一点,同学可以听一听看是不是适合自己哈。 我会下载下来nacos在本地运行起来,log级别调低,然后通过remote debug的方式把本地代码链接到运行的实例中,这时候你通过发起注册、心跳等方式,就很容易在日志中查到对应的响应类名,直接断点打上去顺藤摸瓜即可。 我感觉这个方式比较“直捣黄龙”一些

    2023-08-17归属地:陕西
  • 在路上
    老师可以聊聊这个吗:通过WebClient非阻塞方式优化性能

    作者回复: 非阻塞一般是使用场景是在方法内发生多个并行调用的时候,使用类似future的方式缩短接口访问时间,现在用的比较多的是基于webflux的响应式编程,挺火的~

    2023-01-20归属地:北京
收起评论
显示
设置
留言
18
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部