天天看点

SpringCloud进阶-详解RestTemplate结合Ribbon的使用

作者:架构师面试宝典
SpringCloud进阶-详解RestTemplate结合Ribbon的使用

在上篇文章中,我们介绍了关于Ribbon直接整合调用接口实现负载均衡操作。这也意味着Ribbon可以作为负载均衡器进行单独的使用。但是通过我们之前的文章中对于Spring Boot的讲解,我们也知道如果能将Ribbon结合Spring Boot使用会极大的提升开发效率,在Spring Cloud微服务体系中就对Ribbon进行了封装,并且Ribbon与Spring Cloud的整合极大的提升了Spring Cloud在负载均衡上的优势。下面我们就一起来看如何在SpringCloud中使用Ribbon

RestTemplate与Ribbon的整合

我们知道在RestTemplate是Spring框架中提供了一个方便进行API调用的模板类,与JDBCTemplate类似。那么下面我们就来看看RestTemplate如何与Ribbon进行整合。

首先我们来讲一下RestTemplate具体的使用方式。在之前的项目中我们是通过如下的方式进行RestTemplate对象的注入操作。

@Configuration
public class BaseConfigration {

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}           

并且我们定义了如下的一个Controller进行RestTemplate接口的测试调用

@RestController
public class GoodsController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/goods")
    public String getGoods(){
        return restTemplate.getForObject("http://USER-SERVICE/userInfo",String.class);
    }
}           

这里使用了RestTemplate中的getForObject方法进行了调用。进入RestTemplate源码我们会看到这个Get方法调用是继承了RestOperations接口在这个接口中对于GET方式的调用给出了如下的几种调用方式

/**
	 * Retrieve a representation by doing a GET on the specified URL.
	 * The response (if any) is converted and returned.
	 * <p>URI Template variables are expanded using the given URI variables, if any.
	 * @param url the URL
	 * @param responseType the type of the return value
	 * @param uriVariables the variables to expand the template
	 * @return the converted object
	 */
	@Nullable
	<T> T getForObject(String url, Class<T> responseType, Object... uriVariables) throws RestClientException;

	/**
	 * Retrieve a representation by doing a GET on the URI template.
	 * The response (if any) is converted and returned.
	 * <p>URI Template variables are expanded using the given map.
	 * @param url the URL
	 * @param responseType the type of the return value
	 * @param uriVariables the map containing variables for the URI template
	 * @return the converted object
	 */
	@Nullable
	<T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException;

	/**
	 * Retrieve a representation by doing a GET on the URL .
	 * The response (if any) is converted and returned.
	 * @param url the URL
	 * @param responseType the type of the return value
	 * @return the converted object
	 */
	@Nullable
	<T> T getForObject(URI url, Class<T> responseType) throws RestClientException;

	/**
	 * Retrieve an entity by doing a GET on the specified URL.
	 * The response is converted and stored in an {@link ResponseEntity}.
	 * <p>URI Template variables are expanded using the given URI variables, if any.
	 * @param url the URL
	 * @param responseType the type of the return value
	 * @param uriVariables the variables to expand the template
	 * @return the entity
	 * @since 3.0.2
	 */
	<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
			throws RestClientException;

	/**
	 * Retrieve a representation by doing a GET on the URI template.
	 * The response is converted and stored in an {@link ResponseEntity}.
	 * <p>URI Template variables are expanded using the given map.
	 * @param url the URL
	 * @param responseType the type of the return value
	 * @param uriVariables the map containing variables for the URI template
	 * @return the converted object
	 * @since 3.0.2
	 */
	<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
			throws RestClientException;

	/**
	 * Retrieve a representation by doing a GET on the URL .
	 * The response is converted and stored in an {@link ResponseEntity}.
	 * @param url the URL
	 * @param responseType the type of the return value
	 * @return the converted object
	 * @since 3.0.2
	 */
	<T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType) throws RestClientException;           

其中我们需要知道的就是如下的几个参数介绍

  • url:用来进行调用的请求地址,一种是以字符串的形式传入,一种是以URI的形式传入。
  • responseType:响应返回值的类型设置
  • uriVariables:PathVariable 路径参数,有两种方式一种是可变参数,一种是通过Map的方式进行传入。这个在上面的代码中都有所体现。

从上面我们也可以看到除了可以通过getForObject的方法调用,我们还可以采用getForEntity的方式进行调用。

getForEntity方法所返回的内容与getForObject方法返回的内容是有所差异的,从getForEntity方法中返回的参数可以获取的返回的状态码、请求头信息等等。

当然除了提供GET方式的调用还提供了POST方式的调用。也是同样的,也可以在RestOperations接口中找到对应的规则,从下图中我们可以看到,RestTemplate几乎提供了所有的HTTP请求方法所能支持的各种调用方式。基本上所有的关于RestTemplate的用法在这个接口中都做了规定。并且也在RestTemplate对应的类中有具体的实现操作。当然如果有必要,我们也可以通过继承这个RestTemplate类来自己编写自己的RestTemplate的调用方式。

SpringCloud进阶-详解RestTemplate结合Ribbon的使用

说完RestTemplate接下来就来说说如何将Ribbon整合到其中

整合Ribbon

上面我们介绍了关于RestTemplate相关的内容,下面我们就来完成Ribbon的整合操作。

首先我们就需要在POM文件中加入Ribbon相关的启动依赖,当然对于依赖的选择,对于版本的选择需要根据自己的实际情况具体来选择。

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>           

如何实现RestTemplate的负载均衡在之前的时候我们也介绍过相关的内容。需要在RestTemplate配置中加入关于负载均衡的注解。

@Configuration
public class BaseConfigration {

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}           

然后我们就可以通过调用Eureka注册中心的服务名的方式来实现负载均衡的调用。

@RestController
public class GoodsController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/goods")
    public String getGoods(){
        return restTemplate.getForObject("http://USER-SERVICE/userInfo",String.class);
    }
}           

总结

上面我们介绍了关于RestTemplate如何整合Ribbon来实现负载均衡操作。示例相对简单。但是要想理解这个原理还需要亲自动手实践。希望读者朋友可以亲自实践小例子,通过小例子来深入进行学习。也希望大家能够多多关注,后续也会持续为大家带来不一样的干货。