当前位置: 首页 > news >正文

手把手构建Netty

1.Netty基础

Netty是一个提供了易于使用的API的客户端、服务器框架;
并发高-NIO(非阻塞IO)
传输快-零拷贝:
分析:
使用了NIO的零拷贝;java中内存是分为堆和栈,还有字符串常量池等等;
如果有一些数据需要从IO中读取,并且放到堆里面;中间会经历一些缓冲区;也就是说,读的过程会分为两个步骤:从IO流中读取出来,放到缓存区;缓冲区读取放到堆里面;
当它需要去接受数据或者是传输数据。会去开辟一个新的堆内存;然后数据直接从IO读取到新的堆内存中去

对于协议的支持如下;
在这里插入图片描述
BIO:同步阻塞IO

Server会有一个专门的线程acceptor;专门来监听客户端之间的请求;
客户端增多的时候,就会频繁的创建和销毁相应线程,就要考虑线程池;

NIO:同步非阻塞IO

BIO、NIO与AIO的区别与理解:
三者的区别详细可参考如下链接:
https://blog.csdn.net/TOMORROW6COME/article/details/140048654

使用NIO所遇到的问题:
类库;api相对较为复杂;需要具备java多线程的技能;
断线重连,网络阻塞等问题的处理方式,实现难度较大;NIO内置使用存在一些bug;

Netty优点:高效;简单;支持主流协议;可定制性强;性能高;
Dubbo使用的是Netty;

2.Netty三种线程模型

Reactor线程模型;
在这里插入图片描述
只能用于小型的应用场景;
不适用于高负载高并发场景;因为一个NIO线程要去同时处理成百上千的请求;
性能支撑不了;即便给予服务器负载;对于海量的消息处理,编解码,处理跟发送消息
无法满足;超时,然后不断轮训;会造成恶性循环;

在这里插入图片描述
主从线程模型:一组线程池接受请求;一组线程池处理IO
在这里插入图片描述

3.Netty快速入门

(1)构建Netty的聊天服务器
使用主从线程池构建聊天服务器:
在这里插入图片描述
在启动的时候会返回一个实例;为ChannelFuture;
他的解释如下:大概意思就是因为NIO;所以会立即返回一个结果;同时,可能没有信息;
所以使用ChannelFuture,替代作为一个结果返回;
在这里插入图片描述

public static void main(String[] args) throws Exception {// 构建主从线程池// 定义主线程池,用于接受客户端的连接;但是不做任何处理,比如老板会谈业务,拿到业务就会交给workerGroup进行处理EventLoopGroup bossGroup = new NioEventLoopGroup();// 定义从线程池,处理主线程池交代的任务;公司业务员开展业务,完成老板交代的任务EventLoopGroup workerGroup = new NioEventLoopGroup();try {// 构建Netty服务器ServerBootstrap server = new ServerBootstrap();         // 服务启动类;server.group(bossGroup,workerGroup)                     // 把主从线程池组放入到启动类中.channel(NioServerSocketChannel.class)          // 设置NIO双向通道.childHandler(null);                            // 设置处理器,用于处理workerGroup业务// 启动server,并且绑定端口号875,同时启动方式为同步ChannelFuture channelFuture = server.bind(875).sync();   //.sync是保证服务启动后一直运行;不写sync,代码一运行完就没有了//监听关闭的channelchannelFuture.channel().closeFuture().sync();} finally {// 优雅关闭线程池组bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}
}

(2)设定channel的初始化器
Pipeline需要开发者自己去编写;handler助手类:用于处理请求;
在这里插入图片描述

/*** Created by nly** 初始化器,channel注册后,会执行里面的响应的初始化方法**/
public class HttpServerInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel channel) throws Exception {// 通过SocketChannel 获得对应的管道ChannelPipeline pipeline = channel.pipeline();/*** 通过管道,添加handler处理器*/// HttpServerCodec 是netty 自己提供的助手类,此处可以理解为管道中的拦截器// 当请求到服务端,我们需要进行做解码,相应到客户端做解码pipeline.addLast("",new HttpServerCodec());// 添加自定哦助手类,当请求访问,返回"hello,netty"pipeline.addLast("",null);}
}

