* [Java集合](#java集合)
* [NIO](#nio)
* [NIO特点](#nio特点)
* [BIO的特点以及缺点](#bio的特点以及缺点)
* [特点](#特点)
* [缺点](#缺点)
* [NIO 文件读写](#nio-文件读写)
* [NIO聊天室](#nio聊天室)
* [NIO Server](#nio-server)
* [Nio Client](#nio-client)
* [NIO零拷贝问题](#nio零拷贝问题)
* [mmap](#mmap)
* [sendFile](#sendfile)
* [mmap 和 sendFile 的区别](#mmap-和-sendfile-的区别)
* [Netty](#netty)
* [前言](#前言)
* [Reactor模型](#reactor模型)
* [Netty流程及源码解读](#netty流程及源码解读)
* [启动流程](#启动流程)
* [总体流程](#总体流程)
* [启动流程源码解读](#启动流程源码解读)
* [接受连接OP_ACCEPT请求流程](#接受连接op_accept请求流程)
* [总体流程](#总体流程-1)
* [相关源码](#相关源码)
* [ChannelSocket的PipeLine调度handler流程](#channelsocket的pipeline调度handler流程)
* [总体流程](#总体流程-2)
* [相关源码](#相关源码-1)
* [心跳流程](#心跳流程)
* [总体流程](#总体流程-3)
* [相关源码](#相关源码-2)
* [总结](#总结)
* [handler 中加入线程池和 Context 中添加线程池的源码剖析](#handler-中加入线程池和-context-中添加线程池的源码剖析)
* [两种解决方式](#两种解决方式)
* [要如何选择两种方式?](#要如何选择两种方式)
* [实现类讲解](#实现类讲解)
* [BootStrap、ServerBootStrap](#bootstrapserverbootstrap)
* [常用的方法](#常用的方法)
* [服务器端:](#服务器端)
* [客户端](#客户端)
* [Future、ChannelFuture](#futurechannelfuture)
* [常用方法](#常用方法)
* [Channel](#channel)
* [Selector](#selector)
* [ChannelHandler极其实现类](#channelhandler极其实现类)
* [Pipeline和ChannelPipeline](#pipeline和channelpipeline)
* [常用方法](#常用方法-1)
* [ChannelHandlerContext](#channelhandlercontext)
* [ChannelOption](#channeloption)
* [TCP参数表](#tcp参数表)
* [EventGroupLoop极其实现类NioEventGroupLoop](#eventgrouploop极其实现类nioeventgrouploop)
* [EventLoop](#eventloop)
* [Unpooled](#unpooled)
* [TCP的粘包/拆包问题](#tcp的粘包拆包问题)
* [什么是TCP的粘包拆包?](#什么是tcp的粘包拆包)
* [为什么会发生TCP粘包、拆包?](#为什么会发生tcp粘包拆包)
* [粘包、拆包解决办法](#粘包拆包解决办法)
* [Netty解决粘包拆包的方法](#netty解决粘包拆包的方法)
* [自定义协议包](#自定义协议包)
* [编码器](#编码器)
* [解码器](#解码器)
* [简单的服务器端与客户端交互](#简单的服务器端与客户端交互)
* [服务端](#服务端)
* [客户端](#客户端-1)
* [效果图](#效果图)
* [Http服务器](#http服务器)
* [效果图](#效果图-1)
* [聊天室](#聊天室)
* [服务端](#服务端-1)
* [客户端](#客户端-2)
* [效果图](#效果图-2)
* [简易RPC](#简易rpc)
* [通用类模块](#通用类模块)
* [生产者模块(服务被调用者)](#生产者模块服务被调用者)
* [步骤](#步骤)
* [1. 实现通用类下面的接口](#1-实现通用类下面的接口)
* [2. 实现Netty以及处理类](#2-实现netty以及处理类)
* [消费者模块(服务调用者)](#消费者模块服务调用者)
* [步骤](#步骤-1)
* [1. 暴露接口级注解实现](#1-暴露接口级注解实现)
* [2. 实现Netty以及处理类](#2-实现netty以及处理类-1)
* [3. 代理类实现](#3-代理类实现)
* [4. 处理类实现](#4-处理类实现)
* [效果图](#效果图-3)
* [Thread](#thread)
* [BigData](#bigdata)
* [Hive](#hive)
* [HBase](#hbase)
* [Spark](#spark)
* [Flink](#flink)
# Java集合
待更新
# NIO
## NIO特点
> JavaNIO :同步非阻塞, 服务器实现模式为一个线程处理多个请求(连接),即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求就进行处理
## BIO的特点以及缺点
> 同步并阻塞(传统阻塞型),服务器实现模式为一个连接一一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销
### 特点
BIO的特点就是每个请求都要开一个线程去进行与客户端的通信,进行数据的读写操作,其工作图如下:
![](http://image.tinx.top/img20210730110452.png)
### 缺点
+ 当并发数较大的时候,需要创建大量的线程来处理连接,系统资源占用比较大。
+ 连接建立后,如果当前线程暂时没有数据可以读取,那么这个线程就会被**阻塞**到读取这个命令下,造成资源浪费。
## NIO 文件读写
[文件读](./src/main/java/com/wills/nio/example/ReadExample.java)
[文件先读后写](./src/main/java/com/wills/nio/example/WriteExample.java)
## NIO聊天室
### NIO Server
> 大致流程就是:
>
> 1. 创建一个服务端类NioChatGroupServer,构造方法用于初始化 ServerSocketChannel、Selector、InetSocketAddress,然后注册Select的OP_ACCEPT连接行为
> 2. 创建一个listen方法,用于接收/转发客户端发送的消息
> 3. Listen方法内,首先先调用 selector的select方法,拿到已经准备好io的keys,如果准备好的数量大于0
> 4. 就进行遍历这些key,如果key的状态是 isAcceptable 说明是刚刚连接,就进行客户端通知,xxx上线了
> 5. 如果key的状态时 isReadable 说明是发送了消息,就进行消息读取/转发的操作
效果图:
![](http://image.tinx.top/img20210730115330.png)
[多人聊天室-服务端](./src/main/java/com/wills/nio/example/chat/NioChatGroupServer.java)
### Nio Client
> 大致流程:
>
> 1. 创建一个聊天客户端类NioChatGroupClient,构造方法用于初始化 Selector、SocketChannel,注册selector的消息读取的事件 SelectionKey.OP_READ
> 2. 创建一个 sendSay 方法,该方法用于发送自己说的话,具体的流程就是调用socketChannel的write方法,进行消息的发送
> 3. 创建一个 receiveSay 方法,该方法用于读取别人说的话,具体的流程就是 先调用 selector的select方法,,如果触发了SelectionKey.OP_READ事件的个数大于0,那么就进行channel.read 读取消息,然后显示在屏幕上
客户端上线时,服务器以及另一个客户端的效果图:
![](http://image.tinx.top/img20210730115952.png)
聊天的效果图:
![](http://image.tinx.top/img20210730120052.png)
[多人聊天室-客户端](./src/main/java/com/wills/nio/example/chat/NioChatGroupClient.java)
## NIO零拷贝问题
初学 Java 时,我们在学习 IO 和 网络编程时,会使用以下代码:
```java
File file = new File("index.html");
RandomAccessFile raf = new RandomAccessFile(file, "rw");
byte[] arr = new byte[(int) file.length()];
raf.read(arr);
Socket socket = new ServerSocket(8080).accept();
socket.getOutputStream().write(arr);
```
我们会调用