溫馨提示×

溫馨提示×

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

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

java實用型高并發下RestTemplate的正確使用方法是什么

發布時間:2021-10-23 14:45:00 來源:億速云 閱讀:303 作者:iii 欄目:開發技術

這篇文章主要介紹“java實用型高并發下RestTemplate的正確使用方法是什么”,在日常操作中,相信很多人在java實用型高并發下RestTemplate的正確使用方法是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”java實用型高并發下RestTemplate的正確使用方法是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

    前言

    如果java項目里有調用第三方的http接口,我們可以使用RestTemplate去遠程訪問。也支持配置連接超時和響應超時,還可以配置各種長連接策略,也可以支持長連接預熱,在高并發下,合理的配置使用能夠有效提高第三方接口響應時間。

    一、RestTemplate是什么?

    RestTemplate是Spring提供的用于訪問Rest服務的客戶端,RestTemplate提供了多種便捷訪問遠程Http服務的方法,能夠大大提高客戶端的編寫效率。

    二、如何使用

    1.創建一個bean

    以下代碼配置比較簡單,只設置了連接超時時間和響應超時時間

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

    2.使用步驟

    在需要使用的地方使用@Resource或者@Autowired注入進來

    @Resource
    private RestTemplate restTemplate;

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

    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));
        }

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

    只需要解析返回的參數即可。

    三、高并發下的RestTemplate使用

    在平常的開發中,以上簡單的配置可能就夠用了,但是在高并發下,對接口響應時間要求很高,所以我們需要盡量的提高第三方接口響應時間。在RestTemplate中可以使用httpClient長連接,關于httpClient長連接的介紹我們可以參考:HTTPclient保持長連接

    以下代碼我們設置了長連接預熱的功能,以及路由并發數:

    @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);
            //解決首次預熱耗時長
            if (StringUtils.isNotEmpty(preHeatUrl)) {
                try {
                    restTemplate.postForEntity(preHeatUrl, "", String.class);
                } catch (Exception e) {
                    log.error("preHeat url error:{}", e.getMessage());
                }
            }
            return restTemplate;
        }
        /**
         * ClientHttpRequestFactory接口的另一種實現方式(推薦使用),即:
         * HttpComponentsClientHttpRequestFactory:底層使用Httpclient連接池的方式創建Http連接請求
         *
         * @return
         */
        private HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory(int maxTotal) {
            //Httpclient連接池,長連接保持時間
            PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(1, TimeUnit.HOURS);
            //設置總連接數
            connectionManager.setMaxTotal(maxTotal);
            //設置同路由的并發數
            connectionManager.setDefaultMaxPerRoute(maxTotal);
            //設置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"));
            //創建HttpClient
            HttpClient httpClient = HttpClientBuilder.create()
                    .setConnectionManager(connectionManager)
                    .setDefaultHeaders(headers)
                    .setRetryHandler(new DefaultHttpRequestRetryHandler(3, true)) //設置重試次數
                    .setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()) //設置保持長連接
                    .build();
            //創建HttpComponentsClientHttpRequestFactory實例
            HttpComponentsClientHttpRequestFactory requestFactory =
                    new HttpComponentsClientHttpRequestFactory(httpClient);
            //設置客戶端和服務端建立連接的超時時間
            requestFactory.setConnectTimeout(10000);
            //設置客戶端從服務端讀取數據的超時時間
            requestFactory.setReadTimeout(5000);
            //設置從連接池獲取連接的超時時間,不宜過長
            requestFactory.setConnectionRequestTimeout(2000);
            //緩沖請求數據,默認為true。通過POST或者PUT大量發送數據時,建議將此更改為false,以免耗盡內存
            requestFactory.setBufferRequestBody(false);
            return requestFactory;
        }

    1.設置預熱功能

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

    return restTemplate;

    之前先請求了一次,也就是說在需要使用第三方接口調用的service層注入的時候,提前先調用了一次,根據長連接的特性,一般第一次連接的時間較長,使用完之后,這個連接并不會馬上回收掉,在一定的時間還是存活狀態,所以在高并發下,經過預熱后的接口響應時間會大幅提高。

    2.合理設置maxtotal數量

    我們可以看到以下代碼

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

    我們可以看到這一行,maxTotal是設置總連接數,這個設置需要根據接口的響應時間以及需要支持的QPS來設置,比如接口響應時間是100ms,需要支持的QPS為5000,也就是5000/s,那么一個長連接1s就是能夠處理10個請求,那么總共需要maxTotal為500個,這個就是設置的大概數量,但是有時候QPS不是那么穩定,所以具體設置多少得視具體情況而定。

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

    到此,關于“java實用型高并發下RestTemplate的正確使用方法是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

    向AI問一下細節

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

    AI

    亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女