怎样定位前端线上问题,一直以来,都是很头疼的问题,因为它发生于用户的一系列操作之后。错误的原因可能源于机型,网络环境,接口请求,复杂的操作行为等等,在我们想要去解决的时候很难复现出来,自然也就无法解决。 当然,这些问题并非不能克服,让我们来一起看看如何去监控并定位线上的问题吧。

  这是搭建前端监控系统的第五章,主要是介绍如何处理日志高并发上传的情况,跟着我一步步做,你也能搭建出一个属于自己的前端监控系统。

  如果感觉有帮助,或者有兴趣,请关注 or Star Me 。

  ============================================================================

  本文由 www.webfunny.cn 前端监控提供;只需要简单几步就可以搭建一套属于自己的前端监控系统,快来试试吧 ^ _ ^。

  ============================================================================

  随着监控日志搜集的内容越来越多,终于有一天,由于公司的一波推文,导致了日志的瞬间流量达到历史新高,以至于mysql的连接数过多,系统崩溃。 当然,作为日志上传的服务器,这个是必然会发生的情况,只是早晚的问题。 既然出现了并发问题,那么我们就着手来处理吧。日志上传如何缓解高并发的情况呢?我们分为三个小点来处理。

  •   增加日志上传的时间间隔

  正如我们所知,日志上传的时间间隔越长,用户在这个间隔内离开的几率就会越大,日志的漏传量就会增加,然后会导致日志的准确度降低。因为我们的探针是安插在浏览器内的,用户随时都有可能关掉,所以,理论上讲间隔越短越好,但这并不现实。所以这个需要在服务器的承受能力和日志的准确率之间做个权衡。由具体情况而定

  •   移除探针代码里冗余的参数,缩短参数名字的长度

  另外一点,每台服务器的硬盘有限,带宽有限,如果参数名字太长,参数内容冗余,对服务器的硬盘和带宽都是一种极大的浪费。虽然每条日志都不起眼,但是日志起量了以后,就是会是一笔非常庞大的开销。

  •   Nodejs + RabbitMq 搭建消息队列,缓解瞬间并发量  

  对于一个前端来说,要把消息队列搭建起来还确实费了一番周折。

  1)  ubantu16 安装RabbitMQ服务软件包,很多教程都要求安装erlang, 但是更新apt以后,直接执行安装命令,会自动安装erlang的核心组件的。(erlang始终无法成功安装,真心累。)

$ apt-get update
$ apt-get install rabbitmq-server // 安装
$ rabbitmq-plugins enable rabbitmq_management // 启动插件,浏览器才能访问

  正常情况下是直接成功的,直接访问ip端口号就可以打开了 http://IP:15672, 如下图:

  2)现在我们需要一个有效的登录名和密码,执行如下命令

$ rabbitmqctl add_user username password  // 设置用户名密码
$ rabbitmqctl set_user_tags username administrator // 设置为管理员身份
$ rabbitmqctl set_permissions -p / username ".*" ".*" ".*" //为用户设置读写等权限

  OK, 现在我们登录进来就是这样的界面,如此消息队列服务我们算是搭建完成了。

  3)消息服务启动了,那么如何存消息,如何取消息呢?如下图所示:

  

  我能够接触到的关于消息队列的应用场景实在有限,所以不能介绍更复杂的内容,大致的思维逻辑如上图1:有消息进来,先存入消息队列里,另一端再从队列去取出来,完成接下来的工作。从代码的角度来看如上图2:就是一个生产者和消费者的模式,生产者不停的向消息队列里生产消息,消费者在有需要的时候,从消息队列里取消息, 一旦完成消费,队列里便移除这个消息。消息的生产者和消费者互相没有感知,生产者产生过剩的消息都存放在消息队列里,由消费者慢慢消耗。以此来削峰填谷,达到处理高并发的目的。当然这都是我的浅显理解,但是也足以满足目前日志上传的需求了。

  OK、理论说完了,具体如何实现呢?

  

let amqp = require('amqplib');

module.exports = class RabbitMQ {
constructor() {
this.hosts = ["amqp://localhost"];
this.index = 0;
this.length = this.hosts.length;
this.open = amqp.connect(this.hosts[this.index]);
}
 // 消息生产者
sendQueueMsg(queueName, msg, errCallBack) {
let self = this;
self.open
.then(function (conn) {
return conn.createChannel();
})
.then(function (channel) {
return channel.assertQueue(queueName).then(function (ok) {
return channel.sendToQueue(queueName, new Buffer.from(msg), {
persistent: true
});
})
.then(function (data) {
if (data) {
errCallBack && errCallBack("success");
channel.close();
}
})
.catch(function () {
setTimeout(() => {
if (channel) {
channel.close();
}
}, 500)
});
})
.catch(function () {
      // 这里尝试备用连接,我就一个,所以就处理了
});
}
 
// 消息消费者
receiveQueueMsg(queueName, receiveCallBack, errCallBack) {
let self = this; self.open.then(function (conn) {
return conn.createChannel();
}).then(function (channel) {
return channel.assertQueue(queueName).then(function (ok) {
return channel.consume(queueName, function (msg) {
if (msg !== null) {
let data = msg.content.toString();
channel.ack(msg);
receiveCallBack && receiveCallBack(data);
}
}).finally(function () { });
})
})
.catch(function (e) {
errCallBack(e)
});
}
}

消息队列测试:每隔5秒发送一条消息,每隔5秒取出一条消息,成功

