常見微服務的消費者
本節就常見的微服務的消費者進行介紹。在JAVA領域比較常用的消費者框架主要有HttpClient、Ribbon、Feign 等。
Apache HttpClient
Apache HttpClient是Apache Jakarta Common下的子項目,用來提供高效的、最新的、功能豐富的支持HTTP的客戶端編程工具包,并且它支持HTTP最新的版本和建議。雖然在JDK的java.net包中已經提供了訪問HTTP的基本功能,但是對于大部分應用程序來說,JDK 庫本身提供的功能還不夠豐富和靈活。HttpClient 相比傳統JDK自帶的URLConnection,增加了易用性和靈活性,它不僅使客戶端發送Http請求變得容易,而且也方便了開發人員測試基于HTTP的接口,既提高了開發的效率,也方便提高代碼的健壯性。
在之前章節的示例中,我們也大規模采用了HttpClient來作為REST客戶端。
在程序中,我們經常使用RestTemplate實例來訪問REST服務。RestTemplate 是Spring的核心類,用于同步客戶端的HTTP訪問。它簡化了與HTTP服務器的通信,并強制執行RESTful原則。
默認情況下,RestTemplate 依賴于標準的JDK功能來建立HTTP連接,當然,我們也可以通過setRequestFactory屬性來切換到使用不同的HTTP庫,例如,上面我們所介紹的Apache HttpCli-ent, 以及其他的,如Netty、OkHtp等。
要使用Apache HttpClient,最方便的方式莫過于再添加Apache HttpClient依賴。
//依賴關系
dependencies {//添加Apache HttpClient依賴compile ('org . apache . httpcomponents :httpclient:4.5.3')
}
其次,通過RestTemplateBuilder來創建RestTemplate實例。
import org. spr ingframework .beans. factory .annotation . Autowired;
import org. spr ingframework. boot . web. client. RestTemplateBuilder;
import org. spr ingf r amework. context. annotation. Bean;
import org. springframework . context . annotation . Configuration;
import org. springfr amework . web. client.RestTemplate;
@Configuration
public class RestConfiguration {
@Autowi red
private RestTemplateBuilder builder;@Bean
public RestTemplate restTemplate() {
return builder .build() ;
}}
最后,就能通過RestTemplate實例來訪問RESTfulAPI服務了。
@Service
public class WeatherDataServiceImpl implements WeatherDataService {
CAutowiredprivate RestTemplate restTemplate;private WeatherResponse doGetWeatherData (String uri) {
ResponseEntity<String> response = restTemplate . getForEntity (uri, String.class) ;
//。。
}
// .。}
Ribbon
Spring Cloud Ribbon是基于Netlix Ribbon實現的一套客戶端負載均衡的工具。它是一一個基于HTTP和TCP的客戶端負載均衡器。
Ribbon的一一個中心概念就是命名客戶端。每個負載平衡器都是組合整個服務組件的一部分,它們一起協作,并可以根據需要與遠程服務器進行交互,獲取包含命名客戶端名稱的集合。SpringCloud根據需要,使用RibbonClientConfiguration為每個命名客戶端創建一個新的集合作為Applica-tionContext。這其中包括- - 個ILoadBalancer、一個RestClient和一個ServerListFilter。
Ribbon經常與Eureka結合使用。在典型的分布式部署中,Eureka 為所有微服務實例提供服務注冊,而Ribbon則提供服務消費的客戶端。Ribbon 客戶端組件提供一- 系列完善的配置選項,如連接超時、重試、重試算法等。Ribbon內置可插拔、可定制的負載均衡組件。下 面是用到的一一些負載均衡策略:
●簡單輪詢負載均衡;
●加權響應時間負 載均衡;
●區域感知輪詢負載均衡;
●隨機負載均衡。
其中,區域感知負載均衡器是Ribbon 一個久經考驗的功能,該負載均衡器會采取如下步驟。
●負載均衡器會檢查、計算所有可用區域的狀態。如果某個區域中平均每個服務器的活躍請求已經達到配置的閾值,該區域將從活躍服務器列表中排除。如果多于-一個區域已經到達閾值,平均每服務器擁有最多活躍請求的區域將被排除。
●最差的區域被排除后,從剩下的區域中,將按照服務器實例數的概率抽樣法選擇一 個區域。
●在選定區域中,將會根據給定負載均衡策略規則返回一個服務器。
在micro-weather-eureka-client應用基礎上,我們稍作修改,使其成為一個新的應用mi-cro-weather-eureka-client-ribbon,作為本章節的示例。
1.所需環境
為了演示本例子,需要采用如下開發環境。
JDK 8。
Gradle 4.0。
● redis 3.2.100。
● Spring Boot 2.0.0.M3。
●Spring Cloud Starter Netlix Eureka Client Finchley.M2。
●Spring Cloud Starter Netilix Ribbon。
2.項目配置
要使用Ribbon,最簡單的方式莫過于添加Ribbon依賴。
//依賴關系
dependencies {//添加Spring Cloud Starter Netflix Ribbon依賴compile (' org. spr ingframework. cloud: spring-cloud-starter-netflix-rib-
bon')
}
3.啟用Ribbon
Spring Cloud提供了聲明式@RibbonClient注解來使用Ribbon。
package com. waylau. spring. cloud. weather . config;
import org. springframework.beans. factory . annotation. Autowired;
import org. spr ingf r amework. boot. web. cl ient. RestTemplateBuilder;
import org. springfr amework. cloud.client. loadbalancer .LoadBalanced;
import org.spr ingframework .cloud. netflix. ribbon. RibbonCl ient;
import org. spr ingfr amework. context. annotation. Bean;
import org. springfr amework.context. annotation. Configuration;
import org. springframework. web. client. RestTemplate;
t REST配置類.* @since 1.0.0 2017年11月03日
k Cauthor <a href="https: / /waylau. com">Way Lau</a>
@Configuration
@RibbonClient (name = "ribbon-client", configuration = RibbonConfiguration.
class)
public class RestConfiguration {
@Autowi red
private RestTemplateBuilder builder;@Bean
@LoadBalanced
public RestTemplate restTemplate () {
return builder .build() ;
}}
其中RibbonConfiguration是Ribbon自定義的配置類,定義如下。
/ **
*/package com. waylau. spring.cloud . weather . config;
import org. spr ingframework.cloud.netflix. ribbon. ZonePreferenceServerList
Filter;import org. springfr amework. context. annotation. Bean;
import org. springframework. context. annotation. Configuration;
import com. netflix. loadbalancer. IPing;
import com. netflix. loadbalancer . PingUrl;
/**
城市配置.
* @since 1.0.0 2017年11月3日
@author <a href="https://waylau. com">Way Lau</a>
@Configuration
public class RibbonConfiguration {
@Bean
public ZonePreferenceServerListFilter serverListFilter() {
ZonePreferenceServerListFilter filter = new ZonePreferenceServer-
ListFilter ()
filter .setZone ("myZone") ;
return filter;
@Bean
public IPing ribbonPing() {
return new PingUrl () ;
}
}
這樣,我們就能通過應用名稱msa-weather-city -eureka來訪問微服務了,并且還實現了服務的負載均衡。
4.使用Ribbon
編寫CityController,用于使用Ribbon配置的RestTemplate。
import org. springframework. beans. factory . annotation. Autowired;
import org . springf ramework. web. bind. annotation. GetMapping;
import org.spr ingframework . web. bind. annotation. RestController;
import org. springf ramework. web. cl ient . RestTemplate;
/**
City Controller .
* @since 1.0.0 2017年11月03日
@author <a href="https:/ /waylau. com">Way Lau</a>
@RestController
public class CityController
@Autowired
private RestTemplate res tTemplate;
@GetMapping ("/cities")
public String listCity() {
//通過應用名稱來查找
String body = restTemplate . getForEntity ("http:/ /msa-weather-
city-eureka/cities", String.class) .getBody() ;
return body;
}
}
5.應用配置
該應用同時也是一個 Eureka Client。修改application.properties,將其修改為如下配置。
spring. application. name: micro-weather -eureka-client-ribbon eureka. client. serviceUrl .defaultZone: http://localhost:8761/eureka/
Feign
Feign是一- 個聲明式的Web服務客戶端,這使Web服務客戶端的寫人更加方便。它具有可插拔注解支持,包括Feign注解和JAX-RS注解。Feign 還支持可插拔編碼器和解碼器。Spring Cloud增加了對Spring MVC注解的支持,并且使用了在Spring Web中默認使用的相同的HttpMessageCon-verter。 在使用Feign時,Spring Cloud集成了Ribbon 和Eureka 來提供負載平衡的HTTP客戶端。
在micro-weather-eureka-client應用基礎上,我們稍作修改,使其成為一個新的應用mi-cro-weather- eureka-client-feign,作為本節的示例。
1.所需環境
為了演示本例子,需要采用如下開發環境。
●Gradle 4.0。
●Redis 3.2.100。
●Spring Boot 2.0.0.M3。
●Spring Cloud Starter Netflix Eureka Client Finchley.M2。
●Spring Cloud Starter OpenFeign Finchley.M2。
2.項目配置
為了使用Feign,增加如下配置。
dependencies {
//添加Spring Cloud Starter OpenFeign依賴
compile('org. spr ingframework. cloud:spring-cloud-starter-openfeign')
}
3.啟用Feign
要啟用Feign,最簡單的方式就是在應用的根目錄的Application 類上添加org.springframework.cloud.netlix. feign.EnableFeignClients注解。
import org.springframework .boot. SpringApplication;
import org. springfr amework . boot. autoconfigure . SpringBootApplication;
import org. springframework. cloud. client . discovery . EnableDi scoveryClient;
import org.springframework. cloud. netflix. feign. EnableFeignClients;
/**
★主應用程序.
★asince 1.0.0 2017年11月04日
* Cauthor <a href="https:/ /waylau. com">Way Lau</a>
*/
@SpringBootApplication
@EnableDiscoveryCl ient
@EnableFeignClients
public class Appl ication {
public static void main(String[] args) {
SpringApplication. run (Application.class, args) ;
}}
4.使用Feign
要使用Feign,首先是編寫Feign請求接口。
package com. waylau. spring.cloud. weather .service;
import org. spr ingf ramework. cloud . netflix. feign. FeignClient;
import org. springfr amework. web . bind. annotation . GetMapping;
★訪問城市信息的客戶端.* Gsince 1.0.0 2017年11月4日
* @author <a href="https:/ /waylau. com">Way Lau</a>
*/@FeignClient ("msa-weather-city-eureka")
public interface CityClient {
@GetMapping("/cities")
String listCity() ;}}
其中,@FeignClient指定了要訪問的服務的名稱msa- weather-city-eureka。
在聲明了CityClient 接口之后,我們就能在控制器CityController中使用該接口的實現。
import org. springframework .beans. factory .annotation. Autowired;
import org. springframework. web .bind. annotation. GetMapping;
import org. springf r amework. web.bind. annotation. RestController;
import com. waylau. spring. cloud . weather . service. CityClient;
/★** City Controller.★@since 1.0.0 2017年11月04日
* @author <a href="https:/ /waylau. com">Way Lau</a>
@RestController
public class CityController {
@Autowired
private CityClient cityClient;
@GetMapping("/cities")
public String listCity() {
/通過Feign客戶端來查找String body = cityClient. listCity() ;return body;
}}
CityContoller 控制器專門用于請求獲取城市信息的響應。這里,我們直接注入CityClient 接口即可,Feign框架會為我們提供具體的實現。
最后,修改application.properties。將其修改為如下配置。
spr ing . application. name: micro-weather -eureka-client-feign
eureka. client. serviceUrl. defaultZone: http:/ /localhost: 8761/eureka/
feign.cl ient. config. feignName . connectTimeout: 5000
feign. cl ient. config. feignName . readTimeout: 5000
其中:
● feign.client.config.feignName.connectTimeout為連接超時時間;
feign.client.conig. feignName.readTimeout為讀數據的超時時間。
源碼
本節示例所涉及的源碼,見micro-weather-eureka-server、micro-weather-eureka-client 和msa-weather-city-eureka,以及micro-weather-eureka-client-ribbon和micro-weather- eureka-client-feign。