基于Ribbon+RestTemplate的服务调用

简介: 基于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

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

相关实践学习
部署高可用架构
本场景主要介绍如何使用云服务器ECS、负载均衡SLB、云数据库RDS和数据传输服务产品来部署多可用区高可用架构。
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
18天前
|
负载均衡 Java 网络架构
基于RestTemplate的服务调用
基于RestTemplate的服务调用
19 1
|
18天前
|
存储 JSON 负载均衡
基于OpenFeign的服务调用
基于OpenFeign的服务调用
16 2
|
3月前
|
负载均衡 Java 应用服务中间件
springcloud3-服务到服务调用ribbon及openfeign
springcloud3-服务到服务调用ribbon及openfeign
46 0
|
3月前
|
监控 安全 Java
深入理解Feign
深入理解Feign
78 2
|
3月前
|
微服务
Feign远程调用
Feign远程调用
38 0
|
8月前
SpringCloud-Feign-文件服务调用
SpringCloud-Feign-文件服务调用
37 0
|
4月前
|
负载均衡 算法 Java
SpringCloud - Feign与Ribbon请求负载均衡实践
SpringCloud - Feign与Ribbon请求负载均衡实践
46 0
|
8月前
|
Java Nacos Sentinel
初识SpringCloud以及使用RestTemplate进行服务调用:服务调用初体验
初识SpringCloud以及使用RestTemplate进行服务调用:服务调用初体验
56 0
|
JSON Java API
Feign远程调用
Feign远程调用
87 0
|
缓存 负载均衡 网络协议
Ribbon远程调用
Ribbon远程调用
88 0

热门文章

最新文章