• netty 的流量整形读测试


     先下结论:

    当客户端写的速度比较小的时候, 即 客户端写的速度 <= 服务端 readLimit, 那么, 客户端 写的速度就是 服务端读的速度, 相当于是没有限速,客户端的写不会被阻塞,客户端也不会出现 isWritable = false的情况;(但客户端每次读的数据最大是65536,这个是 缓冲区限制导致的。 )


    当客户端写的速度比较大的时候, 即 客户端写的速度 > 服务端 readLimit, 那么, 实际速度 大于 服务端读速度,小于客户端写的速度, 就是说 总数据量不变,时间不一样!! 平均起来还是 读的速度越大,写的时候isWritable 为false 出现的越少! 细分两个情况:
        如果 客户端写的速度 < ChannelOption.SO_RCVBUF 选项值, 那么,服务端以 ChannelOption.SO_RCVBUF * 5 为准 每N秒接收一次。同时,SO_RCVBUF 越大,N越小,也就是接收越快!
        如果 客户端写的速度 > ChannelOption.SO_RCVBUF 选项值, 那么,服务端 的接收速度可能小于 ChannelOption.SO_RCVBUF *5 。

    需要注意的是,如果 对某一个配置, 同时设置了 option childOption, 那么以 childOption 为准! 但如果childOption的设置 过小,则它无效,还是option 为准 !

    SO_RCVBUF 的意思是, 即使客户端写的数据量、速度最大,服务端需要先经过SO_RCVBUF, SO_RCVBUF满了之后,服务端立即触发一次读。

    但是,ChannelOption.SO_RCVBUF * 5 不能超过 65536 KB,超过了就使用 65536 KB, 不知道为什么, 可能是因为操作系统或者TCP协议本身限制了最大的缓冲! 测试很久才发现,没法调整,开始还以为代码错了!

    另外,客户端 设置WriteBufferWaterMark 和 客户端的 isWritable 有一定关系!

    客户端的 isWritable ,是一个比较奇怪的东西。 说白了,客户端写的时候, 是能够感受到 服务端读的压力的,如果服务端读不过来了(可能导致TCP的buffer 也出现拥塞)比如服务端的接收缓冲区已经满了,那么写也可能会阻塞,这个时候,客户端的 isWritable 自动变成了false。

    同时,客户端也也有写缓冲,也就是 ChannelOption.WRITE_BUFFER_WATER_MARK 选项 ( 可能包括ChannelOption.SO_SNDBUF, 没试过),DEFAULT_HIGH_WATER_MARK 默认是 65535。 当然服务端读出现了阻塞,那么客户端设置的high 越大,写缓冲区就越大,isWritable = false 出现的越少! (因为写满了, 还是会出现 isWritable 自动变成false)

    但是呢,客户端的写,也可以不用理 isWritable,这个时候,写的数据会悉数发送到服务端( 没观察到 数据丢失的情况, 可能是缓存足够大, ),

    测试结果:

    客户端不考虑阻塞,发送数据 100 kb, 每次1 kb,1s 10次, 即客户端写速度是 10KB /s :服务端读限制 1KB /s 。 服务端的 ChannelOption.SO_RCVBUF 分别设置如下 左边数字, 接收完客户端全部数据总花费时间为 中间的 秒数值 : 

    64 - 98 s 接收最大 320,实际 1024 KB, 符合理论。按理计算是花了 100, --- 为什么不是 100s ? 大概因为SO_RCVBUF 不能小于读速度, 而且中间还是出现了窗口重叠,所以小于100s
    1024 - 98 s 接收最大 5120 KB, 因为出现了强制刷新写,时间应该变短,但是还是 98s, 总体不太符合理论, 可能因为 其他一下机制吧。
    2048 - 98 s 接收最大 10240 KB
    4096 - 63 s 接收最大 20480 KB, 因为出现了强制刷新写,时间变短了
    8192 - 48 s 接收最大 40960,实际 32768 KB, 因为出现了强制刷新写,时间更短了
    81920 - 33 s 接收最大 40960, 实际 38912 KB --- 发送端数据不够; , 因为出现了强制刷新写,时间更短了
    819200 - 33 s 接收最大 10240 KB, 因为出现了强制刷新写,时间没有更短了,可能因为 超过了 65536
    8192000 - 33 s 接收最大 10240KB

    可见 ,服务端 花了98s 接收全部数据,基本上是 SO_RCVBUF  越大,强制刷新写的间隔越小, 耗时越少。

    修改一下,

    发送端数据 200 kb, 每次1 kb, 客户端 不 考虑 writable , isWritable = true 次数139, 服务端实际接收 200 KB, 没有丢失
    8192 - 77 s 接收最大 40960,实际 40960 KB

    发送端数据 200 kb, 每次1 kb, 客户端考虑 writable , isWritable = true 次数 148, 服务端实际接收 148 KB, 没有丢失
    8192 - 48 s 接收最大 40960,实际 40960 KB


    发送端数据 2000, 每次10 kb,5ms 一次 10KB, 客户端考虑 writable , isWritable = true 次数 16, 服务端实际接收 160 KB, 没有丢失
    8192 - 62 s 接收最大 40960,实际 40960 KB


    发送端数据 2000, 每次10 kb,50 ms 一次 10KB, 客户端考虑 writable , isWritable = true 次数 23, 服务端实际接收 230 KB, 没有丢失
    8192 - 62 s 接收最大 40960,实际 40960 KB


    发送端数据 2000, 每次1000 kb,50 ms 一次 100KB, 客户端考虑 writable , isWritable = true 次数 2, 服务端实际接收 2000 KB, 没有丢失
    8192 - .. s 接收最大 40960,实际 40960 KB

    当读的数据导致的延迟超出了max(默认15s),那么就最多等待15s,具体实现在 io.netty.handler.traffic.AbstractTrafficShapingHandler#channelRead,

        @Override 
        public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
            long size = calculateSize(msg);
            long now = TrafficCounter.milliSecondFromNano();
            if (size > 0) {
                // compute the number of ms to wait before reopening the channel
                long wait = trafficCounter.readTimeToWait(size, readLimit, maxTime, now);
                wait = checkWaitReadTime(ctx, wait, now);
                if (wait >= MINIMAL_WAIT) { // At least 10ms seems a minimal
                    // time in order to try to limit the traffic
                    // Only AutoRead AND HandlerActive True means Context Active
                    Channel channel = ctx.channel();
                    ChannelConfig config = channel.config();
                    if (logger.isDebugEnabled()) {
                        logger.debug("Read suspend: " + wait + ':' + config.isAutoRead() + ':'
                                + isHandlerActive(ctx));
                    }
                    if (config.isAutoRead() && isHandlerActive(ctx)) {
                        config.setAutoRead(false);
                        channel.attr(READ_SUSPENDED).set(true);
                        // Create a Runnable to reactive the read if needed. If one was create before it will just be
                        // reused to limit object creation
                        Attribute<Runnable> attr = channel.attr(REOPEN_TASK);
                        Runnable reopenTask = attr.get();
                        if (reopenTask == null) {
                            reopenTask = new ReopenReadTimerTask(ctx);
                            attr.set(reopenTask);
                        }
                        ctx.executor().schedule(reopenTask, wait, TimeUnit.MILLISECONDS);
                        if (logger.isDebugEnabled()) {
                            logger.debug("Suspend final status => " + config.isAutoRead() + ':'
                                    + isHandlerActive(ctx) + " will reopened at: " + wait);
                        }
                    }
                }
            }
            informReadOperation(ctx, now);
            ctx.fireChannelRead(msg);
        }


    每隔wait 去重新设置 可读性。 如果 config.isAutoRead 那么设置为false, 然后等待wait 时间,然后重置可读性为true !

    第一次的时候 autoRead 是true,所以进了if,把autoRead 设置为 false(然后就接收不到消息了),然后schedule 一个 reopenTask,delay 是1s,然后1s后, reopen即把把autoRead 设置true,然后又接收数据,然后反复这样。。

    其中 ReopenReadTimerTask 做成了一个属性, 把任务缓存了起来,不用每次创建, 效率起见!

    日志分析:

    客户端不考虑阻塞,发送数据 200 kb, 每次1 kb,1s 10次, 即客户端写速度是 10KB /s :服务端读限制 1KB /s 的时候:

    客户端

    1024  write =  Tue Jun 01 00:10:33 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:33 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:33 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:33 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:33 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:33 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:33 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:33 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:33 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:33 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:34 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:34 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:34 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:34 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:34 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:34 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:34 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:34 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:34 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:34 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:35 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:35 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:35 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:35 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:35 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:35 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:35 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:35 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:35 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:35 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:36 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:36 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:36 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:36 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:36 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:36 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:36 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:36 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:36 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:37 CST 2021 ctx.channel().isWritable()  true
    1024  write =  Tue Jun 01 00:10:37 CST 2021 ctx.channel().isWritable()  true
    ... 略去一部分, 总共是 200 行
    over --- cnt = 200

    可见,基本上是 10 KB/s

    服务端

    ===== receive client   size:1038     Tue Jun 01 00:10:33 CST 2021
    MyServerCommonHandler.channelReadComplete     Tue Jun 01 00:10:33 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):1038  Tue Jun 01 00:10:34 CST 2021
    ===== receive client   size:2048     Tue Jun 01 00:10:34 CST 2021
    MyServerCommonHandler.channelReadComplete     Tue Jun 01 00:10:34 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):2048  Tue Jun 01 00:10:35 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:36 CST 2021
    ===== receive client   size:27648     Tue Jun 01 00:10:36 CST 2021
    MyServerCommonHandler.channelReadComplete     Tue Jun 01 00:10:36 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):27648  Tue Jun 01 00:10:37 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:38 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:39 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:40 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:41 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:42 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:43 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:44 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:45 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:46 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:47 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:48 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:49 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:50 CST 2021
    ===== receive client   size:32768     Tue Jun 01 00:10:51 CST 2021
    MyServerCommonHandler.channelReadComplete     Tue Jun 01 00:10:51 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):32768  Tue Jun 01 00:10:51 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:52 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:53 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:54 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:55 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:56 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:57 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:58 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:10:59 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:00 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:01 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:02 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:03 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:04 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:05 CST 2021
    ===== receive client   size:65536     Tue Jun 01 00:11:06 CST 2021
    MyServerCommonHandler.channelReadComplete     Tue Jun 01 00:11:06 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):65536  Tue Jun 01 00:11:06 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:07 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:08 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:09 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:10 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:11 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:12 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:13 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:14 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:15 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:16 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:17 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:18 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:19 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:20 CST 2021
    ===== receive client   size:65536     Tue Jun 01 00:11:21 CST 2021
    MyServerCommonHandler.channelReadComplete     Tue Jun 01 00:11:21 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):65536  Tue Jun 01 00:11:21 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:22 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:23 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:24 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:25 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:26 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:27 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:28 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:29 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:30 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:31 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:32 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:33 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:34 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:35 CST 2021
    ===== receive client   size:65536     Tue Jun 01 00:11:36 CST 2021
    MyServerCommonHandler.channelReadComplete     Tue Jun 01 00:11:36 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):65536  Tue Jun 01 00:11:36 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:37 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:38 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:39 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:40 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:41 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:42 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:43 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:44 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:45 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:46 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:47 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:48 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:49 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:50 CST 2021
    ===== receive client   size:65536     Tue Jun 01 00:11:51 CST 2021
    MyServerCommonHandler.channelReadComplete     Tue Jun 01 00:11:51 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):65536  Tue Jun 01 00:11:51 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:52 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:53 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:54 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:55 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:56 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:57 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:58 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:11:59 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:12:00 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:12:01 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:12:02 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:12:03 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:12:04 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:12:05 CST 2021
    ===== receive client   size:65536     Tue Jun 01 00:12:06 CST 2021
    MyServerCommonHandler.channelReadComplete     Tue Jun 01 00:12:06 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):65536  Tue Jun 01 00:12:06 CST 2021
    *** /127.0.0.1:28121 rate(KB/S):0  Tue Jun 01 00:12:07 CST 2021

    可见, 第1秒收到 1038 (其中 14B 可能是 建立连接的数据, 也不能忽略), 第2秒是 2048,第4秒是27648, 然后过了 15s 收到 32768 即32 KB  ,, 然后又过了 15s 收到 65536 即64 KB   

    服务端限速 是 1 KB/s, 客户端速度 是 10 KB/s,  但为什么收到的数据是这样的节奏? 估计是缓冲区大小 动态调整的结果。

     

     第1秒之内,客户端总共发送10 KB ,服务端因为限速只接收了其中的第一个 1 KB + 14B,第2个 1 KB则被限流,需要等待1.0137s (可能是异步阻塞),然后把 autoread 设置为false,然后缓冲区大小 调整为2,第3、4个 被放入读缓冲区,被缓冲; 以后7个1KB 可能无法读取,故总共9 KB 被延迟;

     第2秒之内,autoread  reopen, 然后客户端又是发送10 KB ,服务端可能没有接收其中任何 1 KB,因为缓冲区大小 为2, 故消费了2KB, 然后等待2S,然后又设置了autoread 为true,然后缓冲区被设置为27648  即27KB,..

    然后 第3秒接收了0, 因为autoread 为false,无法读取,属于等待期间

     第4秒,接收了27 KB, 但是最大等待时间是 15s,然后 缓冲区大小 被调整为32 、 64 KB, 最大就是 64, 让固定这样一个速度接收。

    客户端代码做一些优化: 

    即链接成功之后休息一秒,然后才进入循环 正式发送数据:

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

     此时服务端日志:

    ===== receive client   size:14     Sun Jun 06 20:39:30 CST 2021
    14  *** /127.0.0.1:47303 rate(KB/S):14  Sun Jun 06 20:39:31 CST 2021
    ===== receive client   size:1024     Sun Jun 06 20:39:31 CST 2021
    ===== receive client   size:2048     Sun Jun 06 20:39:32 CST 2021
    2062  *** /127.0.0.1:47303 rate(KB/S):2048  Sun Jun 06 20:39:32 CST 2021
    ===== receive client   size:16384     Sun Jun 06 20:39:33 CST 2021
    18446  *** /127.0.0.1:47303 rate(KB/S):16384  Sun Jun 06 20:39:33 CST 2021
    ===== receive client   size:65536     Sun Jun 06 20:39:48 CST 2021
    83982  *** /127.0.0.1:47303 rate(KB/S):65536  Sun Jun 06 20:39:49 CST 2021
    ===== receive client   size:65536     Sun Jun 06 20:40:03 CST 2021
    149518  *** /127.0.0.1:47303 rate(KB/S):65536  Sun Jun 06 20:40:03 CST 2021
    ===== receive client   size:55296     Sun Jun 06 20:40:18 CST 2021
    204814  *** /127.0.0.1:47303 rate(KB/S):55296  Sun Jun 06 20:40:18 CST 2021

    基本上是一样的结果


    版权声明
    本文原创发表于 博客园,作者为 阿K .     本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。
    欢迎关注本人微信公众号:觉醒的码农,或者扫码进群:

  • 相关阅读:
    用才情绽放的幸福之花
    我的爱车,你在哪里
    爱在网络,有没有错
    假如能抱着美女写诗
    只想爱你
    创业者和爱因斯坦的10大共同点(不是不可比的)
    心的感谢
    成大事必备9种能力.9种手段.9种心态
    一颗新星在陨落
    C++/C学习笔记(九)
  • 原文地址:https://www.cnblogs.com/FlyAway2013/p/14835409.html
Copyright © 2020-2023  润新知