Rest Template Test

最近后端用到 Http 请求,由于对性能有较高要求,然后又要解耦,顾使用 RestTemplate,然而在各种实现当中,哪种性能最好呢? 写了个单元测试,做个简单的测试。

public class RestTemplateTest {
    int count = 10; // 执行次数
    String ua = ""; 
    // 此 UA okHttp3 会报异常。
//    String ua = " jdapp;android;8.5.12;10;869939042546399-24da3300f7a2;network/4g;model/VCE-AL00;addressid/0;aid/3ef52e7359958728;oaid/7f77ff9b-757e-2241-ff3b-bdfd6a6ff8ed;osVer/29;appBuild/73078;psn/869939042546399-24da3300f7a2|173;psq/14;uid/869939042546399-24da3300f7a2;adk/;ads/;pap/JA2015_311210|8.5.12|ANDROID 10;osv/10;pv/172.17;jdv/0|kong|t_1000170135|tuiguang|notset|1589769462067|1589769462;ref/https://airtickets.jd.com/?fromtype=search&depCity=å\u008C\u0097京&arrCity=ä¸\u008Aæµ·&lineType=OW&lng=104.165616&lat=30.83199&sid=3463647525f7fdc6c376e6351ab834aw&un_area=22_1930_49314_49351;partner/huawei;apprpd/Search_ProductList;Mozilla/5.0 (Linux; Android 10; VCE-AL00 Build/HUAWEIVCE-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/6.2 TBS/045136 Mobile Safari/537.36";

    String url = "https://www.baidu.com";
//    String url = "https://www.jd.com";

    @Test
    public void test() throws SSLException {

        RestTemplate httpClient = new RestTemplate();

        for (int i = 0; i < 3; i++) {
            httpClient.setRequestFactory(simple());
            this.request(httpClient);

            httpClient.setRequestFactory(okHttpClient3());
            this.request(httpClient);

            httpClient.setRequestFactory(apcheHttp());
            this.request(httpClient);

            httpClient.setRequestFactory(apcheHttpAsync());
            this.request(httpClient);


            httpClient.setRequestFactory(netty());
            this.request(httpClient);

//            httpClient.setRequestFactory(okHttpClient());
//            this.request(httpClient);

            System.out.println("--------------------------------");
        }
    }


    private void request(RestTemplate httpclient) {
        System.out.println("");
        System.out.println(httpclient.getRequestFactory().getClass().getSimpleName() + "--");
        long start, end;


        long total = 0, max = Long.MIN_VALUE, min = Long.MAX_VALUE;


        for (int i = 0; i < count; i++) {
            start = System.nanoTime();

            RequestEntity input = RequestEntity.get(URI.create(url + "/?ts=" + i)).header(HttpHeaders.USER_AGENT, ua).build();

            ResponseEntity<String> output = httpclient.exchange(input, String.class);
            String body = output.getBody(); // 确保进行了 content read

            end = System.nanoTime() - start;

            if (end > max) {
                max = end;
            }
            if (end < min) {
                min = end;
            }
            total += end;

        }
        System.out.printf("共执行 %s 次," +
                        "总耗时:%s ms(%s ns)," +
                        "平均耗时:%s ms(%s ns)," +
                        "最长耗时:%s ms(%s ns)," +
                        "最短耗时:%s ms(%s ns) \n",
                count,
                TimeUnit.NANOSECONDS.toMillis(total), total,
                TimeUnit.NANOSECONDS.toMillis(total / count), total / count,
                TimeUnit.NANOSECONDS.toMillis(max), max,
                TimeUnit.NANOSECONDS.toMillis(min), min,
                ""
        );

    }


    private ClientHttpRequestFactory simple() {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setConnectTimeout(500);
        return factory;
    }

    private ClientHttpRequestFactory okHttpClient3() {
        OkHttp3ClientHttpRequestFactory factory = new OkHttp3ClientHttpRequestFactory();
        factory.setConnectTimeout(500);
        return factory;
    }

    private ClientHttpRequestFactory okHttpClient() {
        OkHttpClientHttpRequestFactory factory = new OkHttpClientHttpRequestFactory();
        factory.setConnectTimeout(500);
        return factory;
    }

    private ClientHttpRequestFactory apcheHttp() {
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        factory.setConnectTimeout(500);
        return factory;
    }

    private ClientHttpRequestFactory apcheHttpAsync() {
        HttpComponentsAsyncClientHttpRequestFactory factory = new HttpComponentsAsyncClientHttpRequestFactory();
        factory.setConnectTimeout(500);
        return factory;
    }

