Spring Cloud入門與實踐(二)-Ribbon
阿新 • • 發佈:2018-12-26
前一篇文章介紹了Spring Cloud Eureka的簡單實踐,本篇文章介紹Ribbon的實踐。
What is Ribbon
Spring Cloud Ribbon是一個基於HTTP和TCP的客戶端負載均衡工具,這裡的客戶端是站在伺服器的角度來看的,它基於Netflix Ribbon實現。
通過Spring Cloud的封裝,可以輕鬆的將面向服務的Rest模板請求自動轉化成客戶端負載均衡的服務呼叫。當然這屬於軟體的負載均衡。
例子
下面通過一個簡單例子來用用Ribbon,基於上篇文章程式碼來進行。
- 首先,新建一個專案service-consumer,作為暴露對外的url呼叫,該專案pom檔案如下:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId >
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
</dependencies>
- 寫一個main類
@SpringBootApplication
@EnableEurekaClient
public class RibbonConsumerApplication {
public static void main(String[] args){
SpringApplication.run(RibbonConsumerApplication.class,args);
}
}
- 配置一個RestTemplate的bean:
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
- 定一個公開的controller,用於從另一個服務端獲取資料:
@Autowired
private RestTemplate restTemplate;
@GetMapping(value = "/ribbon/{name}")
public String findInfoById(@PathVariable String name){
//注意以下命名是以eureka的服務名稱來獲取的
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://hello-service/user?name={1}",String.class,name+":test anla");
String body = responseEntity.getBody();
return body;
}
- 此時,hello-service,就做為服務提供者,實際中可能有多個hello-service例項,它們在eureka註冊的名稱需要一致,埠不同,在
hello-service中可以定義眾多restful方法供呼叫:
@RequestMapping(value = "/user",method = RequestMethod.GET)
public String index(@RequestParam String name){
ServiceInstance config = client.getLocalServiceInstance();
String serviceId = config.getServiceId();
String result = "hello: I am "+serviceId+", hello-service"+name+"my port is"+config.getPort();
logger.info(result);
return result;
}
- 分別啟動eureka-server,hello-service,service-consumer,然後改變hello-service的server.port,換一個埠再進行註冊,此時eureka中例項如下:
小窺
在上述示例程式碼中,我使用了RestTemplate來進行對服務端的restful呼叫,當然,在Restful API規範中,對應有不同的操作,而在
RestTemplate中也有對應:
- GET
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
public <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType)
public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables)
public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)
- …
- POST
public <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
- …
public <T> T postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)
- …
- PUT
public void put(String url, Object request, Object... uriVariables)
- …
- DELTE
public void delete(String url, Object... uriVariables)
- …
上述中列舉了四種請求的對應的方法,其中過載則並未列出了。
負載均衡策略
對於Ribbon,負載均衡策略主要有以下幾種:
- RandomRule:隨機
- RoundRobinRule:線性輪詢一次選擇每個伺服器例項
- RetryRule:具備重試機制的例項選擇功能
- WeightedResponseTimeRule:對RoundRobinRule的擴充套件,增加了對例項執行情況來計算權重,並根據權重來挑選例項