1. Spring Cloud服务间调用概述
在微服务架构中,服务间的通信是核心功能之一。Spring Cloud提供了多种服务间调用的方式,其中最常用的是RestTemplate和Feign。这两种方式本质上都是基于HTTP协议的RESTful调用,但在使用方式和功能特性上有所不同。
1.1 为什么需要服务间调用
微服务架构将单体应用拆分为多个小型服务,每个服务专注于单一业务功能。这种架构带来了以下优势:
- 服务独立部署和扩展
- 技术栈灵活性
- 故障隔离
- 团队自治
但同时,服务间的协作需要通过通信来实现。服务A可能需要调用服务B提供的功能来完成自己的业务逻辑,这就需要可靠、高效的服务间调用机制。
1.2 服务注册与发现
在深入讨论调用方式前,必须理解服务注册与发现机制。Spring Cloud默认使用Eureka作为服务注册中心,服务启动时会向Eureka注册自己的网络位置(IP和端口),其他服务可以通过服务名(spring.application.name)来查找和调用该服务。
这种机制解决了硬编码服务地址的问题,使得服务可以动态扩展和替换,而不需要修改调用方的代码。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. RestTemplate方式调用
2.1 基础环境搭建
要演示服务间调用,我们需要搭建以下组件:
- Eureka注册中心
- 服务提供者(Server)
- 服务消费者(Client)
2.1.1 Eureka注册中心配置
Eureka Server的典型配置如下:
yaml复制server:
port: 7001
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false # 不向自己注册
fetch-registry: false # 不从自己获取注册信息
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
2.1.2 服务提供者配置
服务提供者的application.yml配置示例:
yaml复制server:
port: 8001
spring:
application:
name: hello-service
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
对应的Controller实现:
java复制@RestController
public class ServerController {
@RequestMapping("/hello")
public String hello(){
return "hello from server";
}
}
2.1.3 服务消费者配置
服务消费者的application.yml配置与服务提供者类似,主要区别在于应用名称:
yaml复制server:
port: 8002
spring:
application:
name: hello-client
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
2.2 RestTemplate的三种调用方式
2.2.1 直接调用(不推荐)
最简单的方式是直接使用服务提供者的URL进行调用:
java复制@RestController
public class ClientController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/callDirect")
public String callDirect() {
return restTemplate.getForObject(
"http://localhost:8001/hello",
String.class
);
}
}
注意:这种方式将服务地址硬编码在代码中,不推荐在生产环境使用。当服务实例发生变化时,需要修改代码并重新部署。
2.2.2 通过服务发现调用
改进的方式是通过DiscoveryClient获取服务实例信息:
java复制@RestController
public class ClientController {
