一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - RestTemplate集成Ribbbon的示例代碼

RestTemplate集成Ribbbon的示例代碼

2021-05-23 14:49楊輝 Java教程

這篇文章主要介紹了RestTemplate集成Ribbbon的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

上一篇文章我們分析了ribbon的核心原理,接下來我們來看看springcloud是如何集成ribbon的,不同的springcloud的組件(feign,zuul,resttemplate)集成ribbon有所不同,這篇文章先來看看resttemplate。

resttemplate的類圖如下

RestTemplate集成Ribbbon的示例代碼

  • httpaccessor主要根據(jù)clienthttprequestfactory創(chuàng)建clienthttprequest
  • interceptinghttpaccessor擴(kuò)展了httpaccessor,創(chuàng)建攔截的interceptingclienthttprequest,這里會(huì)設(shè)置攔截器clienthttprequestinterceptor,這是集成ribbon的核心,當(dāng)resttemplate發(fā)起http請(qǐng)求調(diào)用的時(shí)候,會(huì)先經(jīng)過攔截器,然后才真正發(fā)起http請(qǐng)求。

攔截器clienthttprequestinterceptor是如何被設(shè)置的呢?在loadbalancerautoconfiguration類中,有如下代碼:

?
1
2
3
@loadbalanced
@autowired(required = false)
private list<resttemplate> resttemplates = collections.emptylist();

只要加入注解@loadbalancedresttemplate會(huì)被注入,在沒有引入spring retry組件的時(shí)候,加載如下配置:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@configuration
@conditionalonmissingclass("org.springframework.retry.support.retrytemplate")
static class loadbalancerinterceptorconfig {
  @bean
  public loadbalancerinterceptor ribboninterceptor(
    loadbalancerclient loadbalancerclient,
    loadbalancerrequestfactory requestfactory) {
    return new loadbalancerinterceptor(loadbalancerclient, requestfactory);
  }
 
  @bean
  @conditionalonmissingbean
  public resttemplatecustomizer resttemplatecustomizer(
    final loadbalancerinterceptor loadbalancerinterceptor) {
    return new resttemplatecustomizer() {
      @override
      public void customize(resttemplate resttemplate) {
        list<clienthttprequestinterceptor> list = new arraylist<>(
          resttemplate.getinterceptors());
        list.add(loadbalancerinterceptor);
        resttemplate.setinterceptors(list);
      }
    };
  }
}

這樣resttemplate就被設(shè)置了loadbalancerinterceptor,下面來看看整個(gè)調(diào)用過程

RestTemplate集成Ribbbon的示例代碼

整個(gè)過程有點(diǎn)復(fù)雜,核心就是經(jīng)過攔截器loadbalancerinterceptor,通過ribbonloadbalancerclient發(fā)起負(fù)載均衡調(diào)用。ribbonloadbalancerclienti組合了loadbalancer,所以具備了負(fù)載均衡的能力,也就是我們?cè)谏弦黄恼陆庾x的ribbon原理。

圖中我們沒有畫出真正發(fā)起http請(qǐng)求的過程,其默認(rèn)是由simpleclienthttprequestfactory創(chuàng)建,clienthttprequestfactory的類圖如下:

RestTemplate集成Ribbbon的示例代碼

從調(diào)用時(shí)序圖上我們看到,開始我們調(diào)用的是interceptingclienthttprequestfactory來獲取interceptingclienthttprequest,它們通過組合的方式集成了clienthttprequestfactory和攔截器,interceptingclienthttprequest發(fā)起調(diào)用的時(shí)候委托了其內(nèi)部類interceptingrequestexecution去處理,核心邏輯:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@override
public clienthttpresponse execute(httprequest request, byte[] body) throws ioexception {
  if (this.iterator.hasnext()) {
    clienthttprequestinterceptor nextinterceptor = this.iterator.next();
    return nextinterceptor.intercept(request, body, this);
  }else {
    clienthttprequest delegate = requestfactory.createrequest(request.geturi(), request.getmethod());
    for (map.entry<string, list<string>> entry : request.getheaders().entryset()) {
      list<string> values = entry.getvalue();
      for (string value : values) {
        delegate.getheaders().add(entry.getkey(), value);
      }
    }
    if (body.length > 0) {
      streamutils.copy(body, delegate.getbody());
    }
    return delegate.execute();
  }
}

首先會(huì)先取出攔截器集合的第一個(gè)執(zhí)行,當(dāng)攔截器執(zhí)行完成后,會(huì)回調(diào)回來,執(zhí)行else的代碼,真正發(fā)起http請(qǐng)求,主要有兩種方式實(shí)現(xiàn)clienthttprequestfactory接口:

  • 一種是simpleclienthttprequestfactory,使用j2se提供的方式(既java.net包提供的方式)創(chuàng)建底層的http請(qǐng)求連接
  • 一種方式是使用httpcomponentsclienthttprequestfactory方式,底層使用httpclient訪問遠(yuǎn)程的http服務(wù),使用httpclient可以配置連接池和證書等信息。

 resttemplate默認(rèn)是使用simpleclienthttprequestfactory,內(nèi)部是調(diào)用jdk的httpconnection,默認(rèn)超時(shí)為-1,可以這樣設(shè)置超時(shí)時(shí)間:

