RPC框架(2)——Netty

106 阅读3分钟
这个rpc是基于netty实现的,所以必须得先了解这个才行
  • 底层实现:Netty是一款基于NIO(Nonblocking I/O,非阻塞IO)开发的网络通信框架,对比于BIO(Blocking I/O,阻塞IO),它的并发性能得到了很大提高

  • 高性能传输 :在Java的内存中,存在有堆内存、栈内存和字符串常量池等等,其中堆内存是占用内存空间最大的一块,也是Java对象存放的地方,一般我们的数据如果需要从IO读取到堆内存,中间需要经过Socket缓冲区,也就是说一个数据会被拷贝两次才能到达它的终点,如果数据量大,就会造成不必要的资源浪费。Netty针对这种情况,使用了NIO中的一大特性——零拷贝,当它需要接收数据的时候,它会在堆内存之外开辟一块内存,数据就直接从IO读到了那块内存中去,在netty里面通过ByteBuf可以直接对这些数据进行直接操作,从而加快了传输速度。

  • 良好的封装性 :相比于JDK内部提供的NIO编码格式,Netty在进行nio技术开发的时候,封装的Api更加方便开发者使用,能够降低开发者对于操控NIO技术的门槛

  • NIO空指针bug :在NIO的select中,即使关注的select轮询事件的key为0的话 ,NIO照样不断从select本应该阻塞的情况中唤醒出来,导致不断轮询,直到cpu占用率为100%。 // 有数据时,内核态以事件驱动的方式获取有事件的文件描述符,但是如果没事件也发出了通知,那可就完蛋了。但是这个bug既然不是linux层epoll设计的bug的话,那就是jdk封装的有bug。 netty作为一个应用框架无法改正jdk对epoll封装这块的代码,只能绕道而行。

1、Netty五大核心组件

1.1 Channel

channel是Java Nio的一个基本构造,可以看作是数据传输的载体,可以被打开或关闭

1.2 EventLoop 与 EventLoopGroup

EventLoop定义了Netty的核心抽象,用来处理链接的生命周期内发生的事件,可以看作是一个线程。一个 Channel 一旦与一个 EventLoop 相绑定,那么在 Channel 的整个生命周期内是不能改变的。一个 EventLoop 可以与多个 Channel 绑定。即 Channel 与 EventLoop 的关系是 n:1,而 EventLoop 与线程的关系是 1:1。(from 敖丙)

而EventLoopGroup是一个EventLoop池,包含多个EventLoop

1.3 ServerBootstrap 与 Bootstrap

它们都是启动引导类对象,通过它们,对应用程序进行配置,并使程序正常运行起来。

ServerBootstrap 是服务端的引导类,ServerBootstarp 在调用 bind() 方法时会创建一个 ServerChannel 来接受来自客户端的连接,并且该 ServerChannel 管理了多个子 Channel 用于同客户端之间的通信。

Bootstrap 是客户端的引导类,Bootstrap 在调用 bind()(连接UDP)和 connect()(连接TCP)方法时,会新创建一个 Channel,仅创建一个单独的、没有父 Channel 的 Channel 来实现所有的网络交换。

1.4 Channel Handler 与 ChannelPipeLine

ChannelHandler是对Channel中数据的处理器,可以是自定义的编解码器,也可以是系统自带的。这些处理器都将被放到ChannelPipeLine的对象中,然后按照添加顺序对channel中的数据进行处理

1.5 ChannelFuture

Netty中所有的操作都是异步执行的,不会立即得到结果,所以定义了ChannelFuture对象来作为这个异步操作的代表。如果想要得到异步操作的返回值,可以利用Channel Future的addListerner()方法,为该异步操作添加一个监视器,每当结果出来的时候,立即执行

Netty的异步编程模型,都是建立在Future与回调的概念之上的 。

2、Netty源码阅读

我自己读去了,你们自己看