编写下载服务器。 第五部分:油门下载速度

在僵尸网络时代,您可以租用几百美元来运行自己的分布式拒绝服务攻击,拥有紧急开关有选择地关闭昂贵的功能或极大地降低性能是一个巨大的胜利。 在缓解问题的同时,您的应用程序仍可运行。 当然,这种安全措施在高峰或工作时间也很有价值。 应用于下载服务器的这种机制之一是动态限制下载速度。 为了防止分布式拒绝服务攻击和过高的云发票,请考虑内置的下载限制,您可以在运行时启用并进行调整。 这样做的目的是限制全局或每个客户端的最大下载速度(IP,Connection,Cookie,用户代理?)。

我必须承认,我喜欢java.io设计,其中包含许多简单的Input / OutputStreamReader / Writer实现,每个实现只承担一项责任。 您要缓冲吗? GZIPing? 字符编码? 文件系统编写? 只需编写所需的类,它们始终可以相互配合。 好的,它仍然处于阻塞状态,但是它是在被动式赶时髦的人出生之前设计的。 没关系, java.io也遵循开闭原则 :只需插入新的装饰器,就可以简单地增强现有的I / O代码而无需触及内置类。 因此,我为InputStream创建了一个简单的装饰器,以减慢我们这一边的资源读取速度,以强制执行给定的下载速度。 我正在使用我最喜欢的RateLimiter类 :

public class ThrottlingInputStream extends InputStream {private final InputStream target;private final RateLimiter maxBytesPerSecond;public ThrottlingInputStream(InputStream target, RateLimiter maxBytesPerSecond) {this.target = target;this.maxBytesPerSecond = maxBytesPerSecond;}@Overridepublic int read() throws IOException {maxBytesPerSecond.acquire(1);return target.read();}@Overridepublic int read(byte[] b) throws IOException {maxBytesPerSecond.acquire(b.length);return target.read(b);}@Overridepublic int read(byte[] b, int off, int len) throws IOException {maxBytesPerSecond.acquire(len);return target.read(b, off, len);}//less important below...@Overridepublic long skip(long n) throws IOException {return target.skip(n);}@Overridepublic int available() throws IOException {return target.available();}@Overridepublic synchronized void mark(int readlimit) {target.mark(readlimit);}@Overridepublic synchronized void reset() throws IOException {target.reset();}@Overridepublic boolean markSupported() {return target.markSupported();}@Overridepublic void close() throws IOException {target.close();}
}

任意InputStream可以与ThrottlingInputStream打包在一起,这样实际上会减慢读取速度。 您可以为每个ThrottlingInputStream创建一个新的RateLimiter ,也可以为所有下载共享一个全局RateLimiter 。 当然,有人可能会争辩说,简单的sleep()RateLimiter在下面执行的操作)会浪费大量资源,但是让我们保持此示例简单,避免非阻塞I / O。 现在我们可以轻松地将装饰器插入:

private InputStreamResource buildResource(FilePointer filePointer) {final InputStream inputStream = filePointer.open();final RateLimiter throttler = RateLimiter.create(64 * FileUtils.ONE_KB);final ThrottlingInputStream throttlingInputStream = new ThrottlingInputStream(inputStream, throttler);return new InputStreamResource(throttlingInputStream);
}

上面的示例将下载速度限制为64 KiB / s –显然,在现实生活中,您可能希望可配置此类编号,最好在运行时进行配置。 顺便说一句,我们已经讨论了Content-Length标头的重要性。 如果您使用pv监视下载进度,它将正确估计剩余时间,这是一个不错的功能:

