httpclient多线程高并发Get请求
作者:meteors99191 | 来源:互联网 | 2023-05-17 07:27
最近公司需要对地址进行清洗,挑选了百度的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 = 2 * 1000 ; // 设置请求超时 2 秒钟 根据业务调整 Integer SO_TIMEOUT = 2 * 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 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 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); } } } } }
推荐阅读
本文详细解析了HTTP状态码的分类及常见代码的意义,帮助开发者和用户更好地理解和解决网络请求中遇到的问题。 ...
[详细]
蜡笔小新 2024-11-28 17:29:06
哈喽^_^一般我们在编写网页爬虫的时候经常会使用到Fiddler这个工具来分析http包,而且通常并不是分析一个包就够了的,所以为了把更多的时间放在分析http包上,自动化生成 ...
[详细]
蜡笔小新 2024-11-28 13:39:49
本文使用聚合数据的短信接口,需要先获取到申请接口的appkey和模板id项目目录下创建ubtils文件夹,定义返回随机验证码和调取短信接口的函数function.py文件se ...
[详细]
蜡笔小新 2024-11-29 05:44:12
本文详细介绍了如何利用go-zero框架从需求分析到最终部署至Kubernetes的全过程,特别聚焦于微服务架构中的网关设计与实现。项目采用了go-zero及其生态组件,涵盖了从API设计到RPC调用,再到生产环境下的监控与维护等多方面内容。 ...
[详细]
蜡笔小新 2024-11-28 17:56:12
本文将探讨如何通过有效的接口测试用例设计和工具选择,显著提高接口测试的效率和质量。 ...
[详细]
蜡笔小新 2024-11-28 16:45:22
本文讨论了在处理分页数据时常见的低级错误,并提供了优化后的代码示例,以减少重复代码并提高可读性和维护性。 ...
[详细]
蜡笔小新 2024-11-28 15:27:32
在现代移动应用开发中,尤其是iOS应用,处理来自服务器的JSON数据是一项基本技能。无论是使用Swift还是PHP,有效地解析和利用JSON数据对于提升用户体验至关重要。本文将探讨如何在Swift中优雅地处理JSON,以及PHP中处理JSON的一些技巧。 ...
[详细]
蜡笔小新 2024-11-28 12:19:40
本文探讨了Java中有效停止线程的多种方法,包括使用标志位、中断机制及处理阻塞I/O操作等,旨在帮助开发者避免使用已废弃的危险方法,确保线程安全和程序稳定性。 ...
[详细]
蜡笔小新 2024-11-25 19:16:54
本文详细介绍了mt_allocator内存分配器在多线程和单线程环境下的实现机制。该分配器以2的幂次方字节为单位分配内存,支持灵活的配置和高效的性能。文章分为内存池特性描述、内存池实现、单线程内存池实现、内存池策略类实现及多线程内存池实现等部分,深入探讨了内存池的初始化、内存分配与回收的具体实现。 ...
[详细]
蜡笔小新 2024-11-25 17:44:11
本文介绍了进程的基本概念及其在操作系统中的重要性,探讨了进程与程序的区别,以及如何通过多进程实现并发和并行。文章还详细讲解了Python中的multiprocessing模块,包括Process类的使用方法、进程间的同步与异步调用、阻塞与非阻塞操作,并通过实例演示了进程池的应用。 ...
[详细]
蜡笔小新 2024-11-25 16:40:13
本文详细介绍了如何在Linux操作系统中安装和配置PHP7,包括检查当前PHP版本、升级PHP以及配置MySQL支持等步骤,适合后端开发者参考。 ...
[详细]
蜡笔小新 2024-11-28 19:14:15
本文介绍了如何使用Executor框架来管理和创建线程池,包括不同的线程池类型及其应用场景,以及如何通过Executors工厂类创建不同类型的Executor实例。 ...
[详细]
蜡笔小新 2024-11-28 19:13:16
Hadoop作为大数据处理的核心技术,包含了一系列组件如HDFS(分布式文件系统)、YARN(资源管理框架)和MapReduce(并行计算模型)。本文将通过实例解析Hadoop的工作原理及其优势。 ...
[详细]
蜡笔小新 2024-11-26 13:26:40
本文详细介绍了如何利用OpenCV构建一个高效的小型图像检索系统,涵盖从图像特征提取、视觉词汇表构建到图像数据库创建及在线检索的全过程。 ...
[详细]
蜡笔小新 2024-11-26 12:58:31
在现代数据密集型环境中,业务团队频繁需要从数据库中提取特定信息。为了提高效率并减少IT部门的工作负担,本文探讨了一种利用Python语言实现的自助数据查询工具的设计与实现。 ...
[详细]
蜡笔小新 2024-11-25 17:55:33
meteors99191
这个家伙很懒,什么也没留下!