第1页
基于Netty构建高性能RPC通信框架
李林锋 neu_lilinfeng@sina.com
新浪微博、微信: Nettying
微信公众号:Netty之家
第2页
大纲
I/O模型选择
序列化框架选型
高效线程模型
反射优化
异步调用
第3页
同步阻塞I/O性能问题
伸缩性差:一连接一线程模型导致服务端的并发接入数和系统吞吐量受到极大限制
效率低:由于I/O操作采用同步阻塞模式,当网络拥塞或者通信对端处理缓慢会导致I/O线程被挂住,阻塞时间无法预测
第4页
非阻塞I/O的优势
I/O多路复用:系统在单线程的情况下可以同时处理多个链接,降低系统资源开销
非阻塞I/O操作:连接、读取、写入等I/O操作均不会阻塞I/O线程
第5页
I/O 通信框架选择
基于Java NIO原生类库自研:复杂性、研发成本等
Mina:版本更新慢、最近几年社区不太活跃等
Netty: 性能高、资料丰富、社区活跃、商用成功案例多等
第6页
序列化技术关键指标
影响序列化性能的关键因素总结如下:
序列化后的码流大小(网络带宽占用)
序列化&反序列化的性能(CPU资源占用)
并发调用的性能表现:稳定性、线性增长、偶现的时延毛刺等
第7页
序列化框架选型
二进制还是文本方式 : Json、XML还是PB
二进制序列化框架:ProtocolBuf、Thrift、 MessagePack...
码流压缩技术:文本类GZIP,二进制类Zig-Zag
第8页
高效线程模型
I/O线程多路复用
I/O线程分组,负载均衡
I/O线程和业务线程分离,各司其职,互不干扰
第9页
高效线程模型
无锁化串行设计: 避免ChannelHandler被并发调用,加锁会降低性能
单线程线程池模型,性能更优:1个线程1个队列。避免JDK线程池的多线程-单阻塞队列导致的激烈锁竞争
第10页
减少反射
反射对性能影响很大,尽量避免反射
RPC框架中,序列化和反序列化是反射的最大受害者
解决对策
POJO对象自编解码,消除反射
IDE自编解码代码自动生成小工具,批量生成或者修改代码
public interface ISelfCodeC{
void encode(Object obj, ByteBuffer codeCBuf) throws Exception;
Object decode(ByteBuffer codeCBuf) throws Exception;
}
第11页
反射优化
类、方法和字段缓存机制
通过setAccessible(true)的方式关闭安全检查,提升反射性能(20倍的性能提升)
直接使用sun.misc.Unsafe.objectFieldOffset(Field)代替反射(慎用,内存越界JVM就会core dump)
使用ASM等字节码框架动态生成字节码代替 JAVA反射提高性能
第12页
异步调用
尽可能的异步
Future - Listener机制,完成之后回调
通过异步实现并行服务调用
第13页
谢谢聆听 ! 李林锋 neu_lilinfeng@sina.com 新浪微博、微信:Nettying 微信公众号:Netty之家
Q & A