基于Ribbon+RestTemplate的服务调用

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
EMR Serverless StarRocks,5000CU*H 48000GB*H
应用型负载均衡 ALB,每月750个小时 15LCU
简介: 基于Ribbon+RestTemplate的服务调用

简介

SpringCloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过SpringCloud 的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。

注意这里的两个关键词:

  1. 客户端:Ribbon需要将注册中心的服务示例拉去到本地进行缓存,并在本地完成负载均衡的动作,默认使用轮询的方式。
  2. 负载均衡:Ribbon只是进行负载均衡的操作,选取合适的微服务示例来提供给RestTemplate,请求的操作由后者完成。

项目准备

必要准备

引入依赖

如果使用的是eureka client 和 consul client,无须引入依赖。因为在eureka、consul中默认集成了ribbon组件

<!--引入Ribbon依赖--> 
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
   <version>2.2.8.RELEASE</version>
</dependency>

创建RestTemplate配置类

这样我们只需要在需要调用其他服务的控制器中使用@Autowired注解注入即可

@Configuration
public class BeansConfig {
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

我使用8083、8084、8085同时运行了订单服务来构成订单服务集群。

编写测试接口

Ribbon提供简单的三种方式来获取配置中心的服务示例或者完成负载均衡

DiscoveryClient

DiscoveryClient可以指定服务的名称来获取配置中心上的实例列表,这个对象是没有实现负载均衡的。

@Slf4j
@RestController
@RequestMapping("/users")
public class UserController {
    /**
     * 服务注册发现客户端对象
     */
    @Autowired
    private DiscoveryClient discoveryClient;
    @Autowired
    private RestTemplate restTemplate;
    /**
     * 获取用户的订单
     */
    @GetMapping("/id/{id}/orders")
    public String getUserOrders(@PathVariable("id") Integer id){
        // 获取注册中心指定服务全部的示例
        List<ServiceInstance> instances = discoveryClient.getInstances("ORDERS");
        instances.forEach(instance -> log.info("DiscoveryClient获取到[ORDERS]服务示例 -> 主机[{}],端口[{}],Uri[{}]", instance.getHost(), instance.getPort(), instance.getUri()));
        // 这里注意,取得是实例列表里面的第一个实例(可能为空),这里可以手动写一个算法,从instances随机获取一个实例
        return restTemplate.getForObject(instances.get(0).getUri+"/orders/uId/"+id, String.class);
    }
}

浏览器访问http://localhost:8082/users/id/2/orders

返回数据:20210726120030X2P8083

多次请求发现还是返回同样的数据,因为我们没有进行负载均衡,在代码中写死了,instances.get(0).getUri,始终都是向第一个实例发送请求的。

LoadBalancerClient

LoadBalancerClient这是一个负载均衡的客户端对象,使用它提供的choose方法可以使用负载均衡来获取一个服务的实例,这里返回的是单个对象,默认的方式也是沦陷。

@Slf4j
@RestController
@RequestMapping("/users")
public class UserController {
    /**
     * 负载均衡客户端对象
     */
    @Autowired
    private LoadBalancerClient loadBalancerClient;
    @Autowired
    private RestTemplate restTemplate;
    /**
     * 获取用户的订单
     */
    @GetMapping("/id/{id}/orders")
    public String getUserOrders(@PathVariable("id") Integer id){
        // 使用负载均衡获取服务示例对象,默认轮询
        ServiceInstance instance = loadBalancerClient.choose("ORDERS");
        log.info("LoadBalancerClient获取到[ORDERS]服务示例 -> 主机[{}],端口[{}],Uri[{}]", instance.getHost(), instance.getPort(), instance.getUri());
        return restTemplate.getForObject(instance.getUri+"/orders/uId/"+id, String.class);
    }
}

多次在浏览器访问http://localhost:8082/users/id/2/orders

返回数据:
20210726120030X2P8085
20210726120030X2P8084
20210726120030X2P8083

这里可以看到,这样就实现了负载均衡。

@LoadBalanced

@LoadBalanced注解可以对上面的LoadBalancerClient进行再一次的简化,省掉编写loadBalancerClient.choose("ORDERS");这个语句,将这个对象声明在RestTemplate的生成方法上面可以让生成的对象具有负载均衡的能力。

@Configuration
public class BeansConfig {
    /**
     * LoadBalanced 为restTemplate对象赋予负载均衡的职责
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}
@Slf4j
@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private RestTemplate restTemplate;
    /**
     * 获取用户的订单
     */
    @GetMapping("/id/{id}/orders")
    public String getUserOrders(@PathVariable("id") Integer id){
        // ORDERS为注册中心服务的名称,框架会进行处理
        return restTemplate.getForObject("http://ORDERS/orders/uId/"+id, String.class);
    }
}

多次在浏览器访问http://localhost:8082/users/id/2/orders

返回数据:
20210726120030X2P8085
20210726120030X2P8084
20210726120030X2P8083

这里可以看到,这样也实现了负载均衡。

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
4月前
|
负载均衡 算法 Java
通用快照方案问题之Ribbon和RestTemplate的结合使用如何解决
通用快照方案问题之Ribbon和RestTemplate的结合使用如何解决
34 0
|
负载均衡 网络协议 算法
SpringCloud服务间通信方式(RestTemplate)及负载均衡(Ribbon)
🍅程序员小王的博客:程序员小王的博客 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 如有编辑错误联系作者,如果有比较好的文章欢迎分享给我,我会取其精华去其糟粕 🍅java自学的学习路线:java自学的学习路线
431 0
SpringCloud服务间通信方式(RestTemplate)及负载均衡(Ribbon)
|
负载均衡 网络协议 Java
Spring Cloud 学习笔记04----服务消费者(RestTemplate+Ribbon(客户端负载均衡))
上一篇《Spring Cloud 学习笔记02----服务治理》我们讲到了服务的注册与发现,在微服务框架中,我们将服务拆分成一个个独立部署的子服务,这些服务通过http rest 来通讯的,Spring Cloud有两种服务调用方式,一种是 RestTemplate+Ribbon, 另外一种是Feign 。
155 0
Spring Cloud 学习笔记04----服务消费者(RestTemplate+Ribbon(客户端负载均衡))
|
负载均衡 Java 容器
【Spring Cloud】 RestTemplate基于Ribbon的负载均衡实现原理 上
都知道 RestTemplate 是基于 Ribbon实现的负载均衡,那么Ribbon又是如何做到的 ? 首先找到 spring-cloud-netflix-ribbon-2.1.0.RELEASE.jar 这个jar包 ## 1.自动配置创建RibbonAutoConfiguration ![image-20220510203440880](https://img-blog.csdnimg.cn/img_convert/f0a478e8490a71010810423dad12e169.png) 查看META-INF下的spring.factories文件
130 0
|
Java 微服务 Spring
11、RestTemplate+Ribbon整合断路器Hystrix
当对某个服务的调用的不可用达到一个阀值(Hystric 默认是5秒20次) 断路器将会被自动被打开。断路打开后, fallback方法可以直接返回一个预先设置的固定值。
192 0
11、RestTemplate+Ribbon整合断路器Hystrix
|
9天前
|
负载均衡 监控 网络协议
SpringCloud之Ribbon使用
通过以上步骤,就可以在Spring Cloud项目中有效地使用Ribbon来实现服务调用的负载均衡,提高系统的可靠性和性能。在实际应用中,根据具体的业务场景和需求选择合适的负载均衡策略,并进行相应的配置和优化,以确保系统的稳定运行。
34 15
|
9天前
|
负载均衡 算法 Java
除了 Ribbon,Spring Cloud 中还有哪些负载均衡组件?
这些负载均衡组件各有特点,在不同的场景和需求下,可以根据项目的具体情况选择合适的负载均衡组件来实现高效、稳定的服务调用。
23 5
|
2月前
|
负载均衡 Java Nacos
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
微服务介绍、SpringCloud、服务拆分和远程调用、Eureka注册中心、Ribbon负载均衡、Nacos注册中心
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
|
3月前
|
负载均衡 算法 Java
SpringCloud之Ribbon使用
通过 Ribbon,可以非常便捷的在微服务架构中实现请求负载均衡,提升系统的高可用性和伸缩性。在实际使用中,需要根据实际场景选择合适的负载均衡策略,并对其进行适当配置,以达到更佳的负载均衡效果。
59 13
|
5月前
|
负载均衡 算法 Java
Spring Cloud Netflix 之 Ribbon
Spring Cloud Netflix Ribbon是客户端负载均衡器,用于在微服务架构中分发请求。它与RestTemplate结合,自动在服务发现(如Eureka)注册的服务之间进行调用。配置包括在pom.xml中添加依赖,设置application.yml以连接Eureka服务器,并在配置类中创建@LoadBalanced的RestTemplate。通过这种方式,当调用如`/user/userInfoList`的接口时,Ribbon会自动处理到多个可用服务实例的负载均衡。