ServerBootstrap
创建netty的ServerBootstrap的一个对象时需要自定义handler和绑定端口号。
当仅仅绑定一个端口号的时候,无论EvenLoopGroup boss有多少个线程,最终都只有一个selector线程生效,连接到该端口的客户端连接都将交由该线程处理。同理,绑定两个端口号就有两个线程处理客户端连接。但是,无论绑定了多少个端口号,最终都是使用同一个handler处理。
如果要使用多个handler,只能创建多个serverbootstrap。什么场景可能会使用到?
结合jvm理解netty处理网络IO的过程
- jvm、网卡、程序、内核都有自己的队列缓冲区。
- 数据到达网卡的队列缓冲区,触发中断,内核将数据从网卡缓冲区拷贝到自己的缓冲区。
- jvm一直在监听内核,如果数据准备好了,内核返回fds的状态给jvm(注意是状态而不是数据!!!),jvm对准备好数据的fds逐一遍历,将数据从内核缓冲区拷贝到直接内存,供程序使用。
思考:当数据来的极快(高并发),意味着内核缓冲区可能不够空间存数据,这就需要线程更加频繁的搬运数据到用户态,这样就会使得程序逻辑处理放缓,用户响应时间变长。
netty的粘包拆包问题
我们知道,io数据何时到达服务端是无法控制的。这时候就有可能多个包一起到达服务端或者一个包分多次到达服务端。
解决方案
- 发送定长包文,服务端只接收定长包文,如果包文长度不够,缓存起来放到下次读。
- 在头部记录本次发送包文的长度。因为头部的长度是确定的,所以可以读取头部报文后,再尝试读取数据报文,如果数据报文长度不够,缓存起来放到下次读。