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

「深入浅出Netty」不愧是阿里架构师,这篇Netty实战文档太实用 前言 什么是Netty? Netty是由JBOSS提供的一个java开源框架。 Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。也就是说,Netty是一个基于NIO的客户,服务器端编程框架,使用Netty可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。 作为当前最流行的NIO框架,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

bugstack虫洞栈 | netty4.1案例文章列表汇总,跟着案例学Netty itstack-demo-netty netty4.x案例 微信公众号:bugstack虫洞栈,欢迎您的关注&获取更多案例与源码!博客栈:https://bugstack.cn 本专题针对netty4.x分为从;基础入门篇(九篇)、中级拓展篇(八篇)、高级应用篇(三章),由浅入深实现netty服务功能,介绍netty如何从上手到实战。 基础入门篇(九篇) netty案例,netty4.1... 阅读详情

相关推荐

netty案例,netty4.1中级拓展篇十二《Netty流量整形数据流速率控制分析与实战》

作者:付政委 | 关注微信公众号:bugstack虫洞栈,获取专题案例源码 前言介绍 你是否使用过某盘,在前几年我们使用的时候速度飞快,上传下载嗖嗖嗖。但是近年来只要不办会员,速度慢的像蜗牛,当然人家也得赚钱我们能理解。那么这样的限速是怎么实现的呢,我们这个案例使用Netty的流量整形进行限速传输,测试过程中当你把流量整形功能去掉后你就是年费VIP。 流量整形(Traffic Shaping...

bugstack虫洞栈 3696

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

Netty实战应用学习笔记-中级拓展篇

java_rutu的博客 1072

netty案例,netty4.1中级拓展篇一《Netty与SpringBoot整合》

前言介绍 在实际的开发中,我们需要对netty服务进行更多的操作,包括;获取它的状态信息、启动/停止、对客户端用户强制下线等等,为此我们需要把netty服务加入到web系统中,那么本章节介绍如何将Netty与SpringBoot整合。 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使...

bugstack虫洞栈 2642

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

Netty实战应用学习笔记-中级拓展篇

java_rutu的博客 630

netty案例,netty4.1中级拓展篇五《基于Netty搭建WebSocket,模仿微信聊天页面》

前言介绍 本章节我们模仿微信聊天页面,开发一个基于Netty搭建WebSocket通信案例。Netty的应用方面非常广;聊天、MQ、RPC、数据等等,在5G到来的时候更加需要大量数据传输,Netty的应用也会更加广阔。 1、这个案例使用SpringBoot+Netty+WebSocket搭建功能。 2、使用Netty提供的HttpServerCodec、HttpObjectAggregator、...

bugstack虫洞栈 3072

netty案例,netty4.1中级拓展篇七《Netty请求响应同步通信》

前言介绍 在我们实现开发RPC框架的时候,需要选择socket的通信方式。而我们知道一般情况下socket通信类似与qq聊天,发过去消息,什么时候回复都可以。但是我们RPC框架通信,从感觉上类似http调用,需要在一定时间内返回,否则就会发生超时断开。这里我们选择netty作为我们的socket框架,采用future方式进行通信。 Dubbo:国内最早开源的 RPC 框架,由阿里巴巴公司开发并于...

bugstack虫洞栈 2265

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

Netty实战应用学习笔记-中级拓展篇

java_rutu的博客 1063

netty案例,netty4.1中级拓展篇三《Netty传输Java对象》

前言介绍 Netty在实际应用级开发中,有时候某些特定场景下会需要使用Java对象类型进行传输,但是如果使用Java本身序列化进行传输,那么对性能的损耗比较大。为此我们需要借助protostuff-core的工具包将对象以二进制形式传输并做编码解码处理。与直接使用protobuf二进制传输方式不同,这里不需要定义proto文件,而是需要实现对象类型编码解码器,用以传输自定义Java对象。 pro...

bugstack虫洞栈 2142

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

Netty实战应用学习笔记-中级拓展篇

java_rutu的博客 640

netty案例,netty4.1中级拓展篇四《Netty传输文件、分片发送、断点续传》

前言介绍 1、在实际应用中我们经常使用到网盘服务,他们可以高效的上传下载较大文件。那么这些高性能文件传输服务,都需要实现的分片发送、断点续传功能。 2、在Java文件操作中有RandomAccessFile类,他可以支持文件的定位读取和写入,这样就满足了我们对文件分片的最基础需求。 3、Netty服务端启动后,可以向客户端发送文件传输指令;允许接收文件、控制读取位点、记录传输标记、文件接收完成。 ...

bugstack虫洞栈 3229

netty案例,netty4.1中级拓展篇二《Netty使用Protobuf传输数据》

前言介绍 在netty数据传输过程中可以有很多选择,比如;字符串、json、xml、java对象,但为了保证传输的数据具备;良好的通用性、方便的操作性和传输的高性能,我们可以选择protobuf作为我们的数据传输格式。目前protobuf可以支持;C++、C#、Dart、Go、Java、Python等,也可以在JS里使用。知识点;ProtobufDecoder、ProtobufEncoder、Pr...

bugstack虫洞栈 2080

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

Netty实战应用学习笔记-中级拓展篇

java_rutu的博客 570

netty案例,netty4.1中级拓展篇八《Netty心跳服务与断线重连》

前言介绍 在我们使用netty中,需要监测服务是否稳定以及在网络异常链接断开时候可以自动重连。需要实现监听;f.addListener(new MyChannelFutureListener()) 环境准备 1、jdk1.8【jdk1.7以下只能部分支持netty】 2、Netty4.1.36.Final【netty3.x 4.x 5每次的变化较大,接口类名也随着变化】 代码示例 itstack-...

bugstack虫洞栈 2069

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

Netty实战应用学习笔记-中级拓展篇

java_rutu的博客 636

netty案例,netty4.1中级拓展篇十一《Netty基于ChunkedStream数据流切块传输》

前言介绍 在Netty这种异步NIO框架的结构下,服务端与客户端通信过程中,高效、频繁、大量的写入大块数据时,因网络传输饱和的可能性就会造成数据处理拥堵、GC频繁、用户掉线的可能性。那么由于写操作是非阻塞的,所以即使没有写出所有的数据,写操作也会在完成时返回并通知ChannelFuture。当这种情况发生时,如果仍然不停地写入,就有内存耗尽的风险。所以在写大块数据时,需要对大块数据进行切割发送处理...

bugstack虫洞栈 3340

jmeter问题系列:Begin size 0 is not equal to fixed size 5

Begin size 0 is not equal to fixed size 5 ,问题的解决

雨水的早晨的博客 2415

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

Netty实战应用学习笔记-中级拓展篇

java_rutu的博客 322

东方财富网API接口逆向分析:手把手教你破解那个带jQuery回调的股票数据接口

本文详细解析了东方财富网股票数据API接口的逆向工程实战技巧,重点介绍了JSONP接口的核心机制、参数解析及数据处理方法。通过Python代码示例演示了如何构造请求、处理分页数据及应对反爬策略,帮助开发者高效获取股票数据。文章还提供了完整的爬虫实现案例和常见问题排查指南。

weixin_30790841的博客 716

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

Netty实战应用学习笔记-中级拓展篇

java_rutu的博客 306

学习心得——COMSOL Multiphysics with MATLAB联合仿真及寻优计算

学习心得——COMSOL Multiphysics with MATLAB联合仿真及寻优计算

weixin_41678956的博客 8658

数字IC物理验证实战 | 从Calibre LVS报告到Innovus定位的Debug全链路解析

本文详细解析了数字IC物理验证中Calibre LVS报告的Debug全流程,从INCORRECT NETS错误的初探到Innovus定位技巧,提供了实战案例和高效工具的使用方法。重点介绍了Calibre高亮功能、Innovus验证命令以及前后端工具联动的关键策略,帮助工程师快速定位和解决LVS问题,提升物理验证效率。

weixin_30919429的博客 127

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

Netty实战应用学习笔记-中级拓展篇

java_rutu的博客 301

LSTM模型股价波动率预测(含Python代码)

源代码文件可在gzh’finance褪黑素'回复【24012203】获取。

celiaweiwei的博客 3776
上一篇: Netty实战应用学习笔记-中级拓展篇(十一)
下一篇: Netty实战应用学习笔记-中级拓展篇(十三)
不早睡不改名@
博客等级 码龄5年 536粉丝 306原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值