~ $ curl localhost:8080/download/4a8883b6-ead6-4b9e-8979-85f9846cab4b | pv > /dev/null% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed0 71.2M    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0  16kB 0:00:01 [14,8kB/s]0 71.2M    0 40960    0     0  30097      0  0:41:21  0:00:01  0:41:20 30095  80kB 0:00:02 [  64kB/s]0 71.2M    0  104k    0     0  45110      0  0:27:35  0:00:02  0:27:33 45106 144kB 0:00:03 [  64kB/s]0 71.2M    0  168k    0     0  51192      0  0:24:18  0:00:03  0:24:15 51184 208kB 0:00:04 [  64kB/s]0 71.2M    0  232k    0     0  54475      0  0:22:51  0:00:04  0:22:47 54475 272kB 0:00:05 [63,9kB/s]0 71.2M    0  296k    0     0  56541      0  0:22:00  0:00:05  0:21:55 67476 336kB 0:00:06 [  64kB/s]0 71.2M    0  360k    0     0  57956      0  0:21:28  0:00:06  0:21:22 65536 400kB 0:00:07 [  64kB/s]0 71.2M    0  424k    0     0  58986      0  0:21:06  0:00:07  0:20:59 65536 464kB 0:00:08 [  64kB/s]0 71.2M    0  488k    0     0  59765      0  0:20:49  0:00:08  0:20:41 65536 528kB 0:00:09 [  64kB/s]0 71.2M    0  552k    0     0  60382      0  0:20:36  0:00:09  0:20:27 65536 592kB 0:00:10 [  64kB/s]0 71.2M    0  616k    0     0  60883      0  0:20:26  0:00:10  0:20:16 65536 656kB 0:00:11 [  64kB/s]0 71.2M    0  680k    0     0  61289      0  0:20:18  0:00:11  0:20:07 65536 720kB 0:00:12 [  64kB/s]

作为一个额外的奖励, pv证明了我们的节流作用(上一栏)。 现在,没有Content-Length pv对于实际的进展一无所知:

~ $ curl localhost:8080/download/4a8883b6-ead6-4b9e-8979-85f9846cab4b | pv > /dev/null% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed
100 16384    0 16384    0     0  21116      0 --:--:-- --:--:-- --:--:-- 21113  32kB 0:00:01 [  31kB/s]
100 81920    0 81920    0     0  46149      0 --:--:--  0:00:01 --:--:-- 46126  96kB 0:00:02 [  64kB/s]
100  144k    0  144k    0     0  53128      0 --:--:--  0:00:02 --:--:-- 53118 160kB 0:00:03 [  64kB/s]
100  208k    0  208k    0     0  56411      0 --:--:--  0:00:03 --:--:-- 56406 224kB 0:00:04 [  64kB/s]
100  272k    0  272k    0     0  58328      0 --:--:--  0:00:04 --:--:-- 58318 288kB 0:00:05 [  64kB/s]
100  336k    0  336k    0     0  59574      0 --:--:--  0:00:05 --:--:-- 65536 352kB 0:00:06 [  64kB/s]
100  400k    0  400k    0     0  60450      0 --:--:--  0:00:06 --:--:-- 65536 416kB 0:00:07 [  64kB/s]
100  464k    0  464k    0     0  61105      0 --:--:--  0:00:07 --:--:-- 65536 480kB 0:00:08 [  64kB/s]
100  528k    0  528k    0     0  61614      0 --:--:--  0:00:08 --:--:-- 65536 544kB 0:00:09 [  64kB/s]
100  592k    0  592k    0     0  62014      0 --:--:--  0:00:09 --:--:-- 65536 608kB 0:00:10 [  64kB/s]
100  656k    0  656k    0     0  62338      0 --:--:--  0:00:10 --:--:-- 65536 672kB 0:00:11 [  64kB/s]
100  720k    0  720k    0     0  62612      0 --:--:--  0:00:11 --:--:-- 65536 736kB 0:00:12 [  64kB/s]

我们看到数据正在流动,但是我们不知道还剩下多少。 因此, Content-Length是一个非常重要的标头。

编写下载服务器

  • 第一部分:始终流式传输,永远不要完全保留在内存中
  • 第二部分:标头:Last-Modified,ETag和If-None-Match
  • 第三部分:标头:内容长度和范围
  • 第四部分:有效地实现HEAD操作
  • 第五部分:油门下载速度
  • 第六部分:描述您发送的内容(内容类型等)
  • 这些文章中开发的示例应用程序可在GitHub上找到。

