玩轉SpringCloud專題(十七)-SpringCloud之Hystrix請求合併

本文我們來演示下Hystrix中解決雪崩效應的第三種方式請求合併的實現

1.請求合併的場景

沒有合併的場景中,對於provider的調用會非常的頻繁,容易造成處理不過來的情況
在這裏插入圖片描述
合併請求的場景
在這裏插入圖片描述

2.什麼情況下使用請求合併

在微服務架構中,我們將一個項目拆分成很多個獨立的模塊,這些獨立的模塊通過遠程調用來互相配合工作,但是,在高併發情況下,通信次數的增加會導致總的通信時間增加,同時,線程池的資源也是有限的,高併發環境會導致有大量的線程處於等待狀態,進而導致響應延遲,爲了解決這些問題,我們需要來了解 Hystrix 的請求合併。

3.請求合併的缺點

設置請求合併之後,本來一個請求可能 5ms 就搞定了,但是現在必須再等 10ms 看看還有沒有其他的請求一起的,這樣一個請求的耗時就從 5ms 增加到 15ms 了,不過,如果我們要發起的命令本身就是一個高延遲的命令,那麼這個時候就可以使用請求合併了,因爲這個時候時間窗的時間消耗就顯得微不足道了,另外高併發也是請求合併的一個非常重要的場景。

4.請求合併案例

4.1.添加依賴

將Hystrix的依賴添加即可

<!--服務熔斷組件-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
4.2.啓動類修改

啓動類中開啓@EnableCircuitBreaker註解。

/**
 * @author bruceliu
 * @create 2019-10-15 14:36
 * @description
 */
@SpringBootApplication
@EnableDiscoveryClient // 開啓EurekaClient功能
@EnableFeignClients // 開啓Feign功能
@EnableCircuitBreaker//對hystrixR熔斷機制的支持
public class ConsumerApp {

    public static void main(String[] args) {
        System.out.println("服務的調用端啓動8082.....");
        SpringApplication.run(ConsumerApp.class,args);
    }
}
4.3.業務層修改

具體代碼如下,要注意的是getUser方法的返回類型必須是Future類型,batchMethod 屬性指定的是請求合併後要執行的方法的名稱。

package com.bruceliu.api;

import com.bruceliu.bean.User;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCollapser;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Future;

/**
 * @BelongsProject: springcloud0310
 * @BelongsPackage: com.bruceliu.api
 * @Author: bruceliu
 * @QQ:1241488705
 * @CreateTime: 2020-03-11 20:00
 * @Description: TODO
 */
@Service
public class UserService {

    /**
     * consumer 的 controller 調用的方法
     * 該方法返回值必須要返回Future 類型
     * 利用 hystrix 合併請求
     */
    @HystrixCollapser(
            batchMethod = "batchUser", scope = com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL, collapserProperties = {
            //請求時間間隔在 20ms 之內的請求會被合併爲一個請求,默認爲 10ms
            @HystrixProperty(name = "timerDelayInMilliseconds", value = "20"),
            //設置觸發批處理執行之前,在批處理中允許的最大請求數。
            @HystrixProperty(name = "maxRequestsInBatch", value = "200"),
    })
    public Future<User> getUser(Integer id) {
        System.out.println("-----------id-------:" + id);
        return null;
    }

    /**
     * 調用 Provider 服務的方法
     *
     * @param ids
     * @return
     */
    @HystrixCommand
    public List<User> batchUser(List<Integer> ids) {
        for (Integer id : ids) {
            System.out.println(id);
        }
        //假設是調用 provider 服務後返回的 list
        List<User> list = new ArrayList<>();
        list.add(new User(1, "張三", 18));
        list.add(new User(2, "李四", 19));
        list.add(new User(3, "王五", 20));
        list.add(new User(4, "小明", 21));
        list.add(new User(100, "小張", 22));
        System.out.println("***********************");
        return list;
    }
}

4.4.控制器調用

調用service的方法,模擬多次請求的場景,具體如下

@RestController
public class UserController {

    @Autowired
    private UserService userService;
    @RequestMapping("/consumer")
    public void getUsers() throws Exception{

        Future<User> f1 = this.userService.getUser(1);
        Future<User> f2 = this.userService.getUser(2);
        Future<User> f3 = this.userService.getUser(3);
        System.out.println(f1.get().toString());
        System.out.println(f2.get().toString());
        System.out.println(f3.get().toString());
    }
}
4.5.測試

啓動服務後訪問,查看控制檯效果,發現雖然請求了多次service,但是batchUser方法只執行了一次
在這裏插入圖片描述
只執行了一次,獲取了三個結果!

4.5.控制器調用
參數 作用/默認值 備註
@HystrixCollapser
batchMethod 合併請求的方法
scope 請求方式/REQUEST 請求方式分爲REQUEST和GLOBAL。REQUEST範圍只對一個request請求內的多次服務請求進行合併 GLOBAL是多單應用中的所有線程的請求中的多次服務請求合併
timerDelayInMilliseconds 請求時間間隔在10ms之內的請求會被合併爲一個請求/10ms 建議儘量設置的小一點,如果併發量不大的話,其實也沒有必要使用HystrixCollapser來處理
maxRequestsInBatch 設置觸發批處理執行之前,在批處理中允許的最大請求數/Integer.MAX_VALUE
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章