中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring Cloud中Hystrix的請求合并方法

發布時間:2021-07-27 15:22:45 來源:億速云 閱讀:187 作者:chen 欄目:大數據

本篇內容介紹了“Spring Cloud中Hystrix的請求合并方法”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

服務提供者接口

我需在在服務提供者中提供兩個接口供服務消費者調用,如下:

@RequestMapping("/getbook6")
public List<Book> book6(String ids) {
    System.out.println("ids>>>>>>>>>>>>>>>>>>>>>" + ids);
    ArrayList<Book> books = new ArrayList<>();
    books.add(new Book("《李自成》", 55, "姚雪垠", "人民文學出版社"));
    books.add(new Book("中國文學簡史", 33, "林庚", "清華大學出版社"));
    books.add(new Book("文學改良芻議", 33, "胡適", "無"));
    books.add(new Book("ids", 22, "helloworld", "haha"));
    return books;
}

@RequestMapping("/getbook6/{id}")
public Book book61(@PathVariable Integer id) {
    Book book = new Book("《李自成》2", 55, "姚雪垠2", "人民文學出版社2");
    return book;
}

第一個接口是一個批處理接口,第二個接口是一個處理單個請求的接口。在批處理接口中,服務消費者傳來的ids參數格式是1,2,3,4…這種格式,正常情況下我們需要根據ids查詢到對應的數據,然后組裝成一個集合返回,我這里為了處理方便,不管什么樣的請求統統都返回一樣的數據集;處理單個請求的接口就比較簡單了,不再贅述。

服務消費者

OK,服務提供者處理好之后,接下來我們來看看服務消費者要怎么處理。

BookService

首先在BookService中添加兩個方法用來調用服務提供者提供的接口,如下:

public Book test8(Long id) {
    return restTemplate.getForObject("http://HELLO-SERVICE/getbook6/{1}", Book.class, id);
}

public List<Book> test9(List<Long> ids) {
    System.out.println("test9---------"+ids+"Thread.currentThread().getName():" + Thread.currentThread().getName());
    Book[] books = restTemplate.getForObject("http://HELLO-SERVICE/getbook6?ids={1}", Book[].class, StringUtils.join(ids, ","));
    return Arrays.asList(books);
}

test8用來調用提供單個id的接口,test9用來調用批處理的接口,在test9中,我將test9執行時所處的線程打印出來,方便我們觀察執行結果,另外,在RestTemplate中,如果返回值是一個集合,我們得先用一個數組接收,然后再轉為集合(或許也有其他辦法,小伙伴們有更好的建議可以提)。

BookBatchCommand

OK,BookService中的方法準備好了后,我們就可以來創建一個BookBatchCommand,這是一個批處理命令,如下:

public class BookBatchCommand extends HystrixCommand<List<Book>> {
    private List<Long> ids;
    private BookService bookService;

    public BookBatchCommand(List<Long> ids, BookService bookService) {
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("CollapsingGroup"))
                .andCommandKey(HystrixCommandKey.Factory.asKey("CollapsingKey")));
        this.ids = ids;
        this.bookService = bookService;
    }

    @Override
    protected List<Book> run() throws Exception {
        return bookService.test9(ids);
    }
}

這個類實際上和我們在上篇博客中介紹的類差不多,都是繼承自HystrixCommand,用來處理合并之后的請求,在run方法中調用BookService中的test9方法。

BookCollapseCommand

接下來我們需要創建BookCollapseCommand繼承自HystrixCollapser來實現請求合并。如下:

public class BookCollapseCommand extends HystrixCollapser<List<Book>, Book, Long> {
    private BookService bookService;
    private Long id;

    public BookCollapseCommand(BookService bookService, Long id) {
        super(Setter.withCollapserKey(HystrixCollapserKey.Factory.asKey("bookCollapseCommand")).andCollapserPropertiesDefaults(HystrixCollapserProperties.Setter().withTimerDelayInMilliseconds(100)));
        this.bookService = bookService;
        this.id = id;
    }

    @Override
    public Long getRequestArgument() {
        return id;
    }

    @Override
    protected HystrixCommand<List<Book>> createCommand(Collection<CollapsedRequest<Book, Long>> collapsedRequests) {
        List<Long> ids = new ArrayList<>(collapsedRequests.size());
        ids.addAll(collapsedRequests.stream().map(CollapsedRequest::getArgument).collect(Collectors.toList()));
        BookBatchCommand bookBatchCommand = new BookBatchCommand(ids, bookService);
        return bookBatchCommand;
    }

    @Override
    protected void mapResponseToRequests(List<Book> batchResponse, Collection<CollapsedRequest<Book, Long>> collapsedRequests) {
        System.out.println("mapResponseToRequests");
        int count = 0;
        for (CollapsedRequest<Book, Long> collapsedRequest : collapsedRequests) {
            Book book = batchResponse.get(count++);
            collapsedRequest.setResponse(book);
        }
    }
}

關于這個類,我說如下幾點:

1.首先在構造方法中,我們設置了請求時間窗為100ms,即請求時間間隔在100ms之內的請求會被合并為一個請求。
2.createCommand方法主要用來合并請求,在這里獲取到各個單個請求的id,將這些單個的id放到一個集合中,然后再創建出一個BookBatchCommand對象,用該對象去發起一個批量請求。
3.mapResponseToRequests方法主要用來為每個請求設置請求結果。該方法的第一個參數batchResponse表示批處理請求的結果,第二個參數collapsedRequests則代表了每一個被合并的請求,然后我們通過遍歷batchResponse來為collapsedRequests設置請求結果。

