jersey2.x集成http连接池过程总结

背景:
最近在用jersey作为代理请求公司后台的restful API取得后端的一些数据,jersey默认是每来一个请求就新发起一个http连接到后台中

一、为什么使用连接池

  • 提高网络传输效率:如果一次请求获取的信息量较少,那么在整个请求周期中,网络上的信息传递将会非常低效.因为建立连接时在网络上传递的数据(用于同步等)远大于我们想要的目标数据

  • 降低延迟:如果不采用连接池,每次连接发起Http请求的时候都会重新建立TCP连接(经历3次握手),用完就会关闭连接(4次挥手),如果采用连接池则减少了这部分时间损耗,别小看这几次握手,本人经过测试发现,基本上3倍的时间延迟

  • 支持更大的并发:如果不采用连接池,每次连接都会打开一个端口,在大并发的情况下系统的端口资源很快就会被用完,导致无法建立新的连接


   但是在网上查阅到关于jersey使用http连接池的资料实在太零散太少了,特别是我用的是jersey1.x版本,目前查到有使用的http连接池的都是jersey2.x版本的,所以只能硬着头皮把jersey升级了.关键是1.x2.x的API以及使用也有很大区别,导致过程中遇到了不少坑,具体区别可参考这个链接,其中要特别注意的是:扫描resource时jersey1.x使用的是sun的com.sun.jersey.config.property.packages,jersey2.x使用的是glassfish的jersey.config.server.provider.packages.所以要记得在server启动程序中修改扫描的类型参数

  本篇文章主要是对jersey2.x使用http连接池进行集成过程的一个知识整理,同时也希望帮助到有同样需求的人

二、依赖准备

  个人是使用maven管理自己的工程,所以下面贴出需要用到的依赖

 <properties>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        <java.version>1.7java.version>
        <jersey.version>2.23jersey.version>
        <jetty.version>9.2.5.v20141112jetty.version>

properties>
        <dependency>
            <groupId>org.glassfish.jersey.coregroupId>
            <artifactId>jersey-serverartifactId>
            <version>${jersey.version}version>
        dependency>
        <dependency>
            <groupId>org.glassfish.jersey.coregroupId>
            <artifactId>jersey-clientartifactId>
            <version>${jersey.version}version>
        dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containersgroupId>
            <artifactId>jersey-container-grizzly2-httpartifactId>
            <version>${jersey.version}version>
        dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containersgroupId>
            <artifactId>jersey-container-servlet-coreartifactId>
            <version>${jersey.version}version>
        dependency>
        <dependency>
            <groupId>org.glassfish.jersey.mediagroupId>
            <artifactId>jersey-media-json-jacksonartifactId>
            <version>${jersey.version}version>
        dependency>  
         

        <dependency>
            <groupId>org.glassfish.jersey.connectorsgroupId>
            <artifactId>jersey-apache-connectorartifactId>
            <version>${jersey.version}version>
        dependency> 
        

        
        

注意,过程中产生java.lang.NoSuchMethodsExcepiton异常的根本原因一般有两个:
- 缺少相应的jar包,也就是没有依赖
- 某些jar文件重复或冲突,导致方法寻址错误(本例就属于这个原因)

三、代码

package io.sugo.http.jersy;

import org.apache.http.config.SocketConfig;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.glassfish.jersey.apache.connector.ApacheClientProperties;
import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientProperties;
import org.glassfish.jersey.jackson.JacksonFeature;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;

/**
 * Created by chenyuzhi on 17-11-4.
 */
public class JersyClientFactory {
    private static final int HTTP_MAX_CONNECTION = 200;
    private static final int DEFAULT_MAX_PERROUTE = 20;
    private static int CONNECT_TIMEOUT = 5000;
    private static int READ_TIMEOUT = 5000;
    private static int POOLCM_SOCKET_TIMEOUT = 3000;

    public static Client create(){
        ClientConfig clientConfig = new ClientConfig();
        clientConfig.property(ClientProperties.CONNECT_TIMEOUT,CONNECT_TIMEOUT);   
        clientConfig.property(ClientProperties.READ_TIMEOUT,READ_TIMEOUT); 

        PoolingHttpClientConnectionManager pcm = new PoolingHttpClientConnectionManager();
        pcm.setDefaultSocketConfig(
                SocketConfig.custom().
                setSoTimeout(POOLCM_SOCKET_TIMEOUT).
                build());               
        pcm.setMaxTotal(HTTP_MAX_CONNECTION);
        pcm.setDefaultMaxPerRoute(DEFAULT_MAX_PERROUTE);

        clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, pcm);

        clientConfig.connectorProvider(new ApacheConnectorProvider());
        clientConfig.register(JacksonFeature.class);

        Client client = ClientBuilder.newClient(clientConfig);
        return client;

    }

}
  • 关键参数说明
参数 意义
CONNECT_TIMEOUT 设置jerseyClient建立http连接的超时时间
READ_TIMEOUT http连接建立后,jersey从服务端读取数据的超时时间
POOLCM_SOCKET_TIMEOUT 设置连接池建立socket连接的超时时间
HTTP_MAX_CONNECTION 设置连接池最大连接数
DEFAULT_MAX_PERROUTE 每个路由最大连接数(这对最大连接数的一个细分和优化)

在集成的过程中,对于超时的设置,不同版本的httpClientPoolingHttpClientConnectionManager都会有不同的设置参数和设置方式,而且网上的资料查到的超时参数设置往往比较杂乱又不全面,这里的参数设置是参考这里的文章进行设置的,里面比较细致的提到了各个超时参数对应的过程,有兴趣的可以点击了解

你可能感兴趣的:(web)