Netty框架模型

NIO 的类库和API繁杂,使用麻烦:需要熟练掌握Selector、ServerSocket、ChannelSocketChannel、 ByteBuffer等。开发工作量和难度都非常大: 例如客户端面临断连重连、 网络闪断、心跳处理、半包读写、 网络拥塞和异常流的处理等等。
Netty 对 JDK 自带的 NIO 的 API 进行了良好的封装,解决了上述问题。且Netty拥有高性能、 吞吐量更高,延迟更低,减少资源消耗,最小化不必要的内存复制等优点。
Netty 现在都在用的是4.x,5.x版本已经废弃,Netty 4.x 需要JDK 6以上版本支持。
Netty的使用场景:
1)互联网行业:在分布式系统中,各个节点之间需要远程服务调用,高性能的 RPC 框架必不可少,Netty 作为异步高性能的通信框架,往往作为基础通信组件被这些 RPC 框架使用。典型的应用有:阿里分布式服务框架 Dubbo 的 RPC 框架使用 Dubbo 协议进行节点间通信,Dubbo 协议默认使用Netty 作为基础通信组件,用于实现。各进程节点之间的内部通信。Rocketmq底层也是用的Netty作为基础通信组件。
2)游戏行业:无论是手游服务端还是大型的网络游戏,Java 语言得到了越来越广泛的应用。Netty作为高性能的基础通信组件,它本身提供了 TCP/UDP 和 HTTP 协议栈。
3)大数据领域:经典的 Hadoop 的高性能通信和序列化组件 Avro 的 RPC 框架,默认采用 Netty进行跨界点通信,它的 Netty Service 基于 Netty 框架二次封装实现。

Netty线程模型


模型解释

  1. Netty抽象2个线程池,Boss Group和Work Group。Boss Group用于处理Accept事件,Work Group 用于处理 Read 和Write事件。
  2. Boss Group和Work Group都属于EventLoopGroup。
  3. NioEventLoopGroup 相当于一个事件循环线程组, 这个组中含有多个事件循环线程 , 每一个事件循环线程是NioEventLoop 。
  4. 每一个NioEventLoop都会有一个Selector用于监听绑定的Chanel
  5. Boss NioEventLoop的处理流程如下:
    a. 进行accpet操作,返回SocketChanel
    b.将该Socketchanel注册到某个work NioEventLoop的seletor上
    c.处理任务队列的任务 , 即runAllTasks
  6. Work NioEventLoop的处理流程如下:
    a. 轮询所有注册到该Loop Seletor上的Socketchanel的Read/Write事件
    b.处理Read/Write事件
    c.runAllTasks处理任务队列TaskQueue的任务 ,一些耗时的业务处理一般可以放入

Netty 实战

