数据与业务结合
- 当想到业务 与 数据结合 , 数据 与 业务结合
- 当看到业务的时候 必须要联想到对应的技术点—- 这才是学习大数据的核心内容
科技带来的发展
(1) 分布式系统
分布式项目
- CDN 动态资源服务器
- nginx 静态资源服务器
(2) 大数据分析系统
1. Web访问日志
日志是用来手机 用户浏览 点击 访问行为的数据
日志的收集 分两种形式
WEB服务器 例如 Httpd,nginx,tomcat 自带日志记录功能
自定义采集用户行为 例如 用jS代码监听用户的行为,ajax异步请求后台记录日志
—– 提示内容
1. Httpd : httpd是一款高效的服务器应用程序,隶属于apache项目
2. Nginx: 通常来说用作 1. 网页静态服务器 2. 反向代理 3. 虚拟主机
网站流量日志数据 自定义 采集 (重点)
1.原理分析
详细介绍
通常来说服务器A为显示数据, 服务器B为数据存储服务器
-
- 埋点 – 在page界面会创建预先写入一段js代码A_JS,A_JS代码会创建一个scrip标签B_JS,这个B_JS代码的src会指向服务器A,服务器会返回一个数据收集C_JS脚本,伪装成图片请求的将获取的参数通过http协议get请求的方式,将数据写入到服务器,解析存储到数据库中 。 服务器端会会相应一个1X1的像素图片,并且想cookie中写入数据用与标识用户
—提示
之所以会伪装成图片请求是因为Ajax不支持跨域请求,通常来说会伪装成图片请求,但是并不是必须的。例如Google 京东都是这么做的 。
GET /log.gif?t=item.010001&m=UA-J2011-1&pin=-&uid=1679790178&sid=1679790178|12&v=je=1 sc=24−bit sr=1600x900 ul=zh−cn cs=GBK
2. 设计实现
- 下面的内容是一个整体流程
2.1 确定收集信息
确定日志的渠道 是web日志 自定义日志
确定收集的信息
2.2 确定埋点代码
<script type="text/javascript">
var _maq = _maq || []; //_maq 是全局数组
_maq.push(['_setAccount', 'UA-XXXXX-X']); //向_map集合中存储数组
//自调用匿名函数用于初始化,而且只会执行一次
(function() {
var ma = document.createElement('script');
ma.type ='text/javascript';
ma.async = true; //ma.async = true 的意思是异步调用外部js文件,防止在加载过程中造成中断这个是H5的新特性
ma.src = ('https:' == document.location.protocol ?'https://ssl' : 'http://www') + '.google-analytics.com/ma.js'; //指定要从B 服务器 加载的src
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ma, s); //把ma加入到s中
})();
</script>
– 提示 js自调用匿名函数
匿名函数
(function(){})() 会自动调用第一对括号内部的函数
2.3 前端数据收集脚本
1. 前端收集脚本要做的事情
1. 通过浏览器内置javascript对象收集信息
例如 document.title,document.cookie,url document.referrer
2. 解析_maq 数组中的参数内容,添加到 var params = {}
3. 将所有数据参数进行拼接
4. 请求后端脚本数据
因为ajax不能进行跨域请求,因此通常用JS请求服务端数据,伪装成请求一个gif图片,将数据发送服务端
<img src="www.ruirui.com/log.gif?ctime=startTime&type="chrome"" />
ma.js示例代码如下 大家一定要注意这个整体就是匿名自调函数
function () {
var params = {}; //1. Document 对象数据,这个是定义一个数组
//2.通过浏览器内置对象获取属性
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 || '';
}
//3.解析_maq 数组,将标签中内容复制给params数组
if(_maq) {
for(var i in _maq) {
switch(_maq[i][0]) {
case '_setAccount':
params.account = _maq[i][1];
break;
default:
break;
}
}
}
//4.拼接参数串
var args = '';
for(var i in params) {
if(args != '') {
args += '&';
}
args += i + '=' + encodeURIComponent(params[i]); //中文装吗
}
//5. 通过 Image 对象请求后端脚本,像素是1X1
var img = new Image(1, 1);
img.src = ' http://xxx.xxxxx.xxxxx/log.gif? ' + args;
})();
2.4 后端脚本
- 获取日志信息 将web日志 与 请求过来的参数 日志进行拼接 生成信息 写入到日志中
2.5 日志格式
日志的分割不能影响程序的解析。具体的分割根据业务的需求,通常来说会按照下面的方式进行分割
固定数量的字符、制表符分隔符、空格分隔符、其他一个或多个字符、特定的开始和结束文本
2.6 日志切分
如果日志不进行切分的话,会造一个文本有好几个G,不比那与管理通常来说都是安装时间来切分,按照小时,天,通常的做发是调用crontab 定时的脚本 。
_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
这个脚本将 ma.log 移动到指定文件夹并重命名为 ma-{yyyymmddhh}.log,
然后向 nginx 发送 USR1 信号令其重新打开日志文件。
USR1 通常被用来告知应用程序重载配置文件, 向服务器发送一个 USR1 信号
将导致以下步骤的发生:停止接受新的连接,等待当前连接停止,重新载入配置
文件,重新打开日志文件,重启服务器,从而实现相对平滑的不关机的更改。
cat ${_prefix}/logs/nginx.pid 取 nginx 的进程号
然后再/etc/crontab 里加入一行:
59 * * * * root /path/to/directory/rotatelog.sh
在每个小时的 59 分启动这个脚本进行日志轮转操作。