我为什么认为netty是java七层应用开发最优解?
对于netty的性能和良好的表现在七层网络应用开发中大家是有目共睹的,我为什么还要再谈这个问题呢?首先在我日常的工作中netty确实给我带来了很多方便的地方,比如netty稳定的性能、良好的并发表现、多协议适配、动态编解码的装配、丰富的编解码器。
我们在享受netty基础网络库开发的便利之处也要结合实际的场景来谈谈它的优势,我们首先从应用的角度来看一个网络应用处理的流程管理。
sequenceDiagram
网络数据->>协议处理: 网络协议解码
协议处理->>业务处理: 业务对象转换
业务处理->>协议处理: 业务对象转换协议
协议处理->>网络数据: 网络协议编码
一个网络框架应该具备的能力
在我没有用netty开发的时候我考虑的问题比较简单比如能力处理tcp协议/udp协议再做一些工具类就可以,虽然下面的图是针对netty的优势画的但是我们能通过它来思考一个优秀的网络框架应该是什么样的。
下面我针对实际的业务场景来说明一下我作为网络应用开发者应该考虑的问题和结合netty做一些说明
1、网络数据接收和发送阶段
对于网络数据的接收和发送我们是离不开byte[]数据流的,那么我们处理网络应用就需要不停的分配byte[]和释放byte[],我们在java编程方面习惯使用new关键字来创建一个对象,那么这个对象从分配到释放要经过gc处理无论是minor gc还是 full gc 都需要通过垃圾回收的扫描处理。我们为了提高性能就考虑到内存池,池化才是我们解决较高对象的分配和释放最好的方式,我们再看池就有很多池比如内存池对象池,我们通过复用的方式来循环利用这样就可以提高性能不再通过gc的方式去管理我们的对象。netty的对于网络过来的数据最大的优势就是内存池管理这里就包含了jemalloc的内存分配管理所以我认为netty对于网络数据的接收和发送有更好的性能表现。
2、业务对象处理阶段
对于网络的数据我们最终要转换成业务对象,如果我们用new的方式去创建,比如1000w个请求如果单纯使用new的方式去创建我们要创建1000w个实例,这里我们不讨论jvm内存模型管理1000w个对象的代价是巨大的,如果我们看总量1000w但实际的qps确是 1w 那是不是我们用对象池的方式来管理这些对象会更好。
3、网络协议编解码处理阶段
对于应用开发来说除非是做是做固定协议的编解码处理,在协议选择上我们会对协议设计选择两种方式,1、选择私有协议作为开发标准,2、选择通用标准协议作为开发标准。在平时大家接触的协议处理中很多都是固定协议的,这里如果你不用netty去做也没问题只要我们实现一套协议就可以,那如果我们需要考虑多协议适配甚至比如tls通道,socks协商,多协议接入,动态变更协议处理,对于这种协议我们就需要一个应变能力较强的框架,netty中的pipline流程动态装配目前是其它网络框架没有的。在理解动态装配这件事情上我们可以想象一个工厂的流水线,而这条流水线是可以动态装配的只需要我进行必要的环节重组就可以生产不同的产品。
4、标准协议编解码支持
对于一个优秀的网络开发框架首先要考虑到通用协议的适配,比如tcp protobuf、http1、http2、http3(quic)、dns、redis、mqtt 这样我们在开发这些协议的时候只需要组装上就可以直接使用,你说这有多方便。