(3)编写HTTP自定义助手类
先处理http;先不构建Netty服务器;
HttpObject是处理的泛型;
先构建基本的逻辑与框架;
通过上下文对象ctx去获取channel;拿到channel之后,就能获取到跟客户端
相关的信息了
概念缓冲区:bytebuf:定义数据发送的消息;读写数据;

/*** 创建自定义助手类***/
public class HttpHandler extends SimpleChannelInboundHandler<HttpObject> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx,HttpObject msg) throws Exception {// 获取channelChannel channel = ctx.channel();// 打印客户端的远程地址System.out.println(channel.remoteAddress());// 通过缓冲区定义发送的消息,读写数据都是通过缓冲区进行数据交换的ByteBuf content = Unpooled.copiedBuffer("hello netty!", CharsetUtil.UTF_8);// 构建http的responseFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,HttpResponseStatus.OK,content);// 为响应添加数据类型和数据长度response.headers().set(HttpHeaderNames.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE);response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());// 把响应数据写到缓冲区再刷到客户端ctx.writeAndFlush(response);}
}

(3)Netty服务的生命周期
关注到netty的生命周期问题;
ChannelInboundHandlerAdapter
在这里插入图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【前端 · 面试 】TCP 总结(一)—— 概述
  • SpringCloud Alibaba 微服务(四):Sentinel
  • Web前端:HTML篇(一)
  • ubuntu修改anaconda权限
  • 配置文件application.properties
  • input().strip()什么意思
  • jdk1.8中HashMap为什么不直接用红黑树
  • 基于opencv的答题卡识别
  • AI的学习明确路径
  • 环境如何搭建部署Nacos
  • 神经网络的参数初始化【PyTorch】
  • arduino程序-MC猜数字1(基础知识)
  • python I 嵌套列表的多种展开方法
  • 32--蜂鸣器
  • 反爬虫限制:有哪些方法可以保护网络爬虫不被限制?
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • 10个最佳ES6特性 ES7与ES8的特性
  • 2017 年终总结 —— 在路上
  • CSS 专业技巧
  • hadoop集群管理系统搭建规划说明
  • Java IO学习笔记一
  • Java,console输出实时的转向GUI textbox
  • LintCode 31. partitionArray 数组划分
  • Linux Process Manage
  • Map集合、散列表、红黑树介绍
  • Material Design
  • PHP变量
  • React Transition Group -- Transition 组件
  • React16时代,该用什么姿势写 React ?
  • webpack项目中使用grunt监听文件变动自动打包编译
  • 阿里云应用高可用服务公测发布
  • 盘点那些不知名却常用的 Git 操作
  • 前端相关框架总和
  • 入门级的git使用指北
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 通过npm或yarn自动生成vue组件
  • 线性表及其算法(java实现)
  • 怎样选择前端框架
  • ​如何在iOS手机上查看应用日志
  • ​探讨元宇宙和VR虚拟现实之间的区别​
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • #include<初见C语言之指针(5)>
  • ()、[]、{}、(())、[[]]等各种括号的使用
  • (03)光刻——半导体电路的绘制
  • (6) 深入探索Python-Pandas库的核心数据结构:DataFrame全面解析
  • (Ruby)Ubuntu12.04安装Rails环境
  • (草履虫都可以看懂的)PyQt子窗口向主窗口传递参数,主窗口接收子窗口信号、参数。
  • (独孤九剑)--文件系统
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (算法设计与分析)第一章算法概述-习题
  • (一)、python程序--模拟电脑鼠走迷宫
  • (转)自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  • (自用)gtest单元测试
  • 、写入Shellcode到注册表上线