Netty的深入浅出--49.Scalable IO in Java的多线程版本分析(二)

多线程设计

*策略性的增加线程为的是可伸缩性,主要应用于多核处理器中

工作线程(对于我们的workGroup)

reactor应该能够快速的触发处理器

*处理器会减慢reactor的处理(原因:因为reactor将任务分发出给handler,因为是单线程,所以处理器被分发的任务变多的时候,就会拖慢reactor的处理)

因此卸去一些非IO的处理交给其他的线程处理

多个reactor线程

reactor线程能够进行IO的处理

分配负载到其他的reactor中

负载均衡,让CPU和IO速率进行匹配

工作线程:

*卸去非IO处理来提高速度

reactor线程

类似于POSA2 Proactor designs

*比起重新计算绑定过程到事件驱动形式更加简单

仍然应该是纯粹的非阻塞的计算

*足够的过程去处理负载

*但是很困难进行IO重叠处理

最好的操作是能够首先将读全部输入到一个buffer中

使用线程池能够进行调整和控制

通常线程的数量比客户端的数量要少

 还是多个客户端与reactor发起连接,我们可以看到它是通过一个线程池来处理请求的

查看线程池的处理方式,

协同任务

*Handoffs

每一个任务都能够被启用,触发或者调用下一个

它是很快的,但是很脆弱

Callbacks  :针对于每个处理器分配器

设置状态,attachment等

一种gof调停者模式

队列

例如:传递buffers在某些阶段

Futures

每一个任务都产生一个结果

在join或者wait/notify的上面实现协同阶段

 使用PoolExecutor

*一个和谐的工作线程池

*主要的方法是execute(Runnable r)

*Controls for:

任务队列的种类

线程的最大数量

线程的最小数量

“Warm”与 on-demand线程

保持存活的时间间隔直到线程死亡

*如果有必要的话,新的可以替换掉老的

饱和的策略:

*阻塞,去除,制作-运行等

多个reactor线程

*使用Reactor Pools

用于匹配CPU和IO的速率

静态的和动态的构建

*每一个都拥有自己的selector、线程、调度循环

主要的acceptor会分发(处理器)给其他的reactor;

 使用多Reactor

mainReactor理解成netty中的bossGroup(parentGroup)

subReactor理解成netty中的workGroup(childGroup)

 使用其他的NIO特性

*每个Reactor对应着多个selectors

将不同的处理器绑定到不同的IO事件。

需要一些同步来协调。

*文件传输

自动化的文件传输到网络或网络传输到文件的拷贝

*记忆映射文件

获取文件通过buffers

*Direct buffers

能够实现0拷贝传输

有些创建和结束

对于那些长连接它的效果是更好的

基于连接的扩展

*而不是单个服务请求

客户端连接

客户端发送一系列的信息和请求

客户端断开连接

例子:

数据库和事务的监控

 

对java的API进行一些说明:

 

 

2023-07-14 15:19:01.215 WARN 7308 --- [sson-netty-2-15] io.netty.util.concurrent.DefaultPromise : An exception was thrown by org.redisson.misc.RedissonPromise$$Lambda$888/0x00000008008f7440.operationComplete() java.lang.NullPointerException: null 2023-07-14 15:19:01.216 ERROR 7308 --- [sson-netty-2-15] o.r.c.SentinelConnectionManager : Can't execute SENTINEL commands on /172.24.107.11:26379 org.redisson.client.RedisException: ERR No such master with that name. channel: [id: 0x2d66827d, L:/172.23.9.103:46812 - R:/172.24.107.11:26379] command: (SENTINEL SLAVES), params: [mymaster] at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:365) ~[redisson-3.13.3.jar:3.13.3] at org.redisson.client.handler.CommandDecoder.decodeCommand(CommandDecoder.java:196) ~[redisson-3.13.3.jar:3.13.3] at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:134) ~[redisson-3.13.3.jar:3.13.3] at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:104) ~[redisson-3.13.3.jar:3.13.3] at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:501) ~[netty-codec-4.1.51.Final.jar:4.1.51.Final] at io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:366) ~[netty-codec-4.1.51.Final.jar:4.1.51.Final] at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276) ~[netty-codec-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) ~[netty-common-4.1.51.Final.jar:4.1.51.Final] at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.51.Final.jar:4.1.51.Final] at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.51.Final.jar:4.1.51.Final] at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na] 解决方法
07-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值