From 13c5304139ab21017eda66e0c73540df19f5945f Mon Sep 17 00:00:00 2001 From: bunny <1319900154@qq.com> Date: Mon, 26 May 2025 13:56:57 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E8=B4=9F=E8=BD=BD=E5=9D=87?= =?UTF-8?q?=E8=A1=A1=E6=B3=A8=E8=A7=A3=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud-demo/ReadMe.md | 85 ++++++++++++++++++- .../service/config/OrderServiceConfig.java | 2 + .../service/impl/OrderServiceImpl.java | 17 +++- 3 files changed, 102 insertions(+), 2 deletions(-) diff --git a/cloud-demo/ReadMe.md b/cloud-demo/ReadMe.md index 1af76a5..bbb6c3c 100644 --- a/cloud-demo/ReadMe.md +++ b/cloud-demo/ReadMe.md @@ -304,7 +304,18 @@ public ClientHttpRequestFactory getRequestFactory() { } ``` -**实现远程调用** +#### 实现远程调用 + +##### 普通方式调用 + +注册`RestTemplate` + +```java +@Bean +public RestTemplate restTemplate() { + return new RestTemplate(); +} +``` 如果我们的服务启动了多个,在下面代码中即使一个服务宕机也可以做到远程调用。 @@ -322,3 +333,75 @@ private Product getProductFromRemote(Long productId) { return restTemplate.getForObject(url, Product.class); } ``` + +##### 负载均衡调用 + +注册`RestTemplate` + +```java +@Bean +public RestTemplate restTemplate() { + return new RestTemplate(); +} +``` + +使用负载均衡`LoadBalancerClient`,通过负载均衡算法动态调用远程服务。 + +```java +/** + * 远程调用商品模块 --- 负载均衡 + * + * @param productId 商品id + * @return 商品对象 + */ +private Product getProductFromRemoteWithLoadBalancer(Long productId) { + // 1. 获取商品服务所有及其的 IP+port + ServiceInstance instance = loadBalancerClient.choose("service-product"); + + // 远程URL + String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/api/product/" + productId; + + // 2. 远程发送请求 + log.info("负载均衡远程调用:{}", url); + return restTemplate.getForObject(url, Product.class); +} +``` + +##### 负载均衡注解调用 + +> [!TIP] +> +> 如果远程注册中心宕机是否可以调用? +> +> 调用过:远程调用不在依赖注册中心,可以通过。 +> +> 没调用过:第一次发起远程调用;不能通过。 + +在`RestTemplate`上加上`@LoadBalanced`注解使用负载均衡。 + +```java +@Bean +@LoadBalanced +public RestTemplate restTemplate() { + return new RestTemplate(); +} +``` + +在实际的调用中并不需要再显式调用,将URL替换成服务名称即可。 + +```java +/** + * 远程调用商品模块 --- 负载均衡注解调用 + * + * @param productId 商品id + * @return 商品对象 + */ +private Product getProductFromRemoteWithLoadBalancerAnnotation(Long productId) { + // 远程URL,实现动态替换 + String url = "http://service-product/api/product/" + productId; + + // 远程发送请求 + log.info("负载均衡注解调用:{}", url); + return restTemplate.getForObject(url, Product.class); +} +``` diff --git a/cloud-demo/services/service-order/src/main/java/cn/bunny/service/config/OrderServiceConfig.java b/cloud-demo/services/service-order/src/main/java/cn/bunny/service/config/OrderServiceConfig.java index a64fe66..c3db747 100644 --- a/cloud-demo/services/service-order/src/main/java/cn/bunny/service/config/OrderServiceConfig.java +++ b/cloud-demo/services/service-order/src/main/java/cn/bunny/service/config/OrderServiceConfig.java @@ -1,5 +1,6 @@ package cn.bunny.service.config; +import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @@ -8,6 +9,7 @@ import org.springframework.web.client.RestTemplate; public class OrderServiceConfig { @Bean + @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } diff --git a/cloud-demo/services/service-order/src/main/java/cn/bunny/service/service/impl/OrderServiceImpl.java b/cloud-demo/services/service-order/src/main/java/cn/bunny/service/service/impl/OrderServiceImpl.java index 0e4e748..2fef61d 100644 --- a/cloud-demo/services/service-order/src/main/java/cn/bunny/service/service/impl/OrderServiceImpl.java +++ b/cloud-demo/services/service-order/src/main/java/cn/bunny/service/service/impl/OrderServiceImpl.java @@ -32,7 +32,7 @@ public class OrderServiceImpl implements OrderService { */ @Override public Order createOrder(Long productId, Long userId) { - Product product = getProductFromRemoteWithLoadBalancer(productId); + Product product = getProductFromRemoteWithLoadBalancerAnnotation(productId); Order order = new Order(); order.setId(1L); @@ -83,4 +83,19 @@ public class OrderServiceImpl implements OrderService { log.info("负载均衡远程调用:{}", url); return restTemplate.getForObject(url, Product.class); } + + /** + * 远程调用商品模块 --- 负载均衡注解调用 + * + * @param productId 商品id + * @return 商品对象 + */ + private Product getProductFromRemoteWithLoadBalancerAnnotation(Long productId) { + // 远程URL,实现动态替换 + String url = "http://service-product/api/product/" + productId; + + // 远程发送请求 + log.info("负载均衡注解调用:{}", url); + return restTemplate.getForObject(url, Product.class); + } }