var mq = new RabbitMQ()
setInterval(function () {
mq.sendQueueMsg("queue1", "这是一个队列消息", function (err) {
console.log(err)
})
}, 5000) setInterval(function () {
mq.receiveQueueMsg("queue1", function (msg) {
console.log(msg)
}, function (error) {
console.log(error)
})
}, 5000)

RabbitMq消息队列使用中遇到的坑:

①   var mq = new RabbitMQ() 多次创建RabbitMQ对象,导致connections, channels, memory 暴增,服务器很快挂掉

②  生产者的channel忘记close, 导致channel太多,服务器超负荷

③   消费者的channel被close掉了,永远只能接收到一条消息,消息队列很快爆掉

最后是消息队列运行的状态:

OK、经过了这么一番处理,我们的日志上传应该能够承受住一定量的并发了,让我们拭目以待吧。

上一章:搭建前端监控系统(四)接口请求异常监控篇

参考: 架构设计之NodeJS操作消息队列RabbitMQ  Ubuntu上安装和使用RabbitMQ

搭建前端监控系统(五)Nodejs怎么搭建消息队列的更多相关文章

  1. 搭建前端监控系统(三)NodeJs服务器部署篇

    ===================================================================== 监控系统预览地址: DEMO地址    GIT代码仓库地址 ...

  2. 搭建前端监控系统(四)Js截图上报篇

    ===================================================================== 前端监控系统: DEMO地址  GIT代码仓库地址 ==== ...

  3. 搭建前端监控系统(二)JS错误监控篇

    ===================================================================== 前端性能监控系统: DEMO地址    GIT代码仓库地址 ...

  4. 从零开始搭建前端监控系统(三)——实现控制iframe前进后退

    前言 本系列文章旨在讲解如何从零开始搭建前端监控系统. 项目已经开源 项目地址: https://github.com/bombayjs/bombayjs (web sdk) https://gith ...

  5. 搭建前端监控系统(六)JS截屏和录屏篇

    怎样定位前端线上问题,一直以来,都是很头疼的问题,因为它发生于用户的一系列操作之后.错误的原因可能源于机型,网络环境,接口请求,复杂的操作行为等等,在我们想要去解决的时候很难复现出来,自然也就无法解决 ...

  6. 搭建zabbix监控系统详解

    搭建zabbix监控系统详解 文:warren   博文大纲:一.前言 二.zabbix监控架构三.搭建Zabbix监控服务器四.搭建过程中遇到有些服务无法正常启动的解决办法 一.前言 : 要想实时的 ...

  7. 使用monit搭建一个监控系统

    上周用monit搭建或者说定制了一个监控系统,来监控服务器发生事情.当然了主要是监控异常,因为我们的产品属于服务器类型,很多进程都daemon,要不停的运行.我们搭建监控目的不过是出现问题能够及时的知 ...

  8. Telegraf+InfluxDB+Grafana快速搭建实时监控系统 监控postgresql

    Telegraf+InfluxDB+Grafana快速搭建实时监控系统  监控postgresql

  9. Node.js躬行记(4)——自建前端监控系统

    这套前端监控系统用到的技术栈是:React+MongoDB+Node.js+Koa2.将性能和错误量化.因为自己平时喜欢吃菠萝,所以就取名叫菠萝系统.其实在很早以前就有这个想法,当时已经实现了前端的参 ...

随机推荐

  1. Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging

    1665 - Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT a ...

  2. ant design pro 的modal

    通常弹框位置有限,如果一行不下,就拆成两行,例如Table

  3. 10 使用 OpenCV、Kafka 和 Spark 技术进行视频流分析

    问题引起 基于分布式计算框架Spark的室内防盗预警系统 首先用摄像头录一段视频,存在电脑里,下载一个ffmpeg的软件对视频进行处理,处理成一张张图片,然后通过hadoop里边的一个文件系统叫做hd ...

  4. restQL 微服务查询语言

    restQL 是一个强大的微服务查询语言,类似sql,支持并行.链式.过滤.同时官方也提供了多种语言的实现 而且还有一个manger 与 graphql 以及Falcor的比较 以下是来自官方的比较说 ...

  5. Excel地址

    这题想了一个小时,也只得了66分,并且是一道看起来很简单的题…… 贴出代码,留给日后的自己 #include <stdio.h> #include <memory.h> #in ...

  6. V8 引擎如何进行垃圾内存的回收?

    JS 语言不像 C/C++, 让程序员自己去开辟或者释放内存,而是类似Java,采用自己的一套垃圾回收算法进行自动的内存管理.作为一名资深的前端工程师,对于JS内存回收的机制是需要非常清楚, 以便于在 ...

  7. 不了解这12个语法糖,别说你会Java!

    阅读本文大概需要 10 分钟. 作者:Hollis 本文从 Java 编译原理角度,深入字节码及 class 文件,抽丝剥茧,了解 Java 中的语法糖原理及用法,帮助大家在学会如何使用 Java 语 ...

  8. kudu 介绍

    kudu的好处: 快速的olap 列式存储,Hadoop parquet 的一种替代方案 对数据的顺序处理和随机处理都很高效 * High availability. Tablet Servers a ...

  9. Maven 教程(18)— 利用 Profile 构建不同环境的部署包

    原文地址:https://blog.csdn.net/liupeifeng3514/article/details/79776257 接上回继续,项目开发好以后,通常要在多个环境部署,象我们公司多达5 ...

  10. Linux命令中service的用法

    用途说明 service命令用于对系统服务进行管理,比如启动(start).停止(stop).重启(restart).查看状态(status)等.相关的命令还包括chkconfig.ntsysv等,c ...