前言
Netty
启动时初始化的的channel
为什么设置为非阻塞的, 同步异步阻塞非阻塞的区别是什么?
这已经是本期活动的第六篇文章了, 浅浅看一下第一周第三个任务还没有完成, 这怎么能行呢, 必须安排一下
打断点开始调栈
我们从定位初始化开始, 按图找断点
在 idea 中双击Shift
输入AbstractNioChannel
找到他的构造函数并打断点, 然后启动我们的Netty
启动类MyServer
从 bind() 开始
我们把我们的调用栈堆拉到最下面, 然后逐层开始查看
启动类执行ServerBootstrap.bind()
方法
调用bind()
方法, 然后进入重写bind()
方法, 执行真正的 bind 实现doBind()
方法, 这个方法我用了三篇文章带大家整体的走了一遍, 感兴趣的可以看一下我之前的文章, 我们知道initAndRegister()
方法是channel
的初始化和注册, 调用栈堆也确实是这么告诉我们的, 我们继续往下看
- Netty服务端启动流程分析 - 掘金 (juejin.cn)
- Netty之第一次 TCP 连接时发生了什么 - 掘金 (juejin.cn)
- Netty之服务启动且注册成功之后 - 掘金 (juejin.cn)
...
在这里执行了我们的创建channel
实例的方法, 截图没放全, 太多了... 还没啥写的, 就是一堆调用方法, 最后我们进入了最终打断点的地方, 在这里将channel
设置为非阻塞模式
先讲一下阻塞非阻塞和同步异步
同步
: 两个或以上的线程在工作时互相协同, 比如线程B要等线程A工作结束, 拿到线程A的结果之后才能开始工作, 他俩就是同步的
异步
: 还是线程A和线程B, 线程B不用等线程A的结果可以直接去工作, 就是异步的
阻塞
: 被调用线程做完请求之后才返回结果, 就是阻塞的非阻塞
: 被调用线程直接给出结果再去执行线程, 就是非阻塞的
同时他们还能两两组合
同步阻塞
:客户端发送请求给服务端, 假设服务端处理任务时间很久, 这个过程中客户端因为在等服务端回复, 所以不能做其他的事情, 同时服务端在处理客户端的请求, 也不会接受其他客户端的请求同步非阻塞
:客户端发送请求给服务端,假设服务端处理这个任务时间很久,这个时候依然客户端会一直等待响应,但是服务端可以处理其他的请求,过一会回来处理原先的。这种方式很高效,一个服务端可以处理很多请求,不会在因为任务没有处理完而堵着,所以这是非阻塞的。异步阻塞
:客户端发送请求给服务端,假设服务端处理任务时间很久,但是客户端不会等待服务器响应,它可以做其他的任务,等服务器处理完毕后再把结果响应给客户端,客户端得到回调后再处理服务端的响应。这种方式可以避免客户端一直处于等待的状态,优化了用户体验,其实就是类似于网页里发起的ajax异步请求。异步非阻塞
:客户端发送请求给服务端,假设服务端处理任务时间很久,这个时候的任务虽然处理时间会很久,但是客户端可以做其他的任务,因为他是异步的,可以在回调函数里处理响应;同时服务端是非阻塞的,所以服务端可以去处理其他的任务,如此,这个模式就显得非常的高效了。
同步 | 异步 | |
阻塞 | 客户端会等服务端处理完请求, 服务端处理完当前请求才会处理下一个请求 | 客户端可以执行其他任务, 服务端处理完请求回调通知给客户端, 服务端必须处理完当前请求才能继续处理下一个请求 |
非阻塞 | 客户端会等服务端处理完请求再进行其他操作, 客户端可以处理多个请求 | 客户端和服务端互不影响 |
为什么将 channel 设置为非阻塞的
经过上面同步异步阻塞非阻塞
的讲解, 我们也知道了为什么要把Channel
设置成非阻塞的了, 相对比来讲异步非阻塞模式是非常高效的.
总结
字数多少有点少, 万万没想到这个任务这么简单