`
xklin04
  • 浏览: 12742 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Netty源码分析之消息的收发

阅读更多
在前面已经说明了在接收新连接时,将向worker注册默认的READ事件。然后worker开始阻塞select监听事件。
发送消息的情况。
这种情况常常是由DownstreamHandler主动发起,在对接收的消息处理后主动发送消息ctx.sendMessage,由内向外经过由DownstreamHandler和encode组成的过滤链,在链的尽头由NioServerSocketPipelineSink处理MessageEvent事件。
1.首先将事件放入channel中的writeBufferQueue中。
 MessageEvent event = (MessageEvent) e;
            NioSocketChannel channel = (NioSocketChannel) event.getChannel();
            boolean offered = channel.writeBufferQueue.offer(event);
            assert offered;
            channel.worker.writeFromUserCode(channel);

2.调用writeFromUserCode()方法写数据,该方法会检测当前执行线程是否是对应worker的IO线程。如果不是,则向该worker添加写任务(执行writeFromTaskLoop,无须检测执行线程)并返回,。
3.对channel.writeLock加锁,防止在写的过程中另外的cleanUpWriterBuffer操作writeBufferQueue
4.依次写各个messge event中的消息写到channel中,如果阻塞无法写入,则向worker注册该channel的可写事件,如果已把事件队列全部写完则取消在worker上channel的可写事件。
5.完成后,在workder的IO线程的通知写完成事件。

在写消息时采用了类似自旋锁方式,在向管道不能正常写入数据时直接重复16次,如还不能写再向worker注册可写事件。在大量数据需要写出时,消息数据将在channel中的queue堆积,worker监听线程疲于发消息而不会去select,直到kernel buffer填满而不能再向channel写入数据时再停止此次写数据回到监听状态。

接收消息的情况
这各情况是从worker的select阻塞退出了开始的,退出阻塞后首先执行任务队列中的任务。然后依次处理各个selectorKey。
1.如果key上有WRITE事件,表明当前channel处于可写状态,调用write0,如同发送消息的情况。
2.如果Key上有READ事件,表明有新的数据可读,通过ReceiveBufferSizePredictor根据上次消息的大小来决定预测本次消息所需的缓存大小。从channel读取数据到缓存到,并向上行流通知消息接收事件。
3.依次调用事件处理链上的decoder,handler。

读消息时使用到了ReceiveBufferSizePredictor来预测这次数据包的大小,其预测方法:
初始化预测索引表格SIZE_TABLE,其中的数据呈类指数增长。当实际数据大小比预测值SIZE_TABLE[index]大时,预测索引向右移动4格index+=4;当比预测值两次小于当前索引值左侧一格的值SIZE_TABLE[index-4]时,则预测索引向左移1格index--;当实际值在预测值索引SIZE_TABLE[index]和SIZE_TABLE[index-1]之前,预测成功,不作调整。

读消息所使用的缓存分析:
1.使用ByteBuffer.allocateDirect向OS直接申请内存空间,并不由GC来管理。
2.通过normalizeCapacity(size)来归一化缓存大小,修改为比size大的最小1024的倍数
3.每个worker都有一个SocketReceiveBufferAllocator分配直接缓存DirectBuffer,这类缓存IO时不需要把数据从OS内存复制到Java堆中,因此性能比堆缓存高,但分配、释放的代价比堆缓存高,Allocator通过尽量重复使用已分配的缓存来降低了分配直接缓存的频率。   
     3.1当首次分配时,直接分配directBuffer。
     3.2如果上次分配的buffer比size小,则释放并重新分配缓存
     3.3如果size持续16小于上次分配buffer大小的80%,则释放并重要分配缓存
     3.4其它情况,则重复使用上次分配的directBuffer
  
    ByteBuffer get(int size) {
        if (buf == null) {
            return newBuffer(size);
        }
        if (buf.capacity() < size) {
            return newBuffer(size);
        }
        if (buf.capacity() * percentual / 100 > size) {
            if (++exceedCount == maxExceedCount) {
               return newBuffer(size);
            } else {
                buf.clear();
            }
        } else {
            exceedCount = 0;
            buf.clear();
        }
        return buf;
    }

4.在用Direct类型ByteBuffer接收完数据后,再处理创建HeapChannelBuffer,复制directBuffer中的字节数据到HeapChannelBuffer。这个类有两个write read两个索引,在复制完数据后,更新write索引,但不需要flip(),因为这时候读索引不会变。
bb.flip();

            final ChannelBuffer buffer = bufferFactory.getBuffer(readBytes);
            buffer.setBytes(0, bb);
            buffer.writerIndex(readBytes);

            // Update the predictor.
            predictor.previousReceiveBufferSize(readBytes);

            // Fire the event.
            fireMessageReceived(channel, buffer);

分享到:
评论

相关推荐

    Netty5.0架构剖析和源码解读

    Netty源码分析 ##### 3.1. 服务端创建 Netty是一个高性能的网络应用程序框架,其核心优势在于异步事件驱动的I/O处理机制。接下来我们将深入分析Netty服务端的创建过程。 ###### 3.1.1. 服务端启动辅助类...

    netty版贪吃蛇

    1. Server模块:实现了Netty服务器端,包括WebSocket服务器处理类,用于处理连接、消息收发和游戏逻辑。 2. Client模块:包含HTML、CSS和JavaScript文件,构建了用户界面和WebSocket客户端逻辑,负责与服务器交互并...

    JAVA版基于netty的物联网高并发智能网关.zip

    用户可以通过阅读源码了解具体的实现细节,如如何配置Netty服务器、如何编写自定义编解码器、如何处理设备连接事件等。同时,该项目可能提供了编译和运行的说明,帮助开发者快速搭建和测试这个智能网关。 总的来说...

    GatewayWorker框架源码

    - `Gateway`类:包含了与客户端连接、断开连接、收发数据等相关操作的接口和内部实现。 - `BusinessWorker`类:处理业务逻辑,用户可以通过继承这个类来编写自己的业务代码。 - `Protocal`类:定义了数据包的封装...

    NettySpringboot仿某信聊天全栈实战 (视频+源码).rar

    至于【源码】部分,你可以通过分析源代码学习到如何利用Netty处理网络连接和消息收发,Spring Boot如何管理应用的生命周期和服务,以及如何使用数据库(如MySQL)进行数据持久化。此外,前端部分可能使用了Vue.js、...

    java开源包3

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    dubbo接口测试调试工具

    所以扣了dubbo的netty模块源码,封装了个收发客户端集成一个工具,可以快速调试dubbo接口。源码地址:https://github.com/VIPJoey/doe 极简模式 普通模式 目录结构 mmc-dubbo-api 接口项目,主要用于测试。 mmc-...

    WPF+Socket+DB(聊天软件).zip

    【客户端源码分析】 客户端源码通常包括UI界面的创建、Socket连接的建立、数据收发逻辑以及与数据库的交互等部分。开发者可能会使用WPF提供的控件(如TextBox、Button、ListView等)来构建聊天界面,利用Socket类...

    java开源包8

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包1

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包11

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包2

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包6

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包5

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包10

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包4

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包7

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包9

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包101

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    Java资源包01

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

Global site tag (gtag.js) - Google Analytics