Netty实战应用学习笔记-中级拓展篇(十二)

⚡ 项目十二:流量整形数据流速率控制

项目概述

项目名称:itstack-demo-netty-2-12
核心功能:使用流量整形技术控制数据流速率(类似某盘限速)
技术要点:TrafficShapingHandler、令牌桶算法、速率监控

为什么需要这个项目?

实际问题

  • 带宽资源有限,需要合理分配
  • 防止某个连接占用过多带宽
  • 需要限制用户下载/上传速度(VIP和普通用户)
  • 保护服务器,防止流量突发

解决方案

  • ✅ TrafficShapingHandler:Netty提供的流量整形处理器
  • ✅ 令牌桶算法:精准控制数据发送速率
  • ✅ 三种实现:Global、Channel、GlobalChannel
  • ✅ 速率监控:实时监控发送速率

适用场景

  • 带宽限制(某盘限速、视频网站限速)
  • 服务保护(防止流量突发,保护服务器)
  • 公平性保证(多用户带宽公平分配)
  • 成本控制(云服务带宽成本控制)

核心问题

什么是流量整形?

流量整形(Traffic Shaping)是一种主动调整流量输出速率的措施。

流量整形 vs 流量监管

特性流量整形流量监管
处理方式缓存超出限制的报文直接丢弃
实现机制放入缓冲区/队列,等待令牌立即丢弃
延迟可能增加延迟几乎不引入延迟
应用场景需要保证数据完整性对实时性要求高

核心知识点

1. Netty三种流量整形实现

GlobalTrafficShapingHandler - 全局限制

@Sharable  // 可以在多个Channel间共享
public class GlobalTrafficShapingHandler extends AbstractTrafficShapingHandler

特点

  • 限制全局带宽,无论开启多少个Channel
  • 所有Channel共享一个计数器
  • 使用 @Sharable 注解,只需创建一个实例

ChannelTrafficShapingHandler - 单Channel限制

public class ChannelTrafficShapingHandler extends AbstractTrafficShapingHandler

特点

  • 限制单个Channel的带宽
  • 每个Channel需要创建独立的Handler实例

GlobalChannelTrafficShapingHandler - 混合限制

@Sharable
public class GlobalChannelTrafficShapingHandler extends AbstractTrafficShapingHandler

特点

  • 同时支持全局限制单Channel限制
  • 增加了误差平衡概念,使各Channel间的读写操作更均衡
2. 客户端流量整形配置
protected void initChannel(SocketChannel channel) {
    // 流量整形:写限制10字节/秒,读限制10字节/秒 ⭐
    channel.pipeline().addLast(new ChannelTrafficShapingHandler(10, 10));
    
    // 其他处理器...
}

参数说明

new ChannelTrafficShapingHandler(writeLimit, readLimit)
  • writeLimit:写速率限制(字节/秒),0表示不限制
  • readLimit:读速率限制(字节/秒),0表示不限制
3. 服务端流量整形配置
protected void initChannel(SocketChannel channel) {
    // 全局流量整形:写限制10字节/秒,读限制10字节/秒 ⭐
    channel.pipeline().addLast(
        new GlobalTrafficShapingHandler(channel.eventLoop().parent(), 10, 10)
    );
    
    // 其他处理器...
}
4. 速率监控实现

MyServerCommonHandler.java

public abstract class MyServerCommonHandler extends SimpleChannelInboundHandler<String> {
    protected boolean sentFlag;
    private AtomicLong consumeMsgLength = new AtomicLong();
    private long priorProgress;
    
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        sendData(ctx);
        
        // 启动监控线程 - 每500ms统计一次发送速率
        new Thread(() -> {
            while (true) {
                try {
                    Thread.sleep(500);
                    long length = consumeMsgLength.getAndSet(0);
                    if (0 == length) continue;
                    System.out.println("数据发送速率(KB/S):" + length);
                } catch (InterruptedException ignored) {
                }
            }
        }).start();
    }
    
    protected ChannelProgressivePromise getChannelProgressivePromise(
        ChannelHandlerContext ctx, 
        Consumer<ChannelProgressiveFuture> completedAction) {
        
        ChannelProgressivePromise promise = ctx.newProgressivePromise();
        promise.addListener(new ChannelProgressiveFutureListener() {
            @Override
            public void operationProgressed(ChannelProgressiveFuture future, 
                                           long progress, long total) {
                // 累计已发送的字节数
                consumeMsgLength.addAndGet(progress - priorProgress);
                priorProgress = progress;
            }
            
            @Override
            public void operationComplete(ChannelProgressiveFuture future) {
                sentFlag = false;
                if (future.isSuccess()) {
                    System.out.println("消息发送成功!");
                    priorProgress -= 10;
                    Optional.ofNullable(completedAction)
                           .ifPresent(action -> action.accept(future));
                }
            }
        });
        return promise;
    }
}
5. 令牌桶算法原理
1. 系统以固定速率向令牌桶中添加令牌
   例如:10字节/秒 = 每100ms添加1字节令牌
   
2. 当需要发送数据时:
   - 检查令牌桶中是否有足够的令牌
   - 有令牌:消耗令牌,发送数据
   - 无令牌:将数据放入队列,等待令牌
   
3. 流量整形效果:
   - 即使应用层快速写入大量数据
   - 实际发送速率被限制在设定值
   - 超出部分被缓存,不会丢失

测试效果

启动服务端

itstack-demo-netty server start done.
数据发送速率(KB/S):10
数据发送速率(KB/S):10
数据发送速率(KB/S):10
消息发送成功!

观察:速率被限制在10字节/秒

项目总结

核心技术

  • ✅ TrafficShapingHandler:Netty提供的流量整形处理器
  • ✅ 令牌桶算法:控制数据发送速率
  • ✅ 速率监控:实时监控发送速率
  • ✅ 三种实现:Global、Channel、GlobalChannel

选择建议

场景推荐Handler
限制整个应用总带宽GlobalTrafficShapingHandler
限制单个连接带宽ChannelTrafficShapingHandler
既要限制总带宽又要保证公平性GlobalChannelTrafficShapingHandler

适用场景

  • 带宽限制(某盘限速)
  • 服务保护(防止流量突发)
  • 公平性保证(多用户带宽分配)
  • 成本控制(云服务带宽成本)

配置建议

// 开发测试:10字节/秒(便于观察效果)
new GlobalTrafficShapingHandler(executor, 10, 10)

// 生产环境:根据实际需求设置
new GlobalTrafficShapingHandler(executor, 1024 * 100, 1024 * 100)  // 100KB/s

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值