SpringCloud整合Nacos使用WebClient实现服务之间的调用

最近在学习SpringBoot响应式编程,所以在自己捣鼓的项目中使用了web reactive,r2dbc等响应式技术
因为是微服务项目,所以首先就想到了使用注册中心和配置中心,这里我选择了Nacos

Nacos下载与使用

Nacos下载地址
下载完成之后,解压文件,先别着急启动,先进入conf文件夹修改application.properties
首先是环境变量中配置好JAVA_HOME,这是最基础的一步
然后正式开始Nacos的配置,这里参考Nacos官方文档
这里主要讲一下Nacos的鉴权
在nacos\conf\application.properties中,默认是关闭鉴权的

nacos.core.auth.enabled=false

如果需要开启鉴权,需要修改成

nacos.core.auth.system.type=nacos
nacos.core.auth.enabled=true

其次就是自定义密钥,2.2.1版本之后,Nacos官方移除了该配置的默认值,在使用时需自己填充,否则无法启动节点,Nacos官方推荐使用Base64编码的字符串,我这里使用的密钥是官方示例的,切勿用于实际部署!!!

nacos.core.auth.default.token.secret.key=VGhpc0lzTXlDdXN0b21TZWNyZXRLZXkwMTIzNDU2Nzg=

若开启鉴权,项目中需要在application.yml中配置如下信息,若没有开启则无需额外配置即可使用

spring:
    cloud:
        nacos:
            discovery:
                username: nacos
                password: nacos

最后就是Nacos集群之间的鉴权

### 开启鉴权
nacos.core.auth.enabled=true
### 关闭使用user-agent判断服务端请求并放行鉴权的功能
nacos.core.auth.enable.userAgentAuthWhite=false
### 配置自定义身份识别的key(不可为空)和value(不可为空)
nacos.core.auth.server.identity.key=example
nacos.core.auth.server.identity.value=example

需要说明的是,如果开启集权鉴权,需要所有Nacos服务节点的server.identity相同,否则可能导致服务端之间数据不一致或无法删除实例等问题

SpringCloud项目集成Nacos做注册中心和配置中心

我这里采用了比较新的SpringBoot3.0.0和SpringCloud2022.0.0:依赖版本对应关系
所以整个版本的对应关系为:SpringBoot3.0.0,SpringCloud2022.0.0,SpringCloudAlibaba2022.0.0.0-RC1
所以在父pom中,配置parent信息

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>3.0.0</version>
</parent>

配置dependencyManagement

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2022.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2022.0.0.0-RC1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

到这里,父pom就算配置完成了

创建微服务module,测试是否能注册到Nacos

在子pom中引入需要依赖的包

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-rsocket</artifactId>
</dependency>
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<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>

编写application.yml

spring:
  cloud:
    nacos:
      config:
        prefix: webflux
        file-extension: yaml
        server-addr: 127.0.0.1:8848
      discovery:
        server-addr: 127.0.0.1:8848
        username: nacos
        password: nacos
    loadbalancer:
      ribbon:
        enabled: false
  config:
    import: nacos:webflux.yaml
  application:
    name: webfluxone
server:
  port: 8887

启动Ncos

startup.cmd -m standalone

Nacos配置管理中的配置


image.png

因为这里还没有讲r2dbc,所以不做过多的说明
需要注意的是SpringCloud2022.0.0,需要添加一个叫spring.config.import=nacos:xxx.yaml的配置,原因是因为该版本的SpringCloud默认不支持bootstrap.yml
其他配置说明:
spring.cloud.nacos.config.prefix和spring.cloud.nacos.config.file-extension:需要对应Nacos中配置管理的dataId,具体规则为:prefix-spring.profiles.active.file-extension(这点官方有很好的说明),如不配置spring.profiles.active,则为:prefix.file-extension,我这里的配置对应的配置管理的配置就是webflux.yaml


image.png

做好上述配置之后,我们就可以启动该服务了
image.png

可以看到,服务已经成功监听到了webflux.yaml,成功!


image.png

并且服务也成功注册到Nacos

使用WebClient实现服务调用

既然是服务调用,那至少需要两个微服务,另一个微服务和上述一致,只需改个端口,这里就不演示了
先定义测试需要的接口

@GetMapping("/hello/{name}")
public Mono<String> hello(@PathVariable String name){
  return Mono.just("Hello, " + name);
}

这是服务的被调用方,Nacos中的服务名称是webfluxtwo,Mono和Flux是spring reactive编程中两个重要的对象,一系列流操作都需要基于这两个对象,并且在webflux中,返回值需要是Mono或者Flux类型的,其中Mono是返回0或者1个对象,Flux是返回多个对象
然后在调用方做如下配置

@Configuration
public class WebClientConfiguration {

    @Bean
    public WebClient webClient(ReactorLoadBalancerExchangeFilterFunction function){
        return WebClient.builder().filter(function).build();
    }
}

配置完成之后,在需要的地方注入

@Autowired
WebClient webClient;

然后编写调用者接口

@GetMapping("/hello/{name}")
public Mono<String> hello(@PathVariable String name){
      return webClient.get().uri("http://webfluxtwo/hello/{name}", name)
                .retrieve().bodyToMono(String.class);
}

到这里就全部完成了,可以进行测试了,我们启动两个微服务
然后访问调用者对外提供的接口


image.png

可以看到,完全是没问题的

最后,如果本文对你有帮助的话麻烦点个赞,因为是新学的技术,我也不是完全能搞懂,如果有人指出问题我会进行修改的

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容