网站流量统计分析系统-05

定时任务计算:br、avgTime、avgDeep

br

编写两个topology

package com.liming.flux;

import java.util.UUID;

import backtype.storm.Config;
import backtype.storm.LocalCluster;
import backtype.storm.generated.StormTopology;
import backtype.storm.spout.SchemeAsMultiScheme;
import backtype.storm.topology.TopologyBuilder;
import backtype.storm.utils.Utils;
import storm.kafka.BrokerHosts;
import storm.kafka.KafkaSpout;
import storm.kafka.SpoutConfig;
import storm.kafka.StringScheme;
import storm.kafka.ZkHosts;

public class FluxTopology {
	public static void main(String[] args) {
		//SPOUT的id 要求唯一
		String KAFKA_SPOUT_ID = "flux_spout";
		//要连接的kafka的topic
		String CONSUME_TOPIC = "flux_topic";
		//要连接的zookeeper的地址
		String ZK_HOSTS = "192.168.239.129:2181";
		//设定连接服务器的参数
		BrokerHosts hosts = new ZkHosts(ZK_HOSTS);
		SpoutConfig spoutConfig = new SpoutConfig(hosts, CONSUME_TOPIC, "/" + CONSUME_TOPIC, UUID.randomUUID().toString());
		spoutConfig.scheme = new SchemeAsMultiScheme(new StringScheme());
		//从kafka读取数据发射
		KafkaSpout kafkaSpout = new KafkaSpout(spoutConfig);
		
		//创建TopologyBuilder类实例
		TopologyBuilder builder = new TopologyBuilder();
		builder.setSpout(KAFKA_SPOUT_ID, kafkaSpout);
		//清理数据
		builder.setBolt("ClearBolt", new ClearBolt()).shuffleGrouping(KAFKA_SPOUT_ID);
		//计算PV
		builder.setBolt("PvBolt", new PvBolt()).shuffleGrouping("ClearBolt");
		//计算Uv
		builder.setBolt("UvBolt", new UvBolt()).shuffleGrouping("PvBolt");
		//计算vv
		builder.setBolt("VvBolt", new VvBolt()).shuffleGrouping("UvBolt");
		//计算newip
		builder.setBolt("NewipBolt", new NewipBolt()).shuffleGrouping("VvBolt");
		//计算newcust
		builder.setBolt("NewcustBolt", new NewcustBolt()).shuffleGrouping("NewipBolt");
		//落地到mysql
		builder.setBolt("ToMysqlBolt", new ToMysqlBolt()).shuffleGrouping("NewcustBolt");
		builder.setBolt("PrintBolt", new PrintBolt()).shuffleGrouping("NewcustBolt");
		builder.setBolt("ToHbaseBolt", new ToHbaseBolt()).shuffleGrouping("NewcustBolt");
		StormTopology topology = builder.createTopology();
		
		/**
		 * 每隔5分钟计算br avgtime avgdeep
		 */
		TopologyBuilder builder2 = new TopologyBuilder();
		builder2.setSpout("flux_spout2", new TimeSpout());
		builder2.setBolt("br_bolt", new BrBolt()).shuffleGrouping("flux_spout2");
		//TODO:计算avgTime
		//TODO:计算avgDeep
		//TODO:写入mysql
		builder2.setBolt("PrintBolt2", new PrintBolt2()).shuffleGrouping("br_bolt");
		StormTopology topology2 = builder2.createTopology();
		
		
		/**
		 * 提交Topology给集群运行
		 */
		Config conf = new Config();
		LocalCluster cluster = new LocalCluster();
		cluster.submitTopology("MyTopology", conf, topology);
		cluster.submitTopology("MyTopology2", conf, topology2);
		//--运行10秒钟后杀死Topology关闭集群
		Utils.sleep(1000 * 1000);
		cluster.killTopology("MyTopology"); 
		cluster.killTopology("MyTopology2"); 
		cluster.shutdown();
	}
}

这个spout只是定时启动这条“定时任务”流水线

package com.liming.flux;

import java.util.Map;

import backtype.storm.spout.SpoutOutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseRichSpout;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Values;

public class TimeSpout extends BaseRichSpout {

	private SpoutOutputCollector collector = null;
	private long time = 0l;
	
	@Override
	public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {
		this.collector = collector;
		time = System.currentTimeMillis();
	}

