大数据-----网站流量日志数据采集--socket机制

1.数据采集的重要性

当前市场环境下,数据对于一个企业的重要性堪比汽车对于石油的重要性,而我们数据采集的手段,采集的准确性,采集的性能,以及采集的内容都是决定了数据能否最终被我们实用起来。

2.数据采集的原理:

埋点:我们在前端会写一个采集的脚本(一段js代码),当用户发起http请求访问的时候就会执行,这时候用户的点击信息(比如访问地址、ip、访问的页面、页面停留的时间)就会被记录下来,存储到nginx中,为了实现跨域的功能,一般情况下会给用户响应一个1*1像素的图片,用来传递数据。

 

3.数据采集架构:

3.1

3.2确定收集信息

比如访问时间、ip、域名、URL、页面标题、分辨率、浏览客户端、状态值等等。

3.3确定埋点js代码

埋点,是网站分析的一种常用的数据采集方法。核心就是在需要进行数据采集的关键点植入统计代码,进行数据的采集。比如以谷歌分析原型来说,需要在页面中插入一段它提供的 javascript 片段,这个片段往往被称为埋点代码。

<script type="text/javascript">

var _maq = _maq || [];

_maq.push(['_setAccount', 'UA-XXXXX-X']);

(function() {

var ma = document.createElement('script'); ma.type =

'text/javascript'; ma.async = true;

ma.src = ('https:' == document.location.protocol ?

'https://ssl' : 'http://www') + '.google-analytics.com/ma.js';

var s = document.getElementsByTagName('script')[0];

s.parentNode.insertBefore( m a, s);

})();

</script>

_maq 的机制不是重点,重点是后面匿名函数的代码

ma.async = true 的意思是异步调用外部 js 文件

自调用匿名函数的好处是,避免重名,自调用匿名函数只会在运行时执行一次,一般用于初始化

3.4 前端数据收集脚本:

3.4.1 通过浏览器内置的js对象接受信息。

3.4.2 解析_maq 数组,收集配置信息。这里面可能会包括用户自定义的事件跟踪、业务数据(如电子商务网站的商品编号等)等。

3.4.3 将上面两步收集的数据按预定义格式解析并拼接(get 请求参数)。

3.4.4 请求一个后端脚本,将信息放在 http request 参数中携带给后端脚本

(function () {

var params = {};

//Document 对象数据

if(document) {

params.domain = document.domain || '';

params.url = document.URL || '';

params.title = document.title || '';

params.referrer = document.referrer || '';

}

//Window 对象数据

if(window && window.screen) {

params.sh = window.screen.height || 0;

params.sw = window.screen.width || 0;

params.cd = window.screen.colorDepth || 0;

}

//navigator 对象数据

if(navigator) {

params.lang = navigator.language || '';

}

//解析_maq 配置

if(_maq) {

for(var i in _maq) {

switch(_maq[i][0]) {

case '_setAccount':

params.account = _maq[i][1];

break;

default:

break;

}

}

}

//拼接参数串

var args = '';

for(var i in params) {

if(args != '') {

args += '&';

}

args += i + '=' + encodeURIComponent(params[i]);

}

//通过 Image 对象请求后端脚本

var img = new Image(1, 1);

img.src = ' http://xxx.xxxxx.xxxxx/log.gif? ' + args;

})();

3.5 后端脚本

log.gif 是后端脚本,是一个伪装成 gif 图片的脚本。后端脚本一般需要完成以下几件事情:

3.5.1 解析 http 请求参数得到信息

3.5.2 从 Web 服务器中获取一些客户端无法获取的信息,如访客 ip 等

3.5.3 将信息按格式写入 log

3.5.4 生成一副 1×1 的空 gif 图片作为响应内容并将响应头的 Content-type设为 image/gif

3.5.5 在响应头中通过 Set-cookie 设置一些需要的 cookie 信息

3.6 日志格式

日志的格式要考虑日志的分隔符,一般会有如下几种格式

固定数量的字符、制表符分隔符、空格分隔符、其他一个或多个字符、特定的开始和结束文本

3.7 日志的切分

日志收集系统访问日志时间一长文件变得很大,而且日志放在一个文件不便于管理。通常要按时间段将日志切分,例如每天或每小时切分一个日志。通过crontab 定时调用一个 shell 脚本实现,如下

