JavaSDK设计规则

JavaSDK提供两个事件触发方法,分别为onChargeSuccess和onChargeRefund。我们在java sdk中通过一个单独的线程来发送线程数据,这样可以减少对业务系统的延时性。

SDK测试

启动集群上的hdfs+nginx+flume进程,通过模拟数据的发送然后将数据发送到nginx服务器中,查看最终是否在hdfs中有数据的写入。

命令:

start-dfs.sh: 启动hdfs命令

su root:切换用户

service nginx restart: 启动nginx进程

启动flume进程:

进入flume安装根目录,执行命令:


flume-ng agent --conf ./conf/ --conf-file ./conf/test2.conf --name agent &


工程目录结构

AnalyticsEngineSDK如下:
package com.kk.ae.sdk;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger; /*
* 分析引擎sdk java服务器数据收集
* */
public class AnalyticsEngineSDK { //日志记录对象
private static final Logger log=Logger.getGlobal();
//请求url的主体部分
public static final String accessUrl="http://hadoop-001:8090/kkImg.gif";
public static final String platformName="java_server";
public static final String sdkName="jdk";
private static final String version = "1";
/**
* 触发订单支付成功事件,发送事件数据到服务器
*
* @param orderId
* 订单支付id
* @param memberIdd
* 订单支付会员id
* @return 如果发送数据成功(加入到发送队列中),那么返回true;否则返回false(参数异常&添加到发送队列失败).
* @throws InterruptedException
*/
public static boolean chargeSuccess(String orderId,String memberId) throws InterruptedException { if (orderId!=null&&!orderId.isEmpty()&&memberId!=null&&!memberId.isEmpty()) {
Map<String, String> map=new HashMap<String,String>();
map.put("u_mid", memberId);
map.put("oid", orderId);
map.put("c_time", String.valueOf(System.currentTimeMillis()));
map.put("ver", version);
map.put("en", "e_cs");
map.put("p1", platformName);
map.put("sdk", sdkName); //创建url
String url= buildUrl(map);
// 发送url&将url加入到队列
SendDataMonitor.addSendUrl(url);
System.out.println(url);
return true;
} else {
log.log(Level.WARNING, "订单id和会员id不能为空");
return false;
} }
/**
* 触发订单退款事件,发送退款数据到服务器
*
* @param orderId
* 退款订单id
* @param memberIdd
* 退款会员id
* @return 如果发送数据成功,返回true。否则返回false。
* @throws InterruptedException
*/
public static boolean chargeRefund(String orderId,String memberId) throws InterruptedException {
if (orderId!=null&&!orderId.isEmpty()&&memberId!=null&&!memberId.isEmpty()) {
Map<String, String> map=new HashMap<String,String>();
map.put("u_mid", memberId);
map.put("oid", orderId);
map.put("c_time", String.valueOf(System.currentTimeMillis()));
map.put("ver", version);
map.put("en", "e_cr");
map.put("p1", platformName);
map.put("sdk", sdkName); //创建url
String url= buildUrl(map);
// 发送url&将url加入到队列
SendDataMonitor.addSendUrl(url);
System.out.println(url);
return true;
} else {
log.log(Level.WARNING, "订单id和会员id不能为空");
return false;
} }
private static String buildUrl(Map<String, String> map) { StringBuffer stringBuffer=new StringBuffer();
stringBuffer.append(accessUrl).append("?");
for(Map.Entry<String, String> entry:map.entrySet()) {
if (entry.getKey()!=null&&!entry.getKey().isEmpty()&&entry.getValue()!=null&&!entry.getValue().isEmpty()) {
{
try {
stringBuffer.append(entry.getKey().trim()).append("=").append(URLEncoder.encode(entry.getValue().trim(),"utf-8")).append("&");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
} }
return stringBuffer.substring(0, stringBuffer.length() - 1);
} }
SendDataMonitor 如下:
package com.kk.ae.sdk;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger; /**
* 发送url数据的监控者,用于启动一个单独的线程来发送数据
*
* @author gerry
*
*/
public class SendDataMonitor {
//收集日志
public static final Logger log=Logger.getGlobal();
// 队列,用户存储发送url
public static final BlockingQueue<String> queue=new LinkedBlockingQueue<String>();
//用于单例的一个类对象
private static SendDataMonitor monitor=null; private SendDataMonitor() {
// 私有构造方法,进行单列模式的创建
} public static SendDataMonitor getMonitor() {
if (monitor==null) {
synchronized (SendDataMonitor.class) {
if (monitor==null) {
monitor=new SendDataMonitor();
Thread thread=new Thread(new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub
SendDataMonitor.monitor.run(); }
});
thread.start();
}
}
}
return monitor;
} protected void run() {
while (true) {
try {
String url=this.queue.take();
// 正式的发送url
HttpRequestUtil.sendData(url);
} catch (Throwable e) {
log.log(Level.WARNING, "发送url异常", e);
}
}
} public static void setMonitor(SendDataMonitor monitor) {
SendDataMonitor.monitor = monitor; } /**
* 添加一个url到队列中去
*
* @param url
* @throws InterruptedException
*/
public static void addSendUrl(String url) throws InterruptedException {
getMonitor().queue.put(url); }
/**
* 内部类,用户发送数据的http工具类
*
* @author gerry
*
*/
public static class HttpRequestUtil{
/**
* 具体发送url的方法
*
* @param url
* @throws IOException
*/
public static void sendData(String url) throws IOException {
HttpURLConnection con=null;
BufferedReader bf=null;
try {
URL obj=new URL(url);
con=(HttpURLConnection) obj.openConnection();
// 设置连接参数
con.setConnectTimeout(5000);//连接过期时间
con.setReadTimeout(5000);//读取数据过期时间
con.setRequestMethod("GET");//设置请求类型为get
System.out.println("发送url:" + url);
// 发送连接请求
bf=new BufferedReader(new InputStreamReader(con.getInputStream())); } finally {
try {
if (bf!=null) {
bf.close(); }
} catch (Throwable e) {
// TODO: handle exception }
try {
con.disconnect();
} catch (Throwable e) {
// TODO: handle exception
}
}
} } }

测试类:

package com.kk.ae.sdk;

public class Test {

public static void main(String[] args) {
try {
AnalyticsEngineSDK.chargeSuccess("order3516", "0958");
AnalyticsEngineSDK.chargeRefund("kk3", "9009");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

大数据离线分析平台 JavaSDK数据收集引擎编写的更多相关文章

  1. 大数据离线分析平台 用户数据Etl

    Etl目标  解析我们收集的日志数据,将解析后的数据保存到hbase中.这里选择hbase来存储数据的主要原因就是: hbase的宽表结构设计适合我们的这样多种数据格式的数据存储(不同event有不同 ...

  2. 大数据离线分析平台 JSSDK数据收集引擎编写

    JsSDK设计规则在js sdk中我们需要收集launch.pageview.chargeRequest和eventDuration四种数据,所以我们需要在js中写入四个方法来分别收集这些数据,另外我 ...

  3. mapReduce 大数据离线分析

    数据分析一般分为两种,一种是在线一种是离线 流程: 一般都是对于日志文件的采集和分析 场景实例(某个电商网站产生的用户访问日志(access.log)进行离线处理与分析的过程) 1.需求: 基于Map ...

  4. 大快DKH大数据智能分析平台监控参数说明

    2018年国内大数据公司50强榜单排名已经公布了出来,大快以黑马之姿闯入50强,并摘得多项桂冠.Hanlp自然语言处理技术也荣膺了“2018中国数据星技术”奖.对这份榜单感兴趣的可以找一下看看.本篇承 ...

  5. 快速构建大数据存储分析平台-ELK平台安装

    一.概述 ELK是由Elastic公司开发的Elasticsearch.Logstash.Kibana三款开源软件的缩写(但不限于这三款软件). 为什么使用ELK? 在目前流行的微服务架构中,一个大型 ...

  6. 从Excel读取数据,然后分析相似的数据,多线程处理(多线程比较相似的字符串,统计出相似的数量及字符串)

    之前的jar包有问题,现已修改. 需要的jar包,已修改 自己去Maven中央仓库下载jar包. excel数据: 直接上代码. 程序再度优化了一遍.之后如果想再度精准,可能需要建模,最近没空继续做了 ...

  7. 分布式大数据系统离线分析技术解决方案(spark2.x)

    一.sark2.x新型的架构系统

  8. 基于Hadoop技术实现的离线电商分析平台(Flume、Hadoop、Hbase、SpringMVC、highcharts)

    离线数据分析平台是一种利用hadoop集群开发工具的一种方式,主要作用是帮助公司对网站的应用有一个比较好的了解.尤其是在电商.旅游.银行.证券.游戏等领域有非常广泛,因为这些领域对数据和用户的特性把握 ...

  9. snmp数据包分析

    今天看了一下snmp数据包的报文格式,用wireshark抓了两个数据包来分析. 先说说snmp get-request的书报包格式吧,get-next-request,get-response,se ...

随机推荐

  1. python flask大型项目目录

    Hello World 作者背景 应用程序简介 要求 安装 Flask 在 Flask 中的 “Hello, World” 下一步? 模板 回顾 为什么我们需要模板 模板从天而降 模板中控制语句 模板 ...

  2. Day5作业及默写

    1,有如下变量(tu是个元祖),请实现要求的功能 tu = ("alex", [11, 22, {"k1": 'v1', "k2": [&q ...

  3. win系统 Mysql 5.7.19 zip 安装

    1 安装运行环境 VC++ 2013 2 下载 https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.19-winx64.zip 3 解压 4 ...

  4. 【Python】多进程-4

    #练习:用event事件控制进程执行顺序,下面例子中,主进程main函数在创建了子进程之后,依然会往下执行,所以会出现主进程先打印出来的情况 import multiprocessing import ...

  5. 微软Power BI 每月功能更新系列——7月Power BI 新功能学习

    Power BI Desktop 7月产品功能摘要 7月是Power BI Desktop团队的重要发布!但由于官方延迟更新,我们的讲述也就更晚了一点,也许大家觉得没有必要了,都8月了,谁还看7月的? ...

  6. e与复利

    e≍2.718 计算一个复利例子,设本金p,年利率为r,每月计算一次利息,月利息为r/12,则一年的本息一共: p(1+r/12)12=pq 当计算复利的时间间隔越来越小,根据上面极限公式,本金所乘的 ...

  7. Java中的内部类————以及jdk1.8的lambda表达式

    一.内部类学习导图 1>.静态内部类: 使用static修饰符来修饰内部类,则这个内部类就属于外部类本身,而不属于外部类的某个对象.因此使用static修饰的内部类被称为静态内部类. publi ...

  8. 获取列表中的最大的N项和最小的N项

    获取列表中的最大的N项和最小的N项 #!/sur/bin/env python # -*- coding:utf-8 -*- # author:zengsf #time:2018/10/31 impo ...

  9. sticky footer 和 flex布局的原理

    Sticky footers设计是最古老和最常见的效果之一,大多数人都曾经经历过.它可以概括如下:如果页面内容不够长的时候,页脚块粘贴在视窗底部:如果内容足够长时,页脚块会被内容向下推送. 一.使用f ...

  10. 2017java文本文件操作(读写操作)

    java的读写操作是学java开发的必经之路,下面就来总结下java的读写操作. 从上图可以开出,java的读写操作(输入输出)可以用“流”这个概念来表示,总体而言,java的读写操作又分为两种:字符 ...