10年 Java程序员,硬核人生!勇往直前,永不退缩!

欢迎围观我的git:https://github.com/R1310328554/spring_security_learn 寻找志同道合的有志于研究技术的朋友,关注本人微信公众号: 觉醒的码农,或Q群 165874185

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

 先下结论:

当客户端写的速度比较小的时候, 即 客户端写的速度 <= 服务端 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

基本上是一样的结果

posted on 2021-06-07 07:07  CanntBelieve  阅读(193)  评论(0编辑  收藏  举报