_prefix="/path/to/nginx"

time=`date +%Y%m%d%H`

mv ${_prefix}/logs/ma.log ${_prefix}/logs/ma/ma-${time}.log

kill -USR1 `cat ${_prefix}/logs/nginx.pid

4.系统环境部署:

4.1上传 LuaJIT-2.0.4.tar.gz 并安装 LuaJI

4.2设置 LuaJIT 环境变量

vi /etc/profile

export LUAJIT_LIB=/usr/local/luajit/lib

export LUAJIT_INC=/usr/local/luajit/include/luajit-2.0

source /etc/profile

4.3创建存储文件夹,保存 nginx 依赖的模块

4.4上传 nginx 依赖的模块

set-misc-nginx-module-0.29.tar.gz

lua-nginx-module-0.10.0.tar.gz

ngx_devel_kit-0.2.19.tar.gz

echo-nginx-module-0.58.tar.g

4.5将依赖的模块直接解压到储存文件

4.6安装 openresty

4.7安装 nginx

4.8编译 nginx 并支持其他模块

5.自定义采集

创建页面 index.html,添加埋点代码,放入 nginx 默认目录 nginx/html 下。

在默认目录 nginx/html 下添加一个数据采集脚本 ma.js。

修改 nginx 的配置文件,添加自定义相关业务逻辑。

启动 nginx

sbin/nginx -c conf/nginx.conf

通过游览器访问 nginx

观察自定义日志采集文件是否有对应的内容输出

tail -f logs/user_defined.log

此时还可以观察 nginx 默认的输出日志文件

tail -f logs/access.log

停止 nginx:

sbin/nginx –s stop

6.Socket机制

6.1 Socket,又称为套接字,用于描述 IP 地址和端口。应用程序通常通过 socket向网络发出请求或者应答网络请求。Socket 就是为网络编程提供的一种机制,在大数据领域在最开始数据的获取底层常常用到:

通信两端都有 socket;

网络通信其实就是 socket 之间的通信;

数据在两个 socket 之间通过 IO 传输。

网络编程也称作为 Socket 编程,套接字编程。

Socket 通信是 Client/Server 模型

6.2 基于UDP协议的socket通信(举例)

发送端:

// 创建发送端 Socket 服务对象

DatagramSocket dSocket = new DatagramSocket();

// 创建数据,打包数据

String message = "hello ,are u UDP ?";

byte[] bys = message.getBytes();

int length = bys.length;

InetAddress address = InetAddress.getByName("localhost");

int port = 12621;

DatagramPacket dPacket = new DatagramPacket(bys, length, address, port);

// 发送数据

dSocket.send(dPacket);

// 资源释放

dSocket.close();

接收端:

//创建接收端 Socket 服务对象

DatagramSocket dSocket = new DatagramSocket(12621);

//创建数据包(接收容器)

byte[] bys = new byte[1024];

DatagramPacket dPacket = new DatagramPacket(bys, bys.length);

//调用接收方法

dSocket.receive(dPacket);

//数据包解析

InetAddress address = dPacket.getAddress();

String hostAddress = address.getHostAddress();

byte[] data = dPacket.getData();

String message = new String(data);

System.out.println(hostAddress+"*********:"+message);

//资源释放

dSocket.close();

6.3 基于TCP协议的socket通信

服务端:

//建立服务端 socket 服务,并且监听一个端口

ServerSocket ss = new ServerSocket(13131);

//监听连接

Socket s = ss.accept();

//获取输入流,读取数据

InputStream inputStream = s.getInputStream();

byte[] bys = new byte[1024];

int len = inputStream.read(bys);

System.out.println(new String(bys, 0, len));

//关闭客户端

s.close();

//关闭服务端,一般服务端不关闭

ss.close();

客户端:

//创建客户端的 socket 服务,指定目的主机和端口

Socket s = new Socket("127.0.0.1", 13131);

//通过 socket 获取输出流,写数据

OutputStream outputStream = s.getOutputStream();

outputStream.write("hello ,this is tcp?".getBytes());

//释放资源

s.close();

猜你喜欢

转载自blog.csdn.net/jinyusheng_1991/article/details/82788602