2.Nacos Discovery 整合 Spring Cloud 服务调用-灵析社区

没晒干的咸鱼

从应用架构上,Spring Cloud 服务调用通常需要两个应用,一个为服务提供者(Provider),一个为服务消费者(Consumer)。从技术上,传统的 Spring Cloud 服务通讯方式是基于 REST 实现的,包好两种内建实现方法,分别是 @LoadBalanced RestTemplate 以及 Open Feign,两者均作用于服务消费者,而服务提供者仅为 WebMVC 或者 WebFlux 应用(需注册到注册中心)。同时,还允许整合 Spring Cloud 负载均衡 API,实现自定义 REST 服务调用。至于,Spring Cloud Alibaba 引入 Dubbo 服务通讯方式,会在后续内容中单独讨论。

一、服务提供者添加 Web 服务

复用应用 nacos-discovery-provider-sample,在引导类 NacosDiscoveryProviderSampleApplication 同包下增加 @RestController 实现类:

Java

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ServiceController {

    @GetMapping("/echo/{message}")
    public String echo(@PathVariable String message) {
        return "[ECHO] : " + message;
    }
}

重启应用 nacos-discovery-provider-sample,测试该 Web 服务端口:

% curl http://127.0.0.1:8080/echo/Hello,World
[ECHO] : Hello,World

结果符合期望,下一步增加消费者应用。

二·、Nacos Discovery 整合 @LoadBalanced RestTemplate

继续使用 Aliyun Java Initializr 创建消费者应用 - nacos-discovery-consumer-sample,选择 Nacos Service Discovery 和 Spring Web 组件:

生成项目,并使用 IDE 导入工程。

增加 Nacos Discovery 外部化配置

与应用 nacos-discovery-provider-sample 配置类似,增加 Nacos Discovery 外部化配置。如果是本地部署的话,请调整应用服务和 Actuator 端口,以免与应用 nacos-discovery-provider-sample 端口冲突 ,完整配置如下:

spring.application.name=nacos-discovery-consumer-sample

management.endpoints.jmx.exposure.include=*
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always

# spring cloud access&secret config
# 可以访问如下地址查看: https://usercenter.console.aliyun.com/#/manage/ak
alibaba.cloud.access-key=****
alibaba.cloud.secret-key=****

# 应用服务 WEB 访问端口
server.port=9090
# Actuator Web 访问端口
management.server.port=9091

## Nacos 注册中心配置地址(无需配置 HTTP 协议部分)
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
## Nacos 客户端认证信息(默认用户名和密码均为 nacos)
spring.cloud.nacos.discovery.user-name=nacos
spring.cloud.nacos.discovery.password=naocs

服务消费者激活 Nacos Discovery 服务注册与发现

与应用 nacos-discovery-provider-sample 实现一样,在引导类上标注 @EnableDiscoveryClient,代码如下:

Java

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class NacosDiscoveryConsumerSampleApplication {

    public static void main(String[] args) {
        SpringApplication.run(NacosDiscoveryConsumerSampleApplication.class, args);
    }
}

服务消费者使用 @LoadBalanced RestTemplate 实现服务调用

前文提到 @LoadBalanced RestTemplate 是 Spring Cloud 内建的服务调用方式,因此需要在应用 nacos-discovery-consumer-sample 增加执行代码,消费应用 nacos-discovery-provider-sample REST 服务 /echo/{message},故在引导类同包下新增 RestController 实现:

Java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class RestTemplateController {

    @LoadBalanced
    @Autowired
    public RestTemplate restTemplate;

    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @GetMapping("/call/echo/{message}")
    public String callEcho(@PathVariable String message) {
        // 访问应用 nacos-discovery-provider-sample 的 REST "/echo/{message}"
        return restTemplate.getForObject("http://nacos-discovery-provider-sample/echo/" + message, String.class);
    }
}

