1. 程式人生 > >Spring Cloud入門與實踐(二)-Ribbon

Spring Cloud入門與實踐(二)-Ribbon

前一篇文章介紹了Spring Cloud Eureka的簡單實踐,本篇文章介紹Ribbon的實踐。

What is Ribbon

Spring Cloud Ribbon是一個基於HTTP和TCP的客戶端負載均衡工具,這裡的客戶端是站在伺服器的角度來看的,它基於Netflix Ribbon實現。
通過Spring Cloud的封裝,可以輕鬆的將面向服務的Rest模板請求自動轉化成客戶端負載均衡的服務呼叫。當然這屬於軟體的負載均衡。

例子

下面通過一個簡單例子來用用Ribbon,基於上篇文章程式碼來進行。

  1. 首先,新建一個專案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>
  1. 寫一個main類
@SpringBootApplication
@EnableEurekaClient
public class RibbonConsumerApplication {
    public static void main(String[] args){
        SpringApplication.run(RibbonConsumerApplication.class,args);
    }
}
  1. 配置一個RestTemplate的bean:
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
  1. 定一個公開的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;
    }
  1. 此時,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;
    }
  1. 分別啟動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的擴充套件,增加了對例項執行情況來計算權重,並根據權重來挑選例項