翻译自: https://www.javacodegeeks.com/2015/07/writing-a-download-server-part-v-throttle-download-speed.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/357729.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高内聚,低耦合——8大核心中间件,微服务基础技术栈技术图谱

什么是微服务? 维基上对其定义为:一种软件开发技术- 面向服务的体系结构(SOA)架构样式的一种变体,将应用程序构造为一组松散耦合的服务。在微服务体系结构中,服务是细粒度的,协议是轻量级的。 微服务(或微服务架构)是一种云原生架构方法,其中单个应用程序由许多松散耦…

java光标移动函数_文件内光标的移动 函数基础 定义函数的三种形式 函数的返回值 调用方式...

# with open(ra.txt, r, encodingutf-8)as f:# data1f.read()# print(>1>:,data1)# print(f.tell()) # 44 只有一种情况下,光标的意思是字符# data2f.read()# print(>2>:,data2) # 第一次有结果,第二次没有,第一次读取数据后光标…

JQuery学习笔记——JQuery基础

#&#xff0c;JQuery避免名称冲突的方法var jq jQuery.noConfilct();jq.ready( function(){jq("p").hidden();});就是为了避免和其他库中$冲突&#xff1b;#&#xff0c;在引用jquery的时候&#xff0c;可以考虑使用google或者微软的cdn的jquery链接&#xff1a;<…

DBA 技能图谱——数据库管理员不在迷茫

导读:DBA一般指数据库管理员。数据库管理员(Database Administrator,简称DBA),是从事管理和维护数据库管理系统(DBMS)的相关工作人员的统称,属于运维工程师的一个分支,主要负责业务数据库从设计、测试到部署交付的全生命周期管理。 目录 DBA 技能图谱 下载地址 DBA 技能…

java的六大_java程序员必备的六大工具!

原标题&#xff1a;java程序员必备的六大工具&#xff01;Java程序员都会有套工具来应对工作上的挑战。多年来&#xff0c;Java 程序员使用软件来完成他们的工作。有很多工具对他们是有用的&#xff0c;不过对于初入行的人员来说&#xff0c;寻找合适的工具是困难的&#xff0c…

用maven运行指定java类main方法

mvn exec:java -Dexec.mainClass"com.java2s.ide.App" 转载于:https://www.cnblogs.com/silvestris/p/5162264.html

dom4j和jaxb_JAXB,SAX,DOM性能

dom4j和jaxb这篇文章研究了使用多种不同方法将XML文档编组为Java对象的性能。 XML文档非常简单。 它包含一个Person实体的集合。 <?xml version"1.0" encoding"UTF-8" standalone"yes"?> <persons><person><id>person…

H5技能图谱——适合各阶段前端程序员的学习地图

导读&#xff1a;学过web前端的都知道&#xff0c;web前端开发主要包括结构、行为和表现。那么要做好web前端&#xff0c;必须知道哪些技能呢?今天孙叫兽给大家介绍web前端的学习地图。 目录 H5技能图谱 下载地址 H5技能图谱 是不是很简单呢&#xff0c;拿赶紧收藏起来学习…

java写exe程序实例_2012软考软件设计师辅导:利用JAVA执行本地EXE文件

曾经为了这样一个需求找了很多资料&#xff0c;今天终于学习到了&#xff01;如何利用java执行exe文件&#xff1f;使用java类Runtime&#xff0c;每个Java应用程序都有一个Runtime类实例&#xff0c;使应用程序能够与其运行的环境相连接。可以通过getRuntime方法获取当前运行时…

Hadoop 家族技能图谱——包含Hive和Mahout两个大类

导读:hadoop是开源的分布式存储和分布式计算平台.由HDFS(分布式文件存储系统,存储海量数据)Mapreduce(并行处理框架,实现任务分配和调度.)组成。可以搭建大型数据仓库,分析海量日志,存储,统计等。Zookeeper 解决分布式环境下的数据管理,统一命名,状态同步,集群管理,配…

java空格 逗号_Java将字符串中的空格换为逗号

