高性能网络应用框架

news/2024/12/2 21:55:38/

技术主题

Netty从本质上讲是一个高性能网络应用框架,之所以说是高性能,依赖于Netty的线程模型。

一网络编程性能的瓶颈

BIO 模型里, read() 操作和 write() 操作都会阻塞当前线程的,如果客户端已经和服务端建立了一个连接,而迟迟不发送数据,那么服务端的 read() 操作会一直阻塞,所以使用 BIO 模型,一般都会为每个 socket 分配一个独立的线程。

BIO线程模型适用于socket连接不是很多的场景,随着互联网的发展,需要支持的连接数也会很多,上万级别,甚至是上百万级别。线程大部分的时间在等待I/O就绪,阻塞,浪费资源。

二Reactor 模式

Reactor中的Handle指的是I/O句柄,本质是一个网络连接
Event Handle事件处理器,handle_event() 方法处理 I/O 事件,也就是每个 Event Handler 处理一个 I/O Handle;get_handle() 方法可以返回这个 I/O 的 Handle
Synchronous Event Demultiplexer 可以理解为操作系统提供的 I/O 多路复用 API


void Reactor::handle_events(){//通过同步事件多路选择器提供的//select()方法监听网络事件select(handlers);//处理网络事件for(h in handlers){h.handle_event();}
}
// 在主程序中启动事件循环
while (true) {handle_events();

三Netty中的线程模型

Netty 中最核心的概念是事件循环(EventLoop),其实也就是 Reactor 模式中的 Reactor,负责监听网络事件并调用事件处理器进行处理。
在这里插入图片描述

四用Netty实现Echo程序服务端

Netty 实现了 echo 程序服务端:首先创建了一个事件处理器(等同于 Reactor 模式中的事件处理器),然后创建了 bossGroup 和 workerGroup,再之后创建并初始化了 ServerBootstrap,代码还是很简单的,不过有两个地方需要注意一下


//事件处理器
final EchoServerHandler serverHandler = new EchoServerHandler();
//boss线程组  
EventLoopGroup bossGroup = new NioEventLoopGroup(1); 
//worker线程组  
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {ServerBootstrap b = new ServerBootstrap();b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {@Overridepublic void initChannel(SocketChannel ch){ch.pipeline().addLast(serverHandler);}});//bind服务端端口  ChannelFuture f = b.bind(9090).sync();f.channel().closeFuture().sync();
} finally {//终止工作线程组workerGroup.shutdownGracefully();//终止boss线程组bossGroup.shutdownGracefully();
}//socket连接处理器
class EchoServerHandler extends ChannelInboundHandlerAdapter {//处理读事件  @Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg){ctx.write(msg);}//处理读完成事件@Overridepublic void channelReadComplete(ChannelHandlerContext ctx){ctx.flush();}//处理异常事件@Overridepublic void exceptionCaught(ChannelHandlerContext ctx,  Throwable cause) {cause.printStackTrace();ctx.close();}
}

五总结

Netty 是一个款优秀的网络编程框架,为了实现高性能的目标,Netty 做了很多优化,例如优化了 ByteBuffer支持零拷贝等等,和并发编程相关的就是它的线程模型了。Netty 的线程模型设计得很精巧,每个网络连接都关联到了一个线程上,这样做的好处是:对于一个网络连接,读写操作都是单线程执行的,从而避免了并发程序的各种问题。


http://www.ppmy.cn/news/271232.html

相关文章

青龙面板·多容器

1.新建主容器&#xff08;如果已经开了的直接跳到步骤二&#xff09; docker run -dit \-v $PWD/ql/config:/ql/config \-v $PWD/ql/log:/ql/log \-v $PWD/ql/db:/ql/db \-v $PWD/ql/repo:/ql/repo \-v $PWD/ql/raw:/ql/raw \-v $PWD/ql/scripts:/ql/scripts \-v $PWD/ql/jbo…

Hive SQL间断日期补数

Hive SQL间断日期补数 0.业务场景 场景&#xff1a;用户间断消费&#xff0c;流水中无消费无记录&#xff0c;对用户每天余额进行补数。 1.补充数据代码 -- 补充间断日期中的数据 with data_test as (select stack(10,Jack,double(5000),2022-09-24,Jack,double(5035),2022…

LeetCode 5710 积压订单中的订单总数

题目链接 给你一个二维整数数组 orders &#xff0c;其中每个 orders[i] [price_i, amount_i, orderType_i] 表示有 amount_i 笔类型为 orderType_i 、价格为 price_i 的订单。 订单类型 orderTypei 可以分为两种&#xff1a; 0 表示这是一批采购订单 buy1 表示这是一批销售…

python实现可视化 基础(全)

建立坐标系 import matplotlib.pyplot as plt #导入matplotlib库 %matplotlib inline #让图标直接在juper notebook中展示 plt.rcParams[“font.sans-serif”]‘SimHei’ #解决中文乱码问题 plt.rcParams[‘axes.unicode_minus’]False #解决负号无法正常显示的问题 %config I…

openwrt设置5G功率

Openwrt 设置5G功率为 30dBm 硬件平台&#xff1a;AR9344 5G单频 2x2 300M 软件平台&#xff1a;openwrt CC版本 DB120参考板 默认编译后&#xff0c;wifi的功率为17dBm&#xff0c;使用iw命令修改功率时&#xff0c;设置不生效。 原因&#xff1a;默认国家码为US&#xff…

SPWM原理及STM32生成

绪论 SPWM在单向逆变器中运用的比较多&#xff0c;在电能与电机控制领域现在大都是用SVPWM。先学好spwm&#xff0c;为以后的进阶做准备&#xff01;本文主要是我学习spwm的一些理解&#xff0c;然后后通过实例代码生成spwm&#xff0c;可以直接复制测试。 一.什么是SPWM 要说…

HDU 5710 Digit-Sum

【题意】 我们要找出最小的正整数n满足—— a*S(n)b*S(2n) a,b的范围都在[1,100] 【分析&推导】 首先可以有这样的基础性结论&#xff1a; 设gcd(a,b)g, 我们可以先使得bb/g, aa/g S(n):S(2n)b:a&#xff0c;那么我们有S(n):S(2n)b:a。 然后&#xff0c;一个好的做法…

Python数据分析--可视化图表

绘制常用图表 折线图柱形图普通柱形图簇状柱形图堆积柱形图 条形图散点图气泡图面积图树地图雷达图箱形图饼图 折线图 plt.plot(x,y,color,linestyle,linewidth,marker,markeredecolor,markeregwidth,markerfacecolor,markersize,lable)x,y表示x轴和y轴的数据&#xff0c;为必…