尚硅谷-Netty篇
学习内容
P1P43,P110P116,中间章节好枯燥啊,暂时用不到,先跳过了
IO模型参考:https://blog.csdn.net/lzb348110175/article/details/98941378
学习链接:https://www.bilibili.com/video/BV1DJ411m7NR?p=42&vd_source=510ec700814c4e5dc4c4fda8f06c10e8
系统优化:要么是分层处理,要么是叫缓存
🔥1. 基本内容
1.1.基本概念
1.1.0 IO模型--前提
1.1.0.1 基本概念
先做一个铺垫吧,IO模型分为同步阻塞BIO、同步非阻塞NIO、多路复用IO、异步AIO。后面详细介绍
1.1.0.2 BIO--同步阻塞IO
BIO(Blocking IO):同步阻塞IO。这种阻塞是针对内核空间而言的,内核空间需要准备数据 。适合连接数少的情况,实际用户请求一次就是开一个线程处理,虽然有线程池可以优化
1.1.0.3 NIO--同步非阻塞IO
NIO(Non-Blocking IO): 同步非阻塞IO。适合连接数多且时长短的,比如聊天连接器
1.1.0.4 多路复用IO--异步阻塞IO(略)
1.1.0.5 AIO--异步非阻塞IO
Asynchronous IO。适合连接数多且时长长的
1.1.1 Netty
1.1.1.1 基本概念
本质就是NIO框架,底层是jdk代码,更下层是TCP/IP协议。比如阿里的Dubbo的RPC框架就是用的Netty、Spark
1.1.1.2 NIO概念
三大组件Channel通道,Buffer缓冲区,Selector选择器
原本BIO是每有一个客户连接服务端就创建一个线程处理,现在NIO就创建一个线程进行选择处理,如果没有通道有数据,那就跳过不阻塞(和Kafka消费者与kafka-Broker关系类似)
1.1.1.3 NIO--三大组件
总结就是一个Selector监听多个Channel,每个Channel又对应一个Buffer。Buffer是面向块(底层是个数组,BIO是面向字节流)
1.1.1.4 Buffer
缓冲区,面向块编程,底层就是个数组,用各个标记控制数组长度与大小,由于可读也可写,所以实时都会改变
1.1.1.5 Channel
Channel本身是个接口,Buffer有源码,Channel也有。可用于读取文件、网络传输等等等等。之前的InputStream内部就包含了Channel
1.1.1.6 Buffer-Channel实战
程序 <=> Buffer <=> Channel <=> 文件:所以不仅可以读取文件内容程序输出,也可以读取文件内容输出到另一个文件。除了单个Buffer,还可以定义Buffer数组(服务器网络交互中进行处理,一个Channel对应一个Buffer数组)
Channel.write(Buffer):表明Buffer往Channel写
Channel.read(Buffer):表明Channel从Buuffer读
1.1.1.7 MappedByteMapper(略)
在直接内存(堆外内存)操作数据,操作系统就不需要拷贝一次
1.1.1.8 Selector
就是将每个Channel注册到Selector中,然后当Channel有数据传入进来时,Selector非阻塞式读取,避免了每个请求都创建一个线程,减少了多线程上下文的切换。
具体注册流程就是客户端通过ServerSocketChannel注册到Selector中,Selector维护一个SelectionKey的集合返回
1.1.1.9 NIO--群聊系统(略)
就是用Selector + Channel + Buffer实现局域网消息单聊与群聊,暂时感觉用不到,比较枯燥,先跳过,先了解理论知识即可。
1.2 基本名词
1.2.1 零拷贝
1.2.1.1 基本概念
DMA:direct memory access 直接内存拷贝,不使用CPU
1.2.1.2 实际场景
参考链接:https://blog.csdn.net/shenchaohao12321/article/details/115464117
零拷贝:本质就是内核缓冲区中间没有重复数据,减少数据拷贝次数
传统IO:用户依次发起read、write请求,整个过程发送4次用户态和内核态上下文切换与数据拷贝
mmap内存映射:4次上下文切换,3次数据拷贝。write的时候减少了一次。适合小文件读取
sendFile(Linux中):3次上下文切换,最少2次数据拷贝,适合大文件读取
1.2.2 AIO
AIO两种模式:Reactor, Proactor。NIO本身也是一个Reactor。
1.2.3 Netty
1.2.3.1 基本概念
Es,dubbo底层都用到了Netty, netty对nio各种api接口进行了封装
1.2.3.2 线程模型
- 传统IO模型:就是类似BIO,每个连接创建一个线程处理
- Reactor模型:就是用一个单独线程处理多个客户端连接,然后类似用线程池分发处理
- 单Reactor单线程:服务器单线程处理客户端某个请求的时候,其他客户端请求会阻塞
1. - 单Reactor多线程:服务器单线程用类似线程池分发处理客户端的多个请求。
1. - 主从Reactor多线程(Netty就是基于这个做了改进):分了3层,主线程建立连接,请求分给多个子线程,每个子线程又分给多个线程来进行handler处理,处理结果可以返回给子线程(不给主线程)。
1.
🔥2.进阶内容
2.1. 基本概念
2.1.1 RPC
2.1.1.1 基本概念
远程过程调用:计算机程序调用另一个计算机子程序。
常见RPC框架:dubbo, springcloud
2.1.1.2 基本开发
实际开发中,使用Netty实现rpc调用,就是需要客户端和服务端都开发netty代码,然后调用返回相应的对象。
我曾七次鄙视自己的灵魂:
第一次,当它本可进取时,却故作谦卑;
第二次,当它在空虚时,用爱欲来填充;
第三次,在困难和容易之间,它选择了容易;
第四次,它犯了错,却借由别人也会犯错来宽慰自己;
第五次,它自由软弱,却把它认为是生命的坚韧;
第六次,当它鄙夷一张丑恶的嘴脸时,却不知那正是自己面具中的一副;
第七次,它侧身于生活的污泥中,虽不甘心,却又畏首畏尾。