一、Netty介绍
Netty是一个高性能、异步事件驱动的网络编程框架。Netty 的所有 IO 操作都是异步非阻塞 的,通过 Future-Listener 机制,基于通知机制获得 IO 操作结果。
二、Netty如何实现高性能
1.多路复用
IO 多路复用技术通过把多个 IO 的阻塞复用到同一个 select 的阻塞上,从而使得系统在
单线程的情况下可以同时处理多个客户端请求。
2.零拷贝
在传统的I/O模型中,数据在发送和接收时需要多次复制,即从应用程序缓冲区到内核缓冲区再到网络协议栈缓冲区,这个过程称为拷贝。而零拷贝将这种数据复制的次数降到最低,可以通过在不同层之间共享数据结构来消除数据移动的需求。
netty实现零拷贝的两种方式:
a、使用Direct Buffers将数据存储到直接内存中,通过操作系统零拷贝技术减少直接内存到内核缓冲区的映射。
b、FileRegion则是将文件内容直接映射到内存中,再将这个映射的内存传输到网络中,同样也避免了数据从磁盘到用户空间的复制。
3.内存池
对于堆外直接内存的分配和回收,是一件耗时的操作。为了尽量重用缓冲区,Netty 提供了基于内存池的缓冲区重用机制。
4.Reactor模型
Reactor模型有专门一个 NIO 线程-Acceptor 线程用于监听服务端,接收客户端的 TCP 连接请求; 网络 IO 操作-读、写 等由一个 NIO 线程池负责。
Protobuf采用采用 T - L - V 的数据存储方式:减少了分隔符的使用 & 数据存储得紧凑,编码 / 解码 方式简单。
5.序列化
Netty 默认提供了对 Google Protobuf 的支持,通过扩展 Netty 的编解码接口,用户可以实现其它的 高性能序列化框架,例如 Thrift 的压缩二进制编解码框架。
三、如何实现一个RPC框架
RPC,即 Remote Procedure Call(远程过程调用),调用远程计算机上的服务,就像调用本地服务一 样。
1.关键技术
a.服务发布与订阅:服务端使用 Zookeeper 注册服务地址,客户端从 Zookeeper 获取可用的服务地址。
b.
通信:使用 Netty 作为网络编程框架,实现网络服务器。
c.spring: 使用 Spring 配置服务,加载 Bean,扫描注解。
d.动态代理:客户端使用代理模式透明化服务调用。
代理逻辑:
1.获取远程服务地址。
2.将方法、参数等组装成能够进行网络传输的消息。
消息格式:接口名称
+
方法名
+
参数类型和参数值
+
超时时间
+ requestID
3.网络调用。
4.服务端本地调用,并将执行结果返回。
5.客户端收到响应,解析响应。
e.消息编解码:使用 Protostuff 序列化和反序列化消息。
2.如何获取异步调用结果
a.基于future-listener机制,在远程调用时将客户端挂起,在获取响应后将客户端唤醒。
b.当客户端获取响应时,解析出requestId,唤醒对应线程。