背景:
-
服务注册用的是 Eureka 集群。
-
服务调用用的是注解 @LoadBalanced 和 RestTemplate
-
服务数量两个:order 服务 和 pyment 服务(order 服务是调用者。payment 服务是被调用者 )
-
首先将 order 服务 和 payment 服务注册 Eureka 集群中。通过 order 调用 payment 服务
-
Eureka 集群 的搭建 和 rder 服务 和 payment 服务注册 Eureka 集群中 可以查看上一篇文章,有详细的步骤。
-
order 服务调用 payment 服务用的 http 方式。用的是 RestTemplate. 后续会使用 RPC 方式
实现代码
整合 Ribbon
,引入依赖。在 eureka 依赖中,已经潜入了 Ribbon
<!-- eureka-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
配置文件 ApplicationContextConfig.java
RestTemplate 可以结合 Eureka 来动态发现服务并进行负载均衡的调用。
修改 RestTemplate 的配置,增加能够让 RestTemplate 具备负载均衡能力的注解 @LoadBalanced
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {return new RestTemplate();
}
}
控制器 OrderController.java
CLOUD-PAYMENT-SERVICE
为 payment 服务注册到 Eureka 集群中的服务名。
@RestController
public class OrderController {
private static final String PROVIDER_URL = "http://CLOUD-PAYMENT-SERVICE";
@Resource
private RestTemplate restTemplate;
@GetMapping("/consumer/create/payment")
public CommonResult<Payment> create(Payment payment) {return restTemplate.postForObject(PROVIDER_URL + "/payment/create", payment, CommonResult.class);
}
@GetMapping("/consumer/payment/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {return restTemplate.getForObject(PROVIDER_URL + "/payment/get/"+id, CommonResult.class);
}
}
@LoadBalanced
@LoadBalanced 采用的是轮训的方式进行服务调用。
为什了加了 @LoadBalanced 就可用通过 Eureka 集群中的服务名称,并可以实现负载均衡呢?
因为 Spring Cloud 给我们做了大量的底层工作,因为它将这些都封装好了。
这里主要的逻辑就是给 RestTemplate 增加拦截器,在请求之前对请求的地址进行替换,或者根据具体的负载策略选择服务地址,然后再去调用。