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); } } } } }
推荐阅读
本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ...
[详细]
蜡笔小新 2023-12-14 19:53:34
本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ...
[详细]
蜡笔小新 2023-12-14 13:53:31
本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ...
[详细]
蜡笔小新 2023-12-13 22:09:56
本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ...
[详细]
蜡笔小新 2023-12-12 15:28:09
预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ...
[详细]
蜡笔小新 2023-12-12 14:06:39
1Lock与ReadWriteLock1.1LockpublicinterfaceLock{voidlock();voidlockInterruptibl ...
[详细]
蜡笔小新 2023-12-09 09:15:17
Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ...
[详细]
蜡笔小新 2023-12-14 17:38:12
阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ...
[详细]
蜡笔小新 2023-12-14 12:40:20
本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ...
[详细]
蜡笔小新 2023-12-14 10:01:13
本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ...
[详细]
蜡笔小新 2023-12-14 03:24:19
本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ...
[详细]
蜡笔小新 2023-12-13 15:43:03
个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ...
[详细]
蜡笔小新 2023-12-13 14:20:23
一、集群间数据拷贝scp实现两个远程主机之间的文件复制scp-rhello.txtroothadoop103:useratguiguhello.txt推pushscp-rr ...
[详细]
蜡笔小新 2023-12-13 13:52:40
本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ...
[详细]
蜡笔小新 2023-12-12 16:19:02
本文由编程笔记#小编整理,主要介绍了关于数论相关的知识,包括数论的算法和百度百科的链接。文章还介绍了欧几里得算法、辗转相除法、gcd、lcm和扩展欧几里得算法的使用方法。此外,文章还提到了数论在求解不定方程、模线性方程和乘法逆元方面的应用。摘要长度:184字。 ...
[详细]
蜡笔小新 2023-12-11 17:31:53
meteors99191
这个家伙很懒,什么也没留下!