🍎框架压测
# 压测环境
# 压测背景
现在有一种场景调用链路如下: AService (执行消耗1000ms) 调用 BService (执行消耗500ms)。
EService (执行消耗500ms) 调用 FService (执行消耗1000ms)
即: AService->BService; EService->FService;
# JVM参数
-Xmx6g -Xms6g -Xmn4g
# Jemeter 压测
并发循环压测 一秒 300次访问
# 创建异步任务
创建AService
AService 任务模拟Http调用,任务流程消耗 1000ms
@Service
public class AService implements AsyncTask<DataContext, DataContext>, ParaExector {
@Override
public void callback(boolean success, DataContext param, TaskResult<DataContext> workResult) {
if (success) {
System.out.println("AService 成功");
} else {
System.out.println("AService 失败");
}
}
@Override
public DataContext task(DataContext params, GobrsAsyncSupport support) {
try {
Thread.sleep(1000);
System.out.println("AService 执行完了");
} catch (InterruptedException e) {
e.printStackTrace();
}
byte[] result = new byte[1024*1024];
Map h = new HashMap();
h.put("result", result);
params.setResult(h);
return params;
}
@Override
public boolean nessary(DataContext params, GobrsAsyncSupport support) {
return true;
}
}
创建BService RPC调用 整个任务流程消耗 500ms
@Service
public class BService implements AsyncTask<DataContext, Map>, SerExector {
@Override
public void callback(boolean success, DataContext param, TaskResult<Map> workResult) {
if (success) {
System.out.println("BService 成功");
} else {
System.out.println("BService 失败");
}
}
@Override
public Map task(DataContext params, GobrsAsyncSupport support) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
HashMap hashMap = new HashMap();
hashMap.put("result", "我是B的结果");
return null;
}
@Override
public boolean nessary(DataContext params, GobrsAsyncSupport support) {
return true;
}
}
创建EService RPC调用 整个任务流程消耗 500ms
@Service
public class EService implements AsyncTask<DataContext, DataContext>, ParaExector {
@Override
public void callback(boolean success, DataContext param, TaskResult<DataContext> workResult) {
if (success) {
System.out.println("EService 成功");
} else {
System.out.println("EService 失败");
}
}
@Override
public DataContext task(DataContext params, GobrsAsyncSupport support) {
try {
// System.out.println(1/0);
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
Map h = new HashMap();
h.put("result", "我是EService 的 结果 恭喜你拿到");
params.setResult(h);
return params;
}
@Override
public boolean nessary(DataContext params, GobrsAsyncSupport support) {
return true;
}
}
创建FService 模拟复杂业务处理,需要消耗1000ms
@Service
public class FService implements AsyncTask<DataContext, Map>, SerExector {
@Override
public void callback(boolean success, DataContext param, TaskResult<Map> workResult) {
if (success) {
System.out.println("FService 成功");
} else {
System.out.println("FService 失败");
}
}
@Override
public Map task(DataContext params, GobrsAsyncSupport support) {
try {
DataContext result = getResult(support, EService.class);
// 复杂的业务场景处理
System.out.println(JSONObject.toJSONString(result.getResult()));
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
public boolean nessary(DataContext params, GobrsAsyncSupport support) {
return true;
}
}
# 方案一 使用普通Future方式开发
看一看到使用普通的开发方式, 代码较为复杂,而且这还是业务流程较少的任务流程
public void testFuture(HttpServletRequest httpServletRequest) {
DataContext dataContext = new DataContext();
dataContext.setHttpServletRequest(httpServletRequest);
List<Future> list = new ArrayList<>();
for (AsyncTask asyncTask : paraExectors) {
Future<?> submit = gobrsThreadPoolExecutor.submit(() -> {
asyncTask.task(dataContext, null);
});
list.add(submit);
}
for (Future future : list) {
try {
future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
List<Future> ser = new ArrayList<>();
for (AsyncTask asyncTask : serExectors) {
Future<?> submit = gobrsThreadPoolExecutor.submit(() -> {
asyncTask.task(dataContext, null);
});
ser.add(submit);
}
for (Future future : ser) {
try {
future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
# 方案二 使用Gobrs-Async
使用极其方便
public void testGobrs(HttpServletRequest httpServletRequest) {
DataContext dataContext = new DataContext();
dataContext.setHttpServletRequest(httpServletRequest);
AsyncResult asyncResult = taskFlow.taskFlow("test", dataContext, 100000);
}
# 流程分析
方案一: 先把需要依赖的任务通过Future 交给线程池执行。先执行 AService
和 EService
方案二: E执行完后会直接执行F,而不是等待 A执行完
# Jemeter 检测QPS
# 方案一
# 方案二
# JProfiler监控性能
# 方案一
# 方案二
# Jstat 监控GC频次
# 方案一
# 方案二
# Console 计算时间戳
# 方案一
# 方案二
# 总结
方案一 的结果永远不会低于 2S以下,因为 Future.get 会阻塞主线程
方案二 Gobrs-Async 则不会等待 AService
的返回 可迅速调用下游任务,提高系统 QPS
可以清楚的看到在使用 Gobrs-Async 后 QPS 从97 提升到 125, 这只是简单的任务流程,任务越复杂那么 Gobrs-Async的优势就越明显
- name: 技术小屋
desc: 大道至简,知易行难
avatar: https://cdn.jsdelivr.net/gh/xugaoyi/image_store/blog/20200122153807.jpg # 可选
link: https://docs.sizegang.cn/ # 可选
bgColor: '#CBEAFA' # 可选,默认var(--bodyBg)。颜色值有#号时请添加单引号
textColor: '#6854A1' # 可选,默认var(--textColor)
- name: 架构师必经之路
desc: '精品学习资源'
avatar: https://cdn.jsdelivr.net/gh/xaoxuu/assets@master/avatar/avatar.png
link: https://learn.sizegang.cn
bgColor: '#718971'
textColor: '#fff'
- name: 平凡的你我
desc: 快乐购物,享受生活
avatar: https://reinness.com/avatar.png
link: https://m.jd.com
bgColor: '#FCDBA0'
textColor: '#A05F2C'
Last Updated: 11/4/2022, 3:19:44 PM