深圳php网站建设,所得税汇算是在12366网站做吗,网站链接优化怎么做,访问紧急升级中通知问升级Netty Netty初体验基础概念Reactor模型传统的阻塞IO模型基础Reactor模型多线程Reactor模型 为什么要使用Netty#xff1f; #xff08;NIO的框架#xff0c;用于解决高并发出现的问题#xff09;
*BIO:同步且阻塞的IO NIO:同步且非阻塞的IO#xff08;不是说线程#x… Netty Netty初体验基础概念Reactor模型传统的阻塞IO模型基础Reactor模型多线程Reactor模型 为什么要使用Netty NIO的框架用于解决高并发出现的问题
*BIO:同步且阻塞的IO NIO:同步且非阻塞的IO不是说线程 AIO:异步且非阻塞的IO 还没有实现业务光写整个流程就非常繁琐。NIO除了实现起来复杂之外还存在一些需要解决的棘手问题比如客户端断线重连如何实现心跳处理(客户端在一定的时间内不断的向服务器发送信息告诉服务器还在)、半包读写处理等等一些列问题此时需要有这么一个框架用于解决和优化NIO存在的问题它就是Netty。
目的客户端越来越多随着客户端的增多代码的复杂程度就变高netty帮我们降低了编写nio的代码复杂程度* Netty初体验
第一步引入依赖
dependenciesdependencygroupIdio.netty/groupIdartifactIdnetty-all/artifactIdversion4.1.35.Final/version/dependency
/dependencies服务器端
public class NettyServer {public static void main(String[] args) throws Exception {//创建只处理连接请求的线程组EventLoopGroup bossGroup new NioEventLoopGroup(10);//创建只处理客户端读写业务的线程组EventLoopGroup workGroup new NioEventLoopGroup(10);//创建服务端启动对象ServerBootstrap bootstrap new ServerBootstrap();//配置参数bootstrap.group(bossGroup,workGroup)//使用NioServerSocketChannel作为服务器的通道实现.channel(NioServerSocketChannel.class)//配置用于存放因没有空闲线程导致连接请求被暂存放到队列中的队列长度.option(ChannelOption.SO_BACKLOG,1024)//创建通道初始化的对象并配置该对象,向该对象中添加处理器来实现具体的业务.childHandler(new ChannelInitializerSocketChannel() {//初始化通道Overrideprotected void initChannel(SocketChannel ch) throws Exception {//添加处理器,处理器里面是真正处理业务的ch.pipeline().addLast(new NettyServerHandler());}});//配置groupSystem.out.println(Netty服务器启动了);//同步阻塞地启动服务器ChannelFuture channelFuture bootstrap.bind(9090).sync();//只要服务没关闭该方法会一直阻塞channelFuture.channel().closeFuture().sync();System.out.println(a);bossGroup.shutdownGracefully();workGroup.shutdownGracefully();}
}public class NettyServerHandler extends ChannelInboundHandlerAdapter {//当有客户端发送数据来的时候该方法就会被调用Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {ByteBuf buf (ByteBuf) msg;System.out.println(客户端发送的数据:buf.toString(StandardCharsets.UTF_8));}//读完数据之后调用的方法:发送数据给客户端Overridepublic void channelReadComplete(ChannelHandlerContext ctx) throws Exception {//创建携带的ByteBuf对象ByteBuf buf Unpooled.copiedBuffer(hello client.getBytes(StandardCharsets.UTF_8));ctx.writeAndFlush(buf);}//异常捕获Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {System.out.println(cause.getMessage());ctx.close();}
}客户端
public class NettyClient {public static void main(String[] args) throws Exception {//创建一个线程组用于事件循环EventLoopGroup eventLoopGroup new NioEventLoopGroup();//创建客户端启动对象Bootstrap bootstrap new Bootstrap();//设置相关参数bootstrap.group(eventLoopGroup)//使用NioSocketChannel作为客户端的通道实现.channel(NioSocketChannel.class)//创建通道初始化对象并设置handler业务处理器.handler(new ChannelInitializerSocketChannel() {Overrideprotected void initChannel(SocketChannel ch) throws Exception {//添加处理器处理器里面是实现具体业务的ch.pipeline().addLast(new NettyClientHandler());}});System.out.println(Netty客户端启动了);//告知客户端的服务器的地址并启动客户端ChannelFuture channelFuture bootstrap.connect(127.0.0.1,9090).sync();channelFuture.channel().closeFuture().sync();//阻塞等待完成操作后关闭通道eventLoopGroup.shutdownGracefully();}
}public class NettyClientHandler extends ChannelInboundHandlerAdapter {//当客户端完成连接服务器后调用该方法Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {ByteBuf buf Unpooled.copiedBuffer(hello server.getBytes(StandardCharsets.UTF_8));ctx.writeAndFlush(buf);}//当通道有读事件发生时调用的方法读取服务器返回的数据Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {ByteBuf buf (ByteBuf) msg;System.out.println(来自服务器ctx.channel().remoteAddress()的消息buf.toString(StandardCharsets.UTF_8));}
}基础概念
NIO中实现多路复用的核心类是Selector当多路复用器Selector调用select方法时将会查找发生事件的 channel问题是该如何在多个注册到selector上的channel中找到哪些channel发生了事件此时NIO不同的版本有不同的做法。 epoll函数 poll函数 select函数
Reactor模型
不同的线程决定了程序的性能多线程是为了充分利用CPU
传统的阻塞IO模型 客户端连接服务端之后会等客户端输入完之后最后响应给客户端才能紧接着为其它的客户端执行任务因为等待会耗费大量时间所以并没有把CPU用到极致
基础Reactor模型 可以执行完连接之后让别的客户端来拿来处理自己的任务各个操作之间是独立的充分利用服务端之间的性能可能是连接的也可以是读的也可以是写的
多线程Reactor模型