写一个聊天室程序,服务端具备上线检测,群发聊天内容等。Netty极大的简化了NIO编程,开发者更多的是编写ChannelHandle逻辑做业务处理
服务端代码 Server

 package com.qinghaihu.chat;import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;/**
* @ClassName ChatServer
* @Description TODO
* @Author:Zhang Lianzhong
* @Date 2020/11/22 10:13 下午
* @Version 1.0
**/
public class ChatServer {public void openServer(int port){ServerBootstrap bootstrap = new ServerBootstrap();EventLoopGroup boss = new NioEventLoopGroup(1);  //create boss group, threadpool size is 1EventLoopGroup work = new NioEventLoopGroup(5); //create work group, threadpool size is 5bootstrap.group(boss,work);   //组合netty组件//配置handle组件bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast("encoder",new StringEncoder());ch.pipeline().addLast("decoder",new StringDecoder());ch.pipeline().addLast(new ServerChanelHandle());}});bootstrap.channel(NioServerSocketChannel.class);try{ChannelFuture channel = bootstrap.bind(port).sync();System.out.println(("服务端已启动,绑定端口:" + port));channel.channel().closeFuture().sync();} catch (InterruptedException e) {e.printStackTrace();}finally {boss.shutdownGracefully();work.shutdownGracefully();}}public static void main(String[] args){ChatServer server = new ChatServer();server.openServer(8090);}}

服务端ChannelHandle

package com.qinghaihu.chat;import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;/*** @ClassName ServerChanelHandle* @Description TODO* @Author:Zhang Lianzhong* @Date 2020/11/22 10:21 下午* @Version 1.0**/
public class ServerChanelHandle extends SimpleChannelInboundHandler {//必须定义为类成员变量。每个客户端连接时,都会new ChatServerHandler。static保证数据共享public static ChannelGroup cg = new  DefaultChannelGroup(GlobalEventExecutor.INSTANCE);@Overridepublic void handlerAdded(ChannelHandlerContext ctx) throws Exception {Channel ch = ctx.channel();for(Channel chanel: cg){chanel.writeAndFlush(ch.remoteAddress()+"进来啦!");}cg.add(ch);}/*** 上线处理* @param ctx* @throws Exception*/@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {Channel channel = ctx.channel();for(Channel ch: cg){ch.writeAndFlush(channel.remoteAddress()+"上线啦");}}@Overrideprotected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {Channel channel = ctx.channel();for(Channel ch: cg){if(channel ==ch){ch.writeAndFlush("我说"+msg);}else {ch.writeAndFlush(channel.remoteAddress()+"说:"+msg);}}}@Overridepublic void handlerRemoved(ChannelHandlerContext ctx) throws Exception {Channel channel = ctx.channel();cg.remove(channel);}@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {Channel channel = ctx.channel();String customerAddress = channel.remoteAddress().toString();for(Channel ch:cg){ch.writeAndFlush("客户端" + customerAddress + "下线了!");}}}

客户端Client

package com.qinghaihu.chat;import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;import java.util.Scanner;/*** @ClassName ChatClient* @Description TODO* @Author:Zhang Lianzhong* @Date 2020/11/22 10:54 下午* @Version 1.0**/
public class ChatClient implements Runnable{private String serverIP;private int port;public ChatClient(String serverIp,int port ){this.serverIP = serverIp;this.port = port;}@Overridepublic void run() {Bootstrap bootstrap = new Bootstrap();EventLoopGroup work = new NioEventLoopGroup(1);bootstrap.group(work);bootstrap.handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast("encode",new StringEncoder());ch.pipeline().addLast("decode",new StringDecoder());ch.pipeline().addLast(new ClientChanelHandle());}});bootstrap.channel(NioSocketChannel.class);ChannelFuture channelFuture = bootstrap.connect(serverIP,port);Channel channel = channelFuture.channel();Scanner scanner = new Scanner(System.in);while(scanner.hasNext()){String sendMsg = scanner.nextLine();channel.writeAndFlush(sendMsg);}work.shutdownGracefully();}public static void main(String[] args){new Thread(new ChatClient("127.0.0.1",8090)).start();}
}

客户端ChannelHandle

package com.qinghaihu.chat;import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;/*** @ClassName ClientChanelHandle* @Description TODO* @Author:Zhang Lianzhong* @Date 2020/11/22 11:08 下午* @Version 1.0**/
public class ClientChanelHandle extends SimpleChannelInboundHandler {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {System.out.println(msg);}
}

运行效果