    private ClientHttpRequestFactory netty() throws SSLException {
        Netty4ClientHttpRequestFactory factory = new Netty4ClientHttpRequestFactory();
        factory.setConnectTimeout(500);
        factory.setSslContext(SslContextBuilder.forClient().build());
        return factory;
    }

}

需要注意的是,okHttp 新老版本之间存在 Jar 包冲突问题,顾不能同时进行测试。

以下为测试结果

SimpleClientHttpRequestFactory--
共执行 10 次,总耗时:542 ms(542633909 ns),平均耗时:54 ms(54263390 ns),最长耗时:477 ms(477163566 ns),最短耗时:5 ms(5635716 ns) 

OkHttp3ClientHttpRequestFactory--
共执行 10 次,总耗时:114 ms(114705228 ns),平均耗时:11 ms(11470522 ns),最长耗时:60 ms(60509177 ns),最短耗时:5 ms(5273339 ns) 

HttpComponentsClientHttpRequestFactory--
共执行 10 次,总耗时:195 ms(195219070 ns),平均耗时:19 ms(19521907 ns),最长耗时:134 ms(134212594 ns),最短耗时:5 ms(5474009 ns) 

HttpComponentsAsyncClientHttpRequestFactory--
共执行 10 次,总耗时:74 ms(74646056 ns),平均耗时:7 ms(7464605 ns),最长耗时:18 ms(18346667 ns),最短耗时:5 ms(5253975 ns) 

Netty4ClientHttpRequestFactory--
共执行 10 次,总耗时:455 ms(455278498 ns),平均耗时:45 ms(45527849 ns),最长耗时:190 ms(190412009 ns),最短耗时:26 ms(26410596 ns) 
--------------------------------

SimpleClientHttpRequestFactory--
共执行 10 次,总耗时:60 ms(60364356 ns),平均耗时:6 ms(6036435 ns),最长耗时:6 ms(6995622 ns),最短耗时:5 ms(5125890 ns) 

OkHttp3ClientHttpRequestFactory--
共执行 10 次,总耗时:140 ms(140261580 ns),平均耗时:14 ms(14026158 ns),最长耗时:32 ms(32825435 ns),最短耗时:5 ms(5473792 ns) 

HttpComponentsClientHttpRequestFactory--
共执行 10 次,总耗时:89 ms(89699477 ns),平均耗时:8 ms(8969947 ns),最长耗时:22 ms(22417619 ns),最短耗时:6 ms(6006689 ns) 

HttpComponentsAsyncClientHttpRequestFactory--
共执行 10 次,总耗时:93 ms(93985978 ns),平均耗时:9 ms(9398597 ns),最长耗时:21 ms(21574814 ns),最短耗时:5 ms(5969015 ns) 

Netty4ClientHttpRequestFactory--
共执行 10 次,总耗时:382 ms(382709684 ns),平均耗时:38 ms(38270968 ns),最长耗时:64 ms(64371437 ns),最短耗时:28 ms(28696667 ns) 
--------------------------------

SimpleClientHttpRequestFactory--
共执行 10 次,总耗时:76 ms(76566207 ns),平均耗时:7 ms(7656620 ns),最长耗时:11 ms(11322061 ns),最短耗时:5 ms(5739523 ns) 

OkHttp3ClientHttpRequestFactory--
共执行 10 次,总耗时:102 ms(102434885 ns),平均耗时:10 ms(10243488 ns),最长耗时:40 ms(40112993 ns),最短耗时:5 ms(5810617 ns) 

HttpComponentsClientHttpRequestFactory--
共执行 10 次,总耗时:90 ms(90013417 ns),平均耗时:9 ms(9001341 ns),最长耗时:21 ms(21347728 ns),最短耗时:6 ms(6392409 ns) 

HttpComponentsAsyncClientHttpRequestFactory--
共执行 10 次,总耗时:89 ms(89806396 ns),平均耗时:8 ms(8980639 ns),最长耗时:23 ms(23757876 ns),最短耗时:5 ms(5845881 ns) 

Netty4ClientHttpRequestFactory--
共执行 10 次,总耗时:371 ms(371003694 ns),平均耗时:37 ms(37100369 ns),最长耗时:47 ms(47806368 ns),最短耗时:30 ms(30156193 ns) 
--------------------------------

综上 HttpComponentsAsyncClientHttpRequestFactory 性能其实是最好的,SimpleClientHttpRequestFactory 不是很稳定。

comments powered by Disqus