异步HttpClient大量请求
由于项目中有用到HttpClient异步发送大量http请求,所以做已记录
思路:使用HttpClient连接池,多线程
public class HttpAsyncClient {
private static int socketTimeout = 500;// 设置等待数据超时时间0.5秒钟 根据业务调整
private static int connectTimeout = 2000;// 连接超时
private static int poolSize = 100;// 连接池最大连接数
private static int maxPerRoute = 100;// 每个主机的并发最多只有1500
private static int connectionRequestTimeout = 3000; //从连接池中后去连接的timeout时间
// http代理相关参数
private String host = "";
private int port = 0;
private String username = "";
private String password = "";
// 异步httpclient
private CloseableHttpAsyncClient asyncHttpClient;
// 异步加代理的httpclient
private CloseableHttpAsyncClient proxyAsyncHttpClient;
public HttpAsyncClient() {
try {
this.asyncHttpClient = createAsyncClient(false);
this.proxyAsyncHttpClient = createAsyncClient(true);
} catch (Exception e) {
e.printStackTrace();
}
}
public CloseableHttpAsyncClient createAsyncClient(boolean proxy)
throws KeyManagementException, UnrecoverableKeyException,
NoSuchAlgorithmException, KeyStoreException,
MalformedChallengeException, IOReactorException {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(connectionRequestTimeout)
.setConnectTimeout(connectTimeout)
.setSocketTimeout(socketTimeout).build();
SSLContext sslcontext = SSLContexts.createDefault();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(
username, password);
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, credentials);
// 设置协议http和https对应的处理socket链接工厂的对象
Registry<SchemeIOSessionStrategy> sessionStrategyRegistry = RegistryBuilder
.<SchemeIOSessionStrategy> create()
.register("http", NoopIOSessionStrategy.INSTANCE)
.register("https", new SSLIOSessionStrategy(sslcontext))
.build();
// 配置io线程
IOReactorConfig ioReactorConfig = IOReactorConfig.custom().setSoKeepAlive(false).setTcpNoDelay(true)
.setIoThreadCount(Runtime.getRuntime().availableProcessors())
.build();
// 设置连接池大小
ConnectingIOReactor ioReactor;
ioReactor = new DefaultConnectingIOReactor(ioReactorConfig);
PoolingNHttpClientConnectionManager conMgr = new PoolingNHttpClientConnectionManager(
ioReactor, null, sessionStrategyRegistry, null);
if (poolSize > 0) {
conMgr.setMaxTotal(poolSize);
}
if (maxPerRoute > 0) {
conMgr.setDefaultMaxPerRoute(maxPerRoute);
} else {
conMgr.setDefaultMaxPerRoute(10);
}
ConnectionConfig connectionConfig = ConnectionConfig.custom()
.setMalformedInputAction(CodingErrorAction.IGNORE)
.setUnmappableInputAction(CodingErrorAction.IGNORE)
.setCharset(Consts.UTF_8).build();
Lookup<AuthSchemeProvider> authSchemeRegistry;
authSchemeRegistry = RegistryBuilder
.<AuthSchemeProvider> create()
.register(AuthSchemes.BASIC, new BasicSchemeFactory())
.register(AuthSchemes.DIGEST, new DigestSchemeFactory())
.register(AuthSchemes.NTLM, new NTLMSchemeFactory())
.register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory())
.register(AuthSchemes.KERBEROS, new KerberosSchemeFactory())
.build();
conMgr.setDefaultConnectionConfig(connectionConfig);
if (proxy) {
return HttpAsyncClients.custom().setConnectionManager(conMgr)
.setDefaultCredentialsProvider(credentialsProvider)
.setDefaultAuthSchemeRegistry(authSchemeRegistry)
.setProxy(new HttpHost(host, port))
.setDefaultCookieStore(new BasicCookieStore())
.setDefaultRequestConfig(requestConfig).build();
} else {
return HttpAsyncClients.custom().setConnectionManager(conMgr)
.setDefaultCredentialsProvider(credentialsProvider)
.setDefaultAuthSchemeRegistry(authSchemeRegistry)
.setDefaultCookieStore(new BasicCookieStore()).build();
}
}
public CloseableHttpAsyncClient getAsyncHttpClient() {
return asyncHttpClient;
}
public CloseableHttpAsyncClient getProxyAsyncHttpClient() {
return proxyAsyncHttpClient;
}
}
public class HttpClientFactory {
private static HttpAsyncClient httpAsyncClient = new HttpAsyncClient();
private HttpClientFactory() {
}
private static HttpClientFactory httpClientFactory = new HttpClientFactory();
public static HttpClientFactory getInstance() {
return httpClientFactory;
}
public HttpAsyncClient getHttpAsyncClientPool() {
return httpAsyncClient;
}
}
public void sendThredPost(List<FaceBookUserQuitEntity> list,String title,String subTitle,String imgUrl){
if(list == null || list.size() == 0){
new BusinessException("亚洲查询用户数据为空");
}
int number = list.size();
int num = number / 10;
PostThread[] threads = new PostThread[1];
if(num > 0){
threads = new PostThread[10];
for(int i = 0; i <= 9; i++) {
List<FaceBookUserQuitEntity> threadList = list.subList(i * num, (i + 1) * num > number ? number : (i + 1) * num);
if (threadList == null || threadList.size() == 0) {
new BusinessException("亚洲切分用户数据为空");
}
threads[i] = new PostThread(HttpClientFactory.getInstance().getHttpAsyncClientPool().getAsyncHttpClient(),
threadList, title, subTitle, imgUrl);
}
for (int k = 0; k< threads.length; k++) {
threads[k].start();
logger.info("亚洲线程: {} 启动",k);
}
for (int j = 0; j < threads.length; j++) {
try {
threads[j].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}else{
threads[0] = new PostThread(HttpClientFactory.getInstance().getHttpAsyncClientPool().getAsyncHttpClient(),
list,title,subTitle, imgUrl);
threads[0].start();
try {
threads[0].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public PostThread(CloseableHttpAsyncClient httpClient, List<FaceBookUserQuitEntity> list, String title, String subTitle,String imgUrl){
this.httpClient = httpClient;
this.list = list;
this. title= title;
this. subTitle= subTitle;
this. imgUrl= imgUrl;
}
@Override
public void run() {
try {
int size = list.size();
for (int k = 0; k < size; k += 100) {
List<FaceBookUserQuitEntity> subList = new ArrayList<FaceBookUserQuitEntity>();
if (k + 100 < size) {
subList = list.subList(k, k + 100);
} else {
subList = list.subList(k, size);
}
if(subList.size() > 0){
httpClient.start();
final long startTime = System.currentTimeMillis();
final CountDownLatch latch = new CountDownLatch(subList.size());
for (FaceBookUserQuitEntity faceBookEntity : subList) {
String senderId = faceBookEntity.getSenderId();
String player_id = faceBookEntity.getPlayer_id();
logger.info("开始发送消息:playerid=" + player_id);
String bodyStr = getPostbody(senderId, player_id, title, subTitle,
imgUrl, "Play Game", "");
if (!bodyStr.isEmpty()) {
final HttpPost httpPost = new HttpPost(URL);
StringEntity stringEntity = new StringEntity(bodyStr, "utf-8");
stringEntity.setContentEncoding("UTF-8");
stringEntity.setContentType("application/json");
httpPost.setEntity(stringEntity);
httpClient.execute(httpPost, new FutureCallback<HttpResponse>() {
@Override
public void completed(HttpResponse result) {
latch.countDown();
int statusCode = result.getStatusLine().getStatusCode();
if(200 == statusCode){
logger.info("请求发消息成功="+bodyStr);
try {
logger.info(EntityUtils.toString(result.getEntity(), "UTF-8"));
} catch (IOException e) {
e.printStackTrace();
}
}else{
logger.info("请求返回状态="+statusCode);
logger.info("请求发消息失败="+bodyStr);
try {
logger.info(EntityUtils.toString(result.getEntity(), "UTF-8"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void failed(Exception ex) {
latch.countDown();
logger.info("请求发消息失败e="+ex);
}
@Override
public void cancelled() {
latch.countDown();
}
});
}
}
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
long leftTime = 10000 - (System.currentTimeMillis() - startTime);
if (leftTime > 0) {
try {
Thread.sleep(leftTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
} catch (UnsupportedCharsetException e) {
e.printStackTrace();
}
}
以上工具代码可直接使用,发送逻辑代码需适当修改。
异步HttpClient大量请求的更多相关文章
- 使用HttpClient来异步发送POST请求并解析GZIP回应
.NET 4.5(C#): 使用HttpClient来异步发送POST请求并解析GZIP回应 在新的C# 5.0和.NET 4.5环境下,微软为C#加入了async/await,同时还加入新的Syst ...
- android 学习随笔十二(网络:使用异步HttpClient框架)
使用异步HttpClient框架发送get.post请求 在https://github.com/ 搜索 asyn-http https://github.com/search?utf8=✓& ...
- 使用异步httpclient框架做get,post提交数据
1.将异步httpclient框架导入 下载地址:http://download.csdn.net/detail/sinat_32804317/9555641 2.代码实现 public class ...
- 异步httpclient(httpasyncclient)的使用与总结
参考:异步httpclient(httpasyncclient)的使用与总结 1. 前言应用层的网络模型有同步与异步.同步意味当前线程是阻塞的,只有本次请求完成后才能进行下一次请求;异步意味着所有的请 ...
- JDK HttpClient 多重请求-响应的处理
HttpClient 多重请求-响应的处理 目录 HttpClient 多重请求-响应的处理 1. 简述 2. 请求响应流程图 3. 用户请求的复制 4. 多重请求处理概览 5. 请求.响应过滤的执行 ...
- 纯js异步无刷新请求(只支持IE)
纯js异步无刷新请求 下载地址:http://pan.baidu.com/s/1slakL1F 所以因为非IE浏览器都禁止跨域请求,所以以只支持IE. <HTML> <!-- 乱码( ...
- 使用HttpClient发送请求、接收响应
使用HttpClient发送请求.接收响应很简单,只要如下几步即可. 1.创建HttpClient对象. CloseableHttpClient httpclient = HttpClients.c ...
- Java HttpClient伪造请求之简易封装满足HTTP以及HTTPS请求
HttpClient简介 HTTP 协议可能是现在 Internet 上使用得最多.最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源.虽然在 JDK 的 jav ...
- 纯js异步无刷新请求(只支持IE)【原】
纯js异步无刷新请求 下载地址:http://pan.baidu.com/s/1slakL1F 所以因为非IE浏览器都禁止跨域请求,所以以只支持IE. <HTML> <!-- 乱码( ...
随机推荐
- Linux性能优化实战学习笔记:第五十四讲
一.上节回顾 上一节,我带你学习了,如何使用 USE 法来监控系统的性能,先简单回顾一下. 系统监控的核心是资源的使用情况,这既包括 CPU.内存.磁盘.文件系统.网络等硬件资源,也包括文件描述符数. ...
- 原生/CM系列网络叹号问题
网络叹号问题: 原因:某墙屏蔽了谷歌,而原生安卓是利用谷歌的服务器来测试网络是否通畅的 解决方案:修改网络测试的服务器地址 方案来源:https://www.noisyfox.io/android-c ...
- CSP2019蒸馏记
Day -\(\infty\) ~ Day -2 认真准备联赛. Day -1 复习模板,全真模拟比赛平衡树 下午进行了湖南大学 2 小时游. Day 0 上午睡过头了 下午日常训练,并没有什么开放日 ...
- gcc编译的时候报错 error trying to exec 'cc1plus': execvp 解决方法
sudo apt install --reinstall build-essential -y
- jar解压后重新打包
因为一些原因修改了jar中的配置文件,但用WinRAR压缩成zip文件后该后缀名为jar,发现重新压缩的文件不可用,所有这些情况下我们必须用jar重新打包. 配置Java环境,让jar命令可用: ja ...
- 用 ubuntu 自带的 gome-screenshot 来实现类似QQ截图那样的功能,同时设置键盘快捷键
在window下习惯了使用ctrl+Alt+A截图,在linux还真有点不习惯,所以下面介绍一下替代的用法. 打开 ubuntu 的系统设置-->键盘-->快捷键:界面如下: 01 添加一 ...
- react的模型:react是如何工作的?
1.jsx:语法模型,语句构建模型: 2.组件:集合模型,组件管理: 3.vdom:分层模型.渲染管理模型: 4.flux:管道模型.数据模型,状态管理模型: 整体上是一个UI系统从上到下的构建: f ...
- java get请求带参数报错 java.io.IOException: Server returned HTTP response code: 400 for URL
解决方案 在使用JAVA发起http请求的时候,经常会遇到这个错误,我们copy请求地址在浏览器中运行的时候又是正常运行的,造成这个错误的原因主要是因为请求的URL中包含空格,这个时候我们要使用URL ...
- EF Code first主从表,删除更新从表
以order和orderItem为例,从表orderItem里有主表的orderId 想通过order.orderitems.add()或者remove()方法直接更新从表的话,必须在从表建立联合主键 ...
- 安全漏洞系列(二)---站点信息侦测(C# MVC)
参考地址:https://jingyan.baidu.com/article/77b8dc7fa657c26174eab631.html 概述:站点信息侦测漏洞会检测到用的版本信息等,然后借此进行一些 ...