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