以上代码实现方式与传统 Spring Cloud 的方式无异,下一步启动引导类 NacosDiscoveryConsumerSampleApplication,并测试运行结果:

Bash

% curl http://127.0.0.1:9090/call/echo/Hello,World
[ECHO] : Hello,World

结果符合期望,说明 Nacos Discovery 整合 @LoadBalanced RestTemplate 的实现与标准 Spring Cloud 实现的差异仅体现在 Maven 依赖 starter 以及外部化配置上。接下来,应用 nacos-discovery-consumer-sample 将继续与 Spring Cloud OpenFeign 整合。

三、Nacos Discovery 整合 Spring Cloud OpenFeign

Spring Cloud OpenFeign 是 Spring Cloud 基于 REST 客户端框架 OpenFeign 而构建,使得服务发现和负载均衡透明,开发人员只需关注服务消费者接口契约。同时,Spring Cloud OpenFeign 可以与 @LoadBalanced RestTemplate 共存,因此,可在原有应用 nacos-discovery-consumer-sample 的基础上,增加 Maven 依赖和代码实现整合。

关于 Spring Cloud OpenFeign 的技术细节,可参考官方文档: https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/

服务消费者增加 Spring Cloud OpenFeign Maven 依赖

在 nacos-discovery-consumer-sample 项目 pom.xml 中追加 Spring Cloud OpenFeign Maven 依赖:

XML

        <!-- Spring Cloud OpenFeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>

下一步,则是新增 Spring Cloud OpenFeign 服务声明接口

服务消费者增加 Spring Cloud OpenFeign 服务声明接口

由于需要消费应用 nacos-discovery-provider-sample 提供的 REST 服务 /echo/{message},根据 Spring Cloud OpenFeign 的要求,需要在消费者应用增加 REST 服务声明接口,即:

Java

@FeignClient("nacos-discovery-provider-sample") // 指向服务提供者应用
public interface EchoService {

    @GetMapping("/echo/{message}")
    String echo(@PathVariable("message") String message);
}

不难发现,echo(String) 方法在 Spring MVC 请求映射的方式与 nacos-discovery-provider-sample 中的 ServiceController 基本相同,唯一区别在于 @PathVariable 注解指定了 value 属性 "message",这是因为默认情况,Java 编译器不会讲接口方法参数名添加到 Java 字节码中。

下一步,激活 Spring Cloud OpenFeign 服务声明接口。

服务消费者激活 Spring Cloud OpenFeign 服务声明接口

激活 Spring Cloud OpenFeign 服务声明接口的方法非常简单,仅需在引导类标注 @EnableFeignClients,如果声明接口与引导类不在同一个包的话,请使用 basePackages属性指定。由于本例的 EchoService 与引导类位于同一包下,因此,无需指定:

Java

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients // 激活 @FeignClient
public class NacosDiscoveryConsumerSampleApplication {

    public static void main(String[] args) {
        SpringApplication.run(NacosDiscoveryConsumerSampleApplication.class, args);
    }
}

激活步骤就此完成,下一步为 Spring Cloud OpenFeign 服务接口增加 RestController 实现。

服务消费者使用 Spring Cloud OpenFeign 服务声明接口实现服务调用

新增名为 OpenFeignController 的实现类:

Java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class OpenFeignController {

    @Autowired
    private EchoService echoService;

    @GetMapping("/feign/echo/{message}")
    public String feignEcho(@PathVariable String message) {
        return echoService.echo(message);
    }
}

重启引导类NacosDiscoveryConsumerSampleApplication,并测试/feign/echo/{message}结果:

Bash

% curl http://127.0.0.1:9090/feign/echo/Hello,World
[ECHO] : Hello,World

结果符合期望,说明 Nacos Discovery 整合 Spring Cloud OpenFeign 与传统方式也是相同的。

综上所述,Nacos Discovery 在 Spring Cloud 服务调用是无侵入的。

阅读量:2013

点赞量:0

收藏量:0