最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java實(shí)用型-高并發(fā)下RestTemplate的正確使用說(shuō)明

 更新時(shí)間:2021年10月23日 11:57:59   作者:我們都愛(ài)松松吧  
這篇文章主要介紹了java實(shí)用型-高并發(fā)下RestTemplate的正確使用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

前言

如果java項(xiàng)目里有調(diào)用第三方的http接口,我們可以使用RestTemplate去遠(yuǎn)程訪(fǎng)問(wèn)。也支持配置連接超時(shí)和響應(yīng)超時(shí),還可以配置各種長(zhǎng)連接策略,也可以支持長(zhǎng)連接預(yù)熱,在高并發(fā)下,合理的配置使用能夠有效提高第三方接口響應(yīng)時(shí)間。

一、RestTemplate是什么?

RestTemplate是Spring提供的用于訪(fǎng)問(wèn)Rest服務(wù)的客戶(hù)端,RestTemplate提供了多種便捷訪(fǎng)問(wèn)遠(yuǎn)程Http服務(wù)的方法,能夠大大提高客戶(hù)端的編寫(xiě)效率。

二、如何使用

1.創(chuàng)建一個(gè)bean

以下代碼配置比較簡(jiǎn)單,只設(shè)置了連接超時(shí)時(shí)間和響應(yīng)超時(shí)時(shí)間

/**
 * restTemplate配置
 *
 * @author Songsong
 * @date 2020-08-17 15:09
 */
@Configuration
public class RestTemplateConfiguration {
    @Bean(name = "restTemplate")
    public RestTemplate restTemplate() {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        //設(shè)置連接超時(shí)時(shí)間1s
        factory.setConnectTimeout(1000);
        //設(shè)置讀取時(shí)間1s
        factory.setReadTimeout(1000);
        return new RestTemplate(factory);
    }
}

2.使用步驟

在需要使用的地方使用@Resource或者@Autowired注入進(jìn)來(lái)

@Resource
private RestTemplate restTemplate;

然后我們平常調(diào)用第三方的接口是get方式和post方式,restTemplate提供getForEntity和postForEntity方法支持這兩種方式,直接調(diào)用即可,源碼分別如下:

getForEntity方法:

 public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables) throws RestClientException {
        RequestCallback requestCallback = this.acceptHeaderRequestCallback(responseType);
        ResponseExtractor<ResponseEntity<T>> responseExtractor = this.responseEntityExtractor(responseType);
        return (ResponseEntity)nonNull(this.execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables));
    }

postForEntity方法:

public <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables) throws RestClientException {
        RequestCallback requestCallback = this.httpEntityCallback(request, responseType);
        ResponseExtractor<ResponseEntity<T>> responseExtractor = this.responseEntityExtractor(responseType);
        return (ResponseEntity)nonNull(this.execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables));
    }

源碼中還有很多以上兩種其他的重載方法,以上是作者平常項(xiàng)目中用的最多的一種,參數(shù)有url(第三方http鏈接)、request是請(qǐng)求所需的參數(shù),responseType是返回類(lèi)型里的泛型。

只需要解析返回的參數(shù)即可。

三、高并發(fā)下的RestTemplate使用

在平常的開(kāi)發(fā)中,以上簡(jiǎn)單的配置可能就夠用了,但是在高并發(fā)下,對(duì)接口響應(yīng)時(shí)間要求很高,所以我們需要盡量的提高第三方接口響應(yīng)時(shí)間。在RestTemplate中可以使用httpClient長(zhǎng)連接,關(guān)于httpClient長(zhǎng)連接的介紹我們可以參考:HTTPclient保持長(zhǎng)連接

以下代碼我們?cè)O(shè)置了長(zhǎng)連接預(yù)熱的功能,以及路由并發(fā)數(shù):