Netty框架介绍及实战相关推荐

  1. Netty介绍及实战(二)之IO与NIO和多路复用与零拷贝

    Netty介绍及实战(一) 一.Netty到底是什么?什么是多路复用?什么叫做零拷贝? Netty是一个NIO客户端服务器框架,可以快速.轻松地开发协议服务器和客户端等网络应用程序.它极大地简化和简化 ...

  2. 【SpringBoot】Logback日志框架介绍和SpringBoot整合实战

    ========================11.Logback日志框架介绍和SpringBoot整合实战 2节课================================ 1.新日志框架L ...

  3. Netty介绍与实战(三)之粘包拆包

    一.传统NIO架构 step1. 我们传统的nio架构已经解决了多路复用,零拷贝等问题,已经十分优秀了,那为什么我们现在Netty如此火热呢? 1) 首先他使用简单,基本上都是模板化,我们可以更专注业 ...

  4. 《企业级ios应用开发实战》一2.2 iOS框架介绍

    2.2 iOS框架介绍 iOS衍生自Mac OS X的成熟内核,但iOS操作系统更紧凑和高效,支持iPhone和iPod Touch的硬件.iOS继承了Mac OS X的风格,包括:统一的OS X 内 ...

  5. 基于 Netty 网络编程项目实战课程

    一 基于 Netty 网络编程项目实战课程 1项目介绍 2Netty 介绍与相关基础知识 2.1Netty 介绍 简介 Netty 是由 JBOSS 提供的一个 java 开源框架.Netty 提供异 ...

  6. 新浪微博新兵训练营系列课程——平台RPC框架介绍

    新浪微博新兵训练营系列课程--平台RPC框架介绍 课程大纲 1.RPC简介 1.1 什么是RPC 1.2 RPC与其他远程调用方式比较 2.Motan RPC框架 2.1 RPC服务框架 2.2 Mo ...

  7. Netty框架架构解析+API+运行流程+网络编程文章集锦

    新手入门:目前为止最透彻的的Netty高性能原理和框架架构解析 <!-- 作者区域 --><div class="author"><a class=& ...

  8. ssm 异常捕获 统一处理_SpringMVC 统一异常处理介绍及实战

    背景 什么是统一异常处理 目标 统一异常处理实战 用 Assert(断言) 替换 throw exception 定义统一异常处理器类 扩展 总结 <Java 2019 超神之路> < ...

  9. 【分布式事务】tcc-transaction分布式TCC型事务框架搭建与实战案例(基于Dubbo/Dubbox)...

    一.背景 有一定分布式开发经验的朋友都知道,产品/项目/系统最初为了能够快速迭代上线,往往不太注重产品/项目/系统的高可靠性.高性能与高扩展性,采用单体应用和单实例数据库的架构方式快速迭代开发:当产品 ...

  10. 【Netty】Netty组件介绍

    Netty组件介绍 Netty有 Bootstrap/ServerBootstrap,Channel,EventLoop,ChannelFuture, ChannelHandler,ChannelPi ...

最新文章

  1. 王树彤IT美女七年磨一剑
  2. php的VC9-VC14运行库分享以及localhost访问404问题
  3. Spring Cloud:查看注册到Eureka上的应用信息
  4. mysql容器重启数据是否丢失_docker容器重启 数据会丢吗
  5. [LAMP]——mod_security和mod_evasive模块的安装
  6. python中yield讲解_「技术」如何深入理解Python中的 yield?
  7. matlab2c使用c++实现matlab函数系列教程-ones函数
  8. Shell命令-系统信息及显示之stat、du
  9. 118页/8万字重磅(附下载)| 全球智能网联汽车产业深度报告:未来已来 掘金智能网联汽车时代【华西汽车 崔琰团队】
  10. 开源软件、自由软件及免费软件的区别
  11. 10种常用数据分析方法
  12. VS Code插件安装位置
  13. 在pycharm中使用pyqt5时clicked().后面connect不自动补全问题解决办法
  14. 数位板使用技巧、个人数位板见解、插画教程...
  15. 企业人脸识别智能门禁系统解决方案
  16. ArcGIS jsAPI 本地部署字体符号乱码
  17. python罗盘时钟代码_jQuery css3创意的罗盘时钟代码
  18. Python爬虫:爬了7天的斗鱼,我们来看一下主播们的真实现状
  19. WPF的打印原理 实现打印页眉页脚和打印预览
  20. 屏蔽 app 开屏广告,舒畅了

热门文章

  1. Xshell 5 注册码
  2. C++ 字符串逆序输出
  3. java 程序计数器_JVM入门系列之程序计数器
  4. 计数器代码php,php的计数器程序_php
  5. OpenCms显示默认作者
  6. Java 运行环境安装(JRE JDK 区别)
  7. PcShare过360服务监控
  8. 重庆的flash游戏开发团队
  9. PHP操控Excel视频教程
  10. ET框架-02 ET框架-开发环境搭建