异步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> <!-- 乱码( ...
随机推荐
- django+uwsgi+nginx 导出excel超时问题
一.问题现象和日志报错 之前在项目实现了excel导入导出:django导入导出excel实践,之前一直稳定运行,突然得知导出用户信息时出现nginx错误报告: 查看nginx日志,报错信息如下所示: ...
- 公告&留言板
这里是公告&留言板.无意义的评论可能会被删除. 2019.10.4 感觉开学之后状态一直都布星啊,可能会在博客里总结一些前面学的东西. 2019.10.14 咕咕咕咕咕咕咕咕 2019.10. ...
- windows php 下的各个版本的资源下载地址
历史版本: https://windows.php.net/downloads/releases/archives/ 新版本: https://windows.php.net/download/ 找的 ...
- cefsharp参考笔记
https://blog.csdn.net/yh0503/article/details/86678115 https://blog.csdn.net/qq_17351077/article/deta ...
- [数据库] SQL 语法之进阶篇
一.创建计算字段 下面介绍什么是计算字段,如何创建计算字段,以及如何从应用程序中使用别名引用它们. 1.1 计算字段 存储在数据库表中的数据一般不是应用程序所需要的格式,下面举几个例子. 需要显示公司 ...
- Data Science: An overview
Week 1 Data Science: An overview Objective: 1.Is data science the same as statistics or analysis? st ...
- HTTP之如何控制缓存
HTTP控制缓存的能力 ===================摘自<HTTP权威指南>==================================== 服务器可以通过HTTP定义的 ...
- SQL-----数据库三种删除方式详解
第一种 使用delete 语句 特点: delete 属于数据库操纵语言DML,表示删除表中的数据, 删除过程是每次从表中删除一行,并把该行删除操作作为事务记录在日志中保存 可以配合事件(tran ...
- 如何将云上的Linux文件自动备份到本地服务器
需求场景: 将云上一台Linux服务器文件备份到本地服务器,一周一备即可. 面对这样一个需求,我们可能面临下列几个问题, 备份方式:是云服务器推文件到本地服务器写入,还是本地服务器从云服务器拉文件?这 ...
- Python的设计哲学--zen of Python
Python的设计哲学--zen of Python Beautiful is better than ugly. 优美胜于丑陋 Explicit is better than ...