OK,所有的這些操作完成后,我們就可以來測試啦。

測試

我們在服務消費者端創建訪問接口,來測試合并請求,測試接口如下:

@RequestMapping("/test7")
@ResponseBody
public void test7() throws ExecutionException, InterruptedException {
    HystrixRequestContext context = HystrixRequestContext.initializeContext();
    BookCollapseCommand bc1 = new BookCollapseCommand(bookService, 1l);
    BookCollapseCommand bc2 = new BookCollapseCommand(bookService, 2l);
    BookCollapseCommand bc3 = new BookCollapseCommand(bookService, 3l);
    BookCollapseCommand bc4 = new BookCollapseCommand(bookService, 4l);
    Future<Book> q1 = bc1.queue();
    Future<Book> q2 = bc2.queue();
    Future<Book> q3 = bc3.queue();
    Book book1 = q1.get();
    Book book2 = q2.get();
    Book book3 = q3.get();
    Thread.sleep(3000);
    Future<Book> q4 = bc4.queue();
    Book book4 = q4.get();
    System.out.println("book1>>>"+book1);
    System.out.println("book2>>>"+book2);
    System.out.println("book3>>>"+book3);
    System.out.println("book4>>>"+book4);
    context.close();
}

關于這個測試接口我說如下兩點:

1.首先要初始化HystrixRequestContext
2.創建BookCollapseCommand類的實例來發起請求,先發送3個請求,然后睡眠3秒鐘,再發起1個請求,這樣,前3個請求就會被合并為一個請求,第四個請求因為間隔的時間比較久,所以不會被合并,而是單獨創建一個線程去處理。

OK,我們來看看執行結果,如下:

Spring Cloud中Hystrix的請求合并方法  

通過注解實現請求合并

OK,上面這種請求合并方式寫起來稍微有一點麻煩,我們可以使用注解來更優雅的實現這一功能。首先在BookService中添加兩個方法,如下:

@HystrixCollapser(batchMethod = "test11",collapserProperties = {@HystrixProperty(name ="timerDelayInMilliseconds",value = "100")})
public Future<Book> test10(Long id) {
    return null;
}

@HystrixCommand
public List<Book> test11(List<Long> ids) {
    System.out.println("test9---------"+ids+"Thread.currentThread().getName():" + Thread.currentThread().getName());
    Book[] books = restTemplate.getForObject("http://HELLO-SERVICE/getbook6?ids={1}", Book[].class, StringUtils.join(ids, ","));
    return Arrays.asList(books);
}

在test10方法上添加@HystrixCollapser注解實現請求合并,用batchMethod屬性指明請求合并后的處理方法,collapserProperties屬性指定其他屬性。

OK,在BookService中寫好之后,直接調用就可以了,如下:

@RequestMapping("/test8")
@ResponseBody
public void test8() throws ExecutionException, InterruptedException {
    HystrixRequestContext context = HystrixRequestContext.initializeContext();
    Future<Book> f1 = bookService.test10(1l);
    Future<Book> f2 = bookService.test10(2l);
    Future<Book> f3 = bookService.test10(3l);
    Book b1 = f1.get();
    Book b2 = f2.get();
    Book b3 = f3.get();
    Thread.sleep(3000);
    Future<Book> f4 = bookService.test10(4l);
    Book b4 = f4.get();
    System.out.println("b1>>>"+b1);
    System.out.println("b2>>>"+b2);
    System.out.println("b3>>>"+b3);
    System.out.println("b4>>>"+b4);
    context.close();
}

和前面的一樣,前三個請求會進行合并,第四個請求會單獨執行,OK,執行結果如下:

Spring Cloud中Hystrix的請求合并方法  

總結

請求合并的優點小伙伴們已經看到了,多個請求被合并為一個請求進行一次性處理,可以有效節省網絡帶寬和線程池資源,但是,有優點必然也有缺點,設置請求合并之后,本來一個請求可能5ms就搞定了,但是現在必須再等10ms看看還有沒有其他的請求一起的,這樣一個請求的耗時就從5ms增加到15ms了,不過,如果我們要發起的命令本身就是一個高延遲的命令,那么這個時候就可以使用請求合并了,因為這個時候時間窗的時間消耗就顯得微不足道了,另外高并發也是請求合并的一個非常重要的場景。

“Spring Cloud中Hystrix的請求合并方法”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

上饶市| 厦门市| 桃源县| 西充县| 牡丹江市| 乐亭县| 西丰县| 伊宁市| 平原县| 安泽县| 汕头市| 鹿泉市| 太和县| 惠东县| 肥乡县| 普兰店市| 武定县| 广宗县| 凌源市| 宝兴县| 咸阳市| 个旧市| 仁寿县| 景泰县| 休宁县| 道孚县| 仙桃市| 谢通门县| 南昌县| 海晏县| 那坡县| 瑞丽市| 重庆市| 长宁区| 台中县| 利辛县| 临夏县| 蒲江县| 昆明市| 呼和浩特市| 礼泉县|