天天看點

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來實作負載均衡操作。示例相對簡單。但是要想了解這個原理還需要親自動手實踐。希望讀者朋友可以親自實踐小例子,通過小例子來深入進行學習。也希望大家能夠多多關注,後續也會持續為大家帶來不一樣的幹貨。