	@Override
	public void nextTuple() {
		try {
			long now = System.currentTimeMillis();
			if(now - time >= 1000 * 10 /** 5*/){
				collector.emit(new Values(now));
				time = now;
			}else{
				Thread.sleep(1);
				return;
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

	@Override
	public void declareOutputFields(OutputFieldsDeclarer declarer) {
		declarer.declare(new Fields("signal"));
	}

}
package com.liming.flux;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.liming.flux.dao.HBaseDao;
import com.liming.flux.domain.FluxInfo;
import com.liming.flux.utils.FluxUtils;

import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseRichBolt;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Tuple;
import backtype.storm.tuple.Values;

public class BrBolt extends BaseRichBolt {

	private OutputCollector collector = null;
	private Map<String,Integer> map = new HashMap<>();
	@Override
	public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
		this.collector = collector;
	}

	@Override
	public void execute(Tuple input) {
		long time = input.getLongByField("signal");
		Date date = new Date(time);
		String dateStr = FluxUtils.formatDate(date);
		List<FluxInfo> list = HBaseDao.queryData("^"+dateStr+"_.*$");
		//遍历数据
		for(FluxInfo fi : list){
			String ss_id = fi.getSs_id();
			map.put(ss_id, map.containsKey(ss_id) ? map.get(ss_id)+1 : 1);
		}
		//计算跳出率
		int ssCount = map.size();
		int brCount = 0;
		for(Map.Entry<String, Integer> entry : map.entrySet()){
			if(entry.getValue() == 1)brCount++;
		}
		double br = Math.round(brCount * 100.0 / ssCount)/100.0;
		
		//输出结果
		collector.emit(new Values(br));
	}

	@Override
	public void declareOutputFields(OutputFieldsDeclarer declarer) {
		declarer.declare(new Fields("br"));
	}

}
package com.liming.flux;

import java.util.Iterator;
import java.util.Map;

import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseRichBolt;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Tuple;

public class PrintBolt2 extends BaseRichBolt{

	private OutputCollector collector = null;
	
	@Override
	public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
		this.collector = collector;
	}

	@Override
	public void execute(Tuple input) {
		Fields fields = input.getFields();
		StringBuffer buf = new StringBuffer();
		Iterator<String> it = fields.iterator();
		while(it.hasNext()){
			String key = it.next();
			Object value = input.getValueByField(key);
			buf.append("----"+key+":"+value+"-----");
		}
		System.out.println(buf.toString());
		
		collector.emit(input.getValues());
		
	}

	@Override
	public void declareOutputFields(OutputFieldsDeclarer declarer) {
		declarer.declare(new Fields("br"));
	}
	
}
点击一次就关闭浏览器:预订跳出率为1,验证正确



BlueBird Website Statistic 2 即蓝鸟网站流量统计软件,是基于 PHP 及 文本方式的应用程序。 本流量统计程序采用文本方式存储数据(对于数据库版本将在以后推出); 运用先进的数据存储结构和程序算法;使用限制日 IP 访问的方式,不仅可 以准确的反映网站访问的真实情况,而且也相对节约了系统资源。 在这个版本中继承了以往版本的优秀之处,修改了全部已知错误。可提供 网站运行期间的年、月、日、24小时及星期流量统计,并可提供历史数据查 询;更增加了浏览者 IP 地址、来访页面、浏览者使用的软件(浏览器和操 作系统)等统计数据。管理员还可以对各种统计资料页面进行锁定,使重要 信息不至于外泄。 本程序为免费程序,仅提供给个人使用,不得用于任何商业用途。用户可 对源代码进行部分的修改、美化,但您不可以从本软件中去掉其版权声明; 并保证为其代码复制版权声明。您有义务向作者提供修改后的代码。在未经 作者本人同意或本站授权,任何人不得擅自将修改后的版本提供下载。 如果在使用中您发现了任何 BUG 或者有好的建议,请尽快反馈给我们。 ================= 安装须知 ================= 将软件解压缩,上传到主页上,默认的数据存储目录是 ./_Data 需要保证该 目录和其下的子目录权限为 777 ;默认的 IP 地址数据库是 ./IP_DATA 。 不建议修改。 配置:在 config.php 中按要求配置即可。默认的帐号 admin 密码为 pass 。 使用:将 stat.php 文件包含在所要统计的网页中。如: include "stat.php"; 对于 JavaScript 的调用还没有时间写。也恨简单,只要在将 stat.php 输出为 JavaScript 格式就行了。 高级:在 main.php 中修改 $StatTypes 参数,设置安全页面。0 表示该页 不可见,只有管理员可见;1 为任何人都可见。如默认的“来访者详 细信息【最近 50 条】”设为 0 你可以看一下效果。 ========================= BlueBird 2 最新特色 ========================= A. 重写全部代码,使程序更紧凑,运行效率更高; B. 全新页面操作风格,方便实用; C. 修改了文本数据格式,使得非法用户无法用浏览器直接获取; D. 增加了 1864 条 IP 地址的地理所在地的数据信息,使来访者“无所盾藏”; E. 增加管理员模块,可以控制各种统计数据页面是否公开; F. 采用增量数据存储方式,对于重要统计数据可以进行历史查询; G. 更新操作系统、浏览器的类型判别模块,可识别 90% 以上的主流软件 BlueBird (蓝鸟)网站流量统计 更新历史 History BlueBird (蓝鸟)网站流量统计 常见问题 FAQ BlueBird (蓝鸟)网站流量统计 自述文件 Readme ============= 程序下载 ============= 安装环境: PHP 4.0 操作系统: Windows/Uinx 文件尺寸: 120k 更新时间: 2004.2.20 下载地址:http://xpower.jilinfarm.com/ http://hotage.myrice.com/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值