NIO
- Buffer类及常用方法(最常见的有:ByteBuffer、CharBuffer等)
- IO多路复用
- select,poll,epoll
- Selector、SelectableChannel、SelectionKey
Netty
服务端Demo
Bootstrap b = new ServerBootstrap();
EventLoopGroup bossLoopGroup = new NioEventLoopGroup(1);
EventLoopGroup workerLoopGroup = new NioEventLoopGroup();
try {
b.group(bossLoopGroup, workerLoopGroup);
b.channel(NioServerSocketChannel.class);
b.localAddress(serverPort);
b.option(ChannelOption.SO_KEEPALIVE, true);
b.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
b.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
b.childHandler(new ChannelInitializer<SocketChannel>() {
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(......);
ch.pipeline().addLast(......);
}
});
ChannelFuture channelFuture = b.bind().sync();
Logger.info(" 服务器启动成功,监听端口: " +
channelFuture.channel().localAddress());
客户端Demo
Bootstrap b = new Bootstrap()
EventLoopGroup g = new NioEventLoopGroup()
try {
b.group(g)
b.channel(NioSocketChannel.class)
b.option(ChannelOption.SO_KEEPALIVE, true)
b.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
b.remoteAddress(host, port)
// 设置通道初始化
b.handler(......)
ChannelFuture f = b.connect()
......
// 此处的future与上面的f是同一个对象
f.addListener((ChannelFuture future) ->
{
final EventLoop eventLoop
= future.channel().eventLoop()
if (!future.isSuccess()) {
// 连接失败!在10s之后准备尝试重连!
eventLoop.schedule(
() -> doConnect(),
10,
TimeUnit.SECONDS)
} else {
channel = future.channel()
}
})
- bossGroup负责服务器通道新连接的IO事件的监听、workerGroup负责传输通道的IO事件的处理
- NioServerSocketChannel负责服务器监听和接收,称为父通道;接收到的NioSocketChannel,称为子通道
- 分配器
- PoolByteBufAllocator:池化ByteBuf分配器
- UnPooledByteBufAllocator:普通的ButeBuf分配器,比较占用内存
- ByteBuf缓冲区
- HeapByteBuf:JVM堆内存
- DirectByteBuf:操作系统物理内存,
是netty默认的缓冲区类型
- childHandler是装配子通道的流水线,父通道的业务处理是固定的:接受新连接后,创建子通道,然后初始化子通道,所以不需要特别的配置
- 每当有客户端连接时,会创建一个channel,同时添加一系列handler处理器
- 发送信息时,pipeline按照从后往前的顺序执行write方法,如果调用super.write(ctx, msg, promise),将其交给下一个Handler处理
- 发送消息完毕后,pipeline按照从后往前的顺序执行flush方法,如果调用super.flush(ctx),将其交给下一个Handler处理
- 接收信息时,pipeline按照添加顺序执行channelRead方法,如果调用super.channelRead(ctx, msg),将其交给下一个Handler处理
- 接收消息完毕后,pipeline按照添加顺序执行channelReadComplete方法,如果调用super.channelReadComplete(ctx),将其交给下一个Handler处理
- 在未调用过channel.close()方法的情况下断开连接时,pipeline按照添加顺序先执行channelReadComplete方法,再执行exceptionCaught方法,如果调用super.exceptionCaught(ctx, cause),将其交给下一个Handler处理
- 连接断开后,pipeline按照添加顺序执行channelInactive方法,如果调用super.channelInactive(ctx),将其交给下一个Handler处理;最后按照添加顺序执行channelUnregistered方法,如果调用super.channelUnregistered(ctx),将其交给下一个Handler处理
- 在Netty中,网络连接通道的输入和输出、入站和出站操作都是异步进行的,会返回一个ChannelFuture接口的实例,可以为实例增加异步回调的监听器。在异步任务真正完成后,回调才会执行。客户端Demo的代码演示的是连接时的异步回调监听。
编码与传输协议
- ByteToMessageDecoder,一个解码器抽象类,继承
ChannelInboundHandlerAdapter,在读取消息时,如果消息是ByteBuf实现类,会执行其实现类的decode方法(如:将ByteBuf解码为Java对象)
- 内置解码器有LineBasedFrameDecoder、DelimeterBasedFrameDecoder、LengthFieldBasedFrameDecoder等
- MessageToByteEncoder
<I>,一个编码器抽象类,继承ChannelOutboundHandlerAdapter,在发送消息时,如果消息是泛型对象I类或其子类,会执行其实现类的encode方法(如:将Java对象编码为ByteBuf)
- MessageToMessageEncoder,将一种Java对象编码成另一种Java对象
- 粘包:接收端收到一个ByteBuf,包含多个发送端的ByteBuf,多个ByteBuf粘在一起
- 半包:一个接收端收到的ByteBuf是发送端的一个ByteBuf的一部分
- ProtoBuf:一种数据交换格式,是一套类似于json或者xml的一种数据传输格式和规范,可以理解为一种序列化与反序列化方案
ZooKeeper
基本知识
- 下载,百度搜索ZooKeeper,在Apache官网下载
- 目录结构
日志目录:/log
数据目录:/data
数据目录下需要创建一个myid文件,记录节点id,要求唯一
配置目录:conf下的.cfg文件
启动服务端: /bin/zkServer.cmd
启动客户端:/bin/zkCli.cmd --server ip:port
- 集群节点要求是奇数,并且需要保证半数以上可用
- 达到半数以上时,会推举一个节点作为Leader节点,其他是Follower节点
- 首次选举
- Leader节点挂了,重新选举
- 节点间同步
- 常用命令
- 查看节点:ls
- 查看节点值:get
- 创建、修改、删除节点:create、set、delete、rmr
- 节点类型
- 持久化节点
- 持久化顺序节点
- 临时节点
- 临时顺序节点
- 存储模型
树形结构,一颗以"/"为根节点的数,每个圆圈是一个节点,称为ZNode,每个ZNode有一个节点值,如下图所示

Java api类:Curator
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.8</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
<version>4.0.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.0.0</version>
</dependency>
ZooKeeper应用
- 分布式Id(利用顺序节点自增)
- 分布式锁(利用Curator的InterProcessMutex)
- 服务监听(利用监听器实现,相关类有ZK原生Watcher、Curator的NodeCache、PathChildrenCache、TreeCache)