Netty源码剖析
LUK流
大数据/java web
展开
-
Netty源码(十五):Recycler工具类
1. Recycler工具类的使用Recycler为了避免我们重复的创建对象,使用对象池将我们使用过的数据保存起来,下一次就可以拿出来使用public class TestRecycler { // 对象池 private static final Recycler<User> RECYCLER = new Recycler<User>() { ...原创 2020-04-17 13:22:55 · 286 阅读 · 0 评论 -
Netty源码(十四):FastThreadLocal工具类
1. 写一个程序来验证FastThreadLocal功能public class TestFastThreadLocal { // FastThreadLocal初始化 public static FastThreadLocal<Object> fastThreadLocal1 = new FastThreadLocal<Object>(){ ...原创 2020-04-16 19:57:34 · 180 阅读 · 0 评论 -
Netty源码(十三):关闭服务
关闭流程:包括了bossGroup和workGroup的关闭开始源码,按照下面的方式完成操作,启动EchoServer1. 进入workerGroup.shutdownGracefully();不断跟进源码,进入到了SingleThreadEventExecutor的shutdownGracefully(long quietPeriod, long timeout, TimeUnit ...原创 2020-04-15 20:48:35 · 503 阅读 · 1 评论 -
Netty源码(十二):断开连接
1.正常关闭的逻辑关闭连接会进入read状态为了直接观察到关闭操作,我们注释上面的代码关闭最后也会进入到read事件里面1.allocHandle.lastBytesRead() <= 0这一行会发现数据小于零,释放byteBuf2.进入到closeOnRead(pipeline);完成关闭事件 @Override public final void re...原创 2020-04-15 19:15:31 · 896 阅读 · 0 评论 -
Netty源码(十一):写数据
write是把数据写入到一个buffer。flush就是将数据发出去。writeAndFlush就是写入数据立马发出去。下面是拿快递和写数据的对比:发送数据分为三部分:1.unflushedEntry所指向的entry,每次向链表中添加数据写到链表尾部2.写好一份完整的数据以后就将unflushedEntry这个头结点变成flushedEntry3.最后写入数据就是从flushe...原创 2020-04-15 16:36:40 · 434 阅读 · 0 评论 -
Netty源码(十):业务处理的过程pipeline
根据上一次接收数据逻辑的学习,可以总结下面的流程,红色就是我们学习的地方。pipeline,下面以inbound和outbound为例。pipeline本质就是一个链表,有head和tail,中间是很多个context,每个context中包含了需要执行的handler。可以看出inbound执行handle的顺序和outbound相反。打断点到EventLoop的读取数据的部分依然会...原创 2020-04-15 14:24:47 · 247 阅读 · 0 评论 -
Netty源码(九):接收数据
整体流程也是在EvenetLoop的run方法中select到了read事件,开始处理read事件。进入AbstractNioByteChannel类,调用其中的read方法 @Override public final void read() { final ChannelConfig config = config(); ...原创 2020-04-15 13:36:47 · 265 阅读 · 0 评论 -
Netty源码(八):建立连接请求的过程
在NioEventLoop中有一个run方法是处理接受请求的部分run方法循环监听事件,里面做了两件事情:1.select阻塞操作2.监听到事件以后处理事件// 死循环监听处理事件 @Override protected void run() { int selectCnt = 0; for (;;) { try {...原创 2020-04-14 21:15:53 · 602 阅读 · 0 评论 -
Netty源码(七):启动源码
1. 主线our thread就是我们自己写的netty服务器的主线程的代码2. 启动在下面三处打上断点2.1 selector初始化是在NioEventLoopGroup初始化运行程序:发现,查看NioEventLoopGroup通过创建一个子的NioEventLoopGroup,然后子的NioEventLoopGroup又NioEventLoop,并完成selector的创建...原创 2020-04-14 19:09:02 · 486 阅读 · 0 评论 -
Netty源码(六):Netty的内存
1. 内存分配方式可以通过下面代码实现内存分配是采用pooled还是unpooled方式,pooled可以增加对内存的使用反复使用下面试netty默认的内存分配方式不断跟进ByteBufAllocator.DEFAULT里面的代码,发现如下代码,可以看出内存的分配默认还是pooled的方式1.1 PooledDirectByteBuf对象池的使用...原创 2020-04-14 15:23:55 · 224 阅读 · 0 评论 -
Netty源码(五):keepalive和Idle处理
1.keepalive和Idle检测keepalive机制:如果对方突然无响应,我们需要发送一个探测帧去查看对方是是否下线。Idle检测:如果你发送数据给对方,对方无响应,你会等一段时间(Idle检测),如果对方无响应,你就会发送心跳包(Idle检测)2. 两种设置keepalive的方式下面两行代码都可以开启keepalive模式,keepalive模式默认是关闭的跟进childOp...原创 2020-04-13 20:12:09 · 1329 阅读 · 0 评论 -
Netty源码(四):Netty的“二次解码器”MessageToMessageDecoder
1. 二次解码器如果说封装成帧是一次解码器,那么二次解码器就是将byte流转化成java对象等。一次解码器和二次解码器的区别,区别一次解码器,而不是将两个两个解码器合二为一主要是因为考虑到分层的思想。如果有一天protobuf协议变成json协议,代码耦合度高,修改代码量大。2. ObjectEncoder如何实现编码的进入源码如图所示的包路径,第48行就是编码的核心方式,看得出来使用...原创 2020-04-13 15:53:59 · 1120 阅读 · 0 评论 -
Netty源码(三):Netty的粘包问题ByteToMessageDecoder
1. 产生粘包和半包的原因粘包产生的原因:两个包小于缓存区的大小,传送数据会将两个包都放在缓冲区中一起发送,就会产生粘包的问题。半包产生的原因:当某一个包的大于缓冲区的大小,会被发送多次,每次就收到的就是一个不完整的数据包。常见的处理手段:netty对不同粘包半包问题的支持类2. 问题一:Netty如何实现编码解码的查看ByteToMessageDecoder,该类是解码器的实现类...原创 2020-04-12 21:16:21 · 849 阅读 · 0 评论 -
Netty源码(二):三种Reactor模式
1. Reactor模型1.1 单线程reactor一个单线程去维护所有的acceptor、read、decode、compute、encode、send。1.2 多线程reactor模型我们认为decode、read、compute比较耗时,使用一个线程池去管理。1.3 主从多线程模型上面有两个reactor,因为所有事件里面acceptor最重要,用一个单独的reactor去...原创 2020-04-12 19:49:23 · 504 阅读 · 0 评论 -
Netty源码(一):OIO和NIO两种模式的切换方式
本项目源码使用的是netty4.11.修改IO模式对应的使用除了修改两个EventLoopGroup类型之外,我们想要修改IO模式,实现对OIO/NIO之间的切换只需要使用如下图所示的channel()方法。跟进channel()方法,我们发现IO模式切换使用的是一个ReflectiveChannelFactory()这个反射工厂实现的。跟进ReflectiveChannelFacto...原创 2020-04-09 20:01:01 · 784 阅读 · 0 评论