`
david.org
  • 浏览: 157131 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

一个记录近某段时间内流量的小程序

阅读更多
在应用程序中, 有时并不希望只是为了存储某些数据而引入数据库这个大载体, 在文件下载服务器中, 可以用一个 List记录某IP, 或者某用户在最近一段时间内所读取的流量.

新建一个用于存放流量的列表:

/** A list for storing recently past 30 minutes reads */
	static final List<UserDescriptor> LINKED = 
									new ArrayList<UserDescriptor>(LINKED_SIZE);


列表的长度:
/** The capaity to initiate LINKED */
	private static final int LINKED_SIZE = 0xa;


再者, 该列表有一个长度, 它指示该表由几个槽组成, 这里假设存储近30分钟的量, 由10个槽组成, 每一个槽存放3分钟之内的量.

setLink(); 方法由多线程在完成数据读取后调用.
void setLink(long transferedSize) {
		if (transferedSize <= 0) {
			return;
		}
		long reads = transferedSize;
		synchronized (LINKED) {
			if (pointer < 0 || pointer >= LINKED_SIZE) {
				// error encounter.
				pointer = 0;
			}
			UserDescriptor ud = LINKED.get(pointer);
			if (ud.lastUpdate == 0) {
				ud.setDescriptor(reads);
				LOG.debug("add new Link point at: " + pointer + " reads: " + reads);
			} else {
				if (now() - ud.lastUpdate < INTERVAL_UPDATE_LINK) {
					// inner the time trough, increase reads !!
					ud.addReads(reads);
					LOG.debug("addLink point at: " + pointer + " reads: " + ud.reads);
				} else {
					// out of the time trough, point to the next one
					pointer = (pointer + 1) % LINKED_SIZE;
					ud = LINKED.get(pointer);
					ud.reset();
					ud.setDescriptor(reads);
					LOG.debug("setLink point at: " + pointer + " reads: " + ud.reads);
				}
			}
		}
	}


另外需要有一个监视线程来跟据时间近迁移, 重新重置trough里的数据. 比如近3分钟时间内如果没有数据流出, 那么最老的一项需要被重置.
void truncate(List<? extends Descriptor> link, int _point) {
			if (link.size() == 0) {
				return;
			}
			if (_point < 0 || _point >= link.size()) {
				_point = 0;
			}
			
			long now = now();
			int size = link.size();
			int _low = size - 1;
			while (_low != -1) {
				if (_point -1 < 0) {
					_point = size;
				}
				int _p = --_point;
				Descriptor dscpt = link.get(_p);
				long lastUpdate = dscpt.getLastUpdate();
				if (lastUpdate != 0) {
					if (now - lastUpdate >= LINKED_WINDOW_SIZE) {
						LOG.info("*XXXXX descriptor will be reset " + dscpt);
						dscpt.reset();
					}
				}
				--_low;
			}
		}


那么在程序运行过程中, 可以读取该列表的总长度, 来获取近30分钟内的流量, 这个实现不是精确的, 但对于统计来说, 已经够用了.
分享到:
评论
6 楼 david.org 2010-02-10  
skydream 写道
楼主是想做一个throttle的控制是吧?
对于这个东西,网上有几种线程的算法,google一下吧。
你的这个,没有细看,似乎比较粗糙。



都说了比较简单, 只是作个流量记录而已, Throttle的实现, Hadoop也有做, 比较经典.
5 楼 skydream 2010-02-10  
楼主是想做一个throttle的控制是吧?
对于这个东西,网上有几种线程的算法,google一下吧。
你的这个,没有细看,似乎比较粗糙。

4 楼 david.org 2010-02-09  
在应用程序中, 有时并不希望只是为了存储某些数据而引入数据库这个大载体, 在文件下载服务器中, 可以用一个 List记录某IP, 或者某用户在最近一段时间内所读取的流量.

新建一个用于存放流量的列表:
/** A list for storing recently past 30 minutes reads */
	static final List<UserDescriptor> LINKED = 
									new ArrayList<UserDescriptor>(LINKED_SIZE);


列表的长度:
/** The capaity to initiate LINKED */
	private static final int LINKED_SIZE = 0xa;


再者, 该列表有一个长度, 它指示该表由几个槽组成, 这里假设存储近30分钟的量, 由10个槽组成, 每一个槽存放3分钟之内的量.

setLink(); 方法由多线程在完成数据读取后调用.

void setLink(long transferedSize) {
		if (transferedSize <= 0) {
			return;
		}
		long reads = transferedSize;
		synchronized (LINKED) {
			if (pointer < 0 || pointer >= LINKED_SIZE) {
				// error encounter.
				pointer = 0;
			}
			UserDescriptor ud = LINKED.get(pointer);
			if (ud.lastUpdate == 0) {
				ud.setDescriptor(reads);
				LOG.debug("add new Link point at: " + pointer + " reads: " + reads);
			} else {
				if (now() - ud.lastUpdate < INTERVAL_UPDATE_LINK) {
					// inner the time trough, increase reads !!
					ud.addReads(reads);
					LOG.debug("addLink point at: " + pointer + " reads: " + ud.reads);
				} else {
					// out of the time trough, point to the next one
					pointer = (pointer + 1) % LINKED_SIZE;
					ud = LINKED.get(pointer);
					ud.reset();
					ud.setDescriptor(reads);
					LOG.debug("setLink point at: " + pointer + " reads: " + ud.reads);
				}
			}
		}
	}

另外需要有一个监视线程来跟据时间近迁移, 重新重置trough里的数据. 比如近3分钟时间内如果没有数据流出, 那么最老的一项需要被重置.

void truncate(List<? extends Descriptor> link, int _point) {
			if (link.size() == 0) {
				return;
			}
			if (_point < 0 || _point >= link.size()) {
				_point = 0;
			}
			
			long now = now();
			int size = link.size();
			int _low = size - 1;
			while (_low != -1) {
				if (_point -1 < 0) {
					_point = size;
				}
				int _p = --_point;
				Descriptor dscpt = link.get(_p);
				long lastUpdate = dscpt.getLastUpdate();
				if (lastUpdate != 0) {
					if (now - lastUpdate >= LINKED_WINDOW_SIZE) {
						LOG.info("*XXXXX descriptor will be reset " + dscpt);
						dscpt.reset();
					}
				}
				--_low;
			}
		}


那么在程序运行过程中, 可以读取该列表的总长度, 来获取近30分钟内的流量, 这个实现不是精确的, 但对于统计来说, 已经够用了.
3 楼 8821249 2010-02-09  
这个是什么?
2 楼 deyami 2010-02-09  
什么乱七八糟的?认真点好不好?
1 楼 viei 2010-02-09  
搞不清楚是什么

相关推荐

    carMoveDected_QT车辆识别_车流量检测小程序_

    此外,"carMoveDected"作为一个小程序,其用户界面可能包括实时视频显示、车辆检测结果的可视化以及车流量统计数据的展示。用户可以通过这个界面直观地查看车辆检测情况,并根据需要调整参数,如检测阈值、帧率等,...

    威盾V3.0模块名称-功能作用

    该模块可以按 6 种模式(地址明细、端口明细、地址类别、端口类别、计算机和地址类别、计算机和端口类别)查询在某段时间计算机(组)或用户(组)的网络流量情况(可按合计、发送或接收分别统计),支持三种文件...

    基于YoLov8与Tesseract-OCR的车流量分析系统源码+实验报告+使用说明+演示视频.zip

    车流量统计部分,系统通过连续追踪视频中的车辆,记录每辆车的进入和离开时间,进而计算出某一时间段内两个方向的车流量。这为交通规划和管理提供了量化数据,有助于了解交通压力分布,预测并避免交通瓶颈。 使用这...

    背景差分法和邻帧检测法对车流数目进行统计(OpenCV+VC2008)_背景差分法_邻帧检测法_车流量检测_VC++.zip

    在初始阶段,我们会记录一段时间内的静态背景图像,形成背景模型。之后,每一帧与背景模型进行比较,计算像素级别的差异,差异较大的区域则被认为是运动物体。在车流量检测中,这种差异可以用来定位车辆的位置,从而...

    -基于RFID的体育馆人流量监测与实现 5.27 10000 30%.docx

    5. **灵活性**:支持多种查询方式,如按时间段、按活动类型等查询人流量数据。 #### 五、关键技术应用 1. **RFID技术**:通过RFID标签和读写器实现人员身份验证及出入记录。 2. **ASP.NET技术**:用于构建系统前端...

    基于PLC实现道路十字路口交通灯模糊控制系统

    在四个方向(东E、南S、西W、北N)的近端J(靠近斑马线)和远端Y(距离斑马线约100米)各设置一个传感器,用于统计通过该处的车辆数。近端的传感器主要用于记录绿灯期间通过路口的车辆数(记为X),而远端的传感器则...

    水文日平均水位计算软件

    日平均水位是指在一天24小时内,每隔一段时间(如每小时或每半小时)记录的水位数据,通过统计计算得出的代表该日水位的平均值。这个值有助于分析河流、湖泊、水库等水体的动态变化,对水文预报、水资源调度和防洪...

    Visual C++ 程序开发范例宝典 源码 光盘 part2

    cc实例269 多表联合查询 cc实例270 对联合查询后的结果进行排序 9.13 内连接查询 cc实例271 简单内连接查询 cc实例272 复杂内连接查询 cc实例273 使用内连接选择一个表与另一个表中行相关的所有行 9.14...

    Visual C++程序开发范例宝典(PDF扫描版).part2

     cc实例184 执行一个外部程序直到其结束   cc实例185 调用具有参数的可执行程序   6.7 线程同步   cc实例186 利用事件对象实现线程同步   cc实例187 利用互斥对象实现线程同步   cc实例188 利用...

    Visual C++程序开发范例宝典(PDF扫描版).part3

     cc实例184 执行一个外部程序直到其结束   cc实例185 调用具有参数的可执行程序   6.7 线程同步   cc实例186 利用事件对象实现线程同步   cc实例187 利用互斥对象实现线程同步   cc实例188 利用...

    钻孔压水试验在工程勘察中的应用.pdf

    一旦在一定时间间隔内流量不再持续增大,且读数变化范围小于最终值的一定比例(如10%)或者小于一定量(如1升/分钟),即可认为达到了水量的稳定状态。此时记录的流量数据可作为岩体渗透性的评估依据。 总之,钻孔...

    Visual C++程序开发范例宝典(光盘) 第四部分

    实例273 使用内连接选择一个表与另一个表中行相关的所有行 9.14 外连接查询 实例274 LEFT OUTER JOIN查询 实例275 RIGHT OUTER JOIN查询 实例276 使用外连接进行多表联合查询 9.15 利用IN进行查询 实例277 ...

    Visual C++程序开发范例宝典(光盘) 第八部分

    实例273 使用内连接选择一个表与另一个表中行相关的所有行 9.14 外连接查询 实例274 LEFT OUTER JOIN查询 实例275 RIGHT OUTER JOIN查询 实例276 使用外连接进行多表联合查询 9.15 利用IN进行查询 实例277 ...

    14特殊路基施工技术(二)-题目.pdf

    2. **真空预压设备与流程**:抽真空设备通常采用真空泵,每个加固场地至少配备一个。真空管路由主干管和支管构成,密封膜边缘需埋入土中以保证密封。在施工过程中,需要监测真空度、沉降速率、孔隙水压力、土体位移...

    操作系统 (2).pdf

    操作系统是计算机系统的核心组成部分,它负责管理和控制计算机硬件与软件资源,为用户提供一个友好的、高效率的工作环境。操作系统的设计原则主要包括可靠工作、方便使用和高效执行。在本题中,涉及了操作系统的一些...

    Sniffer_Pro_图文简明教程捕获内网用户密码

    本文档将详细介绍 Sniffer Pro 的基本使用方法,并提供一个具体的实例来展示如何利用 Sniffer Pro 捕获内网用户的密码。请注意,此教程仅供学习和技术研究使用,切勿用于非法目的。 #### Sniffer Pro 安装与配置 ...

    Cookie'.docx

    Cookie是Web应用程序中常用的一种数据存储机制,它是由服务器端发送到客户端(浏览器)的一小段文本信息,浏览器在后续的请求中会将Cookie回传给服务器,以此来维持会话状态或者存储用户偏好设置。Cookie的主要功能...

    鑫达进销存适用于大、中、小超市,批发商,物流配送中心,商店等

    在每一个货段或货架设定陈列商品的最高上限,越过此上限后需淘汰商品才能录入新品。防止录入商品过多,无位置可摆,互挤占位的问题。并增加淘汰商品库,以存放从正常码库删除的商品。如需恢复淘汰的商品,一键完成。...

    Python 树状数组.docx

    2. **高效的区间查询:** 同样可以在 \(O(\log n)\) 时间内完成对数组中某一段连续区间的元素之和的查询。 3. **空间占用较少:** 只需额外使用一个与原数组大小相等的空间来存储累积和信息。 **应用场景:** - 在...

Global site tag (gtag.js) - Google Analytics