dubbo、rocketmq底层都用到了netty。
用到了基于事件驱动的设计模式reactor。
基于Selector实现:
EventLoop的实现充当Reactor模式中的分发(Dispatcher)的角色。
ChannelPipeline
ChannelPipeline其实是担任着Reactor模式中的请求处理器这个角色
Buffer
- ByteBuf读写指针
- 零拷贝
- 引用计数与池化技术
Netty其实本质上就是Reactor模式的实现Selector作为多路复用器,EventLoop作为转发器,Pipeline作为事件处理器但是和一般的Reactor不同的是,Netty使用串行化实现,并在Pipeline中使用了责任链模式。
说完了 ChannelPipeline 和 ChannelHandler,前者管理后者的排列顺序。那么它们之间的关联就由 ChannelHandlerContext 来表示了。
代理模式在不改变原始类接口的条件下,为原始类定义一个代理类,主要目的是控制访问,而非加强功能,这是它跟装饰器模式最大的不同。一般情况下,我们让代理类和原始类实现同样的接口。但是,如果原始类并没有定义接口,并且原始类代码并不是我们开发维护的。在这种情况下,我们可以通过让代理类继承原始类的方法来实现代理模式。
对于CPU密集型的计算场景,理论上线程的数量=CPU核数就是最合适的。不过在工程上,线程的数量一般会设置为CPU核数+1,这样的话,当线程因为偶尔的内存页失效或其他原因导致阻塞时,这个额外的线程可以顶上,从而保证CPU的利用率
对于I/O密集型的计算场景,最佳线程数=1+(I/O耗时/CPU耗时),针对多核CPU,我目前见过两种比较合理的公式:
最佳线程数=CPU核数×[1+(I/O耗时/CPU耗时)]
线程数=CPU核数×目标CPU利用率×(1+平均等待时间/平均工作时间)