Reactor简介
Reactor是一个基础库,用在构建实时数据流应用、要求有容错和低延迟至毫秒、纳秒、皮秒的服务。
— PrefaceTL;DR
什么是Reactor?
让我们大致了解一下Reactor。在你使用喜欢的搜索敲入一些关键词如Reactive、spring Reactive、Asynchronous java或者仅仅是”What the heck is Reactor?”.简而言之,Reactor是一个轻量级的JVM基础库,它可以帮助我们构建的服务和应用高效而异步的传递消息。
高效的含义是什么呢?
传递一个消息从A到B时GC产生的内存很小或者完全没有。
当消费者处理消息的速度低于生产者产生消息的速度时产生了溢出时,必须尽快处理。
尽可能的提供无锁的异步流。
据以往的经验来看,我们知道异步编程是困难的,特别是当一个平台提供了很多选项如JVM。
Reactor瞄准绝大部分场景中真正的无阻塞,并且提供了一组比原生Jdk的java.util.concurrent库更高效的API。Reactor也提供了一个可选性(不建议使用):
阻塞等待:如Future.get()。
Unsafe数据获取:如ReentrantLock.lock()。
异常抛出:如try ..catch …finally
同步阻塞:如 syschronized
Wrapper配置(GC压力):例如 new Wrapper(event)
让我们先使用一个纯正的Executor方法:
复制代码
private ExecutorService threadPool = Executors.newFixedThreadPool(8);
final List<T> batches = new ArrayList<T>();
Callable<T> t = new Callable<T>() { //1
public T run() {
synchronized(batches) { //2
T result = callDatabase(msg); //3
batches.add(result);
return result;
}
}
};
Future<T> f = threadPool.submit(t); //4
T result = f.get() //5
复制代码
1.分配回调方法—可能会导致gc压力。
2.Synchronization将强制对每个线程停止检查。
3. 存在消费者的消费能力低于生产者生产能力的隐患。
4. 使用线程池将task传递到目标线程–肯定通过FutureTask给gc造成压力。
5. 阻塞直至callDatabase()响应。
从上述的简单示例中,容易看出扩展性会受到严重的影响。
不断分配的对象将导致gc停止工作,特别是耗时比较多的大任务时。当一个gc停止工作时将会从降低全局的性能。
队列默认情况下长度是不受限制的。任务会堆积到数据库中。
后台日志不是一个内存泄露的地方,但是副作用就比较烦人了:在gc暂停工作时需要扫描更多对象;损失数据重要bit的风险;等等。
经典链接Queue分配节点时产生的内存压力。
使用阻塞方式应答请求时发生恶性循环。
阻塞方式应答导致生产者效率慢下来。实际上,因为需要提交更多任务时等待响应,流程变成了基本的同步方式。