# Learningdemo **Repository Path**: hezimige/Learningdemo ## Basic Information - **Project Name**: Learningdemo - **Description**: 学习和研究时编写的demo,目前包含akka,plantUML.策略模式demo,netty常见api运用等; 当前最主要的作用为作为akkacloud项目的试验品,一切新尝试都会先在这里编写demo验证。 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-06-14 - **Last Updated**: 2022-11-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: AKKA, Netty, Java ## README # Learningdemo #### 介绍 包括学习和研究时创建的各种demo #### 1.策略模式+工厂模式demo #### 2.PlantUML的尝试体验 #### 3.Akka相关 #### 3.1 akka untype actor 3.2 akka router pool/group 的各种实验 3.3 akka cluster及对应的cluster配置尝试 集群感知路由器 分布式发布订阅与router结合的实验。 3.4 基于actor实现的异步非阻塞线程安全能扛并发使用kryo序列化传输信息的服务间调用及适用于cluster的负载均衡 3.5 akka http:akka http route, http client 3.6 akka type actor 各类api 3.7 akka distribute data 待完成 #### 4.Netty的服务端与客户端通信及各种api使用方式demo。 #### 5.scheduleExecutor,jdk提供的适用于多线程的定时任务demo #### 6.算法相关 #### 1.快速排序 2.直接插入排序 3.希尔排序 4.快速排序结合希尔排序尽力提升性能:目前成果,长度为五万的数组排序平均值为3.1ms, 比上述所有都快,长度为五十万的数组排序平均值为:36ms #### 7.vert.x demo netty相关知识介绍: ​ Netty的介绍:`Netty`是 一个`异步事件驱动`的网络应用程序框架,用于`快速开发可维护的高性能协议服务器和客户端`。`Netty` 本质是一个 `NIO` 框架,适用于服务器通讯相关的多种应用场景 ​ Netty架构图: ![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91Y2MuYWxpY2RuLmNvbS9waWMvZGV2ZWxvcGVyLWVjb2xvZ3kvMTU5NDRhZGUwMTQyNDcxMzk5OTk3ZWZkNjhlNTI5NDgucG5n?x-oss-process=image/format,png) ``` 绿色的部分Core核心模块,包括零拷贝、API库、可扩展的事件模型。 橙色部分Protocol Support协议支持,包括Http协议、webSocket、SSL(安全套接字协议)、谷歌Protobuf协议、zlib/gzip压缩与解压缩、Large File Transfer大文件传输等等。 红色的部分Transport Services传输服务,包括Socket、Datagram、Http Tunnel等等。 ``` ​ Netty工作原理: ​ 1.server端工作原理:![](https://pic3.zhimg.com/v2-be711058eaa12cbb17c3ce6c60aab4be_r.jpg) ​ server端启动时绑定本地某个端口,将自己NioServerSocketChannel注册到某个boss NioEventLoop的selector上。 ​ server端包含1个boss NioEventLoopGroup和1个worker NioEventLoopGroup,NioEventLoopGroup相当于1个事件循环组,这个组里包含多个事件循环NioEventLoop,每个NioEventLoop包含1个selector和1个事件循环线程。 ``` 每个boss NioEventLoop循环执行的任务包含3步: 1. 轮询accept事件; 2. 处理io任务,即accept事件,与client建立连接,生成NioSocketChannel,并将NioSocketChannel注册到某个worker NioEventLoop的selector上; 3. 处理任务队列中的任务,runAllTasks。任务队列中的任务包括用户调用eventloop.execute或schedule执行的任务,或者其它线程提交到该eventloop的任务。 ``` ``` 每个worker NioEventLoop循环执行的任务包含3步: 1. 轮询read、write事件; 2. 处理io任务,即read、write事件,在NioSocketChannel可读、可写事件发生时进行处理; 3. 处理任务队列中的任务,runAllTasks。 ``` ​ 2.client端工作原理:![](https://pic3.zhimg.com/v2-e5b1bc49e46a32d2dbe42131d5089d02_r.jpg) client端启动时connect到server,建立NioSocketChannel,并注册到某个NioEventLoop的selector上。 ``` client端只包含1个NioEventLoopGroup,每个NioEventLoop循环执行的任务包含3步: 1. 轮询connect、read、write事件; 2. 处理io任务,即connect、read、write事件,在NioSocketChannel连接建立、可读、可写事件发生时进行处理; 3. 处理非io任务,runAllTasks。 ``` ​ Netty的启动 ​ 1.服务端启动流程: ``` 1.首先创建了两个NioEventLoopGroup,这两个对象可以看做是传统IO编程模型的两大线程组,bossGroup表示监听端口,accept 新连接的线程组,workerGroup表示处理每一条连接的数据读写的线程组。 2.接下来创建了一个引导类 ServerBootstrap,这个类将引导我们进行服务端的启动工作,直接new出来开搞。 3.通过.group(bossGroup, workerGroup)给引导类配置两大线程组,这个引导类的线程模型也就定型了。 4.然后指定服务端的 IO 模型为NIO,我们通过.channel(NioServerSocketChannel.class)来指定 IO 模型。 5.最后我们调用childHandler()方法,给这个引导类创建一个ChannelInitializer,这里主要就是定义后续每条连接的数据读写,业务处理逻辑。ChannelInitializer这个类中,我们注意到有一个泛型参数NioSocketChannel,这个类是 Netty 对 NIO 类型的连接的抽象,而我们前面NioServerSocketChannel也是对 NIO 类型的连接的抽象,NioServerSocketChannel和NioSocketChannel的概念可以和 BIO 编程模型中的ServerSocket以及Socket两个概念对应上 ``` *总结:创建一个引导类,然后给他指定线程模型,IO模型,连接读写处理逻辑,绑定端口之后,服务端就启动起来了。* ​ 2.客户端启动流程 ``` 1.首先,与服务端的启动一样,需要给它指定线程模型,驱动着连接的数据读写 2.然后指定 IO 模型为 NioSocketChannel,表示 IO 模型为 NIO 3.接着给引导类指定一个 handler,这里主要就是定义连接的业务处理逻辑 4.配置完线程模型、IO 模型、业务处理逻辑之后,调用 connect 方法进行连接,可以看到 connect 方法有两个参数,第一个参数可以填写 IP 或者域名,第二个参数填写的是端口号,由于 connect 方法返回的是一个 Future,也就是说这个方是异步的,我们通过 addListener 方法可以监听到连接是否成功,进而打印出连接信息 ``` *总结:创建一个引导类,然后给他指定线程模型,IO 模型,连接读写处理逻辑,连接上特定主机和端口,客户端就启动起来了* ​ EventLoopGroup和NioEventLoopGroup的继承体系: ![](https://img-blog.csdnimg.cn/20190430165643707.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NoZW5jaGFvaGFvMTIzMjE=,size_16,color_FFFFFF,t_70) ​ ByteBuf: ``` ByteBuf是一个节点容器,里面数据包括三部分: 1. 已经丢弃的数据,这部分数据是无效的 2. 可读字节,这部分数据是ByteBuf的主体 3. 可写字节 这三段数据被两个指针给划分出来,读指针、写指针。 ``` ByteBuf 本质上就是,它引用了一段内存,这段内存可以是堆内也可以是堆外的,然后用引用计数来控制这段内存是否需要被释放,使用读写指针来控制对 ByteBuf 的读写,可以理解为是外观模式的一种使用 基于读写指针和容量、最大可扩容容量,衍生出一系列的读写方法,要注意 read/write 与 get/set 的区别 多个 ByteBuf 可以引用同一段内存,通过引用计数来控制内存的释放,遵循谁 retain() 谁 release() 的原则 ``` ByteBuf和ByteBuffer的区别 可扩展到用户定义的buffer类型中 通过内置的复合buffer类型实现透明的零拷贝(zero-copy) 容量可以根据需要扩展 切换读写模式不需要调用ByteBuffer.flip()方法 读写采用不同的索引 支持方法链接调用 支持引用计数 ``` ======= #### >>>>>>> origin/master