Spring cloud Ribbon 客戶端負載均衡

Ribbon幾乎存在於每一個Spring cloud構建的微服務和基礎設施中,因爲微服務之間的調用,API網關的請求轉發等內容實際上都是通過Ribbon來實現的,是一個客戶端負載均衡的工具類框架。

通過Spring Cloud Ribbon的封裝,在微服務架構中使用客戶端負載均衡調用很簡單,只需要兩個步驟:

1、服務提供者只需要啓動多個服務實例並註冊到註冊中心

2、服務消費者直接通過調用被@LoadBalanced註解修飾過的RestTemplate來實現面向服務的接口調用

在《Spring cloud Eureka服務治理 (1)》中使用了RestTemplate實現了最簡單的服務訪問,下面介紹一下RestTemplate針對幾種不同請求類型和參數類型的服務調用實現;

GET請求

在 RestTemplate 中, 對 GET 請求可以通過如下兩個方法進行調用實現。

(1)getForEntity

該方法返回的是 ResponseEntity, 該對象是 Spring 對 HTTP 請求響應的封裝, 其中主要存儲了 HTTP 的幾個重要元素, 比如 HTTP 請求狀態 碼的枚舉對象 HttpStatus (也就是我們常說的 404、 500 這些錯誤碼)、 在它的父類 httpEntity 中還存儲着 HTTP 請求的頭信息對象 HttpHeaders 以及泛型類型的請求體 對象。 比如下面的例子, 就是訪問 USER-SERVER 服務的/user 請求, 同時最後一個參數 didi 會替換 url 中的{ 1} 佔位符, 而返回的 ResponseEntity 對象中的 body 內容類型 會根據第二個參數轉換爲 String 類型

Res七Template restTemplate = new RestTemplate();
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://USER­ SERVICE/user?name= {1}", String.class, "didi");
String body = responseEntity. getBody();

還有三種不同的重載方法:

getForEntity(String url, Class responseType, Object... urlVariables):

getForEntity(String url, Class responseType, Map urlVariables):  map中以鍵值對的方法存放參數

getForEntity(URI url, Class responseType)

 

(2)getForObject

getForObject (String url, Class responseType, Object... urlVariables):

getForObject(String url, Class responseType, Map urlVariables)

getForObject(URI url, Class responseType)

RestTemplale restTemplate = new RestTemplate();
String result = restTemplate.getForObject(uri, String.class);

POST請求:

 RestTemplate restTemplate = new RestTemplate(); 
User user = new User("didi", 30); 
ResponseEntity<String> responseEntity =
restTemplate.postForEntity("http://USER-SERVICE/user", user, String.class);
String body = responseEntity.getBody();

postForEntity函數也實現了三種不同的重載方法:

postForEntity(String url, Object request, Class responseType, Object... uriVariables)

postForEntity(String url, Object request, Class responseType, Map uriVariables)

postForEntity(URI url, Object request, Class responseType)

postForObject 函數。 該方法也跟getForObject 的類型類似, 它的作 用是簡化postForEntity的後續處理

RestTemplate restTemplate = new RestTemplate();
User user = new User("didi", 20);
String postResult = restTempla七e.postForObject("http://USER-SERVICE/user", user,
String.class);

postForObjec七函數也實現了三種 不同的重載方法:

• postForObject(String url, Object request, Class responseType, Object... uriVariables)

• postForObject(String url, Object request, Class responseType, Map uriVariables)

• postForObject(URI url, Object request, Class responseType)

User user = new User("didi", 40);
URI responseURI = restTemplate.postForLocation("http://USER-SERVICE/user", user);

postForLocation函數也實現了三種不同的重載方法:

postForLocation(Stringurl, Object request, Object...urlVariables)

postForLocation(String url, Object request, Map urlVariables)

postForLocation(URI url, Object request)

PUT請求:

RestTemplate restTemplate = new RestTemplate ();
Long id = 100011;
User user = new User("didi", 40); 
restTemplate.put("http://USER-SERVICE/user/{l}", user, id);

put函數也實現 了三種不同的重載方法:

• put(String url, Object request, Object... urlVariables)

• put(String url, Object request, Map urlVariables)

• put(URI url, Object request)

DELETE請求:

RestTemplate restTemplate = new RestTemplate();
Long id= 10001L; 
restTemplate.delete("http://USER-SERVICE/user/{1)", id);

delete函數也實現了三種不同的重載方法:

• delete(String url, Object ... urlVariables)

• delete(String url, Map urlVariables)

• delete(URI url)

 

Spring cloud Ribbon自動化配置:

IclientConfig:Ribbon的客戶端配置

IRule:Ribbon的負載均衡策略

IPing:Ribbon的實例檢查策略

ServiceList<Server>:服務實例清單的維護機制

ServerListFilter<Server>:服務實例清單過濾機制

ILoadBalancer:負載均衡器

 

自定義負載均衡策略

兩種方式,

第一,代碼方式:

新建一個類,加上@Configration註解,並且包含一個返回IRule的Bean:

@Configuration
public class RibbonRuleConfiguration {

    @Bean
    public IRule ruleStyle(){
        //        return new BestAvailableRule(); //選擇一個最小的併發請求的server
//        return new WeightedResponseTimeRule(); //根據相應時間分配一個weight,相應時間越長,weight越小,被選中的可能性越低。
//        return new RetryRule(); //對選定的負載均衡策略機上重試機制。
//        return new RoundRobinRule(); //roundRobin方式輪詢選擇server
//        return new RandomRule(); //隨機選擇一個server
//        return new ZoneAvoidanceRule(); //複合判斷server所在區域的性能和server的可用性選擇server
        return new RandomRule();
    }
}

上面是使用了隨機策略,

然後再application上加註解@RibbonClients,表示對調用的所有服務使用這個策略。

@EnableDiscoveryClient
@SpringBootApplication
@RibbonClients(defaultConfiguration = RibbonRuleConfiguration.class)
public class RibbonApplication {

    @Bean
    @LoadBalanced
    RestTemplate restTemplate(){
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(RibbonApplication.class, args);
    }
}

如果想要指定單個服務的策略:

@RibbonClient(name="server-hi",configuration = RibbonRuleConfiguation.class)

上面就是隻對server-hi使用了此策略。

但是使用上訴的方式,如果調用的服務太多,那麼就會有很多configuration類,application中也很臃腫,所以還有一種配置文件方式:

helloservice-1.ribbon.NFLoadBalancerRuleClassNam=com.netflix.loadbalancer.RandomRule

helloservice-1 是服務名,等號後面就是負載均衡策略。

 

重試機制:

Eureka爲了更高的服務可用性,犧牲了一定的一致性,在極端情況下,寧願接受故障實例,也不要丟掉實例,當服務註冊中心的網絡發生故障斷開時, 由於所有 的服務實例無法維持續約心跳, 在強調AP的服務治理中將會把所有服務實例都剔除掉, 而Eureka則會因爲超過85%的實例丟失心跳而會觸發保護機制,註冊中心將會保留此時的 所有節點, 以實現服務間依然可以進行互相調用。

以之前的服務helloservice-1爲例,可以在配置文件中增加以下內容:

helloservice-1.ribbon.ConnectTimeOut=250
#請求連接的超時時間
helloservice-1.ribbon.ReadTimeOut=1000
#請求處理的超時時間
helloservice-1.ribbon.OkToRetryOnAllOperations=true
#對所有服務都進行重試
helloservice-1.ribbon.MaxAutoRetriesNextServer=2
#切換實例重試的次數
helloservice-1.ribbon.MaxAutoRetries=1
#單個實例重試的次數

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章