netty必会基础知识点
以下内容输出来源:拉勾教育-Java高薪训练营
网络编程框架Netty
一、网络编程相关概念
网络通信模型 | 举例 | 特点 |
---|---|---|
BIO阻塞 | 排队点餐,阻塞等待取餐 | 耗资源,效率低,基本已被废弃 |
NIO非阻塞 | 先取号,等待被叫,再去取餐 | 主流应用 |
AIO异步 | 包厢,点餐后等待端上来就行 | 1、windows实现成熟,但windows很少用来作为服务器; 2、linux常用来作为服务器,但AIO实现不够成熟; 3、linux下AIO相比NIO性能提升不够明显; |
类型 | 特点 |
---|---|
阻塞 | 1、读取数据没准备好时,等待数据返回(死等) 2、写操作时缓冲区数据满了,等待数据被消费(死等); |
非阻塞 | 读取数据没准备好或写缓冲满时,都直接返回。 |
类型 | 特点 |
---|---|
同步 | 数据准备就绪后需要调用方主动来读就是同步; |
异步 | 数据准备好在回调给程序就是异步 |
二、BIO与NIO
Jdk 1.4之前,基于Java的所有Socket通信都采用了BIO模式,服务端针对每个连接分配一个线程。
当并发访问量增大时,成千上万的线程会压垮服务器,BIO模型开发的服务端只有通过硬件的不断扩容来满足高并发和低时延,它极大地增加了企业的成本。
1、NIO编程的优点
1、服务端实现方式为每个请求分配一个通道(Channel
),每个连接请求都会注册到Selector
上,只有Selector轮询到该连接有IO 请求时才会启动一个线程。
2、Channel是数据连接的通道,数据可以从Channel读到Buffer
(缓冲区),也可以从Buffer写到Channel。
3、服务端通过Selector(单一线程)就可以实现对大量Channel的监控和维护。
三、Netty的核心组件
四、应用场景有哪些?
在互联网、大数据、网络游戏、企业应用、电信软件等众多行业得到成功商用,证明它已经完全能够满足不同行业的商业应用了。
数据库:Cassandra
大数据处理:Spark、Hadoop
Message Queue:RocketMQ
检索:Elasticsearch
框架:gRPC、Apache Dubbo、Spring5
分布式协调器:ZooKeeper
工具类:async-http-client
其他参考:https://netty.io/wiki/adopters.html
五、为什么用Netty?
jdk提供的NIO API开发异步通信十分复杂,Netty是一个通信框架,API相当简单,开发容易上手。
- Netty做得更多
- 支持常用应用层协议;
- 解决传输问题:粘包、半包现象;
- 支持流量整形;
- 完善的断连、Idle等异常处理等。
-
Netty做得更好之一:规避JDK NIO bug:
-
Netty做得更好之二:API更友好更强大
JDK的NIO一些API不够友好,功能薄弱,例如ByteBuffer-> Netty’s ByteBuf
除了NIO外,也提供了其他一些增强:Theadlocal-> Netty’s FastThreadLocal
六、netty实现通信的步骤
1、创建两个NIO线程组,一个专门用于网络事件处理(接受客户端连接),另一个则进行网络通信处理。
2、创建一个ServerBootStrap,配置netty的一些列参数,例如接收传出数据的缓存大小等。
3、创建一个实际处理数据的类ChannelInitializer,进行初始化的准备工作,比如设置传出数据的字符集、格式、已经实际处理数据的接口。
4、绑定端口,执行同步阻塞方法等待服务器端启动即可。
通过这么简单的几个步骤,就可以实现一个健壮、稳定的服务端通信,这在之前的NIO是不可能实现的。
七、Reactor的三种模式
-
Reactor单线程
单个线程处理所有事情,如饭店迎宾、点菜、做菜、上菜、结账、送客一系列操作 -
Reactor多线程 多线程分别处理以上所有事情
-
主从Reactor
一个线程专门处理连接建立和关闭,其他线程处理业务bossGroup和workerGroup
八、二次编解码器
一次解码器 ByteToMessageDecoder
二次解码器 MessageToMessageDecoder
netty内置的三种编解码器依次为FixedLengthFrameDecoder、LengthFieldBasedFrameDecoder 、DelimiterBasedFrameDecoder,由于一次解码的结果是字节,为了方便和项目中所使用的对象做转化,就需要二次解码
常用二次编解码器:
Java序列化、Marshaling、XML、JSON、MessagePack、Protobuf
九、心跳keepalive+idle
前者即心跳消息,后者为时间间隔,好比和别人通电话,对方突然不讲话了,等待几秒后,询问还在吗,或者直接挂断,或者重拨。Idle监测,只是负责诊断,诊断后作出不同的行为。
实际应用中:结合起来使用。按需keepalive,保证不会空闲,如果空闲,关闭连接。
1、Server端开启TCP keepalive
bootstrap.childOption(ChannelOption.SO_KEEPALIVE,true) bootstrap.childOption(NioChannelOption.of(StandardSocketOptions.SO_KEEPALIVE), true)
提示:.option(ChannelOption.SO_KEEPALIVE,true) 存在但是无效
2、 开启不同的Idle Check:
ch.pipeline().addLast(“idleCheckHandler", new IdleStateHandler(0, 20, 0, TimeUnit.SECONDS));