1. 微服务调用方式概述
在现代微服务架构中,服务间的调用是核心功能之一。与传统的单体应用不同,微服务架构将系统拆分为多个独立部署的服务,这些服务需要通过网络进行通信。服务调用方式的选择直接影响系统的性能、可靠性和开发效率。
1.1 服务发现的基本概念
服务发现是微服务架构中的关键组件,它解决了服务间动态寻址的问题。在传统的单体应用中,服务间的调用通常通过本地方法调用完成,而在微服务架构中,服务可能部署在多台机器上,IP地址和端口都是动态变化的。
服务发现机制通常包含三个核心组件:
- 服务注册中心(如Eureka、Nacos、Zookeeper)
- 服务提供者(向注册中心注册自己的服务)
- 服务消费者(从注册中心获取服务地址)
1.2 服务调用的两种主要方式
根据是否依赖服务发现机制,我们可以将服务调用分为两大类:
-
基于服务发现的服务调用:
- 通过服务名而非具体IP地址进行调用
- 自动处理服务实例的动态变化
- 支持客户端负载均衡
- 典型实现:Feign、Dubbo
-
直接调用配置的服务地址:
- 硬编码或配置具体的服务地址
- 适用于固定不变的服务端点
- 典型实现:RestTemplate、原生HTTP客户端
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 基于服务发现的服务调用
2.1 服务发现的三种实现方式
2.1.1 DiscoveryClient方式
DiscoveryClient是Spring Cloud提供的服务发现抽象接口,支持多种注册中心。以下是使用DiscoveryClient进行服务调用的完整示例:
java复制@Service
public class ProductService {
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private RestTemplate restTemplate;
public List<Product> getProducts() {
// 1. 获取服务实例列表
List<ServiceInstance> instances = discoveryClient.getInstances("product-service");
if (instances.isEmpty()) {
throw new RuntimeException("No available product service instances");
}
// 2. 选择第一个可用实例(简单示例,实际应实现负载均衡)
ServiceInstance instance = instances.get(0);
// 3. 构建请求URL
String url = String.format("http://%s:%s/products",
instance.getHost(), instance.getPort());
// 4. 发起HTTP请求
ResponseEntity<List<Product>> response = restTemplate.exchange(
url,
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<Product>>() {}
);
return response.getBody();
}
}
注意事项:
- 需要确保应用已添加
@EnableDiscoveryClient注解 - 直接使用DiscoveryClient需要自行处理负载均衡逻辑
- 服务实例列表是动态变化的,应考虑缓存机制
2.1.2 LoadBalancerClient方式
LoadBalancerClient提供了更高级的负载均衡能力:
java复制@Service
public class ProductService {
@Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private RestTemplate restTemplate;
public List<Product> getProducts() {
// 1. 通过负载均衡器选择服务实例
ServiceInstance instance = loadBalancerClient.choose("product-service");
if (instance == null) {
throw new RuntimeException("No available product service instances");
}
//
