java 脑洞 - 缓冲调用 开源模块
2019-05-10 本文已影响0人
灰色调诺言
脑洞的由来
场景一:分页查询,某商品首页展示
场景二:缓存分担压力,缓存失效导致大量请求去到下流服务,导致雪崩
缓冲调用和缓存的区别
首先缓冲调用和缓存并不是互相替代的,缓冲调用是瞬点高并的补充优化方案,在某些特殊场景会发挥很大的功效。缓冲调用和缓存的区别,缓冲调用不保留数据,所以无需维护数据的一致性等等,缓冲调用只会增加新生代内存,调用完之后就会删除对应的Future,最后再讨论下缓冲调用的效率问题,缓冲调用最长时间是一次完整调用,最短时间是无须调用就获得结果,所以在调用效率上也会有优化。
更多demo请关注
springboot demo实战项目
java 脑洞
java 面试宝典
开源工具
功能描述
同一时刻多条线程携带同一参数调用同一接口,把调用过程包装成FutureTask,每条线程通过获取到的FutureTask获得返回值
image.pngPS:
缓冲调用出来的对象是同一个对象,在使用时需要注意
核心源码详解
public <T> T execute(String callKey, long waitTime, VoidBufferCall<T> invoke) throws BufferCallException {
// 包装FutureTask
Future<T> future = new FutureTask<>(() -> {
try {
T value = invoke.call();
return value;
} catch (Throwable throwable) {
if (throwable instanceof Exception) {
throw (Exception) throwable;
} else {
throw new Exception(throwable);
}
} finally {
// 执行完移除
futureMap.remove(callKey);
}
});
// 把FutureTask根据callKey放入Map中,如果已存在则获取旧的FutureTask;
Future oldFuture = futureMap.putIfAbsent(callKey, future);
if (oldFuture == null) {
// 如果是新的FutureTask,则执行
((FutureTask) future).run();
} else {
future = oldFuture;
}
try {
if (waitTime > 0) {
return future.get(waitTime, TimeUnit.MILLISECONDS);
} else {
// 获取调用返回值并返回
return future.get();
}
} catch (Exception e) {
throw new BufferCallException(callKey, e);
}
}
源码项目
github : https://gitee.com/wqrzsy/lp-buffercall.git
lp-buffercall
缓冲调用的核心项目
lp-buffercall-spring
lp-buffercall的扩展项目,引入spring来做AOP,可以通过注解来实现调用
调用示例
@Component
public class TestService {
@BufferCall
public String test(@CallKey String name) {
return name + "- Hello !";
}
}
PS: @CallKey 如果没有则默认全参数
公众号
五分钟了解前沿技术,大数据,微服务,区域链,提供java前沿技术干货,独立游戏制作技术分享
五分钟技术如果这篇文章对你有帮助请给个star
image.png