温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java实用型高并发下RestTemplate的正确使用方法是什么

发布时间:2021-10-23 14:45:00 来源:亿速云 阅读:285 作者: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