?
1
2
3
4
5
6
7
8
@bean
@loadbalanced
public resttemplate resttemplate() {
  simpleclienthttprequestfactory factory = new simpleclienthttprequestfactory();
  factory.setconnecttimeout(1000 * 2);//連接超時(shí)時(shí)間
  factory.setreadtimeout(1000 * 1);//讀超時(shí)時(shí)間
  return new resttemplate(factory);
}

使用httpcomponentsclienthttprequestfactory方式可以使用連接池(推薦) ,還可以設(shè)置重試策略(具體沒有研究過)

如果想開啟重試機(jī)制,我們可以引入spring的retry組件

?
1
2
3
4
5
<dependency>
  <groupid>org.springframework.retry</groupid>
  <artifactid>spring-retry</artifactid>
  <version>版本號(hào)</version>
</dependency>

這樣springcloud-ribbon就會(huì)加重如下配置:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
@configuration
@conditionalonclass(retrytemplate.class)
public static class retryautoconfiguration {
  @bean
  public retrytemplate retrytemplate() {
    retrytemplate template = new retrytemplate();
    template.setthrowlastexceptiononexhausted(true);
    return template;
  }
 
  @bean
  @conditionalonmissingbean
  public loadbalancedretrypolicyfactory loadbalancedretrypolicyfactory() {
    return new loadbalancedretrypolicyfactory.neverretryfactory();
  }
}
 
@configuration
@conditionalonclass(retrytemplate.class)
public static class retryinterceptorautoconfiguration {
  @bean
  @conditionalonmissingbean
  public retryloadbalancerinterceptor ribboninterceptor(
    loadbalancerclient loadbalancerclient, loadbalancerretryproperties properties,
    loadbalancedretrypolicyfactory lbretrypolicyfactory,
    loadbalancerrequestfactory requestfactory) {
    return new retryloadbalancerinterceptor(loadbalancerclient, properties,
                        lbretrypolicyfactory, requestfactory);
  }
 
  @bean
  @conditionalonmissingbean
  public resttemplatecustomizer resttemplatecustomizer(
    final retryloadbalancerinterceptor loadbalancerinterceptor) {
    return new resttemplatecustomizer() {
      @override
      public void customize(resttemplate resttemplate) {
        list<clienthttprequestinterceptor> list = new arraylist<>(
          resttemplate.getinterceptors());
        list.add(loadbalancerinterceptor);
        resttemplate.setinterceptors(list);
      }
    };
  }
}
?
1
2
3
4
5
6
@bean
@conditionalonclass(name = "org.springframework.retry.support.retrytemplate")
@conditionalonmissingbean
  public loadbalancedretrypolicyfactory loadbalancedretrypolicyfactory(springclientfactory clientfactory) {
  return new ribbonloadbalancedretrypolicyfactory(clientfactory);
}

攔截器替換成retryloadbalancerinterceptor了,這里集成了retry組件retrytemplate。重試策略由retryhandler接口來配置,默認(rèn)實(shí)現(xiàn)類defaultloadbalancerretryhandler,如下為默認(rèn)的配置參數(shù)

?
1
2
3
4
5
6
7
8
#最大的重試次數(shù)
ribbon.maxautoretries=0
#最大重試server的個(gè)數(shù)
ribbon.maxautoretriesnextserver=1
#是否開啟任何異常都重試(默認(rèn)在get請(qǐng)求下會(huì)重試,其他情況不會(huì)重試,除非設(shè)置為true
ribbon.oktoretryonalloperations=false
#指定重試的http狀態(tài)碼
ribbon.retryablestatuscodes=500,501

以上是對(duì)全局生效,如果加上xxx.ribbon.maxautoretries=1這樣只會(huì)對(duì)某個(gè)ribbon客戶端生效。maxautoretries和maxautoretriesnextserver是配合使用的,最大重試次數(shù)是針對(duì)每一個(gè)server的,如果設(shè)置maxautoretries=1,maxautoretriesnextserver=1這樣觸發(fā)最大重試次數(shù)就是4次。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://segmentfault.com/a/1190000015858648

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本在线一区二区 | 接吻吃胸摸下面啪啪教程 | 欧美高清在线精品一区 | 99久久99久久久精品齐齐鬼色 | 亚洲高清视频在线观看 | 国产自拍专区 | 亚洲国产精品福利片在线观看 | 欧美另类老女人 | 亚飞与亚基国语1080p在线观看 | 久久精品视在线观看2 | 国产精品主播在线 | 女人被男人躁得好爽免费视频 | 国产成人影院一区二区 | 阿 好深 快点 老师受不了 | 久久亚洲成a人片 | 男人视频网站 | 边吃胸边膜下刺激免费男对女 | 91色资源网在线观看 | 日本动漫啪啪动画片mv | 热99这里只有精品 | 91se精品免费观看 | 91尤物在线视频 | 2020最新韩国理论三级0k | 免费观看视频高清在线 | 欧美午夜视频一区二区三区 | 亚洲男人天堂2023 | 色多多在线视频 | 97se亚洲国产综合自在线观看 | china中国小帅gayxnxx | 性做久久久久免费观看 | 亚洲精品久久久WWW游戏好玩 | 国产自在线拍 | 亚洲欧美一区二区三区在线观看 | 精品一区二区三区波多野结衣 | 2020年国产精品午夜福利在线观看 | 男女视频在线观看 | 草莓视频旧版本 | 国产精品一级片 | 无人区在线观看免费视频国语 | 32pao强力打造免费高速高 | 歪歪视频在线播放无遮挡 |