httpclient 多线程高并发Get请求

最近公司需要对地址进行清洗,挑选了百度的LBS平台的Geocoding API v2接口,量级在千万级别。为了达到较高的效率,优化了下httpclient(版本: 4.2.3)的get请求,具体的就是使用http的连接池,这样不需要每次get都需要3次握手,大大提高了并发能力,并且失败率降低了100倍,具体代码如下:

public class HttpRequest {

    private static PoolingClientConnectionManager  conMgr null;

    static {
        HttpParams params =  new BasicHttpParams() ;
        Integer CONNECTION_TIMEOUT =  1000 // 设置请求超时 2 秒钟 根据业务调整
        Integer SO_TIMEOUT =  1000 // 设置等待数据超时时间 2 秒钟 根据业务调整
        Long CONN_MANAGER_TIMEOUT =  500L // 该值就是连接不够用的时候等待超时时间,一定要设置,而且不能太大

        params.setIntParameter(CoreConnectionPNames. CONNECTION_TIMEOUT CONNECTION_TIMEOUT) ;
        params.setIntParameter(CoreConnectionPNames. SO_TIMEOUT SO_TIMEOUT) ;
        params.setLongParameter(ClientPNames. CONN_MANAGER_TIMEOUT CONN_MANAGER_TIMEOUT) ;
        params.setBooleanParameter(CoreConnectionPNames. STALE_CONNECTION_CHECK , true) ;

        conMgr new PoolingClientConnectionManager() ;
        conMgr.setMaxTotal( 2000) ;

        conMgr.setDefaultMaxPerRoute( conMgr.getMaxTotal()) ;
    }

    public static String  get(String url String param) {

        DefaultHttpClient httpClient =  new DefaultHttpClient( conMgr) ;

//        httpClient.setParams(params);

        httpClient.setHttpRequestRetryHandler( new DefaultHttpRequestRetryHandler( 0 , false)) ;

        HttpResponse httpResponse =  null;

        //  发送 get 请求
        try {
            //  get 方法发送 http 请求
            HttpGet get =  new HttpGet(url + URLEncoder. encode(param "UTF-8")) ;
//            HttpGet get = new HttpGet(url + param);
//            get.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
//            get.setHeader("Accept-Encoding", "gzip, deflate, sdch");
//            get.setHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4");
//            get.setHeader("Cache-Control", "max-age=0");
//            get.setHeader("Connection", "keep-alive");
//            get.setHeader("Content-Type", "text/xml;charset=utf-8");
//            get.setHeader("Cookie", "BDUSS=EZZa1RmTVZWU0NqZ2VuM1RNdVhuYjR4QTkzbTNaMGRrNXladmFidFRwZHZmQ1pZQVFBQUFBJCQAAAAAAAAAAAEAAABNtEoNcWlhbmppY2hlbmdhYmMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG~v~ldv7~5XO; BAIDUID=50970119FD0148A9DC0B168BC1DF574C:FG=1; PSTM=1476958371; BDRCVFR[nXyXJys849T]=mk3SLVN4HKm; BIDUPSID=D09F46D9DB5776482C08FA93075CE076; MCITY=-289%3A; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; PSINO=5; H_PS_PSSID=1429_19036_18240_17949_21109_17001_20593_21377_21189_21372");
//            get.setHeader("Host", "180.97.33.90");
//            get.setHeader("Upgrade-Insecure-Requests", "1");
            get.setHeader( "User-Agent" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/51.0.2704.79 Chrome/51.0.2704.79 Safari/537.36") ;
            System. out.println( " 执行 get 请求 , uri: " + get.getURI()) ;
            httpResponse = httpClient.execute(get) ;
            // response 实体
            HttpEntity entity = httpResponse.getEntity() ;
            if ( null != entity) {
                String response = EntityUtils. toString(entity) ;
                int statusCode = httpResponse.getStatusLine().getStatusCode() ;
//                System.out.println(" 响应状态码 :" + statusCode);
//                System.out.println(" 响应内容 :" + response);
                if (statusCode == HttpStatus. SC_OK) {
                    //  成功
                    return response ;
                else {
                    return null;
                }
            }
        }  catch (IOException e) {
            e.printStackTrace() ;
            System. out.println( "httpclient 请求失败 ") ;
            return null;
        finally {
            if (httpResponse !=  null) {
                try {
                    EntityUtils. consume(httpResponse.getEntity()) // 会自动释放连接
                catch (IOException e) {
                    e.printStackTrace() ;
                }
            }
        }
        return null;
    }
}
具体调用的时候可以N个线程使用线程池进行调用

4.5.2最新版的使用(2017-01-03更新)
public class HttpRequest {

    private static Logger  LOGGER = LoggerFactory. getLogger(HttpRequest. class) ;

    private static PoolingHttpClientConnectionManager  cm null;

    static {
        LayeredConnectionSocketFactory sslsf =  null;
        try {
            sslsf =  new SSLConnectionSocketFactory(SSLContext. getDefault()) ;
        catch (NoSuchAlgorithmException e) {
            LOGGER.error( " 创建 SSL 连接失败 ") ;
        }
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()
                .register( "https" sslsf)
                .register( "http" , new PlainConnectionSocketFactory())
                .build() ;
        cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry) ;
        cm.setMaxTotal( 200) ;
        cm.setDefaultMaxPerRoute( 20) ;
    }

    private static CloseableHttpClient  getHttpClient() {
        CloseableHttpClient httpClient = HttpClients. custom()
                .setConnectionManager( cm)
                .build() ;
        return httpClient ;
    }

    public static String  get(String url String param) {
        //  创建默认的 httpClient 实例
        CloseableHttpClient httpClient = HttpRequest. getHttpClient() ;
        CloseableHttpResponse httpResponse =  null;
        //  发送 get 请求
        try {
            //  get 方法发送 http 请求
            HttpGet get =  new HttpGet(url + URLEncoder. encode(param "UTF-8")) ;
            LOGGER.info( " 执行 get 请求 , uri: " + get.getURI()) ;
            httpResponse = httpClient.execute(get) ;
            // response 实体
            HttpEntity entity = httpResponse.getEntity() ;
            if ( null != entity) {
                String response = EntityUtils. toString(entity) ;
                int statusCode = httpResponse.getStatusLine().getStatusCode() ;
                LOGGER.info( " 响应状态码 :" + statusCode) ;
                LOGGER.info( " 响应内容 :" + response) ;
                if (statusCode == HttpStatus. SC_OK) {
                    //  成功
                    return response ;
                else {
                    return null;
                }
            }
            return null;
        catch (IOException e) {
            LOGGER.error( "httpclient 请求失败 " e) ;
            return null;
        finally {
            if (httpResponse !=  null) {
                try {
                    EntityUtils. consume(httpResponse.getEntity()) ;
                    httpResponse.close() ;
                catch (IOException e) {
                    LOGGER.error( " 关闭 response 失败 " e) ;
                }
            }
        }
    }
}

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值