天天看點

RestTemplate Feign RibbonRestTemplateFeignRibbon

RestTemplate

springboot中封裝了基于HttpClient的RestTemplate去調用http請求。能與Ribbon內建。

    @Bean

    // 開啟負載均衡

    @LoadBalanced

    RestTemplate restTemplate() {

        return new RestTemplate();

    }

get請求

    使用占位符 

    String url ="http://provider/getObjParam?name={1}";

    ResponseEntity<Person> entity = restTemplate.getForEntity(url, Person.class,"hehehe...");

post請求

        String url ="http://provider/postParam";

        Map<String, String> map = Collections.singletonMap("name", " memeda");

         ResponseEntity<Person> entity = restTemplate.postForEntity(url, map, Person.class);

攔截器

需要實作

ClientHttpRequestInterceptor

接口

public class LoggingClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
​
        @Override
        public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
            throws IOException {
            System.out.println("攔截啦!!!");
            System.out.println(request.getURI());
            ClientHttpResponse response = execution.execute(request, body);
            System.out.println(response.getHeaders());
            return response;
        }
           
@Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getInterceptors().add(new LoggingClientHttpRequestInterceptor());
        return restTemplate;
    }
           

Feign

springcloud的openFeign是基于RestTemplate實作的,且能與Ribbon內建。

public interface ConsumerApi extends UserApi {

   @GetMapping("/getMap")

   Map<Integer, String> getMap(@RequestParam("id") Integer id);

}

引入pom 才可區分Get Post

        <dependency>

            <groupId>io.github.openfeign</groupId>

            <artifactId>feign-httpclient</artifactId>

        </dependency>

Ribbon

用戶端的負載均衡,配置政策選擇服務。與網關Nginx不同,它不需要單獨啟動服務->選擇服務。

可與Eureka搭配、自定義自己配置選擇的節點資訊。

逾時

Feign預設支援Ribbon;Ribbon的重試機制和Feign的重試機制有沖突,是以源碼中預設關閉Feign的重試機制,使用Ribbon的重試機制

#連接配接逾時時間(ms)
ribbon.ConnectTimeout=1000
#業務邏輯逾時時間(ms)
ribbon.ReadTimeout=6000
           

重試

#同一台執行個體最大重試次數,不包括首次調用
ribbon.MaxAutoRetries=1
#重試負載均衡其他的執行個體最大重試次數,不包括首次調用
ribbon.MaxAutoRetriesNextServer=1
#是否所有操作都重試
ribbon.OkToRetryOnAllOperations=false
           

使用ribbon重試機制,請求失敗後,每個6秒會重新嘗試

Eureka Feign搭配

@FeignClient(name = "user-provider")
public interface ConsumerApi extends UserApi {
   
   /**
    * 這裡 getMapping 是給Feign看的 get請求 user-provider/getMap?id={1}
    * @RequestParam("id") 也是給Feign看的
    * 
    * HttpClient Http協定
    * @param id
    * @return
    */
   @GetMapping("/getMap")
   Map<Integer, String> getMap(@RequestParam("id") Integer id);
}
           

Ribbon脫離Eureka

ribbon.eureka.enabled=false
ribbon.listOfServers=localhost:80,localhost:81
           
@Autowired
LoadBalancerClient lb;
lb.choose("provider");
           

負載均衡算法

預設實作:

ZoneAvoidanceRule(區域權衡政策):複合判斷Server所在區域的性能和Server的可用性,輪詢選擇伺服器。

其他規則:

BestAvailableRule(最低并發政策):會先過濾掉由于多次通路故障而處于斷路器跳閘狀态的服務,然後選擇一個并發量最小的服務。逐個找服務,如果斷路器打開,則忽略。

RoundRobinRule(輪詢政策):以簡單輪詢選擇一個伺服器。按順序循環選擇一個server。

RandomRule(随機政策):随機選擇一個伺服器。

AvailabilityFilteringRule(可用過濾政策):會先過濾掉多次通路故障而處于斷路器跳閘狀态的服務和過濾并發的連接配接數量超過閥值得服務,然後對剩餘的服務清單安裝輪詢政策進行通路。

WeightedResponseTimeRule(響應時間權重政策):據平均響應時間計算所有的服務的權重,響應時間越快服務權重越大,容易被選中的機率就越高。剛啟動時,如果統計資訊不中,則使用RoundRobinRule(輪詢)政策,等統計的資訊足夠了會自動的切換到WeightedResponseTimeRule。響應時間長,權重低,被選擇的機率低。反之,同樣道理。此政策綜合了各種因素(網絡,磁盤,IO等),這些因素直接影響響應時間。

RetryRule(重試政策):先按照RoundRobinRule(輪詢)的政策擷取服務,如果擷取的服務失敗則在指定的時間會進行重試,進行擷取可用的服務。如多次擷取某個服務失敗,就不會再次擷取該服務。主要是在一個時間段内,如果選擇一個服務不成功,就繼續找可用的服務,直到逾時。

切換負載均衡政策

注解方式

@Bean
    public IRule myRule(){
        //return new RoundRobinRule();
        //return new RandomRule();
        return new RetryRule(); 
           

配置檔案

針對服務定ribbon政策:

(服務名)provider.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
​
           

給所有服務定ribbon政策:

ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
           

屬性配置方式優先級高于Java代碼。

繼續閱讀