• 姚远
    2019-10-30
    老师 我想请问一下 pipeline.fireChanlRead(byteBuf)方法的意义是啥呢 一次读取可能不能把所有客户端发送的内容都读到呀。传播下去pipeline里的handlers 也处理不了呀

    作者回复: 一次可能读到多个完整的消息,所以传下去有必要,这样至少前面完整的消息能及时处理,一次也可能读不完,传下去也没必要,一方面,后面的处理器会帮你存起来这些半包数据,另外你可以写一些处理器做些别的事情,总体思想还是有数据就往外扔,而不是死等着,因为这是一个数据流,等意义也不大

     1
     3
  • 冬渐暖
    2019-12-05
    读数据技巧:1.和省内存一样,提前猜测下一次要装的大小
    2.一直读到没有或者别人不满意为止(贪心)

    读数据:接收OP_READ事件,然后对数据进行处理

    处理这些数据的流程:1.创建个初始化为1024的byteBuffer来装channel的数据,如果没装够就记下这一次的,想下下次要分配的大小(allocHandle有个guess和reset的方法)
            2.触发pipeline.fireChannelRead(byteBuf)把读取到的数据传播出去,将事件开始在pipeline中传递。如果读完了的话就跑路,没有的话就扩容来继续把数据读到没有或者直到读了16次(给别人机会)
    需要注意的地方是:1.scoket是可以使一个应用从网络中读取和写入数据;ServerSocket是等待客户端的请求,一旦获得一个连接请求,就创建一个Socket示例来与客户端进行通信。
    所以NioServerSocketChannel read()是创建连接,NioSocketChannel read()是读数据,
    2.一次OP_READ事件可能有多个读数据传播操作


    我的疑问是,alloc自适应大小不是发生在每次读完之后根据有没有读满才扩容吗?应该只有扩容没有缩小啊。。。。难道是这次读完了之后,如果连续两次都发现自己没满,就缩小吗?这个缩小的比例又是多少。。。
    我发现取下次大小是按照maxBytesPerIndividualRead和本次读的大小 两者的最小值,但是maxBytesPerIndividualRead我没看到赋值的地方(maxBytesPerReadPair方法和maxBytesPerIndividualRead方法)有被其它地方引用到啊
    你说的雨露均沾,我还是没明白为什么是16次最优,不是其它的2的幂次方倍??
    展开

    作者回复: 1 你估计看错了类,所以你没有看懂,你看的那个类估计是DefaultMaxBytesRecvByteBufAllocator
    所以我用中文注释了过那个类:
    “//无人调用,加一个@Deprecated标识下”
    2 io.netty.channel.AdaptiveRecvByteBufAllocator.HandleImpl#readComplete会尝试缩小,缩小比例不完全一样(以512为界限,有2种):一种是减小1倍,一种是减小16
    3 "什么是16次最优,不是其它的2的幂次方倍?"我意思这个本身不是问题,因为写32的话,别人也会问为什么不是16,“雨露均沾”是说给别人读的机会,所以要控制中的次数。
    你每次笔记记得挺细致的,哈哈

    
     2
  • T神
    2019-12-26
    老师,我想问下,如何实现当客户端建立连接的时候服务端立马主动给客户端发送一个消息?而不是等客户端发送消息之后再发送消息。我举个例子,比如聊天室系统,当某人加入聊天室的时候立马给他发送一条欢迎消息,这时候客户端还没有发送任何消息,只建立了连接。

    作者回复: 直接在已有的handler里或者新的handler里,实现channelActive这个方法:调用ctx带的write方法写欢迎信息。

    
     1
  • 密码123456
    2020-02-09
    同一个连接,对多次读事件怎么并发处理的?
    
    
  • 密码123456
    2020-02-09
    有个问题,如果读了16次还没有读完。怎么办?
    
    
  • 我已经设置了昵称
    2020-01-19
    老师这节课讲的比较好,现类比现实中的场景,再介绍源码。很容易理解

    作者回复: 嗯,那就好,有些节就不能完全做到,只能说尽量做到如此,谢谢!

    
    
  • 成都小郭
    2019-12-04
    老师,我在线上遇到了netty读取数据延迟很高,几秒到十几秒。。排查了一下,怀疑是服务器聊天类消息推送过多,导致io线程被占用,一直执行写事件。。请问我这个分析有问题吗,另外除了优化推送次数,还有什么优化手段吗

    作者回复: 可以查看下你的线程模型有没有问题(后面的第五章也会提及,IO型的业务要独立出线程池),然后这个问题需要查很多因素,具体可以
    参考上次做直播的ppt说到的一个类似问题(第九个问题):
    https://github.com/geektime-geekbang/geek_netty/

    如果还有疑问,或者不清楚,可以继续提个问题。谢谢

     1
    
  • 九局
    2019-12-04
    老师解析源码非常的细致,赞!
    有一个疑问:如果Channel或者说Pipeline中的所有Handler都执行完了,会重新注册可读事件(OP_READ)吗?或者说处理完后是怎么处理的?

    作者回复: 一般情况(你问的情况),op_read一直注册在,不是重新注册,也不需要重新注册。重新注册的场景是出现在自己主动取消读监听后,又重新注册时,比如流量整形的读暂停到读恢复。正常没有开启各种复杂特性时都是一直注册在,所以只要有数据,就自动处理各种handler。

    
    
  • 飞翔
    2019-11-22
    我想问一下 netty的线程模型, 我们有一个bossnioeventloopgroup 里边有一个nioeventloop 负责接受连接, 我们有一个workeventloopgroup负责接收channel的读写请求,这里边有cpu*2 个nioeventloop,假设cpu是2个,那么也就是4个nioeventloop, 每个eventloop一次只能处理一个channel的读写请求嘛? 也就是eventloop 获取一个channel的读请求,之后读取,channelhandle 处理数据 都是在这个eventloop的线程里,那么这样能同时处理的请求太少了呀

    作者回复: 是的,你可以通过参数调整大点,或者对于io型的业务最好独立出一个线程池来做,参考第五章,下周三更新。

    
    
  • z.l
    2019-11-20
    老师,能讲下 pipeline.fireChannelXXX()方法是如何传播的吗?看源码没看懂

    作者回复: 处理业务那节就介绍了,简单说就是:寻找pipeline中下一个具有执行资格的handler然后来执行。因为不是所有的hanlder都具有资格,比如你触发的是读事件,那专门服务于写事件的handler就不需要执行。

    
    
  • Geek_cyy
    2019-11-20
    老师,多次读,多次fire读时间,怎么确保后面的业务处理器,获取到的数据先后顺序是不变的呢?

    作者回复: 分两种情况:
    1 对于同一个连接而言,实际上收到的数据顺序是按顺序的,因为都是同一个线程(NioEventLoop)来处理的;
    2 而如果不同连接,那就不一定了,它不能保证NioEventLoop的处理是按你发送的顺序来。因为他们不定是同一个NioEventLoop,每个NioEventLoop处理速度可能因工作量不同而不同。

    
    
  • 小不点
    2019-11-07
    哈哈哈,为啥只读16次,不是17次,如果是17次有的同学会问....
    
    
  • 欧阳田
    2019-10-31
    老师。请问:注册的事件会保存到集合中 Set<SelectionKey> selectionKey 。而 Set<SelectionKey> selectedKey 这个集合会去selectionKey中找。程序什么时候,在哪儿给selectedKey赋值的?

    作者回复: 赋值的地方有多个,例如:
    io.netty.channel.nio.AbstractNioChannel#doBeginRead
    注册读。

    
    
我们在线,来聊聊吧