import java.util.regex.Matcher;import java.util.regex.Pattern;public class Math {/*** param args*/public static void main(String[] args) {String str "a c b 1 2.2 3";//结果&#xff1a;a,c,b,1,,,,,,,,,,,2.2,,,,,,,,,3System.out.println(str.replaceA…

使用Spring JUnit规则进行参数化集成测试

Spring 4.2附带了全新的JUnit规则&#xff1a; SpringClassRule和SpringMethodRule 。 使用JUnit规则的主要优点是让开发人员摆脱SpringJUnit4ClassRunner并在Spring集成测试中利用不同的JUnit运行器。 我认为Spring JUnit Rules的最大机会是易于创建参数化的集成测试。 要测试…

逻辑的封闭性

始终认为&#xff0c;代码的好坏&#xff0c;在于思维逻辑的有效性、完整性&#xff08;封闭性&#xff09;&#xff0c;只有这样才可能尽量的保证少出现BUG&#xff0c;或者在需求变更的时候&#xff0c;出现改了一处又出现一处的问题 同样&#xff0c;在解决问题的时候&#…

IOS 开发技能图谱——ios 开发工程师必知必会要点

导读&#xff1a;iOS 开发工程师技能图谱&#xff0c;包含开发基础、开发进阶、设计模式、开源项目、APP上传与审核、第三方服务等。 IOS 开发工程师技能图谱 下载地址 点我下载高清iOS 开发工程师技能图谱 关注公众号 电商程序员&#xff0c;回复 iOS 开发工程师技能图谱&am…

java 数学表达式解析插件_数学表达式解析-JAVA版

1 、工具介绍String exp “v>10&&v<2000&&v%100”;在 js 中&#xff0c;能够直接运行 eval 得到结果&#xff0c; java 中也可以&#xff01;在 java 中运行执行这种字符串格式数学表达式的方法&#xff1a;1、自己写按照算法(逆波兰)一个解析程序。2、…

网络数据包收发流程(四):协议栈之packet_type

进入函数netif_receive_skb()后&#xff0c;skb正式开始协议栈之旅。先上图&#xff0c;协议栈大致过程如下所示&#xff1a;跟OSI七层模型不同&#xff0c;linux根据包结构对网络进行分层。比如&#xff0c;arp头和ip头都是紧跟在以太网头后面的&#xff0c;所以在linux协议栈…

OpenResty学习地图来啦,速速收藏!

导读&#xff1a;OpenResty学习地图&#xff0c;全英文文档 OpenResty学习地图 下载地址 点我下载高清OpenResty技能图谱 关注公众号电商程序员&#xff0c;回复OpenResty技能图谱&#xff0c;获取下载链接&#xff01;

java swing游戏_Java Swing井字游戏

java swing游戏大家好&#xff01; 哇&#xff0c;自从我在这里发布了东西以来已经有一段时间了&#xff01; 我必须说我真的很想写东西&#xff0c;我保证我不会再陷入“作家的障碍”。 希望 ..最近两个月发生了很多事情&#xff0c;我有很多话要说。 但是在这篇文章中&#x…

java子类和父类有相同成员_Java -- 父类和子类拥有同名的成员变量的情况

Java – 父类和子类拥有同名的成员变量取值情况参考文章 结论&#xff1a;当子类的成员变量与父类同名时&#xff0c;若对该成员变量进行操作的方法继承于父类&#xff0c;则改变和获取的是父类的成员变量。若对该成员变量进行操作的方法为子类所独有&#xff0c;或override父类…

恭喜孙叫兽在CSDN年度之“战”中脱颖而出——喜提一等奖(小米手环+定制勋章)

导读&#xff1a;在这个多灾多难又充满惊喜注定不平凡的2020年&#xff0c;大家一起与CSDN共同跨过了艰难的疫情&#xff0c;共同经历烦躁的远程办公&#xff0c;一起为科比的逝世而难过&#xff0c;共同度过2020那所谓世界末日&#xff0c;充满青春&#xff0c;充满活力&#…