热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

httpclient多线程高并发Get请求

最近公司需要对地址进行清洗,挑选了百度的LBS平台的GeocodingAPIv2接口,量级在千万级别。为了达到较高的效率,优化了下httpclient(版本:4.2.3)的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_TIMEOUTCONNECTION_TIMEOUT);
        params.setIntParameter(CoreConnectionPNames.SO_TIMEOUTSO_TIMEOUT);
        params.setLongParameter(ClientPNames.CONN_MANAGER_TIMEOUTCONN_MANAGER_TIMEOUT);
        params.setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, true);

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

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

    public static String get(String urlString 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 socketFactoryRegistry = RegistryBuilder.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 urlString 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);
                }
            }
        }
    }
}


推荐阅读
  • 理解HTTP状态码及其应用
    本文详细解析了HTTP状态码的分类及常见代码的意义,帮助开发者和用户更好地理解和解决网络请求中遇到的问题。 ... [详细]
  • C#爬虫Fiddler插件开发自动生成代码
    哈喽^_^一般我们在编写网页爬虫的时候经常会使用到Fiddler这个工具来分析http包,而且通常并不是分析一个包就够了的,所以为了把更多的时间放在分析http包上,自动化生成 ... [详细]
  • django项目中使用手机号登录
    本文使用聚合数据的短信接口,需要先获取到申请接口的appkey和模板id项目目录下创建ubtils文件夹,定义返回随机验证码和调取短信接口的函数function.py文件se ... [详细]
  • 本文详细介绍了如何利用go-zero框架从需求分析到最终部署至Kubernetes的全过程,特别聚焦于微服务架构中的网关设计与实现。项目采用了go-zero及其生态组件,涵盖了从API设计到RPC调用,再到生产环境下的监控与维护等多方面内容。 ... [详细]
  • 提升接口测试效率的关键:用例与工具的综合应用
    本文将探讨如何通过有效的接口测试用例设计和工具选择,显著提高接口测试的效率和质量。 ... [详细]
  • 本文讨论了在处理分页数据时常见的低级错误,并提供了优化后的代码示例,以减少重复代码并提高可读性和维护性。 ... [详细]
  • 在现代移动应用开发中,尤其是iOS应用,处理来自服务器的JSON数据是一项基本技能。无论是使用Swift还是PHP,有效地解析和利用JSON数据对于提升用户体验至关重要。本文将探讨如何在Swift中优雅地处理JSON,以及PHP中处理JSON的一些技巧。 ... [详细]
  • 本文探讨了Java中有效停止线程的多种方法,包括使用标志位、中断机制及处理阻塞I/O操作等,旨在帮助开发者避免使用已废弃的危险方法,确保线程安全和程序稳定性。 ... [详细]
  • 深入解析mt_allocator内存分配器(二):多线程与单线程场景下的实现
    本文详细介绍了mt_allocator内存分配器在多线程和单线程环境下的实现机制。该分配器以2的幂次方字节为单位分配内存,支持灵活的配置和高效的性能。文章分为内存池特性描述、内存池实现、单线程内存池实现、内存池策略类实现及多线程内存池实现等部分,深入探讨了内存池的初始化、内存分配与回收的具体实现。 ... [详细]
  • 本文介绍了进程的基本概念及其在操作系统中的重要性,探讨了进程与程序的区别,以及如何通过多进程实现并发和并行。文章还详细讲解了Python中的multiprocessing模块,包括Process类的使用方法、进程间的同步与异步调用、阻塞与非阻塞操作,并通过实例演示了进程池的应用。 ... [详细]
  • Linux环境下的PHP7安装与配置指南
    本文详细介绍了如何在Linux操作系统中安装和配置PHP7,包括检查当前PHP版本、升级PHP以及配置MySQL支持等步骤,适合后端开发者参考。 ... [详细]
  • 利用Executor框架管理线程池
    本文介绍了如何使用Executor框架来管理和创建线程池,包括不同的线程池类型及其应用场景,以及如何通过Executors工厂类创建不同类型的Executor实例。 ... [详细]
  • 深入浅出:Hadoop架构详解
    Hadoop作为大数据处理的核心技术,包含了一系列组件如HDFS(分布式文件系统)、YARN(资源管理框架)和MapReduce(并行计算模型)。本文将通过实例解析Hadoop的工作原理及其优势。 ... [详细]
  • 基于OpenCV的小型图像检索系统开发指南
    本文详细介绍了如何利用OpenCV构建一个高效的小型图像检索系统,涵盖从图像特征提取、视觉词汇表构建到图像数据库创建及在线检索的全过程。 ... [详细]
  • 构建Python自助式数据查询系统
    在现代数据密集型环境中,业务团队频繁需要从数据库中提取特定信息。为了提高效率并减少IT部门的工作负担,本文探讨了一种利用Python语言实现的自助数据查询工具的设计与实现。 ... [详细]
author-avatar
meteors99191
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有