HTTP异步连接池和多线程实践
时间:2022-07-24
本文章向大家介绍HTTP异步连接池和多线程实践,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
今天在查询一个列表的时候,突然发现列表由于之前压测导致几万条脏数据积累。导致找一个数据比较麻烦,由于项目没有提供批量删除的功能,所以想了个办法通过接口把数据挨个删除。
思路如下:先去请求分页列表,然后解析数据,通过请求删除接口去一条一条的删除。
虽然比较简单,但是几万条数据还是耗费了比较长的时间,中间进行了一些优化,所以分成了好几个版本来完成。
第一版:串行请求
- 关于测试框架和项目实践可以参考以前的文章:接口测试视频教程
脚本如下:
public static void main(String[] args) {
def base = getBase()
def manager = new TeacherManager(base)
3.upto(1000) {
def list = manager.verifyList(it)
list.getJSONObject("data")?.getJSONArray("list").each { x ->
manager.verify(x.id, x.tel)
}
}
allOver()
}
查询列表和删除记录的方法如下:
public JSONObject verifyList(int page = 3) {
String url = TeacherManagerApi.VERIFY_LIST;
JSONObject params = getParams();
params.put("page", page);
params.put("page_size", 50);
JSONObject response = getPostResponse(url, params);
output(response);
return response;
}
public JSONObject verify(int id = 0, String tel = "") {
String url = TeacherManagerApi.VERIFY;
JSONObject params = getParams();
params.put("action", 2);//2:拒绝
params.put("id", id);
params.put("tel", tel);
params.put("refused_result", "清空脏数据");
JSONObject response = getPostResponse(url, params);
return response;
}
第二版:HTTP异步请求优化
主要是优化了verify
方法,每次可以串行获取完列表之后,删除的接口请求就通过异步方法调用。方法如下:
public JSONObject verify(int id = 0, String tel = "") {
String url = TeacherManagerApi.VERIFY;
JSONObject params = getParams();
params.put("action", 2);//2:拒绝
params.put("id", id);
params.put("tel", tel);
params.put("refused_result", "清空脏数据");
output(params.toString());
HttpPost post = getPost(url, params);
setHeaders(post);
FanLibrary.excuteSyncWithResponse(post);
return null;
}
异步连接池的方法如下:
/**
* 异步发送请求
*
* @param request
*/
public static void excuteSync(HttpRequestBase request) {
if (!ClientManage.httpAsyncClient.isRunning()) ClientManage.httpAsyncClient.start();
ClientManage.httpAsyncClient.execute(request, null);
}
/**
* 异步发送请求获取影响Demo
* <p>经过测试没卵用</p>
*
* @param request
* @throws ExecutionException
* @throws InterruptedException
*/
public static JSONObject excuteSyncWithResponse(HttpRequestBase request) {
if (!ClientManage.httpAsyncClient.isRunning()) ClientManage.httpAsyncClient.start();
Future<HttpResponse> execute = ClientManage.httpAsyncClient.execute(request, null);
try {
HttpResponse httpResponse = execute.get();
String content = getContent(httpResponse);
return getJsonResponse(content, null);
} catch (Exception e) {
logger.error("异步请求获取响应失败!", e);
}
return new JSONObject();
}
获取异步连接池的方法:
/**
* 通过连接池获取https协议请求对象
* <p>
* 增加默认的请求控制器,和请求配置,连接控制器,取消了cookiestore,单独解析响应set-cookie和发送请求的header,适配多用户同时在线的情况
* </p>
*
* @return
*/
private static CloseableHttpAsyncClient getCloseableHttpAsyncClient() {
return HttpAsyncClients.custom().setConnectionManager(NconnManager).setSSLHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER).setSSLContext(sslContext).build();
}
经过测试,异步发送请求的效率果然有所提高,但是有个问题就是不能立刻关闭连接池,不然会导致请求失败,提示连接池已经关闭。
第三版:多线程
核心代码如下:
public static void main(String[] args) {
def base = getBase()
def manager = new TeacherManager(base)
3.upto(100) {
new Thread({ ->
def list = manager.verifyList(it)
list.getJSONObject("data")?.getJSONArray("list").each { x ->
manager.verify(x.id, x.tel)
}
}).start()
}
allOver()
}
经过测试,多线程比异步效率高太多了,而且异步总会出现一些问题,比如不成功,由于不关心返回了,很多情况也无法调试,如果使用异步加上获取响应值,有会其他操作,我觉得有点绕远路了。最后采取了多线程这个方案。一秒钟能删掉上百条数据,一会儿就删完了。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Flutter基础widgets教程-Baseline篇
- 常用Linux脚本集锦
- 大型前端项目的断点调试共享化和复用化实践
- 常用Linux命令集锦
- 使用Azure Functions玩转Serverless
- Best practice on when to use the wrapper class and primitive type in Java
- Flutter基础widgets教程-BottomNavigationBar篇
- 直播系统介绍
- Azure内容审查器之羞羞图审查
- Clickhouse简介和性能对比
- Clickhouse创建分布式表以及表引擎介绍
- Azure 内容审查器之文本审查
- Redis中String数据类型原理实现
- Clickhouse分布式集群搭建
- Redis过期策略以及淘汰机制