@Slf4j
@Configuration
public class RestTemplateConfiguration {
    @Bean(name = "restTemplate")
    public RestTemplate restTemplate() {
       return getRestTemplate(3, "https://www.baidu.com/......");
    }
    private RestTemplate getRestTemplate(int maxTotal, String preHeatUrl) {
        HttpComponentsClientHttpRequestFactory httpRequestFactory = httpComponentsClientHttpRequestFactory(maxTotal);
        RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
        //解決首次預(yù)熱耗時(shí)長(zhǎng)
        if (StringUtils.isNotEmpty(preHeatUrl)) {
            try {
                restTemplate.postForEntity(preHeatUrl, "", String.class);
            } catch (Exception e) {
                log.error("preHeat url error:{}", e.getMessage());
            }
        }
        return restTemplate;
    }
    /**
     * ClientHttpRequestFactory接口的另一種實(shí)現(xiàn)方式(推薦使用),即:
     * HttpComponentsClientHttpRequestFactory:底層使用Httpclient連接池的方式創(chuàng)建Http連接請(qǐng)求
     *
     * @return
     */
    private HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory(int maxTotal) {
        //Httpclient連接池,長(zhǎng)連接保持時(shí)間
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(1, TimeUnit.HOURS);
        //設(shè)置總連接數(shù)
        connectionManager.setMaxTotal(maxTotal);
        //設(shè)置同路由的并發(fā)數(shù)
        connectionManager.setDefaultMaxPerRoute(maxTotal);
        //設(shè)置header
        List<Header> headers = new ArrayList<Header>();
        headers.add(new BasicHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.04"));
        headers.add(new BasicHeader("Accept-Encoding", "gzip, deflate"));
        headers.add(new BasicHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3"));
        headers.add(new BasicHeader("Connection", "keep-alive"));
        //創(chuàng)建HttpClient
        HttpClient httpClient = HttpClientBuilder.create()
                .setConnectionManager(connectionManager)
                .setDefaultHeaders(headers)
                .setRetryHandler(new DefaultHttpRequestRetryHandler(3, true)) //設(shè)置重試次數(shù)
                .setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()) //設(shè)置保持長(zhǎng)連接
                .build();
        //創(chuàng)建HttpComponentsClientHttpRequestFactory實(shí)例
        HttpComponentsClientHttpRequestFactory requestFactory =
                new HttpComponentsClientHttpRequestFactory(httpClient);
        //設(shè)置客戶(hù)端和服務(wù)端建立連接的超時(shí)時(shí)間
        requestFactory.setConnectTimeout(10000);
        //設(shè)置客戶(hù)端從服務(wù)端讀取數(shù)據(jù)的超時(shí)時(shí)間
        requestFactory.setReadTimeout(5000);
        //設(shè)置從連接池獲取連接的超時(shí)時(shí)間,不宜過(guò)長(zhǎng)
        requestFactory.setConnectionRequestTimeout(2000);
        //緩沖請(qǐng)求數(shù)據(jù),默認(rèn)為true。通過(guò)POST或者PUT大量發(fā)送數(shù)據(jù)時(shí),建議將此更改為false,以免耗盡內(nèi)存
        requestFactory.setBufferRequestBody(false);
        return requestFactory;
    }

1.設(shè)置預(yù)熱功能

我們可以看到,在getRestTemplate方法中,

return restTemplate;

之前先請(qǐng)求了一次,也就是說(shuō)在需要使用第三方接口調(diào)用的service層注入的時(shí)候,提前先調(diào)用了一次,根據(jù)長(zhǎng)連接的特性,一般第一次連接的時(shí)間較長(zhǎng),使用完之后,這個(gè)連接并不會(huì)馬上回收掉,在一定的時(shí)間還是存活狀態(tài),所以在高并發(fā)下,經(jīng)過(guò)預(yù)熱后的接口響應(yīng)時(shí)間會(huì)大幅提高。

2.合理設(shè)置maxtotal數(shù)量

我們可以看到以下代碼

//設(shè)置總連接數(shù)
 connectionManager.setMaxTotal(maxTotal);

我們可以看到這一行,maxTotal是設(shè)置總連接數(shù),這個(gè)設(shè)置需要根據(jù)接口的響應(yīng)時(shí)間以及需要支持的QPS來(lái)設(shè)置,比如接口響應(yīng)時(shí)間是100ms,需要支持的QPS為5000,也就是5000/s,那么一個(gè)長(zhǎng)連接1s就是能夠處理10個(gè)請(qǐng)求,那么總共需要maxTotal為500個(gè),這個(gè)就是設(shè)置的大概數(shù)量,但是有時(shí)候QPS不是那么穩(wěn)定,所以具體設(shè)置多少得視具體情況而定。

RestTemplate深度解析可以參考:RestTemplate深度解析

總結(jié)

以上就是關(guān)于RestTemplate的使用介紹,其實(shí)平常使用下還好,看不出來(lái)什么問(wèn)題,但是一旦高并發(fā)情況下,預(yù)熱和設(shè)置總連接數(shù)還有并發(fā)數(shù)以及其他的相關(guān)配置就顯得尤為重要,具體的配置還是得經(jīng)過(guò)實(shí)驗(yàn)才能得知,沒(méi)有最好,只有更好,以上就是作者在高并發(fā)活動(dòng)中的一些實(shí)際經(jīng)歷,希望可以幫助到你!?。∪缬绣e(cuò)誤或未考慮完全的地方,望不吝賜教,也希望大家多多支持腳本之家!

相關(guān)文章

最新評(píng)論

噶尔县| 临夏市| 洛隆县| 灌南县| 乌鲁木齐市| 张家口市| 油尖旺区| 余干县| 雅安市| 定远县| 宁都县| 广水市| 永靖县| 长治市| 当涂县| 海城市| 民丰县| 新闻| 宜兰县| 靖西县| 封开县| 建始县| 武川县| 灵寿县| 临洮县| 绥滨县| 石家庄市| 汾西县| 临朐县| 松原市| 偃师市| 金门县| 吉林省| 京山县| 溧水县| 伽师县| 廉江市| 榆树市| 监利县